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;
40 const struct devlink_linecard_ops *ops;
42 enum devlink_linecard_state state;
43 struct mutex state_lock; /* Protects state */
45 struct devlink_linecard_type *types;
46 unsigned int types_count;
47 struct devlink *nested_devlink;
51 * struct devlink_resource - devlink resource
52 * @name: name of the resource
53 * @id: id, per devlink instance
54 * @size: size of the resource
55 * @size_new: updated size of the resource, reload is needed
56 * @size_valid: valid in case the total size of the resource is valid
57 * including its children
58 * @parent: parent resource
59 * @size_params: size parameters
61 * @resource_list: list of child resources
62 * @occ_get: occupancy getter callback
63 * @occ_get_priv: occupancy getter callback priv
65 struct devlink_resource {
71 struct devlink_resource *parent;
72 struct devlink_resource_size_params size_params;
73 struct list_head list;
74 struct list_head resource_list;
75 devlink_resource_occ_get_t *occ_get;
79 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
81 .name = "destination mac",
82 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
87 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
89 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
90 .fields = devlink_dpipe_fields_ethernet,
91 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
94 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
96 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
98 .name = "destination ip",
99 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
104 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
106 .id = DEVLINK_DPIPE_HEADER_IPV4,
107 .fields = devlink_dpipe_fields_ipv4,
108 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
111 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
113 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
115 .name = "destination ip",
116 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
121 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
123 .id = DEVLINK_DPIPE_HEADER_IPV6,
124 .fields = devlink_dpipe_fields_ipv6,
125 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
128 EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
130 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
131 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
132 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
134 #define DEVLINK_PORT_FN_CAPS_VALID_MASK \
135 (_BITUL(__DEVLINK_PORT_FN_ATTR_CAPS_MAX) - 1)
137 static const struct nla_policy devlink_function_nl_policy[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1] = {
138 [DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] = { .type = NLA_BINARY },
139 [DEVLINK_PORT_FN_ATTR_STATE] =
140 NLA_POLICY_RANGE(NLA_U8, DEVLINK_PORT_FN_STATE_INACTIVE,
141 DEVLINK_PORT_FN_STATE_ACTIVE),
142 [DEVLINK_PORT_FN_ATTR_CAPS] =
143 NLA_POLICY_BITFIELD32(DEVLINK_PORT_FN_CAPS_VALID_MASK),
146 static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = {
147 [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG },
150 #define ASSERT_DEVLINK_PORT_REGISTERED(devlink_port) \
151 WARN_ON_ONCE(!(devlink_port)->registered)
152 #define ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port) \
153 WARN_ON_ONCE((devlink_port)->registered)
154 #define ASSERT_DEVLINK_PORT_INITIALIZED(devlink_port) \
155 WARN_ON_ONCE(!(devlink_port)->initialized)
157 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
158 unsigned int port_index)
160 return xa_load(&devlink->ports, port_index);
163 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
164 struct nlattr **attrs)
166 if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
167 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
168 struct devlink_port *devlink_port;
170 devlink_port = devlink_port_get_by_index(devlink, port_index);
172 return ERR_PTR(-ENODEV);
175 return ERR_PTR(-EINVAL);
178 struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
179 struct genl_info *info)
181 return devlink_port_get_from_attrs(devlink, info->attrs);
185 devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
187 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
191 devlink_rate_is_node(struct devlink_rate *devlink_rate)
193 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
196 static struct devlink_rate *
197 devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
199 struct devlink_rate *devlink_rate;
200 struct devlink_port *devlink_port;
202 devlink_port = devlink_port_get_from_attrs(devlink, info->attrs);
203 if (IS_ERR(devlink_port))
204 return ERR_CAST(devlink_port);
205 devlink_rate = devlink_port->devlink_rate;
206 return devlink_rate ?: ERR_PTR(-ENODEV);
209 static struct devlink_rate *
210 devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
212 static struct devlink_rate *devlink_rate;
214 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
215 if (devlink_rate_is_node(devlink_rate) &&
216 !strcmp(node_name, devlink_rate->name))
219 return ERR_PTR(-ENODEV);
222 static struct devlink_rate *
223 devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
225 const char *rate_node_name;
228 if (!attrs[DEVLINK_ATTR_RATE_NODE_NAME])
229 return ERR_PTR(-EINVAL);
230 rate_node_name = nla_data(attrs[DEVLINK_ATTR_RATE_NODE_NAME]);
231 len = strlen(rate_node_name);
232 /* Name cannot be empty or decimal number */
233 if (!len || strspn(rate_node_name, "0123456789") == len)
234 return ERR_PTR(-EINVAL);
236 return devlink_rate_node_get_by_name(devlink, rate_node_name);
239 struct devlink_rate *
240 devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
242 return devlink_rate_node_get_from_attrs(devlink, info->attrs);
245 struct devlink_rate *
246 devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
248 struct nlattr **attrs = info->attrs;
250 if (attrs[DEVLINK_ATTR_PORT_INDEX])
251 return devlink_rate_leaf_get_from_info(devlink, info);
252 else if (attrs[DEVLINK_ATTR_RATE_NODE_NAME])
253 return devlink_rate_node_get_from_info(devlink, info);
255 return ERR_PTR(-EINVAL);
258 static struct devlink_linecard *
259 devlink_linecard_get_by_index(struct devlink *devlink,
260 unsigned int linecard_index)
262 struct devlink_linecard *devlink_linecard;
264 list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) {
265 if (devlink_linecard->index == linecard_index)
266 return devlink_linecard;
271 static bool devlink_linecard_index_exists(struct devlink *devlink,
272 unsigned int linecard_index)
274 return devlink_linecard_get_by_index(devlink, linecard_index);
277 static struct devlink_linecard *
278 devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
280 if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) {
281 u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]);
282 struct devlink_linecard *linecard;
284 linecard = devlink_linecard_get_by_index(devlink, linecard_index);
286 return ERR_PTR(-ENODEV);
289 return ERR_PTR(-EINVAL);
292 struct devlink_linecard *
293 devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
295 return devlink_linecard_get_from_attrs(devlink, info->attrs);
299 struct list_head list;
302 u16 ingress_pools_count;
303 u16 egress_pools_count;
304 u16 ingress_tc_count;
308 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
310 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
313 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
314 unsigned int sb_index)
316 struct devlink_sb *devlink_sb;
318 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
319 if (devlink_sb->index == sb_index)
325 static bool devlink_sb_index_exists(struct devlink *devlink,
326 unsigned int sb_index)
328 return devlink_sb_get_by_index(devlink, sb_index);
331 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
332 struct nlattr **attrs)
334 if (attrs[DEVLINK_ATTR_SB_INDEX]) {
335 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
336 struct devlink_sb *devlink_sb;
338 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
340 return ERR_PTR(-ENODEV);
343 return ERR_PTR(-EINVAL);
346 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
347 struct genl_info *info)
349 return devlink_sb_get_from_attrs(devlink, info->attrs);
352 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
353 struct nlattr **attrs,
358 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
361 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
362 if (val >= devlink_sb_pool_count(devlink_sb))
368 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
369 struct genl_info *info,
372 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
377 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
378 enum devlink_sb_pool_type *p_pool_type)
382 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
385 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
386 if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
387 val != DEVLINK_SB_POOL_TYPE_EGRESS)
394 devlink_sb_pool_type_get_from_info(struct genl_info *info,
395 enum devlink_sb_pool_type *p_pool_type)
397 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
401 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
402 enum devlink_sb_threshold_type *p_th_type)
406 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
409 val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
410 if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
411 val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
418 devlink_sb_th_type_get_from_info(struct genl_info *info,
419 enum devlink_sb_threshold_type *p_th_type)
421 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
425 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
426 struct nlattr **attrs,
427 enum devlink_sb_pool_type pool_type,
432 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
435 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
436 if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
437 val >= devlink_sb->ingress_tc_count)
439 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
440 val >= devlink_sb->egress_tc_count)
446 static void devlink_port_fn_cap_fill(struct nla_bitfield32 *caps,
447 u32 cap, bool is_enable)
449 caps->selector |= cap;
454 static int devlink_port_fn_roce_fill(const struct devlink_ops *ops,
455 struct devlink_port *devlink_port,
456 struct nla_bitfield32 *caps,
457 struct netlink_ext_ack *extack)
462 if (!ops->port_fn_roce_get)
465 err = ops->port_fn_roce_get(devlink_port, &is_enable, extack);
467 if (err == -EOPNOTSUPP)
472 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_ROCE, is_enable);
476 static int devlink_port_fn_migratable_fill(const struct devlink_ops *ops,
477 struct devlink_port *devlink_port,
478 struct nla_bitfield32 *caps,
479 struct netlink_ext_ack *extack)
484 if (!ops->port_fn_migratable_get ||
485 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF)
488 err = ops->port_fn_migratable_get(devlink_port, &is_enable, extack);
490 if (err == -EOPNOTSUPP)
495 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_MIGRATABLE, is_enable);
499 static int devlink_port_fn_caps_fill(const struct devlink_ops *ops,
500 struct devlink_port *devlink_port,
502 struct netlink_ext_ack *extack,
505 struct nla_bitfield32 caps = {};
508 err = devlink_port_fn_roce_fill(ops, devlink_port, &caps, extack);
512 err = devlink_port_fn_migratable_fill(ops, devlink_port, &caps, extack);
518 err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value,
528 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
529 struct genl_info *info,
530 enum devlink_sb_pool_type pool_type,
533 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
534 pool_type, p_tc_index);
537 struct devlink_region {
538 struct devlink *devlink;
539 struct devlink_port *port;
540 struct list_head list;
542 const struct devlink_region_ops *ops;
543 const struct devlink_port_region_ops *port_ops;
545 struct mutex snapshot_lock; /* protects snapshot_list,
546 * max_snapshots and cur_snapshots
549 struct list_head snapshot_list;
555 struct devlink_snapshot {
556 struct list_head list;
557 struct devlink_region *region;
562 static struct devlink_region *
563 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
565 struct devlink_region *region;
567 list_for_each_entry(region, &devlink->region_list, list)
568 if (!strcmp(region->ops->name, region_name))
574 static struct devlink_region *
575 devlink_port_region_get_by_name(struct devlink_port *port,
576 const char *region_name)
578 struct devlink_region *region;
580 list_for_each_entry(region, &port->region_list, list)
581 if (!strcmp(region->ops->name, region_name))
587 static struct devlink_snapshot *
588 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
590 struct devlink_snapshot *snapshot;
592 list_for_each_entry(snapshot, ®ion->snapshot_list, list)
593 if (snapshot->id == id)
599 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
601 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
603 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
608 static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink)
610 struct nlattr *nested_attr;
612 nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK);
615 if (devlink_nl_put_handle(msg, devlink))
616 goto nla_put_failure;
618 nla_nest_end(msg, nested_attr);
622 nla_nest_cancel(msg, nested_attr);
626 int devlink_nl_port_handle_fill(struct sk_buff *msg, struct devlink_port *devlink_port)
628 if (devlink_nl_put_handle(msg, devlink_port->devlink))
630 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
635 size_t devlink_nl_port_handle_size(struct devlink_port *devlink_port)
637 struct devlink *devlink = devlink_port->devlink;
639 return nla_total_size(strlen(devlink->dev->bus->name) + 1) /* DEVLINK_ATTR_BUS_NAME */
640 + nla_total_size(strlen(dev_name(devlink->dev)) + 1) /* DEVLINK_ATTR_DEV_NAME */
641 + nla_total_size(4); /* DEVLINK_ATTR_PORT_INDEX */
644 struct devlink_reload_combination {
645 enum devlink_reload_action action;
646 enum devlink_reload_limit limit;
649 static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
651 /* can't reinitialize driver with no down time */
652 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
653 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
658 devlink_reload_combination_is_invalid(enum devlink_reload_action action,
659 enum devlink_reload_limit limit)
663 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)
664 if (devlink_reload_invalid_combinations[i].action == action &&
665 devlink_reload_invalid_combinations[i].limit == limit)
671 devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
673 return test_bit(action, &devlink->ops->reload_actions);
677 devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
679 return test_bit(limit, &devlink->ops->reload_limits);
682 static int devlink_reload_stat_put(struct sk_buff *msg,
683 enum devlink_reload_limit limit, u32 value)
685 struct nlattr *reload_stats_entry;
687 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY);
688 if (!reload_stats_entry)
691 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_STATS_LIMIT, limit) ||
692 nla_put_u32(msg, DEVLINK_ATTR_RELOAD_STATS_VALUE, value))
693 goto nla_put_failure;
694 nla_nest_end(msg, reload_stats_entry);
698 nla_nest_cancel(msg, reload_stats_entry);
702 static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
704 struct nlattr *reload_stats_attr, *act_info, *act_stats;
709 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS);
711 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS);
713 if (!reload_stats_attr)
716 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
718 !devlink_reload_action_is_supported(devlink, i)) ||
719 i == DEVLINK_RELOAD_ACTION_UNSPEC)
721 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
723 goto nla_put_failure;
725 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_ACTION, i))
726 goto action_info_nest_cancel;
727 act_stats = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_STATS);
729 goto action_info_nest_cancel;
731 for (j = 0; j <= DEVLINK_RELOAD_LIMIT_MAX; j++) {
732 /* Remote stats are shown even if not locally supported.
733 * Stats of actions with unspecified limit are shown
734 * though drivers don't need to register unspecified
737 if ((!is_remote && j != DEVLINK_RELOAD_LIMIT_UNSPEC &&
738 !devlink_reload_limit_is_supported(devlink, j)) ||
739 devlink_reload_combination_is_invalid(i, j))
742 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i;
744 value = devlink->stats.reload_stats[stat_idx];
746 value = devlink->stats.remote_reload_stats[stat_idx];
747 if (devlink_reload_stat_put(msg, j, value))
748 goto action_stats_nest_cancel;
750 nla_nest_end(msg, act_stats);
751 nla_nest_end(msg, act_info);
753 nla_nest_end(msg, reload_stats_attr);
756 action_stats_nest_cancel:
757 nla_nest_cancel(msg, act_stats);
758 action_info_nest_cancel:
759 nla_nest_cancel(msg, act_info);
761 nla_nest_cancel(msg, reload_stats_attr);
765 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
766 enum devlink_command cmd, u32 portid,
769 struct nlattr *dev_stats;
772 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
776 if (devlink_nl_put_handle(msg, devlink))
777 goto nla_put_failure;
778 if (nla_put_u8(msg, DEVLINK_ATTR_RELOAD_FAILED, devlink->reload_failed))
779 goto nla_put_failure;
781 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS);
783 goto nla_put_failure;
785 if (devlink_reload_stats_put(msg, devlink, false))
786 goto dev_stats_nest_cancel;
787 if (devlink_reload_stats_put(msg, devlink, true))
788 goto dev_stats_nest_cancel;
790 nla_nest_end(msg, dev_stats);
791 genlmsg_end(msg, hdr);
794 dev_stats_nest_cancel:
795 nla_nest_cancel(msg, dev_stats);
797 genlmsg_cancel(msg, hdr);
801 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
806 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
807 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
809 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
813 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
819 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
820 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
823 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
824 struct devlink_port *devlink_port)
826 struct devlink_port_attrs *attrs = &devlink_port->attrs;
828 if (!devlink_port->attrs_set)
831 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
834 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
836 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
838 switch (devlink_port->attrs.flavour) {
839 case DEVLINK_PORT_FLAVOUR_PCI_PF:
840 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
841 attrs->pci_pf.controller) ||
842 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_pf.pf))
844 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
847 case DEVLINK_PORT_FLAVOUR_PCI_VF:
848 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
849 attrs->pci_vf.controller) ||
850 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER, attrs->pci_vf.pf) ||
851 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_VF_NUMBER, attrs->pci_vf.vf))
853 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
856 case DEVLINK_PORT_FLAVOUR_PCI_SF:
857 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_CONTROLLER_NUMBER,
858 attrs->pci_sf.controller) ||
859 nla_put_u16(msg, DEVLINK_ATTR_PORT_PCI_PF_NUMBER,
861 nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
865 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
866 case DEVLINK_PORT_FLAVOUR_CPU:
867 case DEVLINK_PORT_FLAVOUR_DSA:
868 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER,
869 attrs->phys.port_number))
873 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
874 attrs->phys.port_number))
876 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
877 attrs->phys.split_subport_number))
886 static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops,
887 struct devlink_port *port,
889 struct netlink_ext_ack *extack,
892 u8 hw_addr[MAX_ADDR_LEN];
896 if (!ops->port_function_hw_addr_get)
899 err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len,
902 if (err == -EOPNOTSUPP)
906 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
913 static int devlink_nl_rate_fill(struct sk_buff *msg,
914 struct devlink_rate *devlink_rate,
915 enum devlink_command cmd, u32 portid, u32 seq,
916 int flags, struct netlink_ext_ack *extack)
918 struct devlink *devlink = devlink_rate->devlink;
921 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
925 if (devlink_nl_put_handle(msg, devlink))
926 goto nla_put_failure;
928 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
929 goto nla_put_failure;
931 if (devlink_rate_is_leaf(devlink_rate)) {
932 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
933 devlink_rate->devlink_port->index))
934 goto nla_put_failure;
935 } else if (devlink_rate_is_node(devlink_rate)) {
936 if (nla_put_string(msg, DEVLINK_ATTR_RATE_NODE_NAME,
938 goto nla_put_failure;
941 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_SHARE,
942 devlink_rate->tx_share, DEVLINK_ATTR_PAD))
943 goto nla_put_failure;
945 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_RATE_TX_MAX,
946 devlink_rate->tx_max, DEVLINK_ATTR_PAD))
947 goto nla_put_failure;
949 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY,
950 devlink_rate->tx_priority))
951 goto nla_put_failure;
953 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT,
954 devlink_rate->tx_weight))
955 goto nla_put_failure;
957 if (devlink_rate->parent)
958 if (nla_put_string(msg, DEVLINK_ATTR_RATE_PARENT_NODE_NAME,
959 devlink_rate->parent->name))
960 goto nla_put_failure;
962 genlmsg_end(msg, hdr);
966 genlmsg_cancel(msg, hdr);
971 devlink_port_fn_state_valid(enum devlink_port_fn_state state)
973 return state == DEVLINK_PORT_FN_STATE_INACTIVE ||
974 state == DEVLINK_PORT_FN_STATE_ACTIVE;
978 devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
980 return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED ||
981 opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
984 static int devlink_port_fn_state_fill(const struct devlink_ops *ops,
985 struct devlink_port *port,
987 struct netlink_ext_ack *extack,
990 enum devlink_port_fn_opstate opstate;
991 enum devlink_port_fn_state state;
994 if (!ops->port_fn_state_get)
997 err = ops->port_fn_state_get(port, &state, &opstate, extack);
999 if (err == -EOPNOTSUPP)
1003 if (!devlink_port_fn_state_valid(state)) {
1005 NL_SET_ERR_MSG_MOD(extack, "Invalid state read from driver");
1008 if (!devlink_port_fn_opstate_valid(opstate)) {
1010 NL_SET_ERR_MSG_MOD(extack,
1011 "Invalid operational state read from driver");
1014 if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) ||
1015 nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate))
1017 *msg_updated = true;
1022 devlink_port_fn_mig_set(struct devlink_port *devlink_port, bool enable,
1023 struct netlink_ext_ack *extack)
1025 const struct devlink_ops *ops = devlink_port->devlink->ops;
1027 return ops->port_fn_migratable_set(devlink_port, enable, extack);
1031 devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable,
1032 struct netlink_ext_ack *extack)
1034 const struct devlink_ops *ops = devlink_port->devlink->ops;
1036 return ops->port_fn_roce_set(devlink_port, enable, extack);
1039 static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
1040 const struct nlattr *attr,
1041 struct netlink_ext_ack *extack)
1043 struct nla_bitfield32 caps;
1047 caps = nla_get_bitfield32(attr);
1048 caps_value = caps.value & caps.selector;
1049 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE) {
1050 err = devlink_port_fn_roce_set(devlink_port,
1051 caps_value & DEVLINK_PORT_FN_CAP_ROCE,
1056 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
1057 err = devlink_port_fn_mig_set(devlink_port, caps_value &
1058 DEVLINK_PORT_FN_CAP_MIGRATABLE,
1067 devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
1068 struct netlink_ext_ack *extack)
1070 const struct devlink_ops *ops;
1071 struct nlattr *function_attr;
1072 bool msg_updated = false;
1075 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
1079 ops = port->devlink->ops;
1080 err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack,
1084 err = devlink_port_fn_caps_fill(ops, port, msg, extack,
1088 err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated);
1090 if (err || !msg_updated)
1091 nla_nest_cancel(msg, function_attr);
1093 nla_nest_end(msg, function_attr);
1097 static int devlink_nl_port_fill(struct sk_buff *msg,
1098 struct devlink_port *devlink_port,
1099 enum devlink_command cmd, u32 portid, u32 seq,
1100 int flags, struct netlink_ext_ack *extack)
1102 struct devlink *devlink = devlink_port->devlink;
1105 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1109 if (devlink_nl_put_handle(msg, devlink))
1110 goto nla_put_failure;
1111 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1112 goto nla_put_failure;
1114 spin_lock_bh(&devlink_port->type_lock);
1115 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
1116 goto nla_put_failure_type_locked;
1117 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
1118 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
1119 devlink_port->desired_type))
1120 goto nla_put_failure_type_locked;
1121 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
1122 if (devlink_port->type_eth.netdev &&
1123 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
1124 devlink_port->type_eth.ifindex) ||
1125 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
1126 devlink_port->type_eth.ifname)))
1127 goto nla_put_failure_type_locked;
1129 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
1130 struct ib_device *ibdev = devlink_port->type_ib.ibdev;
1133 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
1135 goto nla_put_failure_type_locked;
1137 spin_unlock_bh(&devlink_port->type_lock);
1138 if (devlink_nl_port_attrs_put(msg, devlink_port))
1139 goto nla_put_failure;
1140 if (devlink_nl_port_function_attrs_put(msg, devlink_port, extack))
1141 goto nla_put_failure;
1142 if (devlink_port->linecard &&
1143 nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX,
1144 devlink_port->linecard->index))
1145 goto nla_put_failure;
1147 genlmsg_end(msg, hdr);
1150 nla_put_failure_type_locked:
1151 spin_unlock_bh(&devlink_port->type_lock);
1153 genlmsg_cancel(msg, hdr);
1157 static void devlink_port_notify(struct devlink_port *devlink_port,
1158 enum devlink_command cmd)
1160 struct devlink *devlink = devlink_port->devlink;
1161 struct sk_buff *msg;
1164 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
1166 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1169 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1173 err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
1179 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1180 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1183 static void devlink_rate_notify(struct devlink_rate *devlink_rate,
1184 enum devlink_command cmd)
1186 struct devlink *devlink = devlink_rate->devlink;
1187 struct sk_buff *msg;
1190 WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
1192 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1195 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1199 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
1205 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1206 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1210 devlink_nl_cmd_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1211 struct netlink_callback *cb)
1213 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1214 struct devlink_rate *devlink_rate;
1218 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
1219 enum devlink_command cmd = DEVLINK_CMD_RATE_NEW;
1220 u32 id = NETLINK_CB(cb->skb).portid;
1222 if (idx < state->idx) {
1226 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
1239 const struct devlink_gen_cmd devl_gen_rate_get = {
1240 .dump_one = devlink_nl_cmd_rate_get_dump_one,
1243 static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb,
1244 struct genl_info *info)
1246 struct devlink_rate *devlink_rate = info->user_ptr[1];
1247 struct sk_buff *msg;
1250 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1254 err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
1255 info->snd_portid, info->snd_seq, 0,
1262 return genlmsg_reply(msg, info);
1266 devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
1267 struct devlink_rate *parent)
1270 if (parent == devlink_rate)
1272 parent = parent->parent;
1277 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
1279 struct devlink *devlink = info->user_ptr[0];
1280 struct sk_buff *msg;
1283 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1287 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1288 info->snd_portid, info->snd_seq, 0);
1294 return genlmsg_reply(msg, info);
1298 devlink_nl_cmd_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1299 struct netlink_callback *cb)
1301 return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1302 NETLINK_CB(cb->skb).portid,
1303 cb->nlh->nlmsg_seq, NLM_F_MULTI);
1306 const struct devlink_gen_cmd devl_gen_inst = {
1307 .dump_one = devlink_nl_cmd_get_dump_one,
1310 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
1311 struct genl_info *info)
1313 struct devlink_port *devlink_port = info->user_ptr[1];
1314 struct sk_buff *msg;
1317 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1321 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
1322 info->snd_portid, info->snd_seq, 0,
1329 return genlmsg_reply(msg, info);
1333 devlink_nl_cmd_port_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1334 struct netlink_callback *cb)
1336 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1337 struct devlink_port *devlink_port;
1338 unsigned long port_index;
1342 xa_for_each(&devlink->ports, port_index, devlink_port) {
1343 if (idx < state->idx) {
1347 err = devlink_nl_port_fill(msg, devlink_port,
1349 NETLINK_CB(cb->skb).portid,
1351 NLM_F_MULTI, cb->extack);
1362 const struct devlink_gen_cmd devl_gen_port = {
1363 .dump_one = devlink_nl_cmd_port_get_dump_one,
1366 static int devlink_port_type_set(struct devlink_port *devlink_port,
1367 enum devlink_port_type port_type)
1372 if (!devlink_port->devlink->ops->port_type_set)
1375 if (port_type == devlink_port->type)
1378 err = devlink_port->devlink->ops->port_type_set(devlink_port,
1383 devlink_port->desired_type = port_type;
1384 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1388 static int devlink_port_function_hw_addr_set(struct devlink_port *port,
1389 const struct nlattr *attr,
1390 struct netlink_ext_ack *extack)
1392 const struct devlink_ops *ops = port->devlink->ops;
1396 hw_addr = nla_data(attr);
1397 hw_addr_len = nla_len(attr);
1398 if (hw_addr_len > MAX_ADDR_LEN) {
1399 NL_SET_ERR_MSG_MOD(extack, "Port function hardware address too long");
1402 if (port->type == DEVLINK_PORT_TYPE_ETH) {
1403 if (hw_addr_len != ETH_ALEN) {
1404 NL_SET_ERR_MSG_MOD(extack, "Address must be 6 bytes for Ethernet device");
1407 if (!is_unicast_ether_addr(hw_addr)) {
1408 NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
1413 return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len,
1417 static int devlink_port_fn_state_set(struct devlink_port *port,
1418 const struct nlattr *attr,
1419 struct netlink_ext_ack *extack)
1421 enum devlink_port_fn_state state;
1422 const struct devlink_ops *ops;
1424 state = nla_get_u8(attr);
1425 ops = port->devlink->ops;
1426 return ops->port_fn_state_set(port, state, extack);
1429 static int devlink_port_function_validate(struct devlink_port *devlink_port,
1431 struct netlink_ext_ack *extack)
1433 const struct devlink_ops *ops = devlink_port->devlink->ops;
1434 struct nlattr *attr;
1436 if (tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR] &&
1437 !ops->port_function_hw_addr_set) {
1438 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
1439 "Port doesn't support function attributes");
1442 if (tb[DEVLINK_PORT_FN_ATTR_STATE] && !ops->port_fn_state_set) {
1443 NL_SET_ERR_MSG_ATTR(extack, tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR],
1444 "Function does not support state setting");
1447 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1449 struct nla_bitfield32 caps;
1451 caps = nla_get_bitfield32(attr);
1452 if (caps.selector & DEVLINK_PORT_FN_CAP_ROCE &&
1453 !ops->port_fn_roce_set) {
1454 NL_SET_ERR_MSG_ATTR(extack, attr,
1455 "Port doesn't support RoCE function attribute");
1458 if (caps.selector & DEVLINK_PORT_FN_CAP_MIGRATABLE) {
1459 if (!ops->port_fn_migratable_set) {
1460 NL_SET_ERR_MSG_ATTR(extack, attr,
1461 "Port doesn't support migratable function attribute");
1464 if (devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF) {
1465 NL_SET_ERR_MSG_ATTR(extack, attr,
1466 "migratable function attribute supported for VFs only");
1474 static int devlink_port_function_set(struct devlink_port *port,
1475 const struct nlattr *attr,
1476 struct netlink_ext_ack *extack)
1478 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
1481 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
1482 devlink_function_nl_policy, extack);
1484 NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
1488 err = devlink_port_function_validate(port, tb, extack);
1492 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
1494 err = devlink_port_function_hw_addr_set(port, attr, extack);
1499 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1501 err = devlink_port_fn_caps_set(port, attr, extack);
1506 /* Keep this as the last function attribute set, so that when
1507 * multiple port function attributes are set along with state,
1508 * Those can be applied first before activating the state.
1510 attr = tb[DEVLINK_PORT_FN_ATTR_STATE];
1512 err = devlink_port_fn_state_set(port, attr, extack);
1515 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
1519 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
1520 struct genl_info *info)
1522 struct devlink_port *devlink_port = info->user_ptr[1];
1525 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
1526 enum devlink_port_type port_type;
1528 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
1529 err = devlink_port_type_set(devlink_port, port_type);
1534 if (info->attrs[DEVLINK_ATTR_PORT_FUNCTION]) {
1535 struct nlattr *attr = info->attrs[DEVLINK_ATTR_PORT_FUNCTION];
1536 struct netlink_ext_ack *extack = info->extack;
1538 err = devlink_port_function_set(devlink_port, attr, extack);
1546 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
1547 struct genl_info *info)
1549 struct devlink_port *devlink_port = info->user_ptr[1];
1550 struct devlink *devlink = info->user_ptr[0];
1553 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT))
1555 if (!devlink->ops->port_split)
1558 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
1560 if (!devlink_port->attrs.splittable) {
1561 /* Split ports cannot be split. */
1562 if (devlink_port->attrs.split)
1563 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split further");
1565 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split");
1569 if (count < 2 || !is_power_of_2(count) || count > devlink_port->attrs.lanes) {
1570 NL_SET_ERR_MSG_MOD(info->extack, "Invalid split count");
1574 return devlink->ops->port_split(devlink, devlink_port, count,
1578 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
1579 struct genl_info *info)
1581 struct devlink_port *devlink_port = info->user_ptr[1];
1582 struct devlink *devlink = info->user_ptr[0];
1584 if (!devlink->ops->port_unsplit)
1586 return devlink->ops->port_unsplit(devlink, devlink_port, info->extack);
1589 static int devlink_port_new_notify(struct devlink *devlink,
1590 unsigned int port_index,
1591 struct genl_info *info)
1593 struct devlink_port *devlink_port;
1594 struct sk_buff *msg;
1597 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1601 lockdep_assert_held(&devlink->lock);
1602 devlink_port = devlink_port_get_by_index(devlink, port_index);
1603 if (!devlink_port) {
1608 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
1609 info->snd_portid, info->snd_seq, 0, NULL);
1613 return genlmsg_reply(msg, info);
1620 static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
1621 struct genl_info *info)
1623 struct netlink_ext_ack *extack = info->extack;
1624 struct devlink_port_new_attrs new_attrs = {};
1625 struct devlink *devlink = info->user_ptr[0];
1626 unsigned int new_port_index;
1629 if (!devlink->ops->port_new || !devlink->ops->port_del)
1632 if (!info->attrs[DEVLINK_ATTR_PORT_FLAVOUR] ||
1633 !info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]) {
1634 NL_SET_ERR_MSG_MOD(extack, "Port flavour or PCI PF are not specified");
1637 new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]);
1639 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]);
1641 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
1642 /* Port index of the new port being created by driver. */
1643 new_attrs.port_index =
1644 nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1645 new_attrs.port_index_valid = true;
1647 if (info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]) {
1648 new_attrs.controller =
1649 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_CONTROLLER_NUMBER]);
1650 new_attrs.controller_valid = true;
1652 if (new_attrs.flavour == DEVLINK_PORT_FLAVOUR_PCI_SF &&
1653 info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]) {
1654 new_attrs.sfnum = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_PCI_SF_NUMBER]);
1655 new_attrs.sfnum_valid = true;
1658 err = devlink->ops->port_new(devlink, &new_attrs, extack,
1663 err = devlink_port_new_notify(devlink, new_port_index, info);
1664 if (err && err != -ENODEV) {
1665 /* Fail to send the response; destroy newly created port. */
1666 devlink->ops->port_del(devlink, new_port_index, extack);
1671 static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
1672 struct genl_info *info)
1674 struct netlink_ext_ack *extack = info->extack;
1675 struct devlink *devlink = info->user_ptr[0];
1676 unsigned int port_index;
1678 if (!devlink->ops->port_del)
1681 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_INDEX)) {
1682 NL_SET_ERR_MSG_MOD(extack, "Port index is not specified");
1685 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1687 return devlink->ops->port_del(devlink, port_index, extack);
1691 devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
1692 struct genl_info *info,
1693 struct nlattr *nla_parent)
1695 struct devlink *devlink = devlink_rate->devlink;
1696 const char *parent_name = nla_data(nla_parent);
1697 const struct devlink_ops *ops = devlink->ops;
1698 size_t len = strlen(parent_name);
1699 struct devlink_rate *parent;
1700 int err = -EOPNOTSUPP;
1702 parent = devlink_rate->parent;
1704 if (parent && !len) {
1705 if (devlink_rate_is_leaf(devlink_rate))
1706 err = ops->rate_leaf_parent_set(devlink_rate, NULL,
1707 devlink_rate->priv, NULL,
1709 else if (devlink_rate_is_node(devlink_rate))
1710 err = ops->rate_node_parent_set(devlink_rate, NULL,
1711 devlink_rate->priv, NULL,
1716 refcount_dec(&parent->refcnt);
1717 devlink_rate->parent = NULL;
1719 parent = devlink_rate_node_get_by_name(devlink, parent_name);
1723 if (parent == devlink_rate) {
1724 NL_SET_ERR_MSG_MOD(info->extack, "Parent to self is not allowed");
1728 if (devlink_rate_is_node(devlink_rate) &&
1729 devlink_rate_is_parent_node(devlink_rate, parent->parent)) {
1730 NL_SET_ERR_MSG_MOD(info->extack, "Node is already a parent of parent node.");
1734 if (devlink_rate_is_leaf(devlink_rate))
1735 err = ops->rate_leaf_parent_set(devlink_rate, parent,
1736 devlink_rate->priv, parent->priv,
1738 else if (devlink_rate_is_node(devlink_rate))
1739 err = ops->rate_node_parent_set(devlink_rate, parent,
1740 devlink_rate->priv, parent->priv,
1745 if (devlink_rate->parent)
1746 /* we're reassigning to other parent in this case */
1747 refcount_dec(&devlink_rate->parent->refcnt);
1749 refcount_inc(&parent->refcnt);
1750 devlink_rate->parent = parent;
1756 static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
1757 const struct devlink_ops *ops,
1758 struct genl_info *info)
1760 struct nlattr *nla_parent, **attrs = info->attrs;
1761 int err = -EOPNOTSUPP;
1766 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE]) {
1767 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_SHARE]);
1768 if (devlink_rate_is_leaf(devlink_rate))
1769 err = ops->rate_leaf_tx_share_set(devlink_rate, devlink_rate->priv,
1770 rate, info->extack);
1771 else if (devlink_rate_is_node(devlink_rate))
1772 err = ops->rate_node_tx_share_set(devlink_rate, devlink_rate->priv,
1773 rate, info->extack);
1776 devlink_rate->tx_share = rate;
1779 if (attrs[DEVLINK_ATTR_RATE_TX_MAX]) {
1780 rate = nla_get_u64(attrs[DEVLINK_ATTR_RATE_TX_MAX]);
1781 if (devlink_rate_is_leaf(devlink_rate))
1782 err = ops->rate_leaf_tx_max_set(devlink_rate, devlink_rate->priv,
1783 rate, info->extack);
1784 else if (devlink_rate_is_node(devlink_rate))
1785 err = ops->rate_node_tx_max_set(devlink_rate, devlink_rate->priv,
1786 rate, info->extack);
1789 devlink_rate->tx_max = rate;
1792 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]) {
1793 priority = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_PRIORITY]);
1794 if (devlink_rate_is_leaf(devlink_rate))
1795 err = ops->rate_leaf_tx_priority_set(devlink_rate, devlink_rate->priv,
1796 priority, info->extack);
1797 else if (devlink_rate_is_node(devlink_rate))
1798 err = ops->rate_node_tx_priority_set(devlink_rate, devlink_rate->priv,
1799 priority, info->extack);
1803 devlink_rate->tx_priority = priority;
1806 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]) {
1807 weight = nla_get_u32(attrs[DEVLINK_ATTR_RATE_TX_WEIGHT]);
1808 if (devlink_rate_is_leaf(devlink_rate))
1809 err = ops->rate_leaf_tx_weight_set(devlink_rate, devlink_rate->priv,
1810 weight, info->extack);
1811 else if (devlink_rate_is_node(devlink_rate))
1812 err = ops->rate_node_tx_weight_set(devlink_rate, devlink_rate->priv,
1813 weight, info->extack);
1817 devlink_rate->tx_weight = weight;
1820 nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
1822 err = devlink_nl_rate_parent_node_set(devlink_rate, info,
1831 static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
1832 struct genl_info *info,
1833 enum devlink_rate_type type)
1835 struct nlattr **attrs = info->attrs;
1837 if (type == DEVLINK_RATE_TYPE_LEAF) {
1838 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_leaf_tx_share_set) {
1839 NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the leafs");
1842 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_leaf_tx_max_set) {
1843 NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the leafs");
1846 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1847 !ops->rate_leaf_parent_set) {
1848 NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the leafs");
1851 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_leaf_tx_priority_set) {
1852 NL_SET_ERR_MSG_ATTR(info->extack,
1853 attrs[DEVLINK_ATTR_RATE_TX_PRIORITY],
1854 "TX priority set isn't supported for the leafs");
1857 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_leaf_tx_weight_set) {
1858 NL_SET_ERR_MSG_ATTR(info->extack,
1859 attrs[DEVLINK_ATTR_RATE_TX_WEIGHT],
1860 "TX weight set isn't supported for the leafs");
1863 } else if (type == DEVLINK_RATE_TYPE_NODE) {
1864 if (attrs[DEVLINK_ATTR_RATE_TX_SHARE] && !ops->rate_node_tx_share_set) {
1865 NL_SET_ERR_MSG_MOD(info->extack, "TX share set isn't supported for the nodes");
1868 if (attrs[DEVLINK_ATTR_RATE_TX_MAX] && !ops->rate_node_tx_max_set) {
1869 NL_SET_ERR_MSG_MOD(info->extack, "TX max set isn't supported for the nodes");
1872 if (attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME] &&
1873 !ops->rate_node_parent_set) {
1874 NL_SET_ERR_MSG_MOD(info->extack, "Parent set isn't supported for the nodes");
1877 if (attrs[DEVLINK_ATTR_RATE_TX_PRIORITY] && !ops->rate_node_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 nodes");
1883 if (attrs[DEVLINK_ATTR_RATE_TX_WEIGHT] && !ops->rate_node_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 nodes");
1890 WARN(1, "Unknown type of rate object");
1897 static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb,
1898 struct genl_info *info)
1900 struct devlink_rate *devlink_rate = info->user_ptr[1];
1901 struct devlink *devlink = devlink_rate->devlink;
1902 const struct devlink_ops *ops = devlink->ops;
1905 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
1908 err = devlink_nl_rate_set(devlink_rate, ops, info);
1911 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
1915 static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
1916 struct genl_info *info)
1918 struct devlink *devlink = info->user_ptr[0];
1919 struct devlink_rate *rate_node;
1920 const struct devlink_ops *ops;
1924 if (!ops || !ops->rate_node_new || !ops->rate_node_del) {
1925 NL_SET_ERR_MSG_MOD(info->extack, "Rate nodes aren't supported");
1929 if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
1932 rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
1933 if (!IS_ERR(rate_node))
1935 else if (rate_node == ERR_PTR(-EINVAL))
1938 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
1942 rate_node->devlink = devlink;
1943 rate_node->type = DEVLINK_RATE_TYPE_NODE;
1944 rate_node->name = nla_strdup(info->attrs[DEVLINK_ATTR_RATE_NODE_NAME], GFP_KERNEL);
1945 if (!rate_node->name) {
1950 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
1954 err = devlink_nl_rate_set(rate_node, ops, info);
1958 refcount_set(&rate_node->refcnt, 1);
1959 list_add(&rate_node->list, &devlink->rate_list);
1960 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
1964 ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1966 kfree(rate_node->name);
1972 static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb,
1973 struct genl_info *info)
1975 struct devlink_rate *rate_node = info->user_ptr[1];
1976 struct devlink *devlink = rate_node->devlink;
1977 const struct devlink_ops *ops = devlink->ops;
1980 if (refcount_read(&rate_node->refcnt) > 1) {
1981 NL_SET_ERR_MSG_MOD(info->extack, "Node has children. Cannot delete node.");
1985 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
1986 err = ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1987 if (rate_node->parent)
1988 refcount_dec(&rate_node->parent->refcnt);
1989 list_del(&rate_node->list);
1990 kfree(rate_node->name);
1995 struct devlink_linecard_type {
2000 static int devlink_nl_linecard_fill(struct sk_buff *msg,
2001 struct devlink *devlink,
2002 struct devlink_linecard *linecard,
2003 enum devlink_command cmd, u32 portid,
2005 struct netlink_ext_ack *extack)
2007 struct devlink_linecard_type *linecard_type;
2008 struct nlattr *attr;
2012 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2016 if (devlink_nl_put_handle(msg, devlink))
2017 goto nla_put_failure;
2018 if (nla_put_u32(msg, DEVLINK_ATTR_LINECARD_INDEX, linecard->index))
2019 goto nla_put_failure;
2020 if (nla_put_u8(msg, DEVLINK_ATTR_LINECARD_STATE, linecard->state))
2021 goto nla_put_failure;
2022 if (linecard->type &&
2023 nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE, linecard->type))
2024 goto nla_put_failure;
2026 if (linecard->types_count) {
2027 attr = nla_nest_start(msg,
2028 DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES);
2030 goto nla_put_failure;
2031 for (i = 0; i < linecard->types_count; i++) {
2032 linecard_type = &linecard->types[i];
2033 if (nla_put_string(msg, DEVLINK_ATTR_LINECARD_TYPE,
2034 linecard_type->type)) {
2035 nla_nest_cancel(msg, attr);
2036 goto nla_put_failure;
2039 nla_nest_end(msg, attr);
2042 if (linecard->nested_devlink &&
2043 devlink_nl_put_nested_handle(msg, linecard->nested_devlink))
2044 goto nla_put_failure;
2046 genlmsg_end(msg, hdr);
2050 genlmsg_cancel(msg, hdr);
2054 static void devlink_linecard_notify(struct devlink_linecard *linecard,
2055 enum devlink_command cmd)
2057 struct devlink *devlink = linecard->devlink;
2058 struct sk_buff *msg;
2061 WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW &&
2062 cmd != DEVLINK_CMD_LINECARD_DEL);
2064 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
2067 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2071 err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0,
2078 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2079 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
2082 static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb,
2083 struct genl_info *info)
2085 struct devlink_linecard *linecard = info->user_ptr[1];
2086 struct devlink *devlink = linecard->devlink;
2087 struct sk_buff *msg;
2090 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2094 mutex_lock(&linecard->state_lock);
2095 err = devlink_nl_linecard_fill(msg, devlink, linecard,
2096 DEVLINK_CMD_LINECARD_NEW,
2097 info->snd_portid, info->snd_seq, 0,
2099 mutex_unlock(&linecard->state_lock);
2105 return genlmsg_reply(msg, info);
2108 static int devlink_nl_cmd_linecard_get_dump_one(struct sk_buff *msg,
2109 struct devlink *devlink,
2110 struct netlink_callback *cb)
2112 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2113 struct devlink_linecard *linecard;
2117 list_for_each_entry(linecard, &devlink->linecard_list, list) {
2118 if (idx < state->idx) {
2122 mutex_lock(&linecard->state_lock);
2123 err = devlink_nl_linecard_fill(msg, devlink, linecard,
2124 DEVLINK_CMD_LINECARD_NEW,
2125 NETLINK_CB(cb->skb).portid,
2129 mutex_unlock(&linecard->state_lock);
2140 const struct devlink_gen_cmd devl_gen_linecard = {
2141 .dump_one = devlink_nl_cmd_linecard_get_dump_one,
2144 static struct devlink_linecard_type *
2145 devlink_linecard_type_lookup(struct devlink_linecard *linecard,
2148 struct devlink_linecard_type *linecard_type;
2151 for (i = 0; i < linecard->types_count; i++) {
2152 linecard_type = &linecard->types[i];
2153 if (!strcmp(type, linecard_type->type))
2154 return linecard_type;
2159 static int devlink_linecard_type_set(struct devlink_linecard *linecard,
2161 struct netlink_ext_ack *extack)
2163 const struct devlink_linecard_ops *ops = linecard->ops;
2164 struct devlink_linecard_type *linecard_type;
2167 mutex_lock(&linecard->state_lock);
2168 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
2169 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
2173 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2174 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2179 linecard_type = devlink_linecard_type_lookup(linecard, type);
2180 if (!linecard_type) {
2181 NL_SET_ERR_MSG_MOD(extack, "Unsupported line card type provided");
2186 if (linecard->state != DEVLINK_LINECARD_STATE_UNPROVISIONED &&
2187 linecard->state != DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
2188 NL_SET_ERR_MSG_MOD(extack, "Line card already provisioned");
2190 /* Check if the line card is provisioned in the same
2191 * way the user asks. In case it is, make the operation
2192 * to return success.
2194 if (ops->same_provision &&
2195 ops->same_provision(linecard, linecard->priv,
2196 linecard_type->type,
2197 linecard_type->priv))
2202 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING;
2203 linecard->type = linecard_type->type;
2204 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2205 mutex_unlock(&linecard->state_lock);
2206 err = ops->provision(linecard, linecard->priv, linecard_type->type,
2207 linecard_type->priv, extack);
2209 /* Provisioning failed. Assume the linecard is unprovisioned
2210 * for future operations.
2212 mutex_lock(&linecard->state_lock);
2213 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2214 linecard->type = NULL;
2215 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2216 mutex_unlock(&linecard->state_lock);
2221 mutex_unlock(&linecard->state_lock);
2225 static int devlink_linecard_type_unset(struct devlink_linecard *linecard,
2226 struct netlink_ext_ack *extack)
2230 mutex_lock(&linecard->state_lock);
2231 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING) {
2232 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being provisioned");
2236 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2237 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2241 if (linecard->state == DEVLINK_LINECARD_STATE_PROVISIONING_FAILED) {
2242 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2243 linecard->type = NULL;
2244 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2249 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) {
2250 NL_SET_ERR_MSG_MOD(extack, "Line card is not provisioned");
2254 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONING;
2255 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2256 mutex_unlock(&linecard->state_lock);
2257 err = linecard->ops->unprovision(linecard, linecard->priv,
2260 /* Unprovisioning failed. Assume the linecard is unprovisioned
2261 * for future operations.
2263 mutex_lock(&linecard->state_lock);
2264 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
2265 linecard->type = NULL;
2266 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
2267 mutex_unlock(&linecard->state_lock);
2272 mutex_unlock(&linecard->state_lock);
2276 static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
2277 struct genl_info *info)
2279 struct devlink_linecard *linecard = info->user_ptr[1];
2280 struct netlink_ext_ack *extack = info->extack;
2283 if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) {
2286 type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]);
2287 if (strcmp(type, "")) {
2288 err = devlink_linecard_type_set(linecard, type, extack);
2292 err = devlink_linecard_type_unset(linecard, extack);
2301 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
2302 struct devlink_sb *devlink_sb,
2303 enum devlink_command cmd, u32 portid,
2308 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2312 if (devlink_nl_put_handle(msg, devlink))
2313 goto nla_put_failure;
2314 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2315 goto nla_put_failure;
2316 if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
2317 goto nla_put_failure;
2318 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
2319 devlink_sb->ingress_pools_count))
2320 goto nla_put_failure;
2321 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
2322 devlink_sb->egress_pools_count))
2323 goto nla_put_failure;
2324 if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
2325 devlink_sb->ingress_tc_count))
2326 goto nla_put_failure;
2327 if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
2328 devlink_sb->egress_tc_count))
2329 goto nla_put_failure;
2331 genlmsg_end(msg, hdr);
2335 genlmsg_cancel(msg, hdr);
2339 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
2340 struct genl_info *info)
2342 struct devlink *devlink = info->user_ptr[0];
2343 struct devlink_sb *devlink_sb;
2344 struct sk_buff *msg;
2347 devlink_sb = devlink_sb_get_from_info(devlink, info);
2348 if (IS_ERR(devlink_sb))
2349 return PTR_ERR(devlink_sb);
2351 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2355 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2357 info->snd_portid, info->snd_seq, 0);
2363 return genlmsg_reply(msg, info);
2367 devlink_nl_cmd_sb_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
2368 struct netlink_callback *cb)
2370 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2371 struct devlink_sb *devlink_sb;
2375 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2376 if (idx < state->idx) {
2380 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2382 NETLINK_CB(cb->skb).portid,
2395 const struct devlink_gen_cmd devl_gen_sb = {
2396 .dump_one = devlink_nl_cmd_sb_get_dump_one,
2399 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
2400 struct devlink_sb *devlink_sb,
2401 u16 pool_index, enum devlink_command cmd,
2402 u32 portid, u32 seq, int flags)
2404 struct devlink_sb_pool_info pool_info;
2408 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
2409 pool_index, &pool_info);
2413 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2417 if (devlink_nl_put_handle(msg, devlink))
2418 goto nla_put_failure;
2419 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2420 goto nla_put_failure;
2421 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2422 goto nla_put_failure;
2423 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
2424 goto nla_put_failure;
2425 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
2426 goto nla_put_failure;
2427 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
2428 pool_info.threshold_type))
2429 goto nla_put_failure;
2430 if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
2431 pool_info.cell_size))
2432 goto nla_put_failure;
2434 genlmsg_end(msg, hdr);
2438 genlmsg_cancel(msg, hdr);
2442 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
2443 struct genl_info *info)
2445 struct devlink *devlink = info->user_ptr[0];
2446 struct devlink_sb *devlink_sb;
2447 struct sk_buff *msg;
2451 devlink_sb = devlink_sb_get_from_info(devlink, info);
2452 if (IS_ERR(devlink_sb))
2453 return PTR_ERR(devlink_sb);
2455 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2460 if (!devlink->ops->sb_pool_get)
2463 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2467 err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
2468 DEVLINK_CMD_SB_POOL_NEW,
2469 info->snd_portid, info->snd_seq, 0);
2475 return genlmsg_reply(msg, info);
2478 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2479 struct devlink *devlink,
2480 struct devlink_sb *devlink_sb,
2481 u32 portid, u32 seq)
2483 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2487 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2488 if (*p_idx < start) {
2492 err = devlink_nl_sb_pool_fill(msg, devlink,
2495 DEVLINK_CMD_SB_POOL_NEW,
2496 portid, seq, NLM_F_MULTI);
2505 devlink_nl_cmd_sb_pool_get_dump_one(struct sk_buff *msg,
2506 struct devlink *devlink,
2507 struct netlink_callback *cb)
2509 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2510 struct devlink_sb *devlink_sb;
2514 if (!devlink->ops->sb_pool_get)
2517 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2518 err = __sb_pool_get_dumpit(msg, state->idx, &idx,
2519 devlink, devlink_sb,
2520 NETLINK_CB(cb->skb).portid,
2521 cb->nlh->nlmsg_seq);
2522 if (err == -EOPNOTSUPP) {
2533 const struct devlink_gen_cmd devl_gen_sb_pool = {
2534 .dump_one = devlink_nl_cmd_sb_pool_get_dump_one,
2537 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
2538 u16 pool_index, u32 size,
2539 enum devlink_sb_threshold_type threshold_type,
2540 struct netlink_ext_ack *extack)
2543 const struct devlink_ops *ops = devlink->ops;
2545 if (ops->sb_pool_set)
2546 return ops->sb_pool_set(devlink, sb_index, pool_index,
2547 size, threshold_type, extack);
2551 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
2552 struct genl_info *info)
2554 struct devlink *devlink = info->user_ptr[0];
2555 enum devlink_sb_threshold_type threshold_type;
2556 struct devlink_sb *devlink_sb;
2561 devlink_sb = devlink_sb_get_from_info(devlink, info);
2562 if (IS_ERR(devlink_sb))
2563 return PTR_ERR(devlink_sb);
2565 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2570 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
2574 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE))
2577 size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
2578 return devlink_sb_pool_set(devlink, devlink_sb->index,
2579 pool_index, size, threshold_type,
2583 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
2584 struct devlink *devlink,
2585 struct devlink_port *devlink_port,
2586 struct devlink_sb *devlink_sb,
2588 enum devlink_command cmd,
2589 u32 portid, u32 seq, int flags)
2591 const struct devlink_ops *ops = devlink->ops;
2596 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
2597 pool_index, &threshold);
2601 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2605 if (devlink_nl_put_handle(msg, devlink))
2606 goto nla_put_failure;
2607 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2608 goto nla_put_failure;
2609 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2610 goto nla_put_failure;
2611 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2612 goto nla_put_failure;
2613 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2614 goto nla_put_failure;
2616 if (ops->sb_occ_port_pool_get) {
2620 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
2621 pool_index, &cur, &max);
2622 if (err && err != -EOPNOTSUPP)
2623 goto sb_occ_get_failure;
2625 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2626 goto nla_put_failure;
2627 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2628 goto nla_put_failure;
2632 genlmsg_end(msg, hdr);
2638 genlmsg_cancel(msg, hdr);
2642 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
2643 struct genl_info *info)
2645 struct devlink_port *devlink_port = info->user_ptr[1];
2646 struct devlink *devlink = devlink_port->devlink;
2647 struct devlink_sb *devlink_sb;
2648 struct sk_buff *msg;
2652 devlink_sb = devlink_sb_get_from_info(devlink, info);
2653 if (IS_ERR(devlink_sb))
2654 return PTR_ERR(devlink_sb);
2656 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2661 if (!devlink->ops->sb_port_pool_get)
2664 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2668 err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
2669 devlink_sb, pool_index,
2670 DEVLINK_CMD_SB_PORT_POOL_NEW,
2671 info->snd_portid, info->snd_seq, 0);
2677 return genlmsg_reply(msg, info);
2680 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
2681 struct devlink *devlink,
2682 struct devlink_sb *devlink_sb,
2683 u32 portid, u32 seq)
2685 struct devlink_port *devlink_port;
2686 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2687 unsigned long port_index;
2691 xa_for_each(&devlink->ports, port_index, devlink_port) {
2692 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2693 if (*p_idx < start) {
2697 err = devlink_nl_sb_port_pool_fill(msg, devlink,
2701 DEVLINK_CMD_SB_PORT_POOL_NEW,
2713 devlink_nl_cmd_sb_port_pool_get_dump_one(struct sk_buff *msg,
2714 struct devlink *devlink,
2715 struct netlink_callback *cb)
2717 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2718 struct devlink_sb *devlink_sb;
2722 if (!devlink->ops->sb_port_pool_get)
2725 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2726 err = __sb_port_pool_get_dumpit(msg, state->idx, &idx,
2727 devlink, devlink_sb,
2728 NETLINK_CB(cb->skb).portid,
2729 cb->nlh->nlmsg_seq);
2730 if (err == -EOPNOTSUPP) {
2741 const struct devlink_gen_cmd devl_gen_sb_port_pool = {
2742 .dump_one = devlink_nl_cmd_sb_port_pool_get_dump_one,
2745 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
2746 unsigned int sb_index, u16 pool_index,
2748 struct netlink_ext_ack *extack)
2751 const struct devlink_ops *ops = devlink_port->devlink->ops;
2753 if (ops->sb_port_pool_set)
2754 return ops->sb_port_pool_set(devlink_port, sb_index,
2755 pool_index, threshold, extack);
2759 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
2760 struct genl_info *info)
2762 struct devlink_port *devlink_port = info->user_ptr[1];
2763 struct devlink *devlink = info->user_ptr[0];
2764 struct devlink_sb *devlink_sb;
2769 devlink_sb = devlink_sb_get_from_info(devlink, info);
2770 if (IS_ERR(devlink_sb))
2771 return PTR_ERR(devlink_sb);
2773 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2778 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
2781 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
2782 return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
2783 pool_index, threshold, info->extack);
2787 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
2788 struct devlink_port *devlink_port,
2789 struct devlink_sb *devlink_sb, u16 tc_index,
2790 enum devlink_sb_pool_type pool_type,
2791 enum devlink_command cmd,
2792 u32 portid, u32 seq, int flags)
2794 const struct devlink_ops *ops = devlink->ops;
2800 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
2801 tc_index, pool_type,
2802 &pool_index, &threshold);
2806 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2810 if (devlink_nl_put_handle(msg, devlink))
2811 goto nla_put_failure;
2812 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
2813 goto nla_put_failure;
2814 if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
2815 goto nla_put_failure;
2816 if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
2817 goto nla_put_failure;
2818 if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
2819 goto nla_put_failure;
2820 if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
2821 goto nla_put_failure;
2822 if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
2823 goto nla_put_failure;
2825 if (ops->sb_occ_tc_port_bind_get) {
2829 err = ops->sb_occ_tc_port_bind_get(devlink_port,
2831 tc_index, pool_type,
2833 if (err && err != -EOPNOTSUPP)
2836 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
2837 goto nla_put_failure;
2838 if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
2839 goto nla_put_failure;
2843 genlmsg_end(msg, hdr);
2847 genlmsg_cancel(msg, hdr);
2851 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
2852 struct genl_info *info)
2854 struct devlink_port *devlink_port = info->user_ptr[1];
2855 struct devlink *devlink = devlink_port->devlink;
2856 struct devlink_sb *devlink_sb;
2857 struct sk_buff *msg;
2858 enum devlink_sb_pool_type pool_type;
2862 devlink_sb = devlink_sb_get_from_info(devlink, info);
2863 if (IS_ERR(devlink_sb))
2864 return PTR_ERR(devlink_sb);
2866 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
2870 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
2871 pool_type, &tc_index);
2875 if (!devlink->ops->sb_tc_pool_bind_get)
2878 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2882 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
2883 devlink_sb, tc_index, pool_type,
2884 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2892 return genlmsg_reply(msg, info);
2895 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
2896 int start, int *p_idx,
2897 struct devlink *devlink,
2898 struct devlink_sb *devlink_sb,
2899 u32 portid, u32 seq)
2901 struct devlink_port *devlink_port;
2902 unsigned long port_index;
2906 xa_for_each(&devlink->ports, port_index, devlink_port) {
2908 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
2909 if (*p_idx < start) {
2913 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2917 DEVLINK_SB_POOL_TYPE_INGRESS,
2918 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2926 tc_index < devlink_sb->egress_tc_count; tc_index++) {
2927 if (*p_idx < start) {
2931 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2935 DEVLINK_SB_POOL_TYPE_EGRESS,
2936 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2948 devlink_nl_cmd_sb_tc_pool_bind_get_dump_one(struct sk_buff *msg,
2949 struct devlink *devlink,
2950 struct netlink_callback *cb)
2952 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2953 struct devlink_sb *devlink_sb;
2957 if (!devlink->ops->sb_tc_pool_bind_get)
2960 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2961 err = __sb_tc_pool_bind_get_dumpit(msg, state->idx, &idx,
2962 devlink, devlink_sb,
2963 NETLINK_CB(cb->skb).portid,
2964 cb->nlh->nlmsg_seq);
2965 if (err == -EOPNOTSUPP) {
2976 const struct devlink_gen_cmd devl_gen_sb_tc_pool_bind = {
2977 .dump_one = devlink_nl_cmd_sb_tc_pool_bind_get_dump_one,
2980 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
2981 unsigned int sb_index, u16 tc_index,
2982 enum devlink_sb_pool_type pool_type,
2983 u16 pool_index, u32 threshold,
2984 struct netlink_ext_ack *extack)
2987 const struct devlink_ops *ops = devlink_port->devlink->ops;
2989 if (ops->sb_tc_pool_bind_set)
2990 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
2991 tc_index, pool_type,
2992 pool_index, threshold, extack);
2996 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
2997 struct genl_info *info)
2999 struct devlink_port *devlink_port = info->user_ptr[1];
3000 struct devlink *devlink = info->user_ptr[0];
3001 enum devlink_sb_pool_type pool_type;
3002 struct devlink_sb *devlink_sb;
3008 devlink_sb = devlink_sb_get_from_info(devlink, info);
3009 if (IS_ERR(devlink_sb))
3010 return PTR_ERR(devlink_sb);
3012 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
3016 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
3017 pool_type, &tc_index);
3021 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
3026 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
3029 threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
3030 return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
3031 tc_index, pool_type,
3032 pool_index, threshold, info->extack);
3035 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
3036 struct genl_info *info)
3038 struct devlink *devlink = info->user_ptr[0];
3039 const struct devlink_ops *ops = devlink->ops;
3040 struct devlink_sb *devlink_sb;
3042 devlink_sb = devlink_sb_get_from_info(devlink, info);
3043 if (IS_ERR(devlink_sb))
3044 return PTR_ERR(devlink_sb);
3046 if (ops->sb_occ_snapshot)
3047 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
3051 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
3052 struct genl_info *info)
3054 struct devlink *devlink = info->user_ptr[0];
3055 const struct devlink_ops *ops = devlink->ops;
3056 struct devlink_sb *devlink_sb;
3058 devlink_sb = devlink_sb_get_from_info(devlink, info);
3059 if (IS_ERR(devlink_sb))
3060 return PTR_ERR(devlink_sb);
3062 if (ops->sb_occ_max_clear)
3063 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
3067 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
3068 enum devlink_command cmd, u32 portid,
3071 const struct devlink_ops *ops = devlink->ops;
3072 enum devlink_eswitch_encap_mode encap_mode;
3078 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3082 err = devlink_nl_put_handle(msg, devlink);
3084 goto nla_put_failure;
3086 if (ops->eswitch_mode_get) {
3087 err = ops->eswitch_mode_get(devlink, &mode);
3089 goto nla_put_failure;
3090 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
3092 goto nla_put_failure;
3095 if (ops->eswitch_inline_mode_get) {
3096 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
3098 goto nla_put_failure;
3099 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
3102 goto nla_put_failure;
3105 if (ops->eswitch_encap_mode_get) {
3106 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
3108 goto nla_put_failure;
3109 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
3111 goto nla_put_failure;
3114 genlmsg_end(msg, hdr);
3118 genlmsg_cancel(msg, hdr);
3122 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
3123 struct genl_info *info)
3125 struct devlink *devlink = info->user_ptr[0];
3126 struct sk_buff *msg;
3129 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3133 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
3134 info->snd_portid, info->snd_seq, 0);
3141 return genlmsg_reply(msg, info);
3144 static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
3145 struct netlink_ext_ack *extack)
3147 struct devlink_rate *devlink_rate;
3149 list_for_each_entry(devlink_rate, &devlink->rate_list, list)
3150 if (devlink_rate_is_node(devlink_rate)) {
3151 NL_SET_ERR_MSG_MOD(extack, "Rate node(s) exists.");
3157 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
3158 struct genl_info *info)
3160 struct devlink *devlink = info->user_ptr[0];
3161 const struct devlink_ops *ops = devlink->ops;
3162 enum devlink_eswitch_encap_mode encap_mode;
3167 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
3168 if (!ops->eswitch_mode_set)
3170 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
3171 err = devlink_rate_nodes_check(devlink, mode, info->extack);
3174 err = ops->eswitch_mode_set(devlink, mode, info->extack);
3179 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
3180 if (!ops->eswitch_inline_mode_set)
3182 inline_mode = nla_get_u8(
3183 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
3184 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
3190 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
3191 if (!ops->eswitch_encap_mode_set)
3193 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
3194 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
3203 int devlink_dpipe_match_put(struct sk_buff *skb,
3204 struct devlink_dpipe_match *match)
3206 struct devlink_dpipe_header *header = match->header;
3207 struct devlink_dpipe_field *field = &header->fields[match->field_id];
3208 struct nlattr *match_attr;
3210 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
3214 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
3215 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
3216 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3217 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3218 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3219 goto nla_put_failure;
3221 nla_nest_end(skb, match_attr);
3225 nla_nest_cancel(skb, match_attr);
3228 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
3230 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
3231 struct sk_buff *skb)
3233 struct nlattr *matches_attr;
3235 matches_attr = nla_nest_start_noflag(skb,
3236 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
3240 if (table->table_ops->matches_dump(table->priv, skb))
3241 goto nla_put_failure;
3243 nla_nest_end(skb, matches_attr);
3247 nla_nest_cancel(skb, matches_attr);
3251 int devlink_dpipe_action_put(struct sk_buff *skb,
3252 struct devlink_dpipe_action *action)
3254 struct devlink_dpipe_header *header = action->header;
3255 struct devlink_dpipe_field *field = &header->fields[action->field_id];
3256 struct nlattr *action_attr;
3258 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
3262 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
3263 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
3264 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3265 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3266 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3267 goto nla_put_failure;
3269 nla_nest_end(skb, action_attr);
3273 nla_nest_cancel(skb, action_attr);
3276 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
3278 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
3279 struct sk_buff *skb)
3281 struct nlattr *actions_attr;
3283 actions_attr = nla_nest_start_noflag(skb,
3284 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
3288 if (table->table_ops->actions_dump(table->priv, skb))
3289 goto nla_put_failure;
3291 nla_nest_end(skb, actions_attr);
3295 nla_nest_cancel(skb, actions_attr);
3299 static int devlink_dpipe_table_put(struct sk_buff *skb,
3300 struct devlink_dpipe_table *table)
3302 struct nlattr *table_attr;
3305 table_size = table->table_ops->size_get(table->priv);
3306 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
3310 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
3311 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
3313 goto nla_put_failure;
3314 if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
3315 table->counters_enabled))
3316 goto nla_put_failure;
3318 if (table->resource_valid) {
3319 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
3320 table->resource_id, DEVLINK_ATTR_PAD) ||
3321 nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
3322 table->resource_units, DEVLINK_ATTR_PAD))
3323 goto nla_put_failure;
3325 if (devlink_dpipe_matches_put(table, skb))
3326 goto nla_put_failure;
3328 if (devlink_dpipe_actions_put(table, skb))
3329 goto nla_put_failure;
3331 nla_nest_end(skb, table_attr);
3335 nla_nest_cancel(skb, table_attr);
3339 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
3340 struct genl_info *info)
3345 err = genlmsg_reply(*pskb, info);
3349 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
3355 static int devlink_dpipe_tables_fill(struct genl_info *info,
3356 enum devlink_command cmd, int flags,
3357 struct list_head *dpipe_tables,
3358 const char *table_name)
3360 struct devlink *devlink = info->user_ptr[0];
3361 struct devlink_dpipe_table *table;
3362 struct nlattr *tables_attr;
3363 struct sk_buff *skb = NULL;
3364 struct nlmsghdr *nlh;
3370 table = list_first_entry(dpipe_tables,
3371 struct devlink_dpipe_table, list);
3373 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3377 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3378 &devlink_nl_family, NLM_F_MULTI, cmd);
3384 if (devlink_nl_put_handle(skb, devlink))
3385 goto nla_put_failure;
3386 tables_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLES);
3388 goto nla_put_failure;
3392 list_for_each_entry_from(table, dpipe_tables, list) {
3394 err = devlink_dpipe_table_put(skb, table);
3402 if (!strcmp(table->name, table_name)) {
3403 err = devlink_dpipe_table_put(skb, table);
3411 nla_nest_end(skb, tables_attr);
3412 genlmsg_end(skb, hdr);
3417 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3418 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3420 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3426 return genlmsg_reply(skb, info);
3435 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
3436 struct genl_info *info)
3438 struct devlink *devlink = info->user_ptr[0];
3439 const char *table_name = NULL;
3441 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
3442 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3444 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
3445 &devlink->dpipe_table_list,
3449 static int devlink_dpipe_value_put(struct sk_buff *skb,
3450 struct devlink_dpipe_value *value)
3452 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
3453 value->value_size, value->value))
3456 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
3457 value->value_size, value->mask))
3459 if (value->mapping_valid)
3460 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
3461 value->mapping_value))
3466 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
3467 struct devlink_dpipe_value *value)
3471 if (devlink_dpipe_action_put(skb, value->action))
3473 if (devlink_dpipe_value_put(skb, value))
3478 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
3479 struct devlink_dpipe_value *values,
3480 unsigned int values_count)
3482 struct nlattr *action_attr;
3486 for (i = 0; i < values_count; i++) {
3487 action_attr = nla_nest_start_noflag(skb,
3488 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
3491 err = devlink_dpipe_action_value_put(skb, &values[i]);
3493 goto err_action_value_put;
3494 nla_nest_end(skb, action_attr);
3498 err_action_value_put:
3499 nla_nest_cancel(skb, action_attr);
3503 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
3504 struct devlink_dpipe_value *value)
3508 if (devlink_dpipe_match_put(skb, value->match))
3510 if (devlink_dpipe_value_put(skb, value))
3515 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
3516 struct devlink_dpipe_value *values,
3517 unsigned int values_count)
3519 struct nlattr *match_attr;
3523 for (i = 0; i < values_count; i++) {
3524 match_attr = nla_nest_start_noflag(skb,
3525 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
3528 err = devlink_dpipe_match_value_put(skb, &values[i]);
3530 goto err_match_value_put;
3531 nla_nest_end(skb, match_attr);
3535 err_match_value_put:
3536 nla_nest_cancel(skb, match_attr);
3540 static int devlink_dpipe_entry_put(struct sk_buff *skb,
3541 struct devlink_dpipe_entry *entry)
3543 struct nlattr *entry_attr, *matches_attr, *actions_attr;
3546 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
3550 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
3552 goto nla_put_failure;
3553 if (entry->counter_valid)
3554 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
3555 entry->counter, DEVLINK_ATTR_PAD))
3556 goto nla_put_failure;
3558 matches_attr = nla_nest_start_noflag(skb,
3559 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
3561 goto nla_put_failure;
3563 err = devlink_dpipe_match_values_put(skb, entry->match_values,
3564 entry->match_values_count);
3566 nla_nest_cancel(skb, matches_attr);
3567 goto err_match_values_put;
3569 nla_nest_end(skb, matches_attr);
3571 actions_attr = nla_nest_start_noflag(skb,
3572 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
3574 goto nla_put_failure;
3576 err = devlink_dpipe_action_values_put(skb, entry->action_values,
3577 entry->action_values_count);
3579 nla_nest_cancel(skb, actions_attr);
3580 goto err_action_values_put;
3582 nla_nest_end(skb, actions_attr);
3584 nla_nest_end(skb, entry_attr);
3589 err_match_values_put:
3590 err_action_values_put:
3591 nla_nest_cancel(skb, entry_attr);
3595 static struct devlink_dpipe_table *
3596 devlink_dpipe_table_find(struct list_head *dpipe_tables,
3597 const char *table_name, struct devlink *devlink)
3599 struct devlink_dpipe_table *table;
3600 list_for_each_entry_rcu(table, dpipe_tables, list,
3601 lockdep_is_held(&devlink->lock)) {
3602 if (!strcmp(table->name, table_name))
3608 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
3610 struct devlink *devlink;
3613 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
3618 dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
3619 dump_ctx->info->snd_portid,
3620 dump_ctx->info->snd_seq,
3621 &devlink_nl_family, NLM_F_MULTI,
3624 goto nla_put_failure;
3626 devlink = dump_ctx->info->user_ptr[0];
3627 if (devlink_nl_put_handle(dump_ctx->skb, devlink))
3628 goto nla_put_failure;
3629 dump_ctx->nest = nla_nest_start_noflag(dump_ctx->skb,
3630 DEVLINK_ATTR_DPIPE_ENTRIES);
3631 if (!dump_ctx->nest)
3632 goto nla_put_failure;
3636 nlmsg_free(dump_ctx->skb);
3639 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
3641 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
3642 struct devlink_dpipe_entry *entry)
3644 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
3646 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
3648 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
3650 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
3651 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
3654 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
3656 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
3659 unsigned int value_count, value_index;
3660 struct devlink_dpipe_value *value;
3662 value = entry->action_values;
3663 value_count = entry->action_values_count;
3664 for (value_index = 0; value_index < value_count; value_index++) {
3665 kfree(value[value_index].value);
3666 kfree(value[value_index].mask);
3669 value = entry->match_values;
3670 value_count = entry->match_values_count;
3671 for (value_index = 0; value_index < value_count; value_index++) {
3672 kfree(value[value_index].value);
3673 kfree(value[value_index].mask);
3676 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
3678 static int devlink_dpipe_entries_fill(struct genl_info *info,
3679 enum devlink_command cmd, int flags,
3680 struct devlink_dpipe_table *table)
3682 struct devlink_dpipe_dump_ctx dump_ctx;
3683 struct nlmsghdr *nlh;
3686 dump_ctx.skb = NULL;
3688 dump_ctx.info = info;
3690 err = table->table_ops->entries_dump(table->priv,
3691 table->counters_enabled,
3697 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
3698 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3700 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
3705 return genlmsg_reply(dump_ctx.skb, info);
3708 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
3709 struct genl_info *info)
3711 struct devlink *devlink = info->user_ptr[0];
3712 struct devlink_dpipe_table *table;
3713 const char *table_name;
3715 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME))
3718 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3719 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3720 table_name, devlink);
3724 if (!table->table_ops->entries_dump)
3727 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
3731 static int devlink_dpipe_fields_put(struct sk_buff *skb,
3732 const struct devlink_dpipe_header *header)
3734 struct devlink_dpipe_field *field;
3735 struct nlattr *field_attr;
3738 for (i = 0; i < header->fields_count; i++) {
3739 field = &header->fields[i];
3740 field_attr = nla_nest_start_noflag(skb,
3741 DEVLINK_ATTR_DPIPE_FIELD);
3744 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
3745 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
3746 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
3747 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
3748 goto nla_put_failure;
3749 nla_nest_end(skb, field_attr);
3754 nla_nest_cancel(skb, field_attr);
3758 static int devlink_dpipe_header_put(struct sk_buff *skb,
3759 struct devlink_dpipe_header *header)
3761 struct nlattr *fields_attr, *header_attr;
3764 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
3768 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
3769 nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
3770 nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
3771 goto nla_put_failure;
3773 fields_attr = nla_nest_start_noflag(skb,
3774 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
3776 goto nla_put_failure;
3778 err = devlink_dpipe_fields_put(skb, header);
3780 nla_nest_cancel(skb, fields_attr);
3781 goto nla_put_failure;
3783 nla_nest_end(skb, fields_attr);
3784 nla_nest_end(skb, header_attr);
3789 nla_nest_cancel(skb, header_attr);
3793 static int devlink_dpipe_headers_fill(struct genl_info *info,
3794 enum devlink_command cmd, int flags,
3795 struct devlink_dpipe_headers *
3798 struct devlink *devlink = info->user_ptr[0];
3799 struct nlattr *headers_attr;
3800 struct sk_buff *skb = NULL;
3801 struct nlmsghdr *nlh;
3808 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3812 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3813 &devlink_nl_family, NLM_F_MULTI, cmd);
3819 if (devlink_nl_put_handle(skb, devlink))
3820 goto nla_put_failure;
3821 headers_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADERS);
3823 goto nla_put_failure;
3826 for (; i < dpipe_headers->headers_count; i++) {
3827 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
3835 nla_nest_end(skb, headers_attr);
3836 genlmsg_end(skb, hdr);
3837 if (i != dpipe_headers->headers_count)
3841 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3842 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3844 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3849 return genlmsg_reply(skb, info);
3858 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
3859 struct genl_info *info)
3861 struct devlink *devlink = info->user_ptr[0];
3863 if (!devlink->dpipe_headers)
3865 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
3866 0, devlink->dpipe_headers);
3869 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
3870 const char *table_name,
3873 struct devlink_dpipe_table *table;
3875 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3876 table_name, devlink);
3880 if (table->counter_control_extern)
3883 if (!(table->counters_enabled ^ enable))
3886 table->counters_enabled = enable;
3887 if (table->table_ops->counters_set_update)
3888 table->table_ops->counters_set_update(table->priv, enable);
3892 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
3893 struct genl_info *info)
3895 struct devlink *devlink = info->user_ptr[0];
3896 const char *table_name;
3897 bool counters_enable;
3899 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME) ||
3900 GENL_REQ_ATTR_CHECK(info,
3901 DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED))
3904 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3905 counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
3907 return devlink_dpipe_table_counters_set(devlink, table_name,
3911 static struct devlink_resource *
3912 devlink_resource_find(struct devlink *devlink,
3913 struct devlink_resource *resource, u64 resource_id)
3915 struct list_head *resource_list;
3918 resource_list = &resource->resource_list;
3920 resource_list = &devlink->resource_list;
3922 list_for_each_entry(resource, resource_list, list) {
3923 struct devlink_resource *child_resource;
3925 if (resource->id == resource_id)
3928 child_resource = devlink_resource_find(devlink, resource,
3931 return child_resource;
3937 devlink_resource_validate_children(struct devlink_resource *resource)
3939 struct devlink_resource *child_resource;
3940 bool size_valid = true;
3943 if (list_empty(&resource->resource_list))
3946 list_for_each_entry(child_resource, &resource->resource_list, list)
3947 parts_size += child_resource->size_new;
3949 if (parts_size > resource->size_new)
3952 resource->size_valid = size_valid;
3956 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
3957 struct netlink_ext_ack *extack)
3962 if (size > resource->size_params.size_max) {
3963 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
3967 if (size < resource->size_params.size_min) {
3968 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
3972 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
3974 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
3981 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
3982 struct genl_info *info)
3984 struct devlink *devlink = info->user_ptr[0];
3985 struct devlink_resource *resource;
3990 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) ||
3991 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE))
3993 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
3995 resource = devlink_resource_find(devlink, NULL, resource_id);
3999 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
4000 err = devlink_resource_validate_size(resource, size, info->extack);
4004 resource->size_new = size;
4005 devlink_resource_validate_children(resource);
4006 if (resource->parent)
4007 devlink_resource_validate_children(resource->parent);
4012 devlink_resource_size_params_put(struct devlink_resource *resource,
4013 struct sk_buff *skb)
4015 struct devlink_resource_size_params *size_params;
4017 size_params = &resource->size_params;
4018 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
4019 size_params->size_granularity, DEVLINK_ATTR_PAD) ||
4020 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
4021 size_params->size_max, DEVLINK_ATTR_PAD) ||
4022 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
4023 size_params->size_min, DEVLINK_ATTR_PAD) ||
4024 nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
4029 static int devlink_resource_occ_put(struct devlink_resource *resource,
4030 struct sk_buff *skb)
4032 if (!resource->occ_get)
4034 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
4035 resource->occ_get(resource->occ_get_priv),
4039 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
4040 struct devlink_resource *resource)
4042 struct devlink_resource *child_resource;
4043 struct nlattr *child_resource_attr;
4044 struct nlattr *resource_attr;
4046 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
4050 if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
4051 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
4052 DEVLINK_ATTR_PAD) ||
4053 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
4055 goto nla_put_failure;
4056 if (resource->size != resource->size_new &&
4057 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
4058 resource->size_new, DEVLINK_ATTR_PAD))
4059 goto nla_put_failure;
4060 if (devlink_resource_occ_put(resource, skb))
4061 goto nla_put_failure;
4062 if (devlink_resource_size_params_put(resource, skb))
4063 goto nla_put_failure;
4064 if (list_empty(&resource->resource_list))
4067 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
4068 resource->size_valid))
4069 goto nla_put_failure;
4071 child_resource_attr = nla_nest_start_noflag(skb,
4072 DEVLINK_ATTR_RESOURCE_LIST);
4073 if (!child_resource_attr)
4074 goto nla_put_failure;
4076 list_for_each_entry(child_resource, &resource->resource_list, list) {
4077 if (devlink_resource_put(devlink, skb, child_resource))
4078 goto resource_put_failure;
4081 nla_nest_end(skb, child_resource_attr);
4083 nla_nest_end(skb, resource_attr);
4086 resource_put_failure:
4087 nla_nest_cancel(skb, child_resource_attr);
4089 nla_nest_cancel(skb, resource_attr);
4093 static int devlink_resource_fill(struct genl_info *info,
4094 enum devlink_command cmd, int flags)
4096 struct devlink *devlink = info->user_ptr[0];
4097 struct devlink_resource *resource;
4098 struct nlattr *resources_attr;
4099 struct sk_buff *skb = NULL;
4100 struct nlmsghdr *nlh;
4106 resource = list_first_entry(&devlink->resource_list,
4107 struct devlink_resource, list);
4109 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4113 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4114 &devlink_nl_family, NLM_F_MULTI, cmd);
4120 if (devlink_nl_put_handle(skb, devlink))
4121 goto nla_put_failure;
4123 resources_attr = nla_nest_start_noflag(skb,
4124 DEVLINK_ATTR_RESOURCE_LIST);
4125 if (!resources_attr)
4126 goto nla_put_failure;
4130 list_for_each_entry_from(resource, &devlink->resource_list, list) {
4131 err = devlink_resource_put(devlink, skb, resource);
4134 goto err_resource_put;
4140 nla_nest_end(skb, resources_attr);
4141 genlmsg_end(skb, hdr);
4145 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4146 NLMSG_DONE, 0, flags | NLM_F_MULTI);
4148 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4153 return genlmsg_reply(skb, info);
4162 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
4163 struct genl_info *info)
4165 struct devlink *devlink = info->user_ptr[0];
4167 if (list_empty(&devlink->resource_list))
4170 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
4174 devlink_resources_validate(struct devlink *devlink,
4175 struct devlink_resource *resource,
4176 struct genl_info *info)
4178 struct list_head *resource_list;
4182 resource_list = &resource->resource_list;
4184 resource_list = &devlink->resource_list;
4186 list_for_each_entry(resource, resource_list, list) {
4187 if (!resource->size_valid)
4189 err = devlink_resources_validate(devlink, resource, info);
4196 static struct net *devlink_netns_get(struct sk_buff *skb,
4197 struct genl_info *info)
4199 struct nlattr *netns_pid_attr = info->attrs[DEVLINK_ATTR_NETNS_PID];
4200 struct nlattr *netns_fd_attr = info->attrs[DEVLINK_ATTR_NETNS_FD];
4201 struct nlattr *netns_id_attr = info->attrs[DEVLINK_ATTR_NETNS_ID];
4204 if (!!netns_pid_attr + !!netns_fd_attr + !!netns_id_attr > 1) {
4205 NL_SET_ERR_MSG_MOD(info->extack, "multiple netns identifying attributes specified");
4206 return ERR_PTR(-EINVAL);
4209 if (netns_pid_attr) {
4210 net = get_net_ns_by_pid(nla_get_u32(netns_pid_attr));
4211 } else if (netns_fd_attr) {
4212 net = get_net_ns_by_fd(nla_get_u32(netns_fd_attr));
4213 } else if (netns_id_attr) {
4214 net = get_net_ns_by_id(sock_net(skb->sk),
4215 nla_get_u32(netns_id_attr));
4217 net = ERR_PTR(-EINVAL);
4220 net = ERR_PTR(-EINVAL);
4223 NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace");
4224 return ERR_PTR(-EINVAL);
4226 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
4228 return ERR_PTR(-EPERM);
4233 static void devlink_param_notify(struct devlink *devlink,
4234 unsigned int port_index,
4235 struct devlink_param_item *param_item,
4236 enum devlink_command cmd);
4238 static void devlink_ns_change_notify(struct devlink *devlink,
4239 struct net *dest_net, struct net *curr_net,
4242 struct devlink_param_item *param_item;
4243 enum devlink_command cmd;
4245 /* Userspace needs to be notified about devlink objects
4246 * removed from original and entering new network namespace.
4247 * The rest of the devlink objects are re-created during
4248 * reload process so the notifications are generated separatelly.
4251 if (!dest_net || net_eq(dest_net, curr_net))
4255 devlink_notify(devlink, DEVLINK_CMD_NEW);
4257 cmd = new ? DEVLINK_CMD_PARAM_NEW : DEVLINK_CMD_PARAM_DEL;
4258 list_for_each_entry(param_item, &devlink->param_list, list)
4259 devlink_param_notify(devlink, 0, param_item, cmd);
4262 devlink_notify(devlink, DEVLINK_CMD_DEL);
4265 static void devlink_reload_failed_set(struct devlink *devlink,
4268 if (devlink->reload_failed == reload_failed)
4270 devlink->reload_failed = reload_failed;
4271 devlink_notify(devlink, DEVLINK_CMD_NEW);
4274 bool devlink_is_reload_failed(const struct devlink *devlink)
4276 return devlink->reload_failed;
4278 EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
4281 __devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats,
4282 enum devlink_reload_limit limit, u32 actions_performed)
4284 unsigned long actions = actions_performed;
4288 for_each_set_bit(action, &actions, __DEVLINK_RELOAD_ACTION_MAX) {
4289 stat_idx = limit * __DEVLINK_RELOAD_ACTION_MAX + action;
4290 reload_stats[stat_idx]++;
4292 devlink_notify(devlink, DEVLINK_CMD_NEW);
4296 devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit,
4297 u32 actions_performed)
4299 __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit,
4304 * devlink_remote_reload_actions_performed - Update devlink on reload actions
4305 * performed which are not a direct result of devlink reload call.
4307 * This should be called by a driver after performing reload actions in case it was not
4308 * a result of devlink reload call. For example fw_activate was performed as a result
4309 * of devlink reload triggered fw_activate on another host.
4310 * The motivation for this function is to keep data on reload actions performed on this
4311 * function whether it was done due to direct devlink reload call or not.
4314 * @limit: reload limit
4315 * @actions_performed: bitmask of actions performed
4317 void devlink_remote_reload_actions_performed(struct devlink *devlink,
4318 enum devlink_reload_limit limit,
4319 u32 actions_performed)
4321 if (WARN_ON(!actions_performed ||
4322 actions_performed & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
4323 actions_performed >= BIT(__DEVLINK_RELOAD_ACTION_MAX) ||
4324 limit > DEVLINK_RELOAD_LIMIT_MAX))
4327 __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit,
4330 EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed);
4332 int devlink_reload(struct devlink *devlink, struct net *dest_net,
4333 enum devlink_reload_action action,
4334 enum devlink_reload_limit limit,
4335 u32 *actions_performed, struct netlink_ext_ack *extack)
4337 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
4338 struct net *curr_net;
4341 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
4342 sizeof(remote_reload_stats));
4344 curr_net = devlink_net(devlink);
4345 devlink_ns_change_notify(devlink, dest_net, curr_net, false);
4346 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
4350 if (dest_net && !net_eq(dest_net, curr_net)) {
4351 move_netdevice_notifier_net(curr_net, dest_net,
4352 &devlink->netdevice_nb);
4353 write_pnet(&devlink->_net, dest_net);
4356 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
4357 devlink_reload_failed_set(devlink, !!err);
4361 devlink_ns_change_notify(devlink, dest_net, curr_net, true);
4362 WARN_ON(!(*actions_performed & BIT(action)));
4363 /* Catch driver on updating the remote action within devlink reload */
4364 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
4365 sizeof(remote_reload_stats)));
4366 devlink_reload_stats_update(devlink, limit, *actions_performed);
4371 devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed,
4372 enum devlink_command cmd, struct genl_info *info)
4374 struct sk_buff *msg;
4377 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4381 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd);
4385 if (devlink_nl_put_handle(msg, devlink))
4386 goto nla_put_failure;
4388 if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed,
4390 goto nla_put_failure;
4391 genlmsg_end(msg, hdr);
4393 return genlmsg_reply(msg, info);
4396 genlmsg_cancel(msg, hdr);
4402 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
4404 struct devlink *devlink = info->user_ptr[0];
4405 enum devlink_reload_action action;
4406 enum devlink_reload_limit limit;
4407 struct net *dest_net = NULL;
4408 u32 actions_performed;
4411 if (!(devlink->features & DEVLINK_F_RELOAD))
4414 err = devlink_resources_validate(devlink, NULL, info);
4416 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
4420 if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
4421 action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
4423 action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT;
4425 if (!devlink_reload_action_is_supported(devlink, action)) {
4426 NL_SET_ERR_MSG_MOD(info->extack,
4427 "Requested reload action is not supported by the driver");
4431 limit = DEVLINK_RELOAD_LIMIT_UNSPEC;
4432 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) {
4433 struct nla_bitfield32 limits;
4434 u32 limits_selected;
4436 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]);
4437 limits_selected = limits.value & limits.selector;
4438 if (!limits_selected) {
4439 NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected");
4442 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++)
4443 if (limits_selected & BIT(limit))
4445 /* UAPI enables multiselection, but currently it is not used */
4446 if (limits_selected != BIT(limit)) {
4447 NL_SET_ERR_MSG_MOD(info->extack,
4448 "Multiselection of limit is not supported");
4451 if (!devlink_reload_limit_is_supported(devlink, limit)) {
4452 NL_SET_ERR_MSG_MOD(info->extack,
4453 "Requested limit is not supported by the driver");
4456 if (devlink_reload_combination_is_invalid(action, limit)) {
4457 NL_SET_ERR_MSG_MOD(info->extack,
4458 "Requested limit is invalid for this action");
4462 if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
4463 info->attrs[DEVLINK_ATTR_NETNS_FD] ||
4464 info->attrs[DEVLINK_ATTR_NETNS_ID]) {
4465 dest_net = devlink_netns_get(skb, info);
4466 if (IS_ERR(dest_net))
4467 return PTR_ERR(dest_net);
4470 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
4477 /* For backward compatibility generate reply only if attributes used by user */
4478 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS])
4481 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
4482 DEVLINK_CMD_RELOAD, info);
4485 static int devlink_nl_flash_update_fill(struct sk_buff *msg,
4486 struct devlink *devlink,
4487 enum devlink_command cmd,
4488 struct devlink_flash_notify *params)
4492 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
4496 if (devlink_nl_put_handle(msg, devlink))
4497 goto nla_put_failure;
4499 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
4502 if (params->status_msg &&
4503 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
4504 params->status_msg))
4505 goto nla_put_failure;
4506 if (params->component &&
4507 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
4509 goto nla_put_failure;
4510 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
4511 params->done, DEVLINK_ATTR_PAD))
4512 goto nla_put_failure;
4513 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
4514 params->total, DEVLINK_ATTR_PAD))
4515 goto nla_put_failure;
4516 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT,
4517 params->timeout, DEVLINK_ATTR_PAD))
4518 goto nla_put_failure;
4521 genlmsg_end(msg, hdr);
4525 genlmsg_cancel(msg, hdr);
4529 static void __devlink_flash_update_notify(struct devlink *devlink,
4530 enum devlink_command cmd,
4531 struct devlink_flash_notify *params)
4533 struct sk_buff *msg;
4536 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
4537 cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
4538 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
4540 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
4543 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4547 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params);
4551 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
4552 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4559 static void devlink_flash_update_begin_notify(struct devlink *devlink)
4561 struct devlink_flash_notify params = {};
4563 __devlink_flash_update_notify(devlink,
4564 DEVLINK_CMD_FLASH_UPDATE,
4568 static void devlink_flash_update_end_notify(struct devlink *devlink)
4570 struct devlink_flash_notify params = {};
4572 __devlink_flash_update_notify(devlink,
4573 DEVLINK_CMD_FLASH_UPDATE_END,
4577 void devlink_flash_update_status_notify(struct devlink *devlink,
4578 const char *status_msg,
4579 const char *component,
4581 unsigned long total)
4583 struct devlink_flash_notify params = {
4584 .status_msg = status_msg,
4585 .component = component,
4590 __devlink_flash_update_notify(devlink,
4591 DEVLINK_CMD_FLASH_UPDATE_STATUS,
4594 EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
4596 void devlink_flash_update_timeout_notify(struct devlink *devlink,
4597 const char *status_msg,
4598 const char *component,
4599 unsigned long timeout)
4601 struct devlink_flash_notify params = {
4602 .status_msg = status_msg,
4603 .component = component,
4607 __devlink_flash_update_notify(devlink,
4608 DEVLINK_CMD_FLASH_UPDATE_STATUS,
4611 EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
4613 struct devlink_info_req {
4614 struct sk_buff *msg;
4615 void (*version_cb)(const char *version_name,
4616 enum devlink_info_version_type version_type,
4617 void *version_cb_priv);
4618 void *version_cb_priv;
4621 struct devlink_flash_component_lookup_ctx {
4622 const char *lookup_name;
4623 bool lookup_name_found;
4627 devlink_flash_component_lookup_cb(const char *version_name,
4628 enum devlink_info_version_type version_type,
4629 void *version_cb_priv)
4631 struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv;
4633 if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT ||
4634 lookup_ctx->lookup_name_found)
4637 lookup_ctx->lookup_name_found =
4638 !strcmp(lookup_ctx->lookup_name, version_name);
4641 static int devlink_flash_component_get(struct devlink *devlink,
4642 struct nlattr *nla_component,
4643 const char **p_component,
4644 struct netlink_ext_ack *extack)
4646 struct devlink_flash_component_lookup_ctx lookup_ctx = {};
4647 struct devlink_info_req req = {};
4648 const char *component;
4654 component = nla_data(nla_component);
4656 if (!devlink->ops->info_get) {
4657 NL_SET_ERR_MSG_ATTR(extack, nla_component,
4658 "component update is not supported by this device");
4662 lookup_ctx.lookup_name = component;
4663 req.version_cb = devlink_flash_component_lookup_cb;
4664 req.version_cb_priv = &lookup_ctx;
4666 ret = devlink->ops->info_get(devlink, &req, NULL);
4670 if (!lookup_ctx.lookup_name_found) {
4671 NL_SET_ERR_MSG_ATTR(extack, nla_component,
4672 "selected component is not supported by this device");
4675 *p_component = component;
4679 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
4680 struct genl_info *info)
4682 struct nlattr *nla_overwrite_mask, *nla_file_name;
4683 struct devlink_flash_update_params params = {};
4684 struct devlink *devlink = info->user_ptr[0];
4685 const char *file_name;
4686 u32 supported_params;
4689 if (!devlink->ops->flash_update)
4692 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME))
4695 ret = devlink_flash_component_get(devlink,
4696 info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT],
4697 ¶ms.component, info->extack);
4701 supported_params = devlink->ops->supported_flash_update_params;
4703 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
4704 if (nla_overwrite_mask) {
4705 struct nla_bitfield32 sections;
4707 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
4708 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask,
4709 "overwrite settings are not supported by this device");
4712 sections = nla_get_bitfield32(nla_overwrite_mask);
4713 params.overwrite_mask = sections.value & sections.selector;
4716 nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME];
4717 file_name = nla_data(nla_file_name);
4718 ret = request_firmware(¶ms.fw, file_name, devlink->dev);
4720 NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, "failed to locate the requested firmware file");
4724 devlink_flash_update_begin_notify(devlink);
4725 ret = devlink->ops->flash_update(devlink, ¶ms, info->extack);
4726 devlink_flash_update_end_notify(devlink);
4728 release_firmware(params.fw);
4734 devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink,
4735 u32 portid, u32 seq, int flags,
4736 struct netlink_ext_ack *extack)
4738 struct nlattr *selftests;
4743 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags,
4744 DEVLINK_CMD_SELFTESTS_GET);
4749 if (devlink_nl_put_handle(msg, devlink))
4750 goto err_cancel_msg;
4752 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
4754 goto err_cancel_msg;
4756 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
4757 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
4758 if (devlink->ops->selftest_check(devlink, i, extack)) {
4759 err = nla_put_flag(msg, i);
4761 goto err_cancel_msg;
4765 nla_nest_end(msg, selftests);
4766 genlmsg_end(msg, hdr);
4770 genlmsg_cancel(msg, hdr);
4774 static int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb,
4775 struct genl_info *info)
4777 struct devlink *devlink = info->user_ptr[0];
4778 struct sk_buff *msg;
4781 if (!devlink->ops->selftest_check)
4784 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4788 err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid,
4789 info->snd_seq, 0, info->extack);
4795 return genlmsg_reply(msg, info);
4799 devlink_nl_cmd_selftests_get_dump_one(struct sk_buff *msg,
4800 struct devlink *devlink,
4801 struct netlink_callback *cb)
4803 if (!devlink->ops->selftest_check)
4806 return devlink_nl_selftests_fill(msg, devlink,
4807 NETLINK_CB(cb->skb).portid,
4808 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4812 const struct devlink_gen_cmd devl_gen_selftests = {
4813 .dump_one = devlink_nl_cmd_selftests_get_dump_one,
4816 static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id,
4817 enum devlink_selftest_status test_status)
4819 struct nlattr *result_attr;
4821 result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT);
4825 if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) ||
4826 nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS,
4828 goto nla_put_failure;
4830 nla_nest_end(skb, result_attr);
4834 nla_nest_cancel(skb, result_attr);
4838 static int devlink_nl_cmd_selftests_run(struct sk_buff *skb,
4839 struct genl_info *info)
4841 struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1];
4842 struct devlink *devlink = info->user_ptr[0];
4843 struct nlattr *attrs, *selftests;
4844 struct sk_buff *msg;
4849 if (!devlink->ops->selftest_run || !devlink->ops->selftest_check)
4852 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS))
4855 attrs = info->attrs[DEVLINK_ATTR_SELFTESTS];
4857 err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs,
4858 devlink_selftest_nl_policy, info->extack);
4862 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4867 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
4868 &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN);
4872 if (devlink_nl_put_handle(msg, devlink))
4873 goto genlmsg_cancel;
4875 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
4877 goto genlmsg_cancel;
4879 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
4880 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
4881 enum devlink_selftest_status test_status;
4883 if (nla_get_flag(tb[i])) {
4884 if (!devlink->ops->selftest_check(devlink, i,
4886 if (devlink_selftest_result_put(msg, i,
4887 DEVLINK_SELFTEST_STATUS_SKIP))
4888 goto selftests_nest_cancel;
4892 test_status = devlink->ops->selftest_run(devlink, i,
4894 if (devlink_selftest_result_put(msg, i, test_status))
4895 goto selftests_nest_cancel;
4899 nla_nest_end(msg, selftests);
4900 genlmsg_end(msg, hdr);
4901 return genlmsg_reply(msg, info);
4903 selftests_nest_cancel:
4904 nla_nest_cancel(msg, selftests);
4906 genlmsg_cancel(msg, hdr);
4912 static const struct devlink_param devlink_param_generic[] = {
4914 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
4915 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
4916 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
4919 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
4920 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
4921 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
4924 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
4925 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
4926 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
4929 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
4930 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
4931 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
4934 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
4935 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
4936 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
4939 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
4940 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
4941 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
4944 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
4945 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
4946 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
4949 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
4950 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
4951 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
4954 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
4955 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
4956 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
4959 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
4960 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
4961 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
4964 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
4965 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
4966 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
4969 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
4970 .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
4971 .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
4974 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
4975 .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
4976 .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
4979 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
4980 .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
4981 .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
4984 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
4985 .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
4986 .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
4989 .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
4990 .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
4991 .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
4994 .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
4995 .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
4996 .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
5000 static int devlink_param_generic_verify(const struct devlink_param *param)
5002 /* verify it match generic parameter by id and name */
5003 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
5005 if (strcmp(param->name, devlink_param_generic[param->id].name))
5008 WARN_ON(param->type != devlink_param_generic[param->id].type);
5013 static int devlink_param_driver_verify(const struct devlink_param *param)
5017 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
5019 /* verify no such name in generic params */
5020 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
5021 if (!strcmp(param->name, devlink_param_generic[i].name))
5027 static struct devlink_param_item *
5028 devlink_param_find_by_name(struct list_head *param_list,
5029 const char *param_name)
5031 struct devlink_param_item *param_item;
5033 list_for_each_entry(param_item, param_list, list)
5034 if (!strcmp(param_item->param->name, param_name))
5039 static struct devlink_param_item *
5040 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
5042 struct devlink_param_item *param_item;
5044 list_for_each_entry(param_item, param_list, list)
5045 if (param_item->param->id == param_id)
5051 devlink_param_cmode_is_supported(const struct devlink_param *param,
5052 enum devlink_param_cmode cmode)
5054 return test_bit(cmode, ¶m->supported_cmodes);
5057 static int devlink_param_get(struct devlink *devlink,
5058 const struct devlink_param *param,
5059 struct devlink_param_gset_ctx *ctx)
5061 if (!param->get || devlink->reload_failed)
5063 return param->get(devlink, param->id, ctx);
5066 static int devlink_param_set(struct devlink *devlink,
5067 const struct devlink_param *param,
5068 struct devlink_param_gset_ctx *ctx)
5070 if (!param->set || devlink->reload_failed)
5072 return param->set(devlink, param->id, ctx);
5076 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
5078 switch (param_type) {
5079 case DEVLINK_PARAM_TYPE_U8:
5081 case DEVLINK_PARAM_TYPE_U16:
5083 case DEVLINK_PARAM_TYPE_U32:
5085 case DEVLINK_PARAM_TYPE_STRING:
5087 case DEVLINK_PARAM_TYPE_BOOL:
5095 devlink_nl_param_value_fill_one(struct sk_buff *msg,
5096 enum devlink_param_type type,
5097 enum devlink_param_cmode cmode,
5098 union devlink_param_value val)
5100 struct nlattr *param_value_attr;
5102 param_value_attr = nla_nest_start_noflag(msg,
5103 DEVLINK_ATTR_PARAM_VALUE);
5104 if (!param_value_attr)
5105 goto nla_put_failure;
5107 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
5108 goto value_nest_cancel;
5111 case DEVLINK_PARAM_TYPE_U8:
5112 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
5113 goto value_nest_cancel;
5115 case DEVLINK_PARAM_TYPE_U16:
5116 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
5117 goto value_nest_cancel;
5119 case DEVLINK_PARAM_TYPE_U32:
5120 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
5121 goto value_nest_cancel;
5123 case DEVLINK_PARAM_TYPE_STRING:
5124 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
5126 goto value_nest_cancel;
5128 case DEVLINK_PARAM_TYPE_BOOL:
5130 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
5131 goto value_nest_cancel;
5135 nla_nest_end(msg, param_value_attr);
5139 nla_nest_cancel(msg, param_value_attr);
5144 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
5145 unsigned int port_index,
5146 struct devlink_param_item *param_item,
5147 enum devlink_command cmd,
5148 u32 portid, u32 seq, int flags)
5150 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
5151 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
5152 const struct devlink_param *param = param_item->param;
5153 struct devlink_param_gset_ctx ctx;
5154 struct nlattr *param_values_list;
5155 struct nlattr *param_attr;
5161 /* Get value from driver part to driverinit configuration mode */
5162 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5163 if (!devlink_param_cmode_is_supported(param, i))
5165 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5166 if (!param_item->driverinit_value_valid)
5168 param_value[i] = param_item->driverinit_value;
5171 err = devlink_param_get(devlink, param, &ctx);
5174 param_value[i] = ctx.val;
5176 param_value_set[i] = true;
5179 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5183 if (devlink_nl_put_handle(msg, devlink))
5184 goto genlmsg_cancel;
5186 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
5187 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
5188 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
5189 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
5190 goto genlmsg_cancel;
5192 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
5194 goto genlmsg_cancel;
5195 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
5196 goto param_nest_cancel;
5197 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
5198 goto param_nest_cancel;
5200 nla_type = devlink_param_type_to_nla_type(param->type);
5202 goto param_nest_cancel;
5203 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
5204 goto param_nest_cancel;
5206 param_values_list = nla_nest_start_noflag(msg,
5207 DEVLINK_ATTR_PARAM_VALUES_LIST);
5208 if (!param_values_list)
5209 goto param_nest_cancel;
5211 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5212 if (!param_value_set[i])
5214 err = devlink_nl_param_value_fill_one(msg, param->type,
5217 goto values_list_nest_cancel;
5220 nla_nest_end(msg, param_values_list);
5221 nla_nest_end(msg, param_attr);
5222 genlmsg_end(msg, hdr);
5225 values_list_nest_cancel:
5226 nla_nest_end(msg, param_values_list);
5228 nla_nest_cancel(msg, param_attr);
5230 genlmsg_cancel(msg, hdr);
5234 static void devlink_param_notify(struct devlink *devlink,
5235 unsigned int port_index,
5236 struct devlink_param_item *param_item,
5237 enum devlink_command cmd)
5239 struct sk_buff *msg;
5242 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
5243 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
5244 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
5246 /* devlink_notify_register() / devlink_notify_unregister()
5247 * will replay the notifications if the params are added/removed
5248 * outside of the lifetime of the instance.
5250 if (!devl_is_registered(devlink))
5253 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5256 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
5263 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
5264 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5268 devlink_nl_cmd_param_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
5269 struct netlink_callback *cb)
5271 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5272 struct devlink_param_item *param_item;
5276 list_for_each_entry(param_item, &devlink->param_list, list) {
5277 if (idx < state->idx) {
5281 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5282 DEVLINK_CMD_PARAM_GET,
5283 NETLINK_CB(cb->skb).portid,
5286 if (err == -EOPNOTSUPP) {
5298 const struct devlink_gen_cmd devl_gen_param = {
5299 .dump_one = devlink_nl_cmd_param_get_dump_one,
5303 devlink_param_type_get_from_info(struct genl_info *info,
5304 enum devlink_param_type *param_type)
5306 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
5309 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
5311 *param_type = DEVLINK_PARAM_TYPE_U8;
5314 *param_type = DEVLINK_PARAM_TYPE_U16;
5317 *param_type = DEVLINK_PARAM_TYPE_U32;
5320 *param_type = DEVLINK_PARAM_TYPE_STRING;
5323 *param_type = DEVLINK_PARAM_TYPE_BOOL;
5333 devlink_param_value_get_from_info(const struct devlink_param *param,
5334 struct genl_info *info,
5335 union devlink_param_value *value)
5337 struct nlattr *param_data;
5340 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
5342 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
5345 switch (param->type) {
5346 case DEVLINK_PARAM_TYPE_U8:
5347 if (nla_len(param_data) != sizeof(u8))
5349 value->vu8 = nla_get_u8(param_data);
5351 case DEVLINK_PARAM_TYPE_U16:
5352 if (nla_len(param_data) != sizeof(u16))
5354 value->vu16 = nla_get_u16(param_data);
5356 case DEVLINK_PARAM_TYPE_U32:
5357 if (nla_len(param_data) != sizeof(u32))
5359 value->vu32 = nla_get_u32(param_data);
5361 case DEVLINK_PARAM_TYPE_STRING:
5362 len = strnlen(nla_data(param_data), nla_len(param_data));
5363 if (len == nla_len(param_data) ||
5364 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
5366 strcpy(value->vstr, nla_data(param_data));
5368 case DEVLINK_PARAM_TYPE_BOOL:
5369 if (param_data && nla_len(param_data))
5371 value->vbool = nla_get_flag(param_data);
5377 static struct devlink_param_item *
5378 devlink_param_get_from_info(struct list_head *param_list,
5379 struct genl_info *info)
5383 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME))
5386 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
5387 return devlink_param_find_by_name(param_list, param_name);
5390 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
5391 struct genl_info *info)
5393 struct devlink *devlink = info->user_ptr[0];
5394 struct devlink_param_item *param_item;
5395 struct sk_buff *msg;
5398 param_item = devlink_param_get_from_info(&devlink->param_list, info);
5402 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5406 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5407 DEVLINK_CMD_PARAM_GET,
5408 info->snd_portid, info->snd_seq, 0);
5414 return genlmsg_reply(msg, info);
5417 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
5418 unsigned int port_index,
5419 struct list_head *param_list,
5420 struct genl_info *info,
5421 enum devlink_command cmd)
5423 enum devlink_param_type param_type;
5424 struct devlink_param_gset_ctx ctx;
5425 enum devlink_param_cmode cmode;
5426 struct devlink_param_item *param_item;
5427 const struct devlink_param *param;
5428 union devlink_param_value value;
5431 param_item = devlink_param_get_from_info(param_list, info);
5434 param = param_item->param;
5435 err = devlink_param_type_get_from_info(info, ¶m_type);
5438 if (param_type != param->type)
5440 err = devlink_param_value_get_from_info(param, info, &value);
5443 if (param->validate) {
5444 err = param->validate(devlink, param->id, value, info->extack);
5449 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE))
5451 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
5452 if (!devlink_param_cmode_is_supported(param, cmode))
5455 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5456 if (param->type == DEVLINK_PARAM_TYPE_STRING)
5457 strcpy(param_item->driverinit_value.vstr, value.vstr);
5459 param_item->driverinit_value = value;
5460 param_item->driverinit_value_valid = true;
5466 err = devlink_param_set(devlink, param, &ctx);
5471 devlink_param_notify(devlink, port_index, param_item, cmd);
5475 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
5476 struct genl_info *info)
5478 struct devlink *devlink = info->user_ptr[0];
5480 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
5481 info, DEVLINK_CMD_PARAM_NEW);
5484 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
5485 struct netlink_callback *cb)
5487 NL_SET_ERR_MSG_MOD(cb->extack, "Port params are not supported");
5491 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
5492 struct genl_info *info)
5494 NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
5498 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
5499 struct genl_info *info)
5501 NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
5505 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
5506 struct devlink *devlink,
5507 struct devlink_snapshot *snapshot)
5509 struct nlattr *snap_attr;
5512 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
5516 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
5518 goto nla_put_failure;
5520 nla_nest_end(msg, snap_attr);
5524 nla_nest_cancel(msg, snap_attr);
5528 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
5529 struct devlink *devlink,
5530 struct devlink_region *region)
5532 struct devlink_snapshot *snapshot;
5533 struct nlattr *snapshots_attr;
5536 snapshots_attr = nla_nest_start_noflag(msg,
5537 DEVLINK_ATTR_REGION_SNAPSHOTS);
5538 if (!snapshots_attr)
5541 list_for_each_entry(snapshot, ®ion->snapshot_list, list) {
5542 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
5544 goto nla_put_failure;
5547 nla_nest_end(msg, snapshots_attr);
5551 nla_nest_cancel(msg, snapshots_attr);
5555 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
5556 enum devlink_command cmd, u32 portid,
5558 struct devlink_region *region)
5563 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5567 err = devlink_nl_put_handle(msg, devlink);
5569 goto nla_put_failure;
5572 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5573 region->port->index);
5575 goto nla_put_failure;
5578 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
5580 goto nla_put_failure;
5582 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5586 goto nla_put_failure;
5588 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
5589 region->max_snapshots);
5591 goto nla_put_failure;
5593 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
5595 goto nla_put_failure;
5597 genlmsg_end(msg, hdr);
5601 genlmsg_cancel(msg, hdr);
5605 static struct sk_buff *
5606 devlink_nl_region_notify_build(struct devlink_region *region,
5607 struct devlink_snapshot *snapshot,
5608 enum devlink_command cmd, u32 portid, u32 seq)
5610 struct devlink *devlink = region->devlink;
5611 struct sk_buff *msg;
5616 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5618 return ERR_PTR(-ENOMEM);
5620 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
5626 err = devlink_nl_put_handle(msg, devlink);
5628 goto out_cancel_msg;
5631 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5632 region->port->index);
5634 goto out_cancel_msg;
5637 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
5640 goto out_cancel_msg;
5643 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
5646 goto out_cancel_msg;
5648 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5649 region->size, DEVLINK_ATTR_PAD);
5651 goto out_cancel_msg;
5653 genlmsg_end(msg, hdr);
5658 genlmsg_cancel(msg, hdr);
5661 return ERR_PTR(err);
5664 static void devlink_nl_region_notify(struct devlink_region *region,
5665 struct devlink_snapshot *snapshot,
5666 enum devlink_command cmd)
5668 struct devlink *devlink = region->devlink;
5669 struct sk_buff *msg;
5671 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
5672 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
5675 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
5679 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
5680 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5684 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
5685 * @devlink: devlink instance
5686 * @id: the snapshot id
5688 * Track when a new snapshot begins using an id. Load the count for the
5689 * given id from the snapshot xarray, increment it, and store it back.
5691 * Called when a new snapshot is created with the given id.
5693 * The id *must* have been previously allocated by
5694 * devlink_region_snapshot_id_get().
5696 * Returns 0 on success, or an error on failure.
5698 static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
5700 unsigned long count;
5704 xa_lock(&devlink->snapshot_ids);
5705 p = xa_load(&devlink->snapshot_ids, id);
5711 if (WARN_ON(!xa_is_value(p))) {
5716 count = xa_to_value(p);
5719 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5722 xa_unlock(&devlink->snapshot_ids);
5727 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
5728 * @devlink: devlink instance
5729 * @id: the snapshot id
5731 * Track when a snapshot is deleted and stops using an id. Load the count
5732 * for the given id from the snapshot xarray, decrement it, and store it
5735 * If the count reaches zero, erase this id from the xarray, freeing it
5736 * up for future re-use by devlink_region_snapshot_id_get().
5738 * Called when a snapshot using the given id is deleted, and when the
5739 * initial allocator of the id is finished using it.
5741 static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
5743 unsigned long count;
5746 xa_lock(&devlink->snapshot_ids);
5747 p = xa_load(&devlink->snapshot_ids, id);
5751 if (WARN_ON(!xa_is_value(p)))
5754 count = xa_to_value(p);
5758 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5761 /* If this was the last user, we can erase this id */
5762 __xa_erase(&devlink->snapshot_ids, id);
5765 xa_unlock(&devlink->snapshot_ids);
5769 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
5770 * @devlink: devlink instance
5771 * @id: the snapshot id
5773 * Mark the given snapshot id as used by inserting a zero value into the
5776 * This must be called while holding the devlink instance lock. Unlike
5777 * devlink_snapshot_id_get, the initial reference count is zero, not one.
5778 * It is expected that the id will immediately be used before
5779 * releasing the devlink instance lock.
5781 * Returns zero on success, or an error code if the snapshot id could not
5784 static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
5788 xa_lock(&devlink->snapshot_ids);
5789 if (xa_load(&devlink->snapshot_ids, id)) {
5790 xa_unlock(&devlink->snapshot_ids);
5793 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
5795 xa_unlock(&devlink->snapshot_ids);
5800 * __devlink_region_snapshot_id_get - get snapshot ID
5801 * @devlink: devlink instance
5802 * @id: storage to return snapshot id
5804 * Allocates a new snapshot id. Returns zero on success, or a negative
5805 * error on failure. Must be called while holding the devlink instance
5808 * Snapshot IDs are tracked using an xarray which stores the number of
5809 * users of the snapshot id.
5811 * Note that the caller of this function counts as a 'user', in order to
5812 * avoid race conditions. The caller must release its hold on the
5813 * snapshot by using devlink_region_snapshot_id_put.
5815 static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
5817 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
5818 xa_limit_32b, GFP_KERNEL);
5822 * __devlink_region_snapshot_create - create a new snapshot
5823 * This will add a new snapshot of a region. The snapshot
5824 * will be stored on the region struct and can be accessed
5825 * from devlink. This is useful for future analyses of snapshots.
5826 * Multiple snapshots can be created on a region.
5827 * The @snapshot_id should be obtained using the getter function.
5829 * Must be called only while holding the region snapshot lock.
5831 * @region: devlink region of the snapshot
5832 * @data: snapshot data
5833 * @snapshot_id: snapshot id to be created
5836 __devlink_region_snapshot_create(struct devlink_region *region,
5837 u8 *data, u32 snapshot_id)
5839 struct devlink *devlink = region->devlink;
5840 struct devlink_snapshot *snapshot;
5843 lockdep_assert_held(®ion->snapshot_lock);
5845 /* check if region can hold one more snapshot */
5846 if (region->cur_snapshots == region->max_snapshots)
5849 if (devlink_region_snapshot_get_by_id(region, snapshot_id))
5852 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
5856 err = __devlink_snapshot_id_increment(devlink, snapshot_id);
5858 goto err_snapshot_id_increment;
5860 snapshot->id = snapshot_id;
5861 snapshot->region = region;
5862 snapshot->data = data;
5864 list_add_tail(&snapshot->list, ®ion->snapshot_list);
5866 region->cur_snapshots++;
5868 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
5871 err_snapshot_id_increment:
5876 static void devlink_region_snapshot_del(struct devlink_region *region,
5877 struct devlink_snapshot *snapshot)
5879 struct devlink *devlink = region->devlink;
5881 lockdep_assert_held(®ion->snapshot_lock);
5883 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
5884 region->cur_snapshots--;
5885 list_del(&snapshot->list);
5886 region->ops->destructor(snapshot->data);
5887 __devlink_snapshot_id_decrement(devlink, snapshot->id);
5891 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
5892 struct genl_info *info)
5894 struct devlink *devlink = info->user_ptr[0];
5895 struct devlink_port *port = NULL;
5896 struct devlink_region *region;
5897 const char *region_name;
5898 struct sk_buff *msg;
5902 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME))
5905 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
5906 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
5908 port = devlink_port_get_by_index(devlink, index);
5913 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
5915 region = devlink_port_region_get_by_name(port, region_name);
5917 region = devlink_region_get_by_name(devlink, region_name);
5922 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5926 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
5927 info->snd_portid, info->snd_seq, 0,
5934 return genlmsg_reply(msg, info);
5937 static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
5938 struct netlink_callback *cb,
5939 struct devlink_port *port,
5943 struct devlink_region *region;
5946 list_for_each_entry(region, &port->region_list, list) {
5951 err = devlink_nl_region_fill(msg, port->devlink,
5952 DEVLINK_CMD_REGION_GET,
5953 NETLINK_CB(cb->skb).portid,
5955 NLM_F_MULTI, region);
5966 devlink_nl_cmd_region_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
5967 struct netlink_callback *cb)
5969 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5970 struct devlink_region *region;
5971 struct devlink_port *port;
5972 unsigned long port_index;
5976 list_for_each_entry(region, &devlink->region_list, list) {
5977 if (idx < state->idx) {
5981 err = devlink_nl_region_fill(msg, devlink,
5982 DEVLINK_CMD_REGION_GET,
5983 NETLINK_CB(cb->skb).portid,
5985 NLM_F_MULTI, region);
5993 xa_for_each(&devlink->ports, port_index, port) {
5994 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx,
6005 const struct devlink_gen_cmd devl_gen_region = {
6006 .dump_one = devlink_nl_cmd_region_get_dump_one,
6009 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
6010 struct genl_info *info)
6012 struct devlink *devlink = info->user_ptr[0];
6013 struct devlink_snapshot *snapshot;
6014 struct devlink_port *port = NULL;
6015 struct devlink_region *region;
6016 const char *region_name;
6020 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) ||
6021 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID))
6024 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6025 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
6027 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6028 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6030 port = devlink_port_get_by_index(devlink, index);
6036 region = devlink_port_region_get_by_name(port, region_name);
6038 region = devlink_region_get_by_name(devlink, region_name);
6043 mutex_lock(®ion->snapshot_lock);
6044 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6046 mutex_unlock(®ion->snapshot_lock);
6050 devlink_region_snapshot_del(region, snapshot);
6051 mutex_unlock(®ion->snapshot_lock);
6056 devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
6058 struct devlink *devlink = info->user_ptr[0];
6059 struct devlink_snapshot *snapshot;
6060 struct devlink_port *port = NULL;
6061 struct nlattr *snapshot_id_attr;
6062 struct devlink_region *region;
6063 const char *region_name;
6069 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) {
6070 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
6074 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6076 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6077 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6079 port = devlink_port_get_by_index(devlink, index);
6085 region = devlink_port_region_get_by_name(port, region_name);
6087 region = devlink_region_get_by_name(devlink, region_name);
6090 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
6094 if (!region->ops->snapshot) {
6095 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
6099 mutex_lock(®ion->snapshot_lock);
6101 if (region->cur_snapshots == region->max_snapshots) {
6102 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
6107 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
6108 if (snapshot_id_attr) {
6109 snapshot_id = nla_get_u32(snapshot_id_attr);
6111 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
6112 NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
6117 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
6121 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
6123 NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
6129 err = region->port_ops->snapshot(port, region->port_ops,
6130 info->extack, &data);
6132 err = region->ops->snapshot(devlink, region->ops,
6133 info->extack, &data);
6135 goto err_snapshot_capture;
6137 err = __devlink_region_snapshot_create(region, data, snapshot_id);
6139 goto err_snapshot_create;
6141 if (!snapshot_id_attr) {
6142 struct sk_buff *msg;
6144 snapshot = devlink_region_snapshot_get_by_id(region,
6146 if (WARN_ON(!snapshot)) {
6151 msg = devlink_nl_region_notify_build(region, snapshot,
6152 DEVLINK_CMD_REGION_NEW,
6155 err = PTR_ERR_OR_ZERO(msg);
6159 err = genlmsg_reply(msg, info);
6164 mutex_unlock(®ion->snapshot_lock);
6167 err_snapshot_create:
6168 region->ops->destructor(data);
6169 err_snapshot_capture:
6170 __devlink_snapshot_id_decrement(devlink, snapshot_id);
6171 mutex_unlock(®ion->snapshot_lock);
6175 devlink_region_snapshot_del(region, snapshot);
6177 mutex_unlock(®ion->snapshot_lock);
6181 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
6182 u8 *chunk, u32 chunk_size,
6185 struct nlattr *chunk_attr;
6188 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
6192 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
6194 goto nla_put_failure;
6196 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
6199 goto nla_put_failure;
6201 nla_nest_end(msg, chunk_attr);
6205 nla_nest_cancel(msg, chunk_attr);
6209 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
6211 typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size,
6213 struct netlink_ext_ack *extack);
6216 devlink_nl_region_read_fill(struct sk_buff *skb, devlink_chunk_fill_t *cb,
6217 void *cb_priv, u64 start_offset, u64 end_offset,
6218 u64 *new_offset, struct netlink_ext_ack *extack)
6220 u64 curr_offset = start_offset;
6224 /* Allocate and re-use a single buffer */
6225 data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL);
6229 *new_offset = start_offset;
6231 while (curr_offset < end_offset) {
6234 data_size = min_t(u32, end_offset - curr_offset,
6235 DEVLINK_REGION_READ_CHUNK_SIZE);
6237 err = cb(cb_priv, data, data_size, curr_offset, extack);
6241 err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset);
6245 curr_offset += data_size;
6247 *new_offset = curr_offset;
6255 devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
6257 struct netlink_ext_ack __always_unused *extack)
6259 struct devlink_snapshot *snapshot = cb_priv;
6261 memcpy(chunk, &snapshot->data[curr_offset], chunk_size);
6267 devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
6268 u64 curr_offset, struct netlink_ext_ack *extack)
6270 struct devlink_region *region = cb_priv;
6272 return region->port_ops->read(region->port, region->port_ops, extack,
6273 curr_offset, chunk_size, chunk);
6277 devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
6278 u64 curr_offset, struct netlink_ext_ack *extack)
6280 struct devlink_region *region = cb_priv;
6282 return region->ops->read(region->devlink, region->ops, extack,
6283 curr_offset, chunk_size, chunk);
6286 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
6287 struct netlink_callback *cb)
6289 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
6290 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
6291 struct nlattr *chunks_attr, *region_attr, *snapshot_attr;
6292 u64 ret_offset, start_offset, end_offset = U64_MAX;
6293 struct nlattr **attrs = info->attrs;
6294 struct devlink_port *port = NULL;
6295 devlink_chunk_fill_t *region_cb;
6296 struct devlink_region *region;
6297 const char *region_name;
6298 struct devlink *devlink;
6300 void *region_cb_priv;
6304 start_offset = state->start_offset;
6306 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
6307 if (IS_ERR(devlink))
6308 return PTR_ERR(devlink);
6310 if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
6311 NL_SET_ERR_MSG(cb->extack, "No region name provided");
6316 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6317 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6319 port = devlink_port_get_by_index(devlink, index);
6326 region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
6327 region_name = nla_data(region_attr);
6330 region = devlink_port_region_get_by_name(port, region_name);
6332 region = devlink_region_get_by_name(devlink, region_name);
6335 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
6340 snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
6341 if (!snapshot_attr) {
6342 if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
6343 NL_SET_ERR_MSG(cb->extack, "No snapshot id provided");
6348 if (!region->ops->read) {
6349 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
6355 region_cb = &devlink_region_port_direct_fill;
6357 region_cb = &devlink_region_direct_fill;
6358 region_cb_priv = region;
6360 struct devlink_snapshot *snapshot;
6363 if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
6364 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot");
6369 snapshot_id = nla_get_u32(snapshot_attr);
6370 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6372 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
6376 region_cb = &devlink_region_snapshot_fill;
6377 region_cb_priv = snapshot;
6380 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
6381 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
6384 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6386 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6387 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
6390 if (end_offset > region->size)
6391 end_offset = region->size;
6393 /* return 0 if there is no further data to read */
6394 if (start_offset == end_offset) {
6399 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
6400 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
6401 DEVLINK_CMD_REGION_READ);
6407 err = devlink_nl_put_handle(skb, devlink);
6409 goto nla_put_failure;
6412 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
6413 region->port->index);
6415 goto nla_put_failure;
6418 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
6420 goto nla_put_failure;
6422 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
6425 goto nla_put_failure;
6428 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
6429 start_offset, end_offset, &ret_offset,
6432 if (err && err != -EMSGSIZE)
6433 goto nla_put_failure;
6435 /* Check if there was any progress done to prevent infinite loop */
6436 if (ret_offset == start_offset) {
6438 goto nla_put_failure;
6441 state->start_offset = ret_offset;
6443 nla_nest_end(skb, chunks_attr);
6444 genlmsg_end(skb, hdr);
6445 devl_unlock(devlink);
6446 devlink_put(devlink);
6450 genlmsg_cancel(skb, hdr);
6452 devl_unlock(devlink);
6453 devlink_put(devlink);
6457 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
6461 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
6463 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
6465 int devlink_info_board_serial_number_put(struct devlink_info_req *req,
6470 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
6473 EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
6475 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
6476 const char *version_name,
6477 const char *version_value,
6478 enum devlink_info_version_type version_type)
6480 struct nlattr *nest;
6483 if (req->version_cb)
6484 req->version_cb(version_name, version_type,
6485 req->version_cb_priv);
6490 nest = nla_nest_start_noflag(req->msg, attr);
6494 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
6497 goto nla_put_failure;
6499 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
6502 goto nla_put_failure;
6504 nla_nest_end(req->msg, nest);
6509 nla_nest_cancel(req->msg, nest);
6513 int devlink_info_version_fixed_put(struct devlink_info_req *req,
6514 const char *version_name,
6515 const char *version_value)
6517 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
6518 version_name, version_value,
6519 DEVLINK_INFO_VERSION_TYPE_NONE);
6521 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
6523 int devlink_info_version_stored_put(struct devlink_info_req *req,
6524 const char *version_name,
6525 const char *version_value)
6527 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
6528 version_name, version_value,
6529 DEVLINK_INFO_VERSION_TYPE_NONE);
6531 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
6533 int devlink_info_version_stored_put_ext(struct devlink_info_req *req,
6534 const char *version_name,
6535 const char *version_value,
6536 enum devlink_info_version_type version_type)
6538 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
6539 version_name, version_value,
6542 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext);
6544 int devlink_info_version_running_put(struct devlink_info_req *req,
6545 const char *version_name,
6546 const char *version_value)
6548 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
6549 version_name, version_value,
6550 DEVLINK_INFO_VERSION_TYPE_NONE);
6552 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
6554 int devlink_info_version_running_put_ext(struct devlink_info_req *req,
6555 const char *version_name,
6556 const char *version_value,
6557 enum devlink_info_version_type version_type)
6559 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
6560 version_name, version_value,
6563 EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext);
6565 static int devlink_nl_driver_info_get(struct device_driver *drv,
6566 struct devlink_info_req *req)
6572 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME,
6579 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
6580 enum devlink_command cmd, u32 portid,
6581 u32 seq, int flags, struct netlink_ext_ack *extack)
6583 struct device *dev = devlink_to_dev(devlink);
6584 struct devlink_info_req req = {};
6588 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6593 if (devlink_nl_put_handle(msg, devlink))
6594 goto err_cancel_msg;
6597 if (devlink->ops->info_get) {
6598 err = devlink->ops->info_get(devlink, &req, extack);
6600 goto err_cancel_msg;
6603 err = devlink_nl_driver_info_get(dev->driver, &req);
6605 goto err_cancel_msg;
6607 genlmsg_end(msg, hdr);
6611 genlmsg_cancel(msg, hdr);
6615 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
6616 struct genl_info *info)
6618 struct devlink *devlink = info->user_ptr[0];
6619 struct sk_buff *msg;
6622 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6626 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6627 info->snd_portid, info->snd_seq, 0,
6634 return genlmsg_reply(msg, info);
6638 devlink_nl_cmd_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
6639 struct netlink_callback *cb)
6643 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6644 NETLINK_CB(cb->skb).portid,
6645 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6647 if (err == -EOPNOTSUPP)
6652 const struct devlink_gen_cmd devl_gen_info = {
6653 .dump_one = devlink_nl_cmd_info_get_dump_one,
6656 struct devlink_fmsg_item {
6657 struct list_head list;
6664 struct devlink_fmsg {
6665 struct list_head item_list;
6666 bool putting_binary; /* This flag forces enclosing of binary data
6667 * in an array brackets. It forces using
6668 * of designated API:
6669 * devlink_fmsg_binary_pair_nest_start()
6670 * devlink_fmsg_binary_pair_nest_end()
6674 static struct devlink_fmsg *devlink_fmsg_alloc(void)
6676 struct devlink_fmsg *fmsg;
6678 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
6682 INIT_LIST_HEAD(&fmsg->item_list);
6687 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
6689 struct devlink_fmsg_item *item, *tmp;
6691 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
6692 list_del(&item->list);
6698 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
6701 struct devlink_fmsg_item *item;
6703 item = kzalloc(sizeof(*item), GFP_KERNEL);
6707 item->attrtype = attrtype;
6708 list_add_tail(&item->list, &fmsg->item_list);
6713 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
6715 if (fmsg->putting_binary)
6718 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
6720 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
6722 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
6724 if (fmsg->putting_binary)
6727 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
6730 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
6732 if (fmsg->putting_binary)
6735 return devlink_fmsg_nest_end(fmsg);
6737 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
6739 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
6741 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
6743 struct devlink_fmsg_item *item;
6745 if (fmsg->putting_binary)
6748 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
6751 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
6755 item->nla_type = NLA_NUL_STRING;
6756 item->len = strlen(name) + 1;
6757 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
6758 memcpy(&item->value, name, item->len);
6759 list_add_tail(&item->list, &fmsg->item_list);
6764 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
6768 if (fmsg->putting_binary)
6771 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
6775 err = devlink_fmsg_put_name(fmsg, name);
6781 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
6783 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
6785 if (fmsg->putting_binary)
6788 return devlink_fmsg_nest_end(fmsg);
6790 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
6792 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
6797 if (fmsg->putting_binary)
6800 err = devlink_fmsg_pair_nest_start(fmsg, name);
6804 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
6810 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
6812 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
6816 if (fmsg->putting_binary)
6819 err = devlink_fmsg_nest_end(fmsg);
6823 err = devlink_fmsg_nest_end(fmsg);
6829 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
6831 int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
6836 err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
6840 fmsg->putting_binary = true;
6843 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
6845 int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
6847 if (!fmsg->putting_binary)
6850 fmsg->putting_binary = false;
6851 return devlink_fmsg_arr_pair_nest_end(fmsg);
6853 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
6855 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
6856 const void *value, u16 value_len,
6859 struct devlink_fmsg_item *item;
6861 if (value_len > DEVLINK_FMSG_MAX_SIZE)
6864 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
6868 item->nla_type = value_nla_type;
6869 item->len = value_len;
6870 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
6871 memcpy(&item->value, value, item->len);
6872 list_add_tail(&item->list, &fmsg->item_list);
6877 static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
6879 if (fmsg->putting_binary)
6882 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
6885 static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
6887 if (fmsg->putting_binary)
6890 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
6893 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
6895 if (fmsg->putting_binary)
6898 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
6900 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
6902 static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
6904 if (fmsg->putting_binary)
6907 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
6910 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
6912 if (fmsg->putting_binary)
6915 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
6918 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
6920 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
6923 if (!fmsg->putting_binary)
6926 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
6928 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
6930 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
6935 err = devlink_fmsg_pair_nest_start(fmsg, name);
6939 err = devlink_fmsg_bool_put(fmsg, value);
6943 err = devlink_fmsg_pair_nest_end(fmsg);
6949 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
6951 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
6956 err = devlink_fmsg_pair_nest_start(fmsg, name);
6960 err = devlink_fmsg_u8_put(fmsg, value);
6964 err = devlink_fmsg_pair_nest_end(fmsg);
6970 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
6972 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
6977 err = devlink_fmsg_pair_nest_start(fmsg, name);
6981 err = devlink_fmsg_u32_put(fmsg, value);
6985 err = devlink_fmsg_pair_nest_end(fmsg);
6991 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
6993 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
6998 err = devlink_fmsg_pair_nest_start(fmsg, name);
7002 err = devlink_fmsg_u64_put(fmsg, value);
7006 err = devlink_fmsg_pair_nest_end(fmsg);
7012 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
7014 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
7019 err = devlink_fmsg_pair_nest_start(fmsg, name);
7023 err = devlink_fmsg_string_put(fmsg, value);
7027 err = devlink_fmsg_pair_nest_end(fmsg);
7033 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
7035 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
7036 const void *value, u32 value_len)
7043 err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
7047 for (offset = 0; offset < value_len; offset += data_size) {
7048 data_size = value_len - offset;
7049 if (data_size > DEVLINK_FMSG_MAX_SIZE)
7050 data_size = DEVLINK_FMSG_MAX_SIZE;
7051 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
7054 /* Exit from loop with a break (instead of
7055 * return) to make sure putting_binary is turned off in
7056 * devlink_fmsg_binary_pair_nest_end
7060 end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
7066 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
7069 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
7071 switch (msg->nla_type) {
7076 case NLA_NUL_STRING:
7078 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
7086 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
7088 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
7091 switch (msg->nla_type) {
7093 /* Always provide flag data, regardless of its value */
7094 tmp = *(bool *) msg->value;
7096 return nla_put_u8(skb, attrtype, tmp);
7098 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
7100 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
7102 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
7104 case NLA_NUL_STRING:
7105 return nla_put_string(skb, attrtype, (char *) &msg->value);
7107 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
7114 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7117 struct devlink_fmsg_item *item;
7118 struct nlattr *fmsg_nlattr;
7122 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
7126 list_for_each_entry(item, &fmsg->item_list, list) {
7132 switch (item->attrtype) {
7133 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
7134 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
7135 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
7136 case DEVLINK_ATTR_FMSG_NEST_END:
7137 err = nla_put_flag(skb, item->attrtype);
7139 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
7140 err = devlink_fmsg_item_fill_type(item, skb);
7143 err = devlink_fmsg_item_fill_data(item, skb);
7145 case DEVLINK_ATTR_FMSG_OBJ_NAME:
7146 err = nla_put_string(skb, item->attrtype,
7147 (char *) &item->value);
7159 nla_nest_end(skb, fmsg_nlattr);
7163 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
7164 struct genl_info *info,
7165 enum devlink_command cmd, int flags)
7167 struct nlmsghdr *nlh;
7168 struct sk_buff *skb;
7175 int tmp_index = index;
7177 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7181 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
7182 &devlink_nl_family, flags | NLM_F_MULTI, cmd);
7185 goto nla_put_failure;
7188 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7191 else if (err != -EMSGSIZE || tmp_index == index)
7192 goto nla_put_failure;
7194 genlmsg_end(skb, hdr);
7195 err = genlmsg_reply(skb, info);
7200 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7203 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
7204 NLMSG_DONE, 0, flags | NLM_F_MULTI);
7207 goto nla_put_failure;
7210 return genlmsg_reply(skb, info);
7217 static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7218 struct netlink_callback *cb,
7219 enum devlink_command cmd)
7221 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7222 int index = state->idx;
7223 int tmp_index = index;
7227 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
7228 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
7231 goto nla_put_failure;
7234 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7235 if ((err && err != -EMSGSIZE) || tmp_index == index)
7236 goto nla_put_failure;
7239 genlmsg_end(skb, hdr);
7243 genlmsg_cancel(skb, hdr);
7247 struct devlink_health_reporter {
7248 struct list_head list;
7250 const struct devlink_health_reporter_ops *ops;
7251 struct devlink *devlink;
7252 struct devlink_port *devlink_port;
7253 struct devlink_fmsg *dump_fmsg;
7254 struct mutex dump_lock; /* lock parallel read/write from dump buffers */
7255 u64 graceful_period;
7263 u64 last_recovery_ts;
7267 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
7269 return reporter->priv;
7271 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
7273 static struct devlink_health_reporter *
7274 __devlink_health_reporter_find_by_name(struct list_head *reporter_list,
7275 const char *reporter_name)
7277 struct devlink_health_reporter *reporter;
7279 list_for_each_entry(reporter, reporter_list, list)
7280 if (!strcmp(reporter->ops->name, reporter_name))
7285 static struct devlink_health_reporter *
7286 devlink_health_reporter_find_by_name(struct devlink *devlink,
7287 const char *reporter_name)
7289 return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
7293 static struct devlink_health_reporter *
7294 devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
7295 const char *reporter_name)
7297 return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
7301 static struct devlink_health_reporter *
7302 __devlink_health_reporter_create(struct devlink *devlink,
7303 const struct devlink_health_reporter_ops *ops,
7304 u64 graceful_period, void *priv)
7306 struct devlink_health_reporter *reporter;
7308 if (WARN_ON(graceful_period && !ops->recover))
7309 return ERR_PTR(-EINVAL);
7311 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
7313 return ERR_PTR(-ENOMEM);
7315 reporter->priv = priv;
7316 reporter->ops = ops;
7317 reporter->devlink = devlink;
7318 reporter->graceful_period = graceful_period;
7319 reporter->auto_recover = !!ops->recover;
7320 reporter->auto_dump = !!ops->dump;
7321 mutex_init(&reporter->dump_lock);
7326 * devl_port_health_reporter_create - create devlink health reporter for
7327 * specified port instance
7329 * @port: devlink_port which should contain the new reporter
7331 * @graceful_period: to avoid recovery loops, in msecs
7334 struct devlink_health_reporter *
7335 devl_port_health_reporter_create(struct devlink_port *port,
7336 const struct devlink_health_reporter_ops *ops,
7337 u64 graceful_period, void *priv)
7339 struct devlink_health_reporter *reporter;
7341 devl_assert_locked(port->devlink);
7343 if (__devlink_health_reporter_find_by_name(&port->reporter_list,
7345 return ERR_PTR(-EEXIST);
7347 reporter = __devlink_health_reporter_create(port->devlink, ops,
7348 graceful_period, priv);
7349 if (IS_ERR(reporter))
7352 reporter->devlink_port = port;
7353 list_add_tail(&reporter->list, &port->reporter_list);
7356 EXPORT_SYMBOL_GPL(devl_port_health_reporter_create);
7358 struct devlink_health_reporter *
7359 devlink_port_health_reporter_create(struct devlink_port *port,
7360 const struct devlink_health_reporter_ops *ops,
7361 u64 graceful_period, void *priv)
7363 struct devlink_health_reporter *reporter;
7364 struct devlink *devlink = port->devlink;
7367 reporter = devl_port_health_reporter_create(port, ops,
7368 graceful_period, priv);
7369 devl_unlock(devlink);
7372 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
7375 * devl_health_reporter_create - create devlink health reporter
7379 * @graceful_period: to avoid recovery loops, in msecs
7382 struct devlink_health_reporter *
7383 devl_health_reporter_create(struct devlink *devlink,
7384 const struct devlink_health_reporter_ops *ops,
7385 u64 graceful_period, void *priv)
7387 struct devlink_health_reporter *reporter;
7389 devl_assert_locked(devlink);
7391 if (devlink_health_reporter_find_by_name(devlink, ops->name))
7392 return ERR_PTR(-EEXIST);
7394 reporter = __devlink_health_reporter_create(devlink, ops,
7395 graceful_period, priv);
7396 if (IS_ERR(reporter))
7399 list_add_tail(&reporter->list, &devlink->reporter_list);
7402 EXPORT_SYMBOL_GPL(devl_health_reporter_create);
7404 struct devlink_health_reporter *
7405 devlink_health_reporter_create(struct devlink *devlink,
7406 const struct devlink_health_reporter_ops *ops,
7407 u64 graceful_period, void *priv)
7409 struct devlink_health_reporter *reporter;
7412 reporter = devl_health_reporter_create(devlink, ops,
7413 graceful_period, priv);
7414 devl_unlock(devlink);
7417 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
7420 devlink_health_reporter_free(struct devlink_health_reporter *reporter)
7422 mutex_destroy(&reporter->dump_lock);
7423 if (reporter->dump_fmsg)
7424 devlink_fmsg_free(reporter->dump_fmsg);
7429 * devl_health_reporter_destroy - destroy devlink health reporter
7431 * @reporter: devlink health reporter to destroy
7434 devl_health_reporter_destroy(struct devlink_health_reporter *reporter)
7436 devl_assert_locked(reporter->devlink);
7438 list_del(&reporter->list);
7439 devlink_health_reporter_free(reporter);
7441 EXPORT_SYMBOL_GPL(devl_health_reporter_destroy);
7444 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
7446 struct devlink *devlink = reporter->devlink;
7449 devl_health_reporter_destroy(reporter);
7450 devl_unlock(devlink);
7452 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
7455 devlink_nl_health_reporter_fill(struct sk_buff *msg,
7456 struct devlink_health_reporter *reporter,
7457 enum devlink_command cmd, u32 portid,
7460 struct devlink *devlink = reporter->devlink;
7461 struct nlattr *reporter_attr;
7464 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7468 if (devlink_nl_put_handle(msg, devlink))
7469 goto genlmsg_cancel;
7471 if (reporter->devlink_port) {
7472 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
7473 goto genlmsg_cancel;
7475 reporter_attr = nla_nest_start_noflag(msg,
7476 DEVLINK_ATTR_HEALTH_REPORTER);
7478 goto genlmsg_cancel;
7479 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
7480 reporter->ops->name))
7481 goto reporter_nest_cancel;
7482 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
7483 reporter->health_state))
7484 goto reporter_nest_cancel;
7485 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
7486 reporter->error_count, DEVLINK_ATTR_PAD))
7487 goto reporter_nest_cancel;
7488 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
7489 reporter->recovery_count, DEVLINK_ATTR_PAD))
7490 goto reporter_nest_cancel;
7491 if (reporter->ops->recover &&
7492 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
7493 reporter->graceful_period,
7495 goto reporter_nest_cancel;
7496 if (reporter->ops->recover &&
7497 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
7498 reporter->auto_recover))
7499 goto reporter_nest_cancel;
7500 if (reporter->dump_fmsg &&
7501 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
7502 jiffies_to_msecs(reporter->dump_ts),
7504 goto reporter_nest_cancel;
7505 if (reporter->dump_fmsg &&
7506 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
7507 reporter->dump_real_ts, DEVLINK_ATTR_PAD))
7508 goto reporter_nest_cancel;
7509 if (reporter->ops->dump &&
7510 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
7511 reporter->auto_dump))
7512 goto reporter_nest_cancel;
7514 nla_nest_end(msg, reporter_attr);
7515 genlmsg_end(msg, hdr);
7518 reporter_nest_cancel:
7519 nla_nest_end(msg, reporter_attr);
7521 genlmsg_cancel(msg, hdr);
7525 static void devlink_recover_notify(struct devlink_health_reporter *reporter,
7526 enum devlink_command cmd)
7528 struct devlink *devlink = reporter->devlink;
7529 struct sk_buff *msg;
7532 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7533 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
7535 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7539 err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0);
7545 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
7546 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7550 devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
7552 reporter->recovery_count++;
7553 reporter->last_recovery_ts = jiffies;
7555 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
7558 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
7559 void *priv_ctx, struct netlink_ext_ack *extack)
7563 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
7566 if (!reporter->ops->recover)
7569 err = reporter->ops->recover(reporter, priv_ctx, extack);
7573 devlink_health_reporter_recovery_done(reporter);
7574 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
7575 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7581 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
7583 if (!reporter->dump_fmsg)
7585 devlink_fmsg_free(reporter->dump_fmsg);
7586 reporter->dump_fmsg = NULL;
7589 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
7591 struct netlink_ext_ack *extack)
7595 if (!reporter->ops->dump)
7598 if (reporter->dump_fmsg)
7601 reporter->dump_fmsg = devlink_fmsg_alloc();
7602 if (!reporter->dump_fmsg) {
7607 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
7611 err = reporter->ops->dump(reporter, reporter->dump_fmsg,
7616 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
7620 reporter->dump_ts = jiffies;
7621 reporter->dump_real_ts = ktime_get_real_ns();
7626 devlink_health_dump_clear(reporter);
7630 int devlink_health_report(struct devlink_health_reporter *reporter,
7631 const char *msg, void *priv_ctx)
7633 enum devlink_health_reporter_state prev_health_state;
7634 struct devlink *devlink = reporter->devlink;
7635 unsigned long recover_ts_threshold;
7638 /* write a log message of the current error */
7640 trace_devlink_health_report(devlink, reporter->ops->name, msg);
7641 reporter->error_count++;
7642 prev_health_state = reporter->health_state;
7643 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
7644 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7646 /* abort if the previous error wasn't recovered */
7647 recover_ts_threshold = reporter->last_recovery_ts +
7648 msecs_to_jiffies(reporter->graceful_period);
7649 if (reporter->auto_recover &&
7650 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
7651 (reporter->last_recovery_ts && reporter->recovery_count &&
7652 time_is_after_jiffies(recover_ts_threshold)))) {
7653 trace_devlink_health_recover_aborted(devlink,
7654 reporter->ops->name,
7655 reporter->health_state,
7657 reporter->last_recovery_ts);
7661 if (reporter->auto_dump) {
7662 mutex_lock(&reporter->dump_lock);
7663 /* store current dump of current error, for later analysis */
7664 devlink_health_do_dump(reporter, priv_ctx, NULL);
7665 mutex_unlock(&reporter->dump_lock);
7668 if (!reporter->auto_recover)
7672 ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL);
7673 devl_unlock(devlink);
7677 EXPORT_SYMBOL_GPL(devlink_health_report);
7679 static struct devlink_health_reporter *
7680 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
7681 struct nlattr **attrs)
7683 struct devlink_port *devlink_port;
7684 char *reporter_name;
7686 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
7689 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
7690 devlink_port = devlink_port_get_from_attrs(devlink, attrs);
7691 if (IS_ERR(devlink_port))
7692 return devlink_health_reporter_find_by_name(devlink,
7695 return devlink_port_health_reporter_find_by_name(devlink_port,
7699 static struct devlink_health_reporter *
7700 devlink_health_reporter_get_from_info(struct devlink *devlink,
7701 struct genl_info *info)
7703 return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
7706 static struct devlink_health_reporter *
7707 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
7709 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
7710 struct devlink_health_reporter *reporter;
7711 struct nlattr **attrs = info->attrs;
7712 struct devlink *devlink;
7714 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
7715 if (IS_ERR(devlink))
7717 devl_unlock(devlink);
7719 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
7720 devlink_put(devlink);
7725 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
7726 enum devlink_health_reporter_state state)
7728 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
7729 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
7732 if (reporter->health_state == state)
7735 reporter->health_state = state;
7736 trace_devlink_health_reporter_state_update(reporter->devlink,
7737 reporter->ops->name, state);
7738 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7740 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
7742 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
7743 struct genl_info *info)
7745 struct devlink *devlink = info->user_ptr[0];
7746 struct devlink_health_reporter *reporter;
7747 struct sk_buff *msg;
7750 reporter = devlink_health_reporter_get_from_info(devlink, info);
7754 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7758 err = devlink_nl_health_reporter_fill(msg, reporter,
7759 DEVLINK_CMD_HEALTH_REPORTER_GET,
7760 info->snd_portid, info->snd_seq,
7767 return genlmsg_reply(msg, info);
7771 devlink_nl_cmd_health_reporter_get_dump_one(struct sk_buff *msg,
7772 struct devlink *devlink,
7773 struct netlink_callback *cb)
7775 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7776 struct devlink_health_reporter *reporter;
7777 struct devlink_port *port;
7778 unsigned long port_index;
7782 list_for_each_entry(reporter, &devlink->reporter_list, list) {
7783 if (idx < state->idx) {
7787 err = devlink_nl_health_reporter_fill(msg, reporter,
7788 DEVLINK_CMD_HEALTH_REPORTER_GET,
7789 NETLINK_CB(cb->skb).portid,
7798 xa_for_each(&devlink->ports, port_index, port) {
7799 list_for_each_entry(reporter, &port->reporter_list, list) {
7800 if (idx < state->idx) {
7804 err = devlink_nl_health_reporter_fill(msg, reporter,
7805 DEVLINK_CMD_HEALTH_REPORTER_GET,
7806 NETLINK_CB(cb->skb).portid,
7820 const struct devlink_gen_cmd devl_gen_health_reporter = {
7821 .dump_one = devlink_nl_cmd_health_reporter_get_dump_one,
7825 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
7826 struct genl_info *info)
7828 struct devlink *devlink = info->user_ptr[0];
7829 struct devlink_health_reporter *reporter;
7831 reporter = devlink_health_reporter_get_from_info(devlink, info);
7835 if (!reporter->ops->recover &&
7836 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
7837 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]))
7840 if (!reporter->ops->dump &&
7841 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
7844 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
7845 reporter->graceful_period =
7846 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
7848 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
7849 reporter->auto_recover =
7850 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
7852 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
7853 reporter->auto_dump =
7854 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
7859 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
7860 struct genl_info *info)
7862 struct devlink *devlink = info->user_ptr[0];
7863 struct devlink_health_reporter *reporter;
7865 reporter = devlink_health_reporter_get_from_info(devlink, info);
7869 return devlink_health_reporter_recover(reporter, NULL, info->extack);
7872 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
7873 struct genl_info *info)
7875 struct devlink *devlink = info->user_ptr[0];
7876 struct devlink_health_reporter *reporter;
7877 struct devlink_fmsg *fmsg;
7880 reporter = devlink_health_reporter_get_from_info(devlink, info);
7884 if (!reporter->ops->diagnose)
7887 fmsg = devlink_fmsg_alloc();
7891 err = devlink_fmsg_obj_nest_start(fmsg);
7895 err = reporter->ops->diagnose(reporter, fmsg, info->extack);
7899 err = devlink_fmsg_obj_nest_end(fmsg);
7903 return devlink_fmsg_snd(fmsg, info,
7904 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
7908 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
7909 struct netlink_callback *cb)
7911 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7912 struct devlink_health_reporter *reporter;
7915 reporter = devlink_health_reporter_get_from_cb(cb);
7919 if (!reporter->ops->dump)
7922 mutex_lock(&reporter->dump_lock);
7924 err = devlink_health_do_dump(reporter, NULL, cb->extack);
7927 state->dump_ts = reporter->dump_ts;
7929 if (!reporter->dump_fmsg || state->dump_ts != reporter->dump_ts) {
7930 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
7935 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
7936 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
7938 mutex_unlock(&reporter->dump_lock);
7943 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
7944 struct genl_info *info)
7946 struct devlink *devlink = info->user_ptr[0];
7947 struct devlink_health_reporter *reporter;
7949 reporter = devlink_health_reporter_get_from_info(devlink, info);
7953 if (!reporter->ops->dump)
7956 mutex_lock(&reporter->dump_lock);
7957 devlink_health_dump_clear(reporter);
7958 mutex_unlock(&reporter->dump_lock);
7962 static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
7963 struct genl_info *info)
7965 struct devlink *devlink = info->user_ptr[0];
7966 struct devlink_health_reporter *reporter;
7968 reporter = devlink_health_reporter_get_from_info(devlink, info);
7972 if (!reporter->ops->test)
7975 return reporter->ops->test(reporter, info->extack);
7978 struct devlink_stats {
7979 u64_stats_t rx_bytes;
7980 u64_stats_t rx_packets;
7981 struct u64_stats_sync syncp;
7985 * struct devlink_trap_policer_item - Packet trap policer attributes.
7986 * @policer: Immutable packet trap policer attributes.
7987 * @rate: Rate in packets / sec.
7988 * @burst: Burst size in packets.
7989 * @list: trap_policer_list member.
7991 * Describes packet trap policer attributes. Created by devlink during trap
7992 * policer registration.
7994 struct devlink_trap_policer_item {
7995 const struct devlink_trap_policer *policer;
7998 struct list_head list;
8002 * struct devlink_trap_group_item - Packet trap group attributes.
8003 * @group: Immutable packet trap group attributes.
8004 * @policer_item: Associated policer item. Can be NULL.
8005 * @list: trap_group_list member.
8006 * @stats: Trap group statistics.
8008 * Describes packet trap group attributes. Created by devlink during trap
8009 * group registration.
8011 struct devlink_trap_group_item {
8012 const struct devlink_trap_group *group;
8013 struct devlink_trap_policer_item *policer_item;
8014 struct list_head list;
8015 struct devlink_stats __percpu *stats;
8019 * struct devlink_trap_item - Packet trap attributes.
8020 * @trap: Immutable packet trap attributes.
8021 * @group_item: Associated group item.
8022 * @list: trap_list member.
8023 * @action: Trap action.
8024 * @stats: Trap statistics.
8025 * @priv: Driver private information.
8027 * Describes both mutable and immutable packet trap attributes. Created by
8028 * devlink during trap registration and used for all trap related operations.
8030 struct devlink_trap_item {
8031 const struct devlink_trap *trap;
8032 struct devlink_trap_group_item *group_item;
8033 struct list_head list;
8034 enum devlink_trap_action action;
8035 struct devlink_stats __percpu *stats;
8039 static struct devlink_trap_policer_item *
8040 devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
8042 struct devlink_trap_policer_item *policer_item;
8044 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
8045 if (policer_item->policer->id == id)
8046 return policer_item;
8052 static struct devlink_trap_item *
8053 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
8055 struct devlink_trap_item *trap_item;
8057 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8058 if (!strcmp(trap_item->trap->name, name))
8065 static struct devlink_trap_item *
8066 devlink_trap_item_get_from_info(struct devlink *devlink,
8067 struct genl_info *info)
8069 struct nlattr *attr;
8071 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
8073 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
8075 return devlink_trap_item_lookup(devlink, nla_data(attr));
8079 devlink_trap_action_get_from_info(struct genl_info *info,
8080 enum devlink_trap_action *p_trap_action)
8084 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
8086 case DEVLINK_TRAP_ACTION_DROP:
8087 case DEVLINK_TRAP_ACTION_TRAP:
8088 case DEVLINK_TRAP_ACTION_MIRROR:
8089 *p_trap_action = val;
8098 static int devlink_trap_metadata_put(struct sk_buff *msg,
8099 const struct devlink_trap *trap)
8101 struct nlattr *attr;
8103 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
8107 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
8108 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
8109 goto nla_put_failure;
8110 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
8111 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
8112 goto nla_put_failure;
8114 nla_nest_end(msg, attr);
8119 nla_nest_cancel(msg, attr);
8123 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
8124 struct devlink_stats *stats)
8128 memset(stats, 0, sizeof(*stats));
8129 for_each_possible_cpu(i) {
8130 struct devlink_stats *cpu_stats;
8131 u64 rx_packets, rx_bytes;
8134 cpu_stats = per_cpu_ptr(trap_stats, i);
8136 start = u64_stats_fetch_begin(&cpu_stats->syncp);
8137 rx_packets = u64_stats_read(&cpu_stats->rx_packets);
8138 rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
8139 } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
8141 u64_stats_add(&stats->rx_packets, rx_packets);
8142 u64_stats_add(&stats->rx_bytes, rx_bytes);
8147 devlink_trap_group_stats_put(struct sk_buff *msg,
8148 struct devlink_stats __percpu *trap_stats)
8150 struct devlink_stats stats;
8151 struct nlattr *attr;
8153 devlink_trap_stats_read(trap_stats, &stats);
8155 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8159 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8160 u64_stats_read(&stats.rx_packets),
8162 goto nla_put_failure;
8164 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8165 u64_stats_read(&stats.rx_bytes),
8167 goto nla_put_failure;
8169 nla_nest_end(msg, attr);
8174 nla_nest_cancel(msg, attr);
8178 static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink,
8179 const struct devlink_trap_item *trap_item)
8181 struct devlink_stats stats;
8182 struct nlattr *attr;
8186 if (devlink->ops->trap_drop_counter_get) {
8187 err = devlink->ops->trap_drop_counter_get(devlink,
8194 devlink_trap_stats_read(trap_item->stats, &stats);
8196 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8200 if (devlink->ops->trap_drop_counter_get &&
8201 nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8203 goto nla_put_failure;
8205 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8206 u64_stats_read(&stats.rx_packets),
8208 goto nla_put_failure;
8210 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8211 u64_stats_read(&stats.rx_bytes),
8213 goto nla_put_failure;
8215 nla_nest_end(msg, attr);
8220 nla_nest_cancel(msg, attr);
8224 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
8225 const struct devlink_trap_item *trap_item,
8226 enum devlink_command cmd, u32 portid, u32 seq,
8229 struct devlink_trap_group_item *group_item = trap_item->group_item;
8233 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8237 if (devlink_nl_put_handle(msg, devlink))
8238 goto nla_put_failure;
8240 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8241 group_item->group->name))
8242 goto nla_put_failure;
8244 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
8245 goto nla_put_failure;
8247 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
8248 goto nla_put_failure;
8250 if (trap_item->trap->generic &&
8251 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8252 goto nla_put_failure;
8254 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
8255 goto nla_put_failure;
8257 err = devlink_trap_metadata_put(msg, trap_item->trap);
8259 goto nla_put_failure;
8261 err = devlink_trap_stats_put(msg, devlink, trap_item);
8263 goto nla_put_failure;
8265 genlmsg_end(msg, hdr);
8270 genlmsg_cancel(msg, hdr);
8274 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
8275 struct genl_info *info)
8277 struct netlink_ext_ack *extack = info->extack;
8278 struct devlink *devlink = info->user_ptr[0];
8279 struct devlink_trap_item *trap_item;
8280 struct sk_buff *msg;
8283 if (list_empty(&devlink->trap_list))
8286 trap_item = devlink_trap_item_get_from_info(devlink, info);
8288 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8292 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8296 err = devlink_nl_trap_fill(msg, devlink, trap_item,
8297 DEVLINK_CMD_TRAP_NEW, info->snd_portid,
8302 return genlmsg_reply(msg, info);
8310 devlink_nl_cmd_trap_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
8311 struct netlink_callback *cb)
8313 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8314 struct devlink_trap_item *trap_item;
8318 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8319 if (idx < state->idx) {
8323 err = devlink_nl_trap_fill(msg, devlink, trap_item,
8324 DEVLINK_CMD_TRAP_NEW,
8325 NETLINK_CB(cb->skb).portid,
8338 const struct devlink_gen_cmd devl_gen_trap = {
8339 .dump_one = devlink_nl_cmd_trap_get_dump_one,
8342 static int __devlink_trap_action_set(struct devlink *devlink,
8343 struct devlink_trap_item *trap_item,
8344 enum devlink_trap_action trap_action,
8345 struct netlink_ext_ack *extack)
8349 if (trap_item->action != trap_action &&
8350 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
8351 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
8355 err = devlink->ops->trap_action_set(devlink, trap_item->trap,
8356 trap_action, extack);
8360 trap_item->action = trap_action;
8365 static int devlink_trap_action_set(struct devlink *devlink,
8366 struct devlink_trap_item *trap_item,
8367 struct genl_info *info)
8369 enum devlink_trap_action trap_action;
8372 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8375 err = devlink_trap_action_get_from_info(info, &trap_action);
8377 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8381 return __devlink_trap_action_set(devlink, trap_item, trap_action,
8385 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
8386 struct genl_info *info)
8388 struct netlink_ext_ack *extack = info->extack;
8389 struct devlink *devlink = info->user_ptr[0];
8390 struct devlink_trap_item *trap_item;
8392 if (list_empty(&devlink->trap_list))
8395 trap_item = devlink_trap_item_get_from_info(devlink, info);
8397 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8401 return devlink_trap_action_set(devlink, trap_item, info);
8404 static struct devlink_trap_group_item *
8405 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
8407 struct devlink_trap_group_item *group_item;
8409 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8410 if (!strcmp(group_item->group->name, name))
8417 static struct devlink_trap_group_item *
8418 devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
8420 struct devlink_trap_group_item *group_item;
8422 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8423 if (group_item->group->id == id)
8430 static struct devlink_trap_group_item *
8431 devlink_trap_group_item_get_from_info(struct devlink *devlink,
8432 struct genl_info *info)
8436 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
8438 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
8440 return devlink_trap_group_item_lookup(devlink, name);
8444 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
8445 const struct devlink_trap_group_item *group_item,
8446 enum devlink_command cmd, u32 portid, u32 seq,
8452 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8456 if (devlink_nl_put_handle(msg, devlink))
8457 goto nla_put_failure;
8459 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8460 group_item->group->name))
8461 goto nla_put_failure;
8463 if (group_item->group->generic &&
8464 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8465 goto nla_put_failure;
8467 if (group_item->policer_item &&
8468 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8469 group_item->policer_item->policer->id))
8470 goto nla_put_failure;
8472 err = devlink_trap_group_stats_put(msg, group_item->stats);
8474 goto nla_put_failure;
8476 genlmsg_end(msg, hdr);
8481 genlmsg_cancel(msg, hdr);
8485 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
8486 struct genl_info *info)
8488 struct netlink_ext_ack *extack = info->extack;
8489 struct devlink *devlink = info->user_ptr[0];
8490 struct devlink_trap_group_item *group_item;
8491 struct sk_buff *msg;
8494 if (list_empty(&devlink->trap_group_list))
8497 group_item = devlink_trap_group_item_get_from_info(devlink, info);
8499 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8503 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8507 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
8508 DEVLINK_CMD_TRAP_GROUP_NEW,
8509 info->snd_portid, info->snd_seq, 0);
8511 goto err_trap_group_fill;
8513 return genlmsg_reply(msg, info);
8515 err_trap_group_fill:
8521 devlink_nl_cmd_trap_group_get_dump_one(struct sk_buff *msg,
8522 struct devlink *devlink,
8523 struct netlink_callback *cb)
8525 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8526 struct devlink_trap_group_item *group_item;
8531 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8532 if (idx < state->idx) {
8536 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
8537 DEVLINK_CMD_TRAP_GROUP_NEW,
8538 NETLINK_CB(cb->skb).portid,
8551 const struct devlink_gen_cmd devl_gen_trap_group = {
8552 .dump_one = devlink_nl_cmd_trap_group_get_dump_one,
8556 __devlink_trap_group_action_set(struct devlink *devlink,
8557 struct devlink_trap_group_item *group_item,
8558 enum devlink_trap_action trap_action,
8559 struct netlink_ext_ack *extack)
8561 const char *group_name = group_item->group->name;
8562 struct devlink_trap_item *trap_item;
8565 if (devlink->ops->trap_group_action_set) {
8566 err = devlink->ops->trap_group_action_set(devlink, group_item->group,
8567 trap_action, extack);
8571 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8572 if (strcmp(trap_item->group_item->group->name, group_name))
8574 if (trap_item->action != trap_action &&
8575 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
8577 trap_item->action = trap_action;
8583 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8584 if (strcmp(trap_item->group_item->group->name, group_name))
8586 err = __devlink_trap_action_set(devlink, trap_item,
8587 trap_action, extack);
8596 devlink_trap_group_action_set(struct devlink *devlink,
8597 struct devlink_trap_group_item *group_item,
8598 struct genl_info *info, bool *p_modified)
8600 enum devlink_trap_action trap_action;
8603 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8606 err = devlink_trap_action_get_from_info(info, &trap_action);
8608 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8612 err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
8622 static int devlink_trap_group_set(struct devlink *devlink,
8623 struct devlink_trap_group_item *group_item,
8624 struct genl_info *info)
8626 struct devlink_trap_policer_item *policer_item;
8627 struct netlink_ext_ack *extack = info->extack;
8628 const struct devlink_trap_policer *policer;
8629 struct nlattr **attrs = info->attrs;
8633 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8636 if (!devlink->ops->trap_group_set)
8639 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8640 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
8641 if (policer_id && !policer_item) {
8642 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8645 policer = policer_item ? policer_item->policer : NULL;
8647 err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
8652 group_item->policer_item = policer_item;
8657 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
8658 struct genl_info *info)
8660 struct netlink_ext_ack *extack = info->extack;
8661 struct devlink *devlink = info->user_ptr[0];
8662 struct devlink_trap_group_item *group_item;
8663 bool modified = false;
8666 if (list_empty(&devlink->trap_group_list))
8669 group_item = devlink_trap_group_item_get_from_info(devlink, info);
8671 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8675 err = devlink_trap_group_action_set(devlink, group_item, info,
8680 err = devlink_trap_group_set(devlink, group_item, info);
8682 goto err_trap_group_set;
8688 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
8692 static struct devlink_trap_policer_item *
8693 devlink_trap_policer_item_get_from_info(struct devlink *devlink,
8694 struct genl_info *info)
8698 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8700 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8702 return devlink_trap_policer_item_lookup(devlink, id);
8706 devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
8707 const struct devlink_trap_policer *policer)
8709 struct nlattr *attr;
8713 if (!devlink->ops->trap_policer_counter_get)
8716 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
8720 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8724 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8726 goto nla_put_failure;
8728 nla_nest_end(msg, attr);
8733 nla_nest_cancel(msg, attr);
8738 devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
8739 const struct devlink_trap_policer_item *policer_item,
8740 enum devlink_command cmd, u32 portid, u32 seq,
8746 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8750 if (devlink_nl_put_handle(msg, devlink))
8751 goto nla_put_failure;
8753 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8754 policer_item->policer->id))
8755 goto nla_put_failure;
8757 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
8758 policer_item->rate, DEVLINK_ATTR_PAD))
8759 goto nla_put_failure;
8761 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
8762 policer_item->burst, DEVLINK_ATTR_PAD))
8763 goto nla_put_failure;
8765 err = devlink_trap_policer_stats_put(msg, devlink,
8766 policer_item->policer);
8768 goto nla_put_failure;
8770 genlmsg_end(msg, hdr);
8775 genlmsg_cancel(msg, hdr);
8779 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
8780 struct genl_info *info)
8782 struct devlink_trap_policer_item *policer_item;
8783 struct netlink_ext_ack *extack = info->extack;
8784 struct devlink *devlink = info->user_ptr[0];
8785 struct sk_buff *msg;
8788 if (list_empty(&devlink->trap_policer_list))
8791 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8792 if (!policer_item) {
8793 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8797 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8801 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
8802 DEVLINK_CMD_TRAP_POLICER_NEW,
8803 info->snd_portid, info->snd_seq, 0);
8805 goto err_trap_policer_fill;
8807 return genlmsg_reply(msg, info);
8809 err_trap_policer_fill:
8815 devlink_nl_cmd_trap_policer_get_dump_one(struct sk_buff *msg,
8816 struct devlink *devlink,
8817 struct netlink_callback *cb)
8819 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8820 struct devlink_trap_policer_item *policer_item;
8824 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
8825 if (idx < state->idx) {
8829 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
8830 DEVLINK_CMD_TRAP_POLICER_NEW,
8831 NETLINK_CB(cb->skb).portid,
8844 const struct devlink_gen_cmd devl_gen_trap_policer = {
8845 .dump_one = devlink_nl_cmd_trap_policer_get_dump_one,
8849 devlink_trap_policer_set(struct devlink *devlink,
8850 struct devlink_trap_policer_item *policer_item,
8851 struct genl_info *info)
8853 struct netlink_ext_ack *extack = info->extack;
8854 struct nlattr **attrs = info->attrs;
8858 rate = policer_item->rate;
8859 burst = policer_item->burst;
8861 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
8862 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
8864 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
8865 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
8867 if (rate < policer_item->policer->min_rate) {
8868 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
8872 if (rate > policer_item->policer->max_rate) {
8873 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
8877 if (burst < policer_item->policer->min_burst) {
8878 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
8882 if (burst > policer_item->policer->max_burst) {
8883 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
8887 err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
8888 rate, burst, info->extack);
8892 policer_item->rate = rate;
8893 policer_item->burst = burst;
8898 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
8899 struct genl_info *info)
8901 struct devlink_trap_policer_item *policer_item;
8902 struct netlink_ext_ack *extack = info->extack;
8903 struct devlink *devlink = info->user_ptr[0];
8905 if (list_empty(&devlink->trap_policer_list))
8908 if (!devlink->ops->trap_policer_set)
8911 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8912 if (!policer_item) {
8913 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8917 return devlink_trap_policer_set(devlink, policer_item, info);
8920 const struct genl_small_ops devlink_nl_ops[56] = {
8922 .cmd = DEVLINK_CMD_GET,
8923 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8924 .doit = devlink_nl_cmd_get_doit,
8925 .dumpit = devlink_nl_instance_iter_dump,
8926 /* can be retrieved by unprivileged users */
8929 .cmd = DEVLINK_CMD_PORT_GET,
8930 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8931 .doit = devlink_nl_cmd_port_get_doit,
8932 .dumpit = devlink_nl_instance_iter_dump,
8933 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8934 /* can be retrieved by unprivileged users */
8937 .cmd = DEVLINK_CMD_PORT_SET,
8938 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8939 .doit = devlink_nl_cmd_port_set_doit,
8940 .flags = GENL_ADMIN_PERM,
8941 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8944 .cmd = DEVLINK_CMD_RATE_GET,
8945 .doit = devlink_nl_cmd_rate_get_doit,
8946 .dumpit = devlink_nl_instance_iter_dump,
8947 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
8948 /* can be retrieved by unprivileged users */
8951 .cmd = DEVLINK_CMD_RATE_SET,
8952 .doit = devlink_nl_cmd_rate_set_doit,
8953 .flags = GENL_ADMIN_PERM,
8954 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
8957 .cmd = DEVLINK_CMD_RATE_NEW,
8958 .doit = devlink_nl_cmd_rate_new_doit,
8959 .flags = GENL_ADMIN_PERM,
8962 .cmd = DEVLINK_CMD_RATE_DEL,
8963 .doit = devlink_nl_cmd_rate_del_doit,
8964 .flags = GENL_ADMIN_PERM,
8965 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE,
8968 .cmd = DEVLINK_CMD_PORT_SPLIT,
8969 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8970 .doit = devlink_nl_cmd_port_split_doit,
8971 .flags = GENL_ADMIN_PERM,
8972 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8975 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
8976 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8977 .doit = devlink_nl_cmd_port_unsplit_doit,
8978 .flags = GENL_ADMIN_PERM,
8979 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8982 .cmd = DEVLINK_CMD_PORT_NEW,
8983 .doit = devlink_nl_cmd_port_new_doit,
8984 .flags = GENL_ADMIN_PERM,
8987 .cmd = DEVLINK_CMD_PORT_DEL,
8988 .doit = devlink_nl_cmd_port_del_doit,
8989 .flags = GENL_ADMIN_PERM,
8992 .cmd = DEVLINK_CMD_LINECARD_GET,
8993 .doit = devlink_nl_cmd_linecard_get_doit,
8994 .dumpit = devlink_nl_instance_iter_dump,
8995 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
8996 /* can be retrieved by unprivileged users */
8999 .cmd = DEVLINK_CMD_LINECARD_SET,
9000 .doit = devlink_nl_cmd_linecard_set_doit,
9001 .flags = GENL_ADMIN_PERM,
9002 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9005 .cmd = DEVLINK_CMD_SB_GET,
9006 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9007 .doit = devlink_nl_cmd_sb_get_doit,
9008 .dumpit = devlink_nl_instance_iter_dump,
9009 /* can be retrieved by unprivileged users */
9012 .cmd = DEVLINK_CMD_SB_POOL_GET,
9013 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9014 .doit = devlink_nl_cmd_sb_pool_get_doit,
9015 .dumpit = devlink_nl_instance_iter_dump,
9016 /* can be retrieved by unprivileged users */
9019 .cmd = DEVLINK_CMD_SB_POOL_SET,
9020 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9021 .doit = devlink_nl_cmd_sb_pool_set_doit,
9022 .flags = GENL_ADMIN_PERM,
9025 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
9026 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9027 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
9028 .dumpit = devlink_nl_instance_iter_dump,
9029 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9030 /* can be retrieved by unprivileged users */
9033 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
9034 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9035 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
9036 .flags = GENL_ADMIN_PERM,
9037 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9040 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
9041 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9042 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
9043 .dumpit = devlink_nl_instance_iter_dump,
9044 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9045 /* can be retrieved by unprivileged users */
9048 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
9049 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9050 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
9051 .flags = GENL_ADMIN_PERM,
9052 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9055 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
9056 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9057 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
9058 .flags = GENL_ADMIN_PERM,
9061 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
9062 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9063 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
9064 .flags = GENL_ADMIN_PERM,
9067 .cmd = DEVLINK_CMD_ESWITCH_GET,
9068 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9069 .doit = devlink_nl_cmd_eswitch_get_doit,
9070 .flags = GENL_ADMIN_PERM,
9073 .cmd = DEVLINK_CMD_ESWITCH_SET,
9074 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9075 .doit = devlink_nl_cmd_eswitch_set_doit,
9076 .flags = GENL_ADMIN_PERM,
9079 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
9080 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9081 .doit = devlink_nl_cmd_dpipe_table_get,
9082 /* can be retrieved by unprivileged users */
9085 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
9086 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9087 .doit = devlink_nl_cmd_dpipe_entries_get,
9088 /* can be retrieved by unprivileged users */
9091 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
9092 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9093 .doit = devlink_nl_cmd_dpipe_headers_get,
9094 /* can be retrieved by unprivileged users */
9097 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
9098 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9099 .doit = devlink_nl_cmd_dpipe_table_counters_set,
9100 .flags = GENL_ADMIN_PERM,
9103 .cmd = DEVLINK_CMD_RESOURCE_SET,
9104 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9105 .doit = devlink_nl_cmd_resource_set,
9106 .flags = GENL_ADMIN_PERM,
9109 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
9110 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9111 .doit = devlink_nl_cmd_resource_dump,
9112 /* can be retrieved by unprivileged users */
9115 .cmd = DEVLINK_CMD_RELOAD,
9116 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9117 .doit = devlink_nl_cmd_reload,
9118 .flags = GENL_ADMIN_PERM,
9121 .cmd = DEVLINK_CMD_PARAM_GET,
9122 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9123 .doit = devlink_nl_cmd_param_get_doit,
9124 .dumpit = devlink_nl_instance_iter_dump,
9125 /* can be retrieved by unprivileged users */
9128 .cmd = DEVLINK_CMD_PARAM_SET,
9129 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9130 .doit = devlink_nl_cmd_param_set_doit,
9131 .flags = GENL_ADMIN_PERM,
9134 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
9135 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9136 .doit = devlink_nl_cmd_port_param_get_doit,
9137 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
9138 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9139 /* can be retrieved by unprivileged users */
9142 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
9143 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9144 .doit = devlink_nl_cmd_port_param_set_doit,
9145 .flags = GENL_ADMIN_PERM,
9146 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9149 .cmd = DEVLINK_CMD_REGION_GET,
9150 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9151 .doit = devlink_nl_cmd_region_get_doit,
9152 .dumpit = devlink_nl_instance_iter_dump,
9153 .flags = GENL_ADMIN_PERM,
9156 .cmd = DEVLINK_CMD_REGION_NEW,
9157 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9158 .doit = devlink_nl_cmd_region_new,
9159 .flags = GENL_ADMIN_PERM,
9162 .cmd = DEVLINK_CMD_REGION_DEL,
9163 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9164 .doit = devlink_nl_cmd_region_del,
9165 .flags = GENL_ADMIN_PERM,
9168 .cmd = DEVLINK_CMD_REGION_READ,
9169 .validate = GENL_DONT_VALIDATE_STRICT |
9170 GENL_DONT_VALIDATE_DUMP_STRICT,
9171 .dumpit = devlink_nl_cmd_region_read_dumpit,
9172 .flags = GENL_ADMIN_PERM,
9175 .cmd = DEVLINK_CMD_INFO_GET,
9176 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9177 .doit = devlink_nl_cmd_info_get_doit,
9178 .dumpit = devlink_nl_instance_iter_dump,
9179 /* can be retrieved by unprivileged users */
9182 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
9183 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9184 .doit = devlink_nl_cmd_health_reporter_get_doit,
9185 .dumpit = devlink_nl_instance_iter_dump,
9186 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9187 /* can be retrieved by unprivileged users */
9190 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
9191 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9192 .doit = devlink_nl_cmd_health_reporter_set_doit,
9193 .flags = GENL_ADMIN_PERM,
9194 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9197 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
9198 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9199 .doit = devlink_nl_cmd_health_reporter_recover_doit,
9200 .flags = GENL_ADMIN_PERM,
9201 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9204 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
9205 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9206 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
9207 .flags = GENL_ADMIN_PERM,
9208 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9211 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
9212 .validate = GENL_DONT_VALIDATE_STRICT |
9213 GENL_DONT_VALIDATE_DUMP_STRICT,
9214 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
9215 .flags = GENL_ADMIN_PERM,
9218 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
9219 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9220 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
9221 .flags = GENL_ADMIN_PERM,
9222 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9225 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
9226 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9227 .doit = devlink_nl_cmd_health_reporter_test_doit,
9228 .flags = GENL_ADMIN_PERM,
9229 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9232 .cmd = DEVLINK_CMD_FLASH_UPDATE,
9233 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9234 .doit = devlink_nl_cmd_flash_update,
9235 .flags = GENL_ADMIN_PERM,
9238 .cmd = DEVLINK_CMD_TRAP_GET,
9239 .doit = devlink_nl_cmd_trap_get_doit,
9240 .dumpit = devlink_nl_instance_iter_dump,
9241 /* can be retrieved by unprivileged users */
9244 .cmd = DEVLINK_CMD_TRAP_SET,
9245 .doit = devlink_nl_cmd_trap_set_doit,
9246 .flags = GENL_ADMIN_PERM,
9249 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
9250 .doit = devlink_nl_cmd_trap_group_get_doit,
9251 .dumpit = devlink_nl_instance_iter_dump,
9252 /* can be retrieved by unprivileged users */
9255 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
9256 .doit = devlink_nl_cmd_trap_group_set_doit,
9257 .flags = GENL_ADMIN_PERM,
9260 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
9261 .doit = devlink_nl_cmd_trap_policer_get_doit,
9262 .dumpit = devlink_nl_instance_iter_dump,
9263 /* can be retrieved by unprivileged users */
9266 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
9267 .doit = devlink_nl_cmd_trap_policer_set_doit,
9268 .flags = GENL_ADMIN_PERM,
9271 .cmd = DEVLINK_CMD_SELFTESTS_GET,
9272 .doit = devlink_nl_cmd_selftests_get_doit,
9273 .dumpit = devlink_nl_instance_iter_dump,
9274 /* can be retrieved by unprivileged users */
9277 .cmd = DEVLINK_CMD_SELFTESTS_RUN,
9278 .doit = devlink_nl_cmd_selftests_run,
9279 .flags = GENL_ADMIN_PERM,
9281 /* -- No new ops here! Use split ops going forward! -- */
9284 bool devlink_reload_actions_valid(const struct devlink_ops *ops)
9286 const struct devlink_reload_combination *comb;
9289 if (!devlink_reload_supported(ops)) {
9290 if (WARN_ON(ops->reload_actions))
9295 if (WARN_ON(!ops->reload_actions ||
9296 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
9297 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
9300 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
9301 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
9304 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) {
9305 comb = &devlink_reload_invalid_combinations[i];
9306 if (ops->reload_actions == BIT(comb->action) &&
9307 ops->reload_limits == BIT(comb->limit))
9314 devlink_trap_policer_notify(struct devlink *devlink,
9315 const struct devlink_trap_policer_item *policer_item,
9316 enum devlink_command cmd);
9318 devlink_trap_group_notify(struct devlink *devlink,
9319 const struct devlink_trap_group_item *group_item,
9320 enum devlink_command cmd);
9321 static void devlink_trap_notify(struct devlink *devlink,
9322 const struct devlink_trap_item *trap_item,
9323 enum devlink_command cmd);
9325 void devlink_notify_register(struct devlink *devlink)
9327 struct devlink_trap_policer_item *policer_item;
9328 struct devlink_trap_group_item *group_item;
9329 struct devlink_param_item *param_item;
9330 struct devlink_trap_item *trap_item;
9331 struct devlink_port *devlink_port;
9332 struct devlink_linecard *linecard;
9333 struct devlink_rate *rate_node;
9334 struct devlink_region *region;
9335 unsigned long port_index;
9337 devlink_notify(devlink, DEVLINK_CMD_NEW);
9338 list_for_each_entry(linecard, &devlink->linecard_list, list)
9339 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
9341 xa_for_each(&devlink->ports, port_index, devlink_port)
9342 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9344 list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
9345 devlink_trap_policer_notify(devlink, policer_item,
9346 DEVLINK_CMD_TRAP_POLICER_NEW);
9348 list_for_each_entry(group_item, &devlink->trap_group_list, list)
9349 devlink_trap_group_notify(devlink, group_item,
9350 DEVLINK_CMD_TRAP_GROUP_NEW);
9352 list_for_each_entry(trap_item, &devlink->trap_list, list)
9353 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
9355 list_for_each_entry(rate_node, &devlink->rate_list, list)
9356 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
9358 list_for_each_entry(region, &devlink->region_list, list)
9359 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9361 list_for_each_entry(param_item, &devlink->param_list, list)
9362 devlink_param_notify(devlink, 0, param_item,
9363 DEVLINK_CMD_PARAM_NEW);
9366 void devlink_notify_unregister(struct devlink *devlink)
9368 struct devlink_trap_policer_item *policer_item;
9369 struct devlink_trap_group_item *group_item;
9370 struct devlink_param_item *param_item;
9371 struct devlink_trap_item *trap_item;
9372 struct devlink_port *devlink_port;
9373 struct devlink_rate *rate_node;
9374 struct devlink_region *region;
9375 unsigned long port_index;
9377 list_for_each_entry_reverse(param_item, &devlink->param_list, list)
9378 devlink_param_notify(devlink, 0, param_item,
9379 DEVLINK_CMD_PARAM_DEL);
9381 list_for_each_entry_reverse(region, &devlink->region_list, list)
9382 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
9384 list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
9385 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
9387 list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
9388 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
9390 list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
9391 devlink_trap_group_notify(devlink, group_item,
9392 DEVLINK_CMD_TRAP_GROUP_DEL);
9393 list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
9395 devlink_trap_policer_notify(devlink, policer_item,
9396 DEVLINK_CMD_TRAP_POLICER_DEL);
9398 xa_for_each(&devlink->ports, port_index, devlink_port)
9399 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9400 devlink_notify(devlink, DEVLINK_CMD_DEL);
9403 static void devlink_port_type_warn(struct work_struct *work)
9405 WARN(true, "Type was not set for devlink port.");
9408 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
9410 /* Ignore CPU and DSA flavours. */
9411 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
9412 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
9413 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
9416 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
9418 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
9420 if (!devlink_port_type_should_warn(devlink_port))
9422 /* Schedule a work to WARN in case driver does not set port
9423 * type within timeout.
9425 schedule_delayed_work(&devlink_port->type_warn_dw,
9426 DEVLINK_PORT_TYPE_WARN_TIMEOUT);
9429 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
9431 if (!devlink_port_type_should_warn(devlink_port))
9433 cancel_delayed_work_sync(&devlink_port->type_warn_dw);
9437 * devlink_port_init() - Init devlink port
9440 * @devlink_port: devlink port
9442 * Initialize essencial stuff that is needed for functions
9443 * that may be called before devlink port registration.
9444 * Call to this function is optional and not needed
9445 * in case the driver does not use such functions.
9447 void devlink_port_init(struct devlink *devlink,
9448 struct devlink_port *devlink_port)
9450 if (devlink_port->initialized)
9452 devlink_port->devlink = devlink;
9453 INIT_LIST_HEAD(&devlink_port->region_list);
9454 devlink_port->initialized = true;
9456 EXPORT_SYMBOL_GPL(devlink_port_init);
9459 * devlink_port_fini() - Deinitialize devlink port
9461 * @devlink_port: devlink port
9463 * Deinitialize essencial stuff that is in use for functions
9464 * that may be called after devlink port unregistration.
9465 * Call to this function is optional and not needed
9466 * in case the driver does not use such functions.
9468 void devlink_port_fini(struct devlink_port *devlink_port)
9470 WARN_ON(!list_empty(&devlink_port->region_list));
9472 EXPORT_SYMBOL_GPL(devlink_port_fini);
9475 * devl_port_register() - Register devlink port
9478 * @devlink_port: devlink port
9479 * @port_index: driver-specific numerical identifier of the port
9481 * Register devlink port with provided port index. User can use
9482 * any indexing, even hw-related one. devlink_port structure
9483 * is convenient to be embedded inside user driver private structure.
9484 * Note that the caller should take care of zeroing the devlink_port
9487 int devl_port_register(struct devlink *devlink,
9488 struct devlink_port *devlink_port,
9489 unsigned int port_index)
9493 devl_assert_locked(devlink);
9495 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9497 devlink_port_init(devlink, devlink_port);
9498 devlink_port->registered = true;
9499 devlink_port->index = port_index;
9500 spin_lock_init(&devlink_port->type_lock);
9501 INIT_LIST_HEAD(&devlink_port->reporter_list);
9502 err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL);
9506 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
9507 devlink_port_type_warn_schedule(devlink_port);
9508 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9511 EXPORT_SYMBOL_GPL(devl_port_register);
9514 * devlink_port_register - Register devlink port
9517 * @devlink_port: devlink port
9518 * @port_index: driver-specific numerical identifier of the port
9520 * Register devlink port with provided port index. User can use
9521 * any indexing, even hw-related one. devlink_port structure
9522 * is convenient to be embedded inside user driver private structure.
9523 * Note that the caller should take care of zeroing the devlink_port
9526 * Context: Takes and release devlink->lock <mutex>.
9528 int devlink_port_register(struct devlink *devlink,
9529 struct devlink_port *devlink_port,
9530 unsigned int port_index)
9535 err = devl_port_register(devlink, devlink_port, port_index);
9536 devl_unlock(devlink);
9539 EXPORT_SYMBOL_GPL(devlink_port_register);
9542 * devl_port_unregister() - Unregister devlink port
9544 * @devlink_port: devlink port
9546 void devl_port_unregister(struct devlink_port *devlink_port)
9548 lockdep_assert_held(&devlink_port->devlink->lock);
9549 WARN_ON(devlink_port->type != DEVLINK_PORT_TYPE_NOTSET);
9551 devlink_port_type_warn_cancel(devlink_port);
9552 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9553 xa_erase(&devlink_port->devlink->ports, devlink_port->index);
9554 WARN_ON(!list_empty(&devlink_port->reporter_list));
9555 devlink_port->registered = false;
9557 EXPORT_SYMBOL_GPL(devl_port_unregister);
9560 * devlink_port_unregister - Unregister devlink port
9562 * @devlink_port: devlink port
9564 * Context: Takes and release devlink->lock <mutex>.
9566 void devlink_port_unregister(struct devlink_port *devlink_port)
9568 struct devlink *devlink = devlink_port->devlink;
9571 devl_port_unregister(devlink_port);
9572 devl_unlock(devlink);
9574 EXPORT_SYMBOL_GPL(devlink_port_unregister);
9576 static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
9577 struct net_device *netdev)
9579 const struct net_device_ops *ops = netdev->netdev_ops;
9581 /* If driver registers devlink port, it should set devlink port
9582 * attributes accordingly so the compat functions are called
9583 * and the original ops are not used.
9585 if (ops->ndo_get_phys_port_name) {
9586 /* Some drivers use the same set of ndos for netdevs
9587 * that have devlink_port registered and also for
9588 * those who don't. Make sure that ndo_get_phys_port_name
9589 * returns -EOPNOTSUPP here in case it is defined.
9592 char name[IFNAMSIZ];
9595 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
9596 WARN_ON(err != -EOPNOTSUPP);
9598 if (ops->ndo_get_port_parent_id) {
9599 /* Some drivers use the same set of ndos for netdevs
9600 * that have devlink_port registered and also for
9601 * those who don't. Make sure that ndo_get_port_parent_id
9602 * returns -EOPNOTSUPP here in case it is defined.
9605 struct netdev_phys_item_id ppid;
9608 err = ops->ndo_get_port_parent_id(netdev, &ppid);
9609 WARN_ON(err != -EOPNOTSUPP);
9613 static void __devlink_port_type_set(struct devlink_port *devlink_port,
9614 enum devlink_port_type type,
9617 struct net_device *netdev = type_dev;
9619 ASSERT_DEVLINK_PORT_REGISTERED(devlink_port);
9621 if (type == DEVLINK_PORT_TYPE_NOTSET) {
9622 devlink_port_type_warn_schedule(devlink_port);
9624 devlink_port_type_warn_cancel(devlink_port);
9625 if (type == DEVLINK_PORT_TYPE_ETH && netdev)
9626 devlink_port_type_netdev_checks(devlink_port, netdev);
9629 spin_lock_bh(&devlink_port->type_lock);
9630 devlink_port->type = type;
9632 case DEVLINK_PORT_TYPE_ETH:
9633 devlink_port->type_eth.netdev = netdev;
9636 devlink_port->type_eth.ifindex = netdev->ifindex;
9637 BUILD_BUG_ON(sizeof(devlink_port->type_eth.ifname) !=
9638 sizeof(netdev->name));
9639 strcpy(devlink_port->type_eth.ifname, netdev->name);
9642 case DEVLINK_PORT_TYPE_IB:
9643 devlink_port->type_ib.ibdev = type_dev;
9648 spin_unlock_bh(&devlink_port->type_lock);
9649 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9653 * devlink_port_type_eth_set - Set port type to Ethernet
9655 * @devlink_port: devlink port
9657 * If driver is calling this, most likely it is doing something wrong.
9659 void devlink_port_type_eth_set(struct devlink_port *devlink_port)
9661 dev_warn(devlink_port->devlink->dev,
9662 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
9663 devlink_port->index);
9664 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL);
9666 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
9669 * devlink_port_type_ib_set - Set port type to InfiniBand
9671 * @devlink_port: devlink port
9672 * @ibdev: related IB device
9674 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
9675 struct ib_device *ibdev)
9677 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
9679 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
9682 * devlink_port_type_clear - Clear port type
9684 * @devlink_port: devlink port
9686 * If driver is calling this for clearing Ethernet type, most likely
9687 * it is doing something wrong.
9689 void devlink_port_type_clear(struct devlink_port *devlink_port)
9691 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH)
9692 dev_warn(devlink_port->devlink->dev,
9693 "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n",
9694 devlink_port->index);
9695 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
9697 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
9699 int devlink_port_netdevice_event(struct notifier_block *nb,
9700 unsigned long event, void *ptr)
9702 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
9703 struct devlink_port *devlink_port = netdev->devlink_port;
9704 struct devlink *devlink;
9706 devlink = container_of(nb, struct devlink, netdevice_nb);
9708 if (!devlink_port || devlink_port->devlink != devlink)
9712 case NETDEV_POST_INIT:
9713 /* Set the type but not netdev pointer. It is going to be set
9714 * later on by NETDEV_REGISTER event. Happens once during
9715 * netdevice register
9717 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH,
9720 case NETDEV_REGISTER:
9721 case NETDEV_CHANGENAME:
9722 /* Set the netdev on top of previously set type. Note this
9723 * event happens also during net namespace change so here
9724 * we take into account netdev pointer appearing in this
9727 __devlink_port_type_set(devlink_port, devlink_port->type,
9730 case NETDEV_UNREGISTER:
9731 /* Clear netdev pointer, but not the type. This event happens
9732 * also during net namespace change so we need to clear
9733 * pointer to netdev that is going to another net namespace.
9735 __devlink_port_type_set(devlink_port, devlink_port->type,
9738 case NETDEV_PRE_UNINIT:
9739 /* Clear the type and the netdev pointer. Happens one during
9740 * netdevice unregister.
9742 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET,
9750 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
9751 enum devlink_port_flavour flavour)
9753 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9755 devlink_port->attrs_set = true;
9756 attrs->flavour = flavour;
9757 if (attrs->switch_id.id_len) {
9758 devlink_port->switch_port = true;
9759 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
9760 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
9762 devlink_port->switch_port = false;
9768 * devlink_port_attrs_set - Set port attributes
9770 * @devlink_port: devlink port
9771 * @attrs: devlink port attrs
9773 void devlink_port_attrs_set(struct devlink_port *devlink_port,
9774 struct devlink_port_attrs *attrs)
9778 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9780 devlink_port->attrs = *attrs;
9781 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
9784 WARN_ON(attrs->splittable && attrs->split);
9786 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
9789 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
9791 * @devlink_port: devlink port
9792 * @controller: associated controller number for the devlink port instance
9793 * @pf: associated PF for the devlink port instance
9794 * @external: indicates if the port is for an external controller
9796 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
9797 u16 pf, bool external)
9799 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9802 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9804 ret = __devlink_port_attrs_set(devlink_port,
9805 DEVLINK_PORT_FLAVOUR_PCI_PF);
9808 attrs->pci_pf.controller = controller;
9809 attrs->pci_pf.pf = pf;
9810 attrs->pci_pf.external = external;
9812 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
9815 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
9817 * @devlink_port: devlink port
9818 * @controller: associated controller number for the devlink port instance
9819 * @pf: associated PF for the devlink port instance
9820 * @vf: associated VF of a PF for the devlink port instance
9821 * @external: indicates if the port is for an external controller
9823 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
9824 u16 pf, u16 vf, bool external)
9826 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9829 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9831 ret = __devlink_port_attrs_set(devlink_port,
9832 DEVLINK_PORT_FLAVOUR_PCI_VF);
9835 attrs->pci_vf.controller = controller;
9836 attrs->pci_vf.pf = pf;
9837 attrs->pci_vf.vf = vf;
9838 attrs->pci_vf.external = external;
9840 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
9843 * devlink_port_attrs_pci_sf_set - Set PCI SF port attributes
9845 * @devlink_port: devlink port
9846 * @controller: associated controller number for the devlink port instance
9847 * @pf: associated PF for the devlink port instance
9848 * @sf: associated SF of a PF for the devlink port instance
9849 * @external: indicates if the port is for an external controller
9851 void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller,
9852 u16 pf, u32 sf, bool external)
9854 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9857 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9859 ret = __devlink_port_attrs_set(devlink_port,
9860 DEVLINK_PORT_FLAVOUR_PCI_SF);
9863 attrs->pci_sf.controller = controller;
9864 attrs->pci_sf.pf = pf;
9865 attrs->pci_sf.sf = sf;
9866 attrs->pci_sf.external = external;
9868 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
9871 * devl_rate_node_create - create devlink rate node
9872 * @devlink: devlink instance
9873 * @priv: driver private data
9874 * @node_name: name of the resulting node
9875 * @parent: parent devlink_rate struct
9877 * Create devlink rate object of type node
9879 struct devlink_rate *
9880 devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
9881 struct devlink_rate *parent)
9883 struct devlink_rate *rate_node;
9885 rate_node = devlink_rate_node_get_by_name(devlink, node_name);
9886 if (!IS_ERR(rate_node))
9887 return ERR_PTR(-EEXIST);
9889 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
9891 return ERR_PTR(-ENOMEM);
9894 rate_node->parent = parent;
9895 refcount_inc(&rate_node->parent->refcnt);
9898 rate_node->type = DEVLINK_RATE_TYPE_NODE;
9899 rate_node->devlink = devlink;
9900 rate_node->priv = priv;
9902 rate_node->name = kstrdup(node_name, GFP_KERNEL);
9903 if (!rate_node->name) {
9905 return ERR_PTR(-ENOMEM);
9908 refcount_set(&rate_node->refcnt, 1);
9909 list_add(&rate_node->list, &devlink->rate_list);
9910 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
9913 EXPORT_SYMBOL_GPL(devl_rate_node_create);
9916 * devl_rate_leaf_create - create devlink rate leaf
9917 * @devlink_port: devlink port object to create rate object on
9918 * @priv: driver private data
9919 * @parent: parent devlink_rate struct
9921 * Create devlink rate object of type leaf on provided @devlink_port.
9923 int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv,
9924 struct devlink_rate *parent)
9926 struct devlink *devlink = devlink_port->devlink;
9927 struct devlink_rate *devlink_rate;
9929 devl_assert_locked(devlink_port->devlink);
9931 if (WARN_ON(devlink_port->devlink_rate))
9934 devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL);
9939 devlink_rate->parent = parent;
9940 refcount_inc(&devlink_rate->parent->refcnt);
9943 devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
9944 devlink_rate->devlink = devlink;
9945 devlink_rate->devlink_port = devlink_port;
9946 devlink_rate->priv = priv;
9947 list_add_tail(&devlink_rate->list, &devlink->rate_list);
9948 devlink_port->devlink_rate = devlink_rate;
9949 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
9953 EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
9956 * devl_rate_leaf_destroy - destroy devlink rate leaf
9958 * @devlink_port: devlink port linked to the rate object
9960 * Destroy the devlink rate object of type leaf on provided @devlink_port.
9962 void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
9964 struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
9966 devl_assert_locked(devlink_port->devlink);
9970 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
9971 if (devlink_rate->parent)
9972 refcount_dec(&devlink_rate->parent->refcnt);
9973 list_del(&devlink_rate->list);
9974 devlink_port->devlink_rate = NULL;
9975 kfree(devlink_rate);
9977 EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
9980 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
9981 * @devlink: devlink instance
9983 * Unset parent for all rate objects and destroy all rate nodes
9984 * on specified device.
9986 void devl_rate_nodes_destroy(struct devlink *devlink)
9988 static struct devlink_rate *devlink_rate, *tmp;
9989 const struct devlink_ops *ops = devlink->ops;
9991 devl_assert_locked(devlink);
9993 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
9994 if (!devlink_rate->parent)
9997 refcount_dec(&devlink_rate->parent->refcnt);
9998 if (devlink_rate_is_leaf(devlink_rate))
9999 ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
10001 else if (devlink_rate_is_node(devlink_rate))
10002 ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
10005 list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
10006 if (devlink_rate_is_node(devlink_rate)) {
10007 ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
10008 list_del(&devlink_rate->list);
10009 kfree(devlink_rate->name);
10010 kfree(devlink_rate);
10014 EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);
10017 * devlink_port_linecard_set - Link port with a linecard
10019 * @devlink_port: devlink port
10020 * @linecard: devlink linecard
10022 void devlink_port_linecard_set(struct devlink_port *devlink_port,
10023 struct devlink_linecard *linecard)
10025 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10027 devlink_port->linecard = linecard;
10029 EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
10031 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
10032 char *name, size_t len)
10034 struct devlink_port_attrs *attrs = &devlink_port->attrs;
10037 if (!devlink_port->attrs_set)
10038 return -EOPNOTSUPP;
10040 switch (attrs->flavour) {
10041 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
10042 if (devlink_port->linecard)
10043 n = snprintf(name, len, "l%u",
10044 devlink_port->linecard->index);
10046 n += snprintf(name + n, len - n, "p%u",
10047 attrs->phys.port_number);
10048 if (n < len && attrs->split)
10049 n += snprintf(name + n, len - n, "s%u",
10050 attrs->phys.split_subport_number);
10052 case DEVLINK_PORT_FLAVOUR_CPU:
10053 case DEVLINK_PORT_FLAVOUR_DSA:
10054 case DEVLINK_PORT_FLAVOUR_UNUSED:
10055 /* As CPU and DSA ports do not have a netdevice associated
10056 * case should not ever happen.
10060 case DEVLINK_PORT_FLAVOUR_PCI_PF:
10061 if (attrs->pci_pf.external) {
10062 n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
10068 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
10070 case DEVLINK_PORT_FLAVOUR_PCI_VF:
10071 if (attrs->pci_vf.external) {
10072 n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
10078 n = snprintf(name, len, "pf%uvf%u",
10079 attrs->pci_vf.pf, attrs->pci_vf.vf);
10081 case DEVLINK_PORT_FLAVOUR_PCI_SF:
10082 if (attrs->pci_sf.external) {
10083 n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
10089 n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf,
10092 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
10093 return -EOPNOTSUPP;
10102 static int devlink_linecard_types_init(struct devlink_linecard *linecard)
10104 struct devlink_linecard_type *linecard_type;
10105 unsigned int count;
10108 count = linecard->ops->types_count(linecard, linecard->priv);
10109 linecard->types = kmalloc_array(count, sizeof(*linecard_type),
10111 if (!linecard->types)
10113 linecard->types_count = count;
10115 for (i = 0; i < count; i++) {
10116 linecard_type = &linecard->types[i];
10117 linecard->ops->types_get(linecard, linecard->priv, i,
10118 &linecard_type->type,
10119 &linecard_type->priv);
10124 static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
10126 kfree(linecard->types);
10130 * devl_linecard_create - Create devlink linecard
10132 * @devlink: devlink
10133 * @linecard_index: driver-specific numerical identifier of the linecard
10134 * @ops: linecards ops
10135 * @priv: user priv pointer
10137 * Create devlink linecard instance with provided linecard index.
10138 * Caller can use any indexing, even hw-related one.
10140 * Return: Line card structure or an ERR_PTR() encoded error code.
10142 struct devlink_linecard *
10143 devl_linecard_create(struct devlink *devlink, unsigned int linecard_index,
10144 const struct devlink_linecard_ops *ops, void *priv)
10146 struct devlink_linecard *linecard;
10149 if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
10150 !ops->types_count || !ops->types_get))
10151 return ERR_PTR(-EINVAL);
10153 if (devlink_linecard_index_exists(devlink, linecard_index))
10154 return ERR_PTR(-EEXIST);
10156 linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
10158 return ERR_PTR(-ENOMEM);
10160 linecard->devlink = devlink;
10161 linecard->index = linecard_index;
10162 linecard->ops = ops;
10163 linecard->priv = priv;
10164 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10165 mutex_init(&linecard->state_lock);
10167 err = devlink_linecard_types_init(linecard);
10169 mutex_destroy(&linecard->state_lock);
10171 return ERR_PTR(err);
10174 list_add_tail(&linecard->list, &devlink->linecard_list);
10175 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10178 EXPORT_SYMBOL_GPL(devl_linecard_create);
10181 * devl_linecard_destroy - Destroy devlink linecard
10183 * @linecard: devlink linecard
10185 void devl_linecard_destroy(struct devlink_linecard *linecard)
10187 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
10188 list_del(&linecard->list);
10189 devlink_linecard_types_fini(linecard);
10190 mutex_destroy(&linecard->state_lock);
10193 EXPORT_SYMBOL_GPL(devl_linecard_destroy);
10196 * devlink_linecard_provision_set - Set provisioning on linecard
10198 * @linecard: devlink linecard
10199 * @type: linecard type
10201 * This is either called directly from the provision() op call or
10202 * as a result of the provision() op call asynchronously.
10204 void devlink_linecard_provision_set(struct devlink_linecard *linecard,
10207 mutex_lock(&linecard->state_lock);
10208 WARN_ON(linecard->type && strcmp(linecard->type, type));
10209 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10210 linecard->type = type;
10211 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10212 mutex_unlock(&linecard->state_lock);
10214 EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
10217 * devlink_linecard_provision_clear - Clear provisioning on linecard
10219 * @linecard: devlink linecard
10221 * This is either called directly from the unprovision() op call or
10222 * as a result of the unprovision() op call asynchronously.
10224 void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
10226 mutex_lock(&linecard->state_lock);
10227 WARN_ON(linecard->nested_devlink);
10228 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10229 linecard->type = NULL;
10230 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10231 mutex_unlock(&linecard->state_lock);
10233 EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
10236 * devlink_linecard_provision_fail - Fail provisioning on linecard
10238 * @linecard: devlink linecard
10240 * This is either called directly from the provision() op call or
10241 * as a result of the provision() op call asynchronously.
10243 void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
10245 mutex_lock(&linecard->state_lock);
10246 WARN_ON(linecard->nested_devlink);
10247 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
10248 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10249 mutex_unlock(&linecard->state_lock);
10251 EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
10254 * devlink_linecard_activate - Set linecard active
10256 * @linecard: devlink linecard
10258 void devlink_linecard_activate(struct devlink_linecard *linecard)
10260 mutex_lock(&linecard->state_lock);
10261 WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
10262 linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
10263 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10264 mutex_unlock(&linecard->state_lock);
10266 EXPORT_SYMBOL_GPL(devlink_linecard_activate);
10269 * devlink_linecard_deactivate - Set linecard inactive
10271 * @linecard: devlink linecard
10273 void devlink_linecard_deactivate(struct devlink_linecard *linecard)
10275 mutex_lock(&linecard->state_lock);
10276 switch (linecard->state) {
10277 case DEVLINK_LINECARD_STATE_ACTIVE:
10278 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10279 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10281 case DEVLINK_LINECARD_STATE_UNPROVISIONING:
10282 /* Line card is being deactivated as part
10283 * of unprovisioning flow.
10290 mutex_unlock(&linecard->state_lock);
10292 EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
10295 * devlink_linecard_nested_dl_set - Attach/detach nested devlink
10296 * instance to linecard.
10298 * @linecard: devlink linecard
10299 * @nested_devlink: devlink instance to attach or NULL to detach
10301 void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
10302 struct devlink *nested_devlink)
10304 mutex_lock(&linecard->state_lock);
10305 linecard->nested_devlink = nested_devlink;
10306 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10307 mutex_unlock(&linecard->state_lock);
10309 EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
10311 int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
10312 u32 size, u16 ingress_pools_count,
10313 u16 egress_pools_count, u16 ingress_tc_count,
10314 u16 egress_tc_count)
10316 struct devlink_sb *devlink_sb;
10318 lockdep_assert_held(&devlink->lock);
10320 if (devlink_sb_index_exists(devlink, sb_index))
10323 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
10326 devlink_sb->index = sb_index;
10327 devlink_sb->size = size;
10328 devlink_sb->ingress_pools_count = ingress_pools_count;
10329 devlink_sb->egress_pools_count = egress_pools_count;
10330 devlink_sb->ingress_tc_count = ingress_tc_count;
10331 devlink_sb->egress_tc_count = egress_tc_count;
10332 list_add_tail(&devlink_sb->list, &devlink->sb_list);
10335 EXPORT_SYMBOL_GPL(devl_sb_register);
10337 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
10338 u32 size, u16 ingress_pools_count,
10339 u16 egress_pools_count, u16 ingress_tc_count,
10340 u16 egress_tc_count)
10344 devl_lock(devlink);
10345 err = devl_sb_register(devlink, sb_index, size, ingress_pools_count,
10346 egress_pools_count, ingress_tc_count,
10348 devl_unlock(devlink);
10351 EXPORT_SYMBOL_GPL(devlink_sb_register);
10353 void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10355 struct devlink_sb *devlink_sb;
10357 lockdep_assert_held(&devlink->lock);
10359 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
10360 WARN_ON(!devlink_sb);
10361 list_del(&devlink_sb->list);
10364 EXPORT_SYMBOL_GPL(devl_sb_unregister);
10366 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10368 devl_lock(devlink);
10369 devl_sb_unregister(devlink, sb_index);
10370 devl_unlock(devlink);
10372 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
10375 * devl_dpipe_headers_register - register dpipe headers
10377 * @devlink: devlink
10378 * @dpipe_headers: dpipe header array
10380 * Register the headers supported by hardware.
10382 void devl_dpipe_headers_register(struct devlink *devlink,
10383 struct devlink_dpipe_headers *dpipe_headers)
10385 lockdep_assert_held(&devlink->lock);
10387 devlink->dpipe_headers = dpipe_headers;
10389 EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
10392 * devl_dpipe_headers_unregister - unregister dpipe headers
10394 * @devlink: devlink
10396 * Unregister the headers supported by hardware.
10398 void devl_dpipe_headers_unregister(struct devlink *devlink)
10400 lockdep_assert_held(&devlink->lock);
10402 devlink->dpipe_headers = NULL;
10404 EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
10407 * devlink_dpipe_table_counter_enabled - check if counter allocation
10409 * @devlink: devlink
10410 * @table_name: tables name
10412 * Used by driver to check if counter allocation is required.
10413 * After counter allocation is turned on the table entries
10414 * are updated to include counter statistics.
10416 * After that point on the driver must respect the counter
10417 * state so that each entry added to the table is added
10420 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
10421 const char *table_name)
10423 struct devlink_dpipe_table *table;
10427 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10428 table_name, devlink);
10431 enabled = table->counters_enabled;
10435 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
10438 * devl_dpipe_table_register - register dpipe table
10440 * @devlink: devlink
10441 * @table_name: table name
10442 * @table_ops: table ops
10444 * @counter_control_extern: external control for counters
10446 int devl_dpipe_table_register(struct devlink *devlink,
10447 const char *table_name,
10448 struct devlink_dpipe_table_ops *table_ops,
10449 void *priv, bool counter_control_extern)
10451 struct devlink_dpipe_table *table;
10453 lockdep_assert_held(&devlink->lock);
10455 if (WARN_ON(!table_ops->size_get))
10458 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
10462 table = kzalloc(sizeof(*table), GFP_KERNEL);
10466 table->name = table_name;
10467 table->table_ops = table_ops;
10468 table->priv = priv;
10469 table->counter_control_extern = counter_control_extern;
10471 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
10475 EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
10478 * devl_dpipe_table_unregister - unregister dpipe table
10480 * @devlink: devlink
10481 * @table_name: table name
10483 void devl_dpipe_table_unregister(struct devlink *devlink,
10484 const char *table_name)
10486 struct devlink_dpipe_table *table;
10488 lockdep_assert_held(&devlink->lock);
10490 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10491 table_name, devlink);
10494 list_del_rcu(&table->list);
10495 kfree_rcu(table, rcu);
10497 EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
10500 * devl_resource_register - devlink resource register
10502 * @devlink: devlink
10503 * @resource_name: resource's name
10504 * @resource_size: resource's size
10505 * @resource_id: resource's id
10506 * @parent_resource_id: resource's parent id
10507 * @size_params: size parameters
10509 * Generic resources should reuse the same names across drivers.
10510 * Please see the generic resources list at:
10511 * Documentation/networking/devlink/devlink-resource.rst
10513 int devl_resource_register(struct devlink *devlink,
10514 const char *resource_name,
10517 u64 parent_resource_id,
10518 const struct devlink_resource_size_params *size_params)
10520 struct devlink_resource *resource;
10521 struct list_head *resource_list;
10522 bool top_hierarchy;
10524 lockdep_assert_held(&devlink->lock);
10526 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
10528 resource = devlink_resource_find(devlink, NULL, resource_id);
10532 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
10536 if (top_hierarchy) {
10537 resource_list = &devlink->resource_list;
10539 struct devlink_resource *parent_resource;
10541 parent_resource = devlink_resource_find(devlink, NULL,
10542 parent_resource_id);
10543 if (parent_resource) {
10544 resource_list = &parent_resource->resource_list;
10545 resource->parent = parent_resource;
10552 resource->name = resource_name;
10553 resource->size = resource_size;
10554 resource->size_new = resource_size;
10555 resource->id = resource_id;
10556 resource->size_valid = true;
10557 memcpy(&resource->size_params, size_params,
10558 sizeof(resource->size_params));
10559 INIT_LIST_HEAD(&resource->resource_list);
10560 list_add_tail(&resource->list, resource_list);
10564 EXPORT_SYMBOL_GPL(devl_resource_register);
10567 * devlink_resource_register - devlink resource register
10569 * @devlink: devlink
10570 * @resource_name: resource's name
10571 * @resource_size: resource's size
10572 * @resource_id: resource's id
10573 * @parent_resource_id: resource's parent id
10574 * @size_params: size parameters
10576 * Generic resources should reuse the same names across drivers.
10577 * Please see the generic resources list at:
10578 * Documentation/networking/devlink/devlink-resource.rst
10580 * Context: Takes and release devlink->lock <mutex>.
10582 int devlink_resource_register(struct devlink *devlink,
10583 const char *resource_name,
10586 u64 parent_resource_id,
10587 const struct devlink_resource_size_params *size_params)
10591 devl_lock(devlink);
10592 err = devl_resource_register(devlink, resource_name, resource_size,
10593 resource_id, parent_resource_id, size_params);
10594 devl_unlock(devlink);
10597 EXPORT_SYMBOL_GPL(devlink_resource_register);
10599 static void devlink_resource_unregister(struct devlink *devlink,
10600 struct devlink_resource *resource)
10602 struct devlink_resource *tmp, *child_resource;
10604 list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
10606 devlink_resource_unregister(devlink, child_resource);
10607 list_del(&child_resource->list);
10608 kfree(child_resource);
10613 * devl_resources_unregister - free all resources
10615 * @devlink: devlink
10617 void devl_resources_unregister(struct devlink *devlink)
10619 struct devlink_resource *tmp, *child_resource;
10621 lockdep_assert_held(&devlink->lock);
10623 list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
10625 devlink_resource_unregister(devlink, child_resource);
10626 list_del(&child_resource->list);
10627 kfree(child_resource);
10630 EXPORT_SYMBOL_GPL(devl_resources_unregister);
10633 * devlink_resources_unregister - free all resources
10635 * @devlink: devlink
10637 * Context: Takes and release devlink->lock <mutex>.
10639 void devlink_resources_unregister(struct devlink *devlink)
10641 devl_lock(devlink);
10642 devl_resources_unregister(devlink);
10643 devl_unlock(devlink);
10645 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
10648 * devl_resource_size_get - get and update size
10650 * @devlink: devlink
10651 * @resource_id: the requested resource id
10652 * @p_resource_size: ptr to update
10654 int devl_resource_size_get(struct devlink *devlink,
10656 u64 *p_resource_size)
10658 struct devlink_resource *resource;
10660 lockdep_assert_held(&devlink->lock);
10662 resource = devlink_resource_find(devlink, NULL, resource_id);
10665 *p_resource_size = resource->size_new;
10666 resource->size = resource->size_new;
10669 EXPORT_SYMBOL_GPL(devl_resource_size_get);
10672 * devl_dpipe_table_resource_set - set the resource id
10674 * @devlink: devlink
10675 * @table_name: table name
10676 * @resource_id: resource id
10677 * @resource_units: number of resource's units consumed per table's entry
10679 int devl_dpipe_table_resource_set(struct devlink *devlink,
10680 const char *table_name, u64 resource_id,
10681 u64 resource_units)
10683 struct devlink_dpipe_table *table;
10685 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10686 table_name, devlink);
10690 table->resource_id = resource_id;
10691 table->resource_units = resource_units;
10692 table->resource_valid = true;
10695 EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
10698 * devl_resource_occ_get_register - register occupancy getter
10700 * @devlink: devlink
10701 * @resource_id: resource id
10702 * @occ_get: occupancy getter callback
10703 * @occ_get_priv: occupancy getter callback priv
10705 void devl_resource_occ_get_register(struct devlink *devlink,
10707 devlink_resource_occ_get_t *occ_get,
10708 void *occ_get_priv)
10710 struct devlink_resource *resource;
10712 lockdep_assert_held(&devlink->lock);
10714 resource = devlink_resource_find(devlink, NULL, resource_id);
10715 if (WARN_ON(!resource))
10717 WARN_ON(resource->occ_get);
10719 resource->occ_get = occ_get;
10720 resource->occ_get_priv = occ_get_priv;
10722 EXPORT_SYMBOL_GPL(devl_resource_occ_get_register);
10725 * devlink_resource_occ_get_register - register occupancy getter
10727 * @devlink: devlink
10728 * @resource_id: resource id
10729 * @occ_get: occupancy getter callback
10730 * @occ_get_priv: occupancy getter callback priv
10732 * Context: Takes and release devlink->lock <mutex>.
10734 void devlink_resource_occ_get_register(struct devlink *devlink,
10736 devlink_resource_occ_get_t *occ_get,
10737 void *occ_get_priv)
10739 devl_lock(devlink);
10740 devl_resource_occ_get_register(devlink, resource_id,
10741 occ_get, occ_get_priv);
10742 devl_unlock(devlink);
10744 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
10747 * devl_resource_occ_get_unregister - unregister occupancy getter
10749 * @devlink: devlink
10750 * @resource_id: resource id
10752 void devl_resource_occ_get_unregister(struct devlink *devlink,
10755 struct devlink_resource *resource;
10757 lockdep_assert_held(&devlink->lock);
10759 resource = devlink_resource_find(devlink, NULL, resource_id);
10760 if (WARN_ON(!resource))
10762 WARN_ON(!resource->occ_get);
10764 resource->occ_get = NULL;
10765 resource->occ_get_priv = NULL;
10767 EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
10770 * devlink_resource_occ_get_unregister - unregister occupancy getter
10772 * @devlink: devlink
10773 * @resource_id: resource id
10775 * Context: Takes and release devlink->lock <mutex>.
10777 void devlink_resource_occ_get_unregister(struct devlink *devlink,
10780 devl_lock(devlink);
10781 devl_resource_occ_get_unregister(devlink, resource_id);
10782 devl_unlock(devlink);
10784 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
10786 static int devlink_param_verify(const struct devlink_param *param)
10788 if (!param || !param->name || !param->supported_cmodes)
10790 if (param->generic)
10791 return devlink_param_generic_verify(param);
10793 return devlink_param_driver_verify(param);
10796 static int devlink_param_register(struct devlink *devlink,
10797 const struct devlink_param *param)
10799 struct devlink_param_item *param_item;
10801 WARN_ON(devlink_param_verify(param));
10802 WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name));
10804 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
10805 WARN_ON(param->get || param->set);
10807 WARN_ON(!param->get || !param->set);
10809 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
10813 param_item->param = param;
10815 list_add_tail(¶m_item->list, &devlink->param_list);
10816 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
10820 static void devlink_param_unregister(struct devlink *devlink,
10821 const struct devlink_param *param)
10823 struct devlink_param_item *param_item;
10826 devlink_param_find_by_name(&devlink->param_list, param->name);
10827 if (WARN_ON(!param_item))
10829 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL);
10830 list_del(¶m_item->list);
10835 * devl_params_register - register configuration parameters
10837 * @devlink: devlink
10838 * @params: configuration parameters array
10839 * @params_count: number of parameters provided
10841 * Register the configuration parameters supported by the driver.
10843 int devl_params_register(struct devlink *devlink,
10844 const struct devlink_param *params,
10845 size_t params_count)
10847 const struct devlink_param *param = params;
10850 lockdep_assert_held(&devlink->lock);
10852 for (i = 0; i < params_count; i++, param++) {
10853 err = devlink_param_register(devlink, param);
10863 for (param--; i > 0; i--, param--)
10864 devlink_param_unregister(devlink, param);
10867 EXPORT_SYMBOL_GPL(devl_params_register);
10869 int devlink_params_register(struct devlink *devlink,
10870 const struct devlink_param *params,
10871 size_t params_count)
10875 devl_lock(devlink);
10876 err = devl_params_register(devlink, params, params_count);
10877 devl_unlock(devlink);
10880 EXPORT_SYMBOL_GPL(devlink_params_register);
10883 * devl_params_unregister - unregister configuration parameters
10884 * @devlink: devlink
10885 * @params: configuration parameters to unregister
10886 * @params_count: number of parameters provided
10888 void devl_params_unregister(struct devlink *devlink,
10889 const struct devlink_param *params,
10890 size_t params_count)
10892 const struct devlink_param *param = params;
10895 lockdep_assert_held(&devlink->lock);
10897 for (i = 0; i < params_count; i++, param++)
10898 devlink_param_unregister(devlink, param);
10900 EXPORT_SYMBOL_GPL(devl_params_unregister);
10902 void devlink_params_unregister(struct devlink *devlink,
10903 const struct devlink_param *params,
10904 size_t params_count)
10906 devl_lock(devlink);
10907 devl_params_unregister(devlink, params, params_count);
10908 devl_unlock(devlink);
10910 EXPORT_SYMBOL_GPL(devlink_params_unregister);
10913 * devl_param_driverinit_value_get - get configuration parameter
10914 * value for driver initializing
10916 * @devlink: devlink
10917 * @param_id: parameter ID
10918 * @init_val: value of parameter in driverinit configuration mode
10920 * This function should be used by the driver to get driverinit
10921 * configuration for initialization after reload command.
10923 int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
10924 union devlink_param_value *init_val)
10926 struct devlink_param_item *param_item;
10928 lockdep_assert_held(&devlink->lock);
10930 if (WARN_ON(!devlink_reload_supported(devlink->ops)))
10931 return -EOPNOTSUPP;
10933 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
10937 if (!param_item->driverinit_value_valid)
10938 return -EOPNOTSUPP;
10940 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
10941 DEVLINK_PARAM_CMODE_DRIVERINIT)))
10942 return -EOPNOTSUPP;
10944 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
10945 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
10947 *init_val = param_item->driverinit_value;
10951 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_get);
10954 * devl_param_driverinit_value_set - set value of configuration
10955 * parameter for driverinit
10956 * configuration mode
10958 * @devlink: devlink
10959 * @param_id: parameter ID
10960 * @init_val: value of parameter to set for driverinit configuration mode
10962 * This function should be used by the driver to set driverinit
10963 * configuration mode default value.
10965 void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
10966 union devlink_param_value init_val)
10968 struct devlink_param_item *param_item;
10970 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
10971 if (WARN_ON(!param_item))
10974 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
10975 DEVLINK_PARAM_CMODE_DRIVERINIT)))
10978 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
10979 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
10981 param_item->driverinit_value = init_val;
10982 param_item->driverinit_value_valid = true;
10984 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
10986 EXPORT_SYMBOL_GPL(devl_param_driverinit_value_set);
10989 * devl_param_value_changed - notify devlink on a parameter's value
10990 * change. Should be called by the driver
10991 * right after the change.
10993 * @devlink: devlink
10994 * @param_id: parameter ID
10996 * This function should be used by the driver to notify devlink on value
10997 * change, excluding driverinit configuration mode.
10998 * For driverinit configuration mode driver should use the function
11000 void devl_param_value_changed(struct devlink *devlink, u32 param_id)
11002 struct devlink_param_item *param_item;
11004 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11005 WARN_ON(!param_item);
11007 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
11009 EXPORT_SYMBOL_GPL(devl_param_value_changed);
11012 * devl_region_create - create a new address region
11014 * @devlink: devlink
11015 * @ops: region operations and name
11016 * @region_max_snapshots: Maximum supported number of snapshots for region
11017 * @region_size: size of region
11019 struct devlink_region *devl_region_create(struct devlink *devlink,
11020 const struct devlink_region_ops *ops,
11021 u32 region_max_snapshots,
11024 struct devlink_region *region;
11026 devl_assert_locked(devlink);
11028 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11029 return ERR_PTR(-EINVAL);
11031 if (devlink_region_get_by_name(devlink, ops->name))
11032 return ERR_PTR(-EEXIST);
11034 region = kzalloc(sizeof(*region), GFP_KERNEL);
11036 return ERR_PTR(-ENOMEM);
11038 region->devlink = devlink;
11039 region->max_snapshots = region_max_snapshots;
11041 region->size = region_size;
11042 INIT_LIST_HEAD(®ion->snapshot_list);
11043 mutex_init(®ion->snapshot_lock);
11044 list_add_tail(®ion->list, &devlink->region_list);
11045 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11049 EXPORT_SYMBOL_GPL(devl_region_create);
11052 * devlink_region_create - create a new address region
11054 * @devlink: devlink
11055 * @ops: region operations and name
11056 * @region_max_snapshots: Maximum supported number of snapshots for region
11057 * @region_size: size of region
11059 * Context: Takes and release devlink->lock <mutex>.
11061 struct devlink_region *
11062 devlink_region_create(struct devlink *devlink,
11063 const struct devlink_region_ops *ops,
11064 u32 region_max_snapshots, u64 region_size)
11066 struct devlink_region *region;
11068 devl_lock(devlink);
11069 region = devl_region_create(devlink, ops, region_max_snapshots,
11071 devl_unlock(devlink);
11074 EXPORT_SYMBOL_GPL(devlink_region_create);
11077 * devlink_port_region_create - create a new address region for a port
11079 * @port: devlink port
11080 * @ops: region operations and name
11081 * @region_max_snapshots: Maximum supported number of snapshots for region
11082 * @region_size: size of region
11084 * Context: Takes and release devlink->lock <mutex>.
11086 struct devlink_region *
11087 devlink_port_region_create(struct devlink_port *port,
11088 const struct devlink_port_region_ops *ops,
11089 u32 region_max_snapshots, u64 region_size)
11091 struct devlink *devlink = port->devlink;
11092 struct devlink_region *region;
11095 ASSERT_DEVLINK_PORT_INITIALIZED(port);
11097 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11098 return ERR_PTR(-EINVAL);
11100 devl_lock(devlink);
11102 if (devlink_port_region_get_by_name(port, ops->name)) {
11107 region = kzalloc(sizeof(*region), GFP_KERNEL);
11113 region->devlink = devlink;
11114 region->port = port;
11115 region->max_snapshots = region_max_snapshots;
11116 region->port_ops = ops;
11117 region->size = region_size;
11118 INIT_LIST_HEAD(®ion->snapshot_list);
11119 mutex_init(®ion->snapshot_lock);
11120 list_add_tail(®ion->list, &port->region_list);
11121 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11123 devl_unlock(devlink);
11127 devl_unlock(devlink);
11128 return ERR_PTR(err);
11130 EXPORT_SYMBOL_GPL(devlink_port_region_create);
11133 * devl_region_destroy - destroy address region
11135 * @region: devlink region to destroy
11137 void devl_region_destroy(struct devlink_region *region)
11139 struct devlink *devlink = region->devlink;
11140 struct devlink_snapshot *snapshot, *ts;
11142 devl_assert_locked(devlink);
11144 /* Free all snapshots of region */
11145 mutex_lock(®ion->snapshot_lock);
11146 list_for_each_entry_safe(snapshot, ts, ®ion->snapshot_list, list)
11147 devlink_region_snapshot_del(region, snapshot);
11148 mutex_unlock(®ion->snapshot_lock);
11150 list_del(®ion->list);
11151 mutex_destroy(®ion->snapshot_lock);
11153 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
11156 EXPORT_SYMBOL_GPL(devl_region_destroy);
11159 * devlink_region_destroy - destroy address region
11161 * @region: devlink region to destroy
11163 * Context: Takes and release devlink->lock <mutex>.
11165 void devlink_region_destroy(struct devlink_region *region)
11167 struct devlink *devlink = region->devlink;
11169 devl_lock(devlink);
11170 devl_region_destroy(region);
11171 devl_unlock(devlink);
11173 EXPORT_SYMBOL_GPL(devlink_region_destroy);
11176 * devlink_region_snapshot_id_get - get snapshot ID
11178 * This callback should be called when adding a new snapshot,
11179 * Driver should use the same id for multiple snapshots taken
11180 * on multiple regions at the same time/by the same trigger.
11182 * The caller of this function must use devlink_region_snapshot_id_put
11183 * when finished creating regions using this id.
11185 * Returns zero on success, or a negative error code on failure.
11187 * @devlink: devlink
11188 * @id: storage to return id
11190 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
11192 return __devlink_region_snapshot_id_get(devlink, id);
11194 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
11197 * devlink_region_snapshot_id_put - put snapshot ID reference
11199 * This should be called by a driver after finishing creating snapshots
11200 * with an id. Doing so ensures that the ID can later be released in the
11201 * event that all snapshots using it have been destroyed.
11203 * @devlink: devlink
11204 * @id: id to release reference on
11206 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
11208 __devlink_snapshot_id_decrement(devlink, id);
11210 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
11213 * devlink_region_snapshot_create - create a new snapshot
11214 * This will add a new snapshot of a region. The snapshot
11215 * will be stored on the region struct and can be accessed
11216 * from devlink. This is useful for future analyses of snapshots.
11217 * Multiple snapshots can be created on a region.
11218 * The @snapshot_id should be obtained using the getter function.
11220 * @region: devlink region of the snapshot
11221 * @data: snapshot data
11222 * @snapshot_id: snapshot id to be created
11224 int devlink_region_snapshot_create(struct devlink_region *region,
11225 u8 *data, u32 snapshot_id)
11229 mutex_lock(®ion->snapshot_lock);
11230 err = __devlink_region_snapshot_create(region, data, snapshot_id);
11231 mutex_unlock(®ion->snapshot_lock);
11234 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
11236 #define DEVLINK_TRAP(_id, _type) \
11238 .type = DEVLINK_TRAP_TYPE_##_type, \
11239 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
11240 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
11243 static const struct devlink_trap devlink_trap_generic[] = {
11244 DEVLINK_TRAP(SMAC_MC, DROP),
11245 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
11246 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
11247 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
11248 DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
11249 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
11250 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
11251 DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
11252 DEVLINK_TRAP(TAIL_DROP, DROP),
11253 DEVLINK_TRAP(NON_IP_PACKET, DROP),
11254 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
11255 DEVLINK_TRAP(DIP_LB, DROP),
11256 DEVLINK_TRAP(SIP_MC, DROP),
11257 DEVLINK_TRAP(SIP_LB, DROP),
11258 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
11259 DEVLINK_TRAP(IPV4_SIP_BC, DROP),
11260 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
11261 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
11262 DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
11263 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
11264 DEVLINK_TRAP(RPF, EXCEPTION),
11265 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
11266 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
11267 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
11268 DEVLINK_TRAP(NON_ROUTABLE, DROP),
11269 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
11270 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
11271 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
11272 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
11273 DEVLINK_TRAP(STP, CONTROL),
11274 DEVLINK_TRAP(LACP, CONTROL),
11275 DEVLINK_TRAP(LLDP, CONTROL),
11276 DEVLINK_TRAP(IGMP_QUERY, CONTROL),
11277 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
11278 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
11279 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
11280 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
11281 DEVLINK_TRAP(MLD_QUERY, CONTROL),
11282 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
11283 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
11284 DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
11285 DEVLINK_TRAP(IPV4_DHCP, CONTROL),
11286 DEVLINK_TRAP(IPV6_DHCP, CONTROL),
11287 DEVLINK_TRAP(ARP_REQUEST, CONTROL),
11288 DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
11289 DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
11290 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
11291 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
11292 DEVLINK_TRAP(IPV4_BFD, CONTROL),
11293 DEVLINK_TRAP(IPV6_BFD, CONTROL),
11294 DEVLINK_TRAP(IPV4_OSPF, CONTROL),
11295 DEVLINK_TRAP(IPV6_OSPF, CONTROL),
11296 DEVLINK_TRAP(IPV4_BGP, CONTROL),
11297 DEVLINK_TRAP(IPV6_BGP, CONTROL),
11298 DEVLINK_TRAP(IPV4_VRRP, CONTROL),
11299 DEVLINK_TRAP(IPV6_VRRP, CONTROL),
11300 DEVLINK_TRAP(IPV4_PIM, CONTROL),
11301 DEVLINK_TRAP(IPV6_PIM, CONTROL),
11302 DEVLINK_TRAP(UC_LB, CONTROL),
11303 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
11304 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
11305 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
11306 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
11307 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
11308 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
11309 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
11310 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
11311 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
11312 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
11313 DEVLINK_TRAP(PTP_EVENT, CONTROL),
11314 DEVLINK_TRAP(PTP_GENERAL, CONTROL),
11315 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
11316 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
11317 DEVLINK_TRAP(EARLY_DROP, DROP),
11318 DEVLINK_TRAP(VXLAN_PARSING, DROP),
11319 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
11320 DEVLINK_TRAP(VLAN_PARSING, DROP),
11321 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
11322 DEVLINK_TRAP(MPLS_PARSING, DROP),
11323 DEVLINK_TRAP(ARP_PARSING, DROP),
11324 DEVLINK_TRAP(IP_1_PARSING, DROP),
11325 DEVLINK_TRAP(IP_N_PARSING, DROP),
11326 DEVLINK_TRAP(GRE_PARSING, DROP),
11327 DEVLINK_TRAP(UDP_PARSING, DROP),
11328 DEVLINK_TRAP(TCP_PARSING, DROP),
11329 DEVLINK_TRAP(IPSEC_PARSING, DROP),
11330 DEVLINK_TRAP(SCTP_PARSING, DROP),
11331 DEVLINK_TRAP(DCCP_PARSING, DROP),
11332 DEVLINK_TRAP(GTP_PARSING, DROP),
11333 DEVLINK_TRAP(ESP_PARSING, DROP),
11334 DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP),
11335 DEVLINK_TRAP(DMAC_FILTER, DROP),
11336 DEVLINK_TRAP(EAPOL, CONTROL),
11337 DEVLINK_TRAP(LOCKED_PORT, DROP),
11340 #define DEVLINK_TRAP_GROUP(_id) \
11342 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
11343 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
11346 static const struct devlink_trap_group devlink_trap_group_generic[] = {
11347 DEVLINK_TRAP_GROUP(L2_DROPS),
11348 DEVLINK_TRAP_GROUP(L3_DROPS),
11349 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
11350 DEVLINK_TRAP_GROUP(BUFFER_DROPS),
11351 DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
11352 DEVLINK_TRAP_GROUP(ACL_DROPS),
11353 DEVLINK_TRAP_GROUP(STP),
11354 DEVLINK_TRAP_GROUP(LACP),
11355 DEVLINK_TRAP_GROUP(LLDP),
11356 DEVLINK_TRAP_GROUP(MC_SNOOPING),
11357 DEVLINK_TRAP_GROUP(DHCP),
11358 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
11359 DEVLINK_TRAP_GROUP(BFD),
11360 DEVLINK_TRAP_GROUP(OSPF),
11361 DEVLINK_TRAP_GROUP(BGP),
11362 DEVLINK_TRAP_GROUP(VRRP),
11363 DEVLINK_TRAP_GROUP(PIM),
11364 DEVLINK_TRAP_GROUP(UC_LB),
11365 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
11366 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
11367 DEVLINK_TRAP_GROUP(IPV6),
11368 DEVLINK_TRAP_GROUP(PTP_EVENT),
11369 DEVLINK_TRAP_GROUP(PTP_GENERAL),
11370 DEVLINK_TRAP_GROUP(ACL_SAMPLE),
11371 DEVLINK_TRAP_GROUP(ACL_TRAP),
11372 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
11373 DEVLINK_TRAP_GROUP(EAPOL),
11376 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
11378 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
11381 if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
11384 if (trap->type != devlink_trap_generic[trap->id].type)
11390 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
11394 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
11397 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
11398 if (!strcmp(trap->name, devlink_trap_generic[i].name))
11405 static int devlink_trap_verify(const struct devlink_trap *trap)
11407 if (!trap || !trap->name)
11411 return devlink_trap_generic_verify(trap);
11413 return devlink_trap_driver_verify(trap);
11417 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
11419 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11422 if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
11429 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
11433 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11436 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
11437 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
11444 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
11446 if (group->generic)
11447 return devlink_trap_group_generic_verify(group);
11449 return devlink_trap_group_driver_verify(group);
11453 devlink_trap_group_notify(struct devlink *devlink,
11454 const struct devlink_trap_group_item *group_item,
11455 enum devlink_command cmd)
11457 struct sk_buff *msg;
11460 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
11461 cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
11462 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11465 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11469 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
11476 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11477 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11481 devlink_trap_item_group_link(struct devlink *devlink,
11482 struct devlink_trap_item *trap_item)
11484 u16 group_id = trap_item->trap->init_group_id;
11485 struct devlink_trap_group_item *group_item;
11487 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
11488 if (WARN_ON_ONCE(!group_item))
11491 trap_item->group_item = group_item;
11496 static void devlink_trap_notify(struct devlink *devlink,
11497 const struct devlink_trap_item *trap_item,
11498 enum devlink_command cmd)
11500 struct sk_buff *msg;
11503 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
11504 cmd != DEVLINK_CMD_TRAP_DEL);
11505 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11508 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11512 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
11518 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11519 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11523 devlink_trap_register(struct devlink *devlink,
11524 const struct devlink_trap *trap, void *priv)
11526 struct devlink_trap_item *trap_item;
11529 if (devlink_trap_item_lookup(devlink, trap->name))
11532 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
11536 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11537 if (!trap_item->stats) {
11539 goto err_stats_alloc;
11542 trap_item->trap = trap;
11543 trap_item->action = trap->init_action;
11544 trap_item->priv = priv;
11546 err = devlink_trap_item_group_link(devlink, trap_item);
11548 goto err_group_link;
11550 err = devlink->ops->trap_init(devlink, trap, trap_item);
11552 goto err_trap_init;
11554 list_add_tail(&trap_item->list, &devlink->trap_list);
11555 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
11561 free_percpu(trap_item->stats);
11567 static void devlink_trap_unregister(struct devlink *devlink,
11568 const struct devlink_trap *trap)
11570 struct devlink_trap_item *trap_item;
11572 trap_item = devlink_trap_item_lookup(devlink, trap->name);
11573 if (WARN_ON_ONCE(!trap_item))
11576 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
11577 list_del(&trap_item->list);
11578 if (devlink->ops->trap_fini)
11579 devlink->ops->trap_fini(devlink, trap, trap_item);
11580 free_percpu(trap_item->stats);
11584 static void devlink_trap_disable(struct devlink *devlink,
11585 const struct devlink_trap *trap)
11587 struct devlink_trap_item *trap_item;
11589 trap_item = devlink_trap_item_lookup(devlink, trap->name);
11590 if (WARN_ON_ONCE(!trap_item))
11593 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
11595 trap_item->action = DEVLINK_TRAP_ACTION_DROP;
11599 * devl_traps_register - Register packet traps with devlink.
11600 * @devlink: devlink.
11601 * @traps: Packet traps.
11602 * @traps_count: Count of provided packet traps.
11603 * @priv: Driver private information.
11605 * Return: Non-zero value on failure.
11607 int devl_traps_register(struct devlink *devlink,
11608 const struct devlink_trap *traps,
11609 size_t traps_count, void *priv)
11613 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
11616 devl_assert_locked(devlink);
11617 for (i = 0; i < traps_count; i++) {
11618 const struct devlink_trap *trap = &traps[i];
11620 err = devlink_trap_verify(trap);
11622 goto err_trap_verify;
11624 err = devlink_trap_register(devlink, trap, priv);
11626 goto err_trap_register;
11633 for (i--; i >= 0; i--)
11634 devlink_trap_unregister(devlink, &traps[i]);
11637 EXPORT_SYMBOL_GPL(devl_traps_register);
11640 * devlink_traps_register - Register packet traps with devlink.
11641 * @devlink: devlink.
11642 * @traps: Packet traps.
11643 * @traps_count: Count of provided packet traps.
11644 * @priv: Driver private information.
11646 * Context: Takes and release devlink->lock <mutex>.
11648 * Return: Non-zero value on failure.
11650 int devlink_traps_register(struct devlink *devlink,
11651 const struct devlink_trap *traps,
11652 size_t traps_count, void *priv)
11656 devl_lock(devlink);
11657 err = devl_traps_register(devlink, traps, traps_count, priv);
11658 devl_unlock(devlink);
11661 EXPORT_SYMBOL_GPL(devlink_traps_register);
11664 * devl_traps_unregister - Unregister packet traps from devlink.
11665 * @devlink: devlink.
11666 * @traps: Packet traps.
11667 * @traps_count: Count of provided packet traps.
11669 void devl_traps_unregister(struct devlink *devlink,
11670 const struct devlink_trap *traps,
11671 size_t traps_count)
11675 devl_assert_locked(devlink);
11676 /* Make sure we do not have any packets in-flight while unregistering
11677 * traps by disabling all of them and waiting for a grace period.
11679 for (i = traps_count - 1; i >= 0; i--)
11680 devlink_trap_disable(devlink, &traps[i]);
11682 for (i = traps_count - 1; i >= 0; i--)
11683 devlink_trap_unregister(devlink, &traps[i]);
11685 EXPORT_SYMBOL_GPL(devl_traps_unregister);
11688 * devlink_traps_unregister - Unregister packet traps from devlink.
11689 * @devlink: devlink.
11690 * @traps: Packet traps.
11691 * @traps_count: Count of provided packet traps.
11693 * Context: Takes and release devlink->lock <mutex>.
11695 void devlink_traps_unregister(struct devlink *devlink,
11696 const struct devlink_trap *traps,
11697 size_t traps_count)
11699 devl_lock(devlink);
11700 devl_traps_unregister(devlink, traps, traps_count);
11701 devl_unlock(devlink);
11703 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
11706 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
11709 struct devlink_stats *stats;
11711 stats = this_cpu_ptr(trap_stats);
11712 u64_stats_update_begin(&stats->syncp);
11713 u64_stats_add(&stats->rx_bytes, skb_len);
11714 u64_stats_inc(&stats->rx_packets);
11715 u64_stats_update_end(&stats->syncp);
11719 devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
11720 const struct devlink_trap_item *trap_item,
11721 struct devlink_port *in_devlink_port,
11722 const struct flow_action_cookie *fa_cookie)
11724 metadata->trap_name = trap_item->trap->name;
11725 metadata->trap_group_name = trap_item->group_item->group->name;
11726 metadata->fa_cookie = fa_cookie;
11727 metadata->trap_type = trap_item->trap->type;
11729 spin_lock(&in_devlink_port->type_lock);
11730 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
11731 metadata->input_dev = in_devlink_port->type_eth.netdev;
11732 spin_unlock(&in_devlink_port->type_lock);
11736 * devlink_trap_report - Report trapped packet to drop monitor.
11737 * @devlink: devlink.
11738 * @skb: Trapped packet.
11739 * @trap_ctx: Trap context.
11740 * @in_devlink_port: Input devlink port.
11741 * @fa_cookie: Flow action cookie. Could be NULL.
11743 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
11744 void *trap_ctx, struct devlink_port *in_devlink_port,
11745 const struct flow_action_cookie *fa_cookie)
11748 struct devlink_trap_item *trap_item = trap_ctx;
11750 devlink_trap_stats_update(trap_item->stats, skb->len);
11751 devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
11753 if (trace_devlink_trap_report_enabled()) {
11754 struct devlink_trap_metadata metadata = {};
11756 devlink_trap_report_metadata_set(&metadata, trap_item,
11757 in_devlink_port, fa_cookie);
11758 trace_devlink_trap_report(devlink, skb, &metadata);
11761 EXPORT_SYMBOL_GPL(devlink_trap_report);
11764 * devlink_trap_ctx_priv - Trap context to driver private information.
11765 * @trap_ctx: Trap context.
11767 * Return: Driver private information passed during registration.
11769 void *devlink_trap_ctx_priv(void *trap_ctx)
11771 struct devlink_trap_item *trap_item = trap_ctx;
11773 return trap_item->priv;
11775 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
11778 devlink_trap_group_item_policer_link(struct devlink *devlink,
11779 struct devlink_trap_group_item *group_item)
11781 u32 policer_id = group_item->group->init_policer_id;
11782 struct devlink_trap_policer_item *policer_item;
11784 if (policer_id == 0)
11787 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
11788 if (WARN_ON_ONCE(!policer_item))
11791 group_item->policer_item = policer_item;
11797 devlink_trap_group_register(struct devlink *devlink,
11798 const struct devlink_trap_group *group)
11800 struct devlink_trap_group_item *group_item;
11803 if (devlink_trap_group_item_lookup(devlink, group->name))
11806 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
11810 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11811 if (!group_item->stats) {
11813 goto err_stats_alloc;
11816 group_item->group = group;
11818 err = devlink_trap_group_item_policer_link(devlink, group_item);
11820 goto err_policer_link;
11822 if (devlink->ops->trap_group_init) {
11823 err = devlink->ops->trap_group_init(devlink, group);
11825 goto err_group_init;
11828 list_add_tail(&group_item->list, &devlink->trap_group_list);
11829 devlink_trap_group_notify(devlink, group_item,
11830 DEVLINK_CMD_TRAP_GROUP_NEW);
11836 free_percpu(group_item->stats);
11843 devlink_trap_group_unregister(struct devlink *devlink,
11844 const struct devlink_trap_group *group)
11846 struct devlink_trap_group_item *group_item;
11848 group_item = devlink_trap_group_item_lookup(devlink, group->name);
11849 if (WARN_ON_ONCE(!group_item))
11852 devlink_trap_group_notify(devlink, group_item,
11853 DEVLINK_CMD_TRAP_GROUP_DEL);
11854 list_del(&group_item->list);
11855 free_percpu(group_item->stats);
11860 * devl_trap_groups_register - Register packet trap groups with devlink.
11861 * @devlink: devlink.
11862 * @groups: Packet trap groups.
11863 * @groups_count: Count of provided packet trap groups.
11865 * Return: Non-zero value on failure.
11867 int devl_trap_groups_register(struct devlink *devlink,
11868 const struct devlink_trap_group *groups,
11869 size_t groups_count)
11873 devl_assert_locked(devlink);
11874 for (i = 0; i < groups_count; i++) {
11875 const struct devlink_trap_group *group = &groups[i];
11877 err = devlink_trap_group_verify(group);
11879 goto err_trap_group_verify;
11881 err = devlink_trap_group_register(devlink, group);
11883 goto err_trap_group_register;
11888 err_trap_group_register:
11889 err_trap_group_verify:
11890 for (i--; i >= 0; i--)
11891 devlink_trap_group_unregister(devlink, &groups[i]);
11894 EXPORT_SYMBOL_GPL(devl_trap_groups_register);
11897 * devlink_trap_groups_register - Register packet trap groups with devlink.
11898 * @devlink: devlink.
11899 * @groups: Packet trap groups.
11900 * @groups_count: Count of provided packet trap groups.
11902 * Context: Takes and release devlink->lock <mutex>.
11904 * Return: Non-zero value on failure.
11906 int devlink_trap_groups_register(struct devlink *devlink,
11907 const struct devlink_trap_group *groups,
11908 size_t groups_count)
11912 devl_lock(devlink);
11913 err = devl_trap_groups_register(devlink, groups, groups_count);
11914 devl_unlock(devlink);
11917 EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
11920 * devl_trap_groups_unregister - Unregister packet trap groups from devlink.
11921 * @devlink: devlink.
11922 * @groups: Packet trap groups.
11923 * @groups_count: Count of provided packet trap groups.
11925 void devl_trap_groups_unregister(struct devlink *devlink,
11926 const struct devlink_trap_group *groups,
11927 size_t groups_count)
11931 devl_assert_locked(devlink);
11932 for (i = groups_count - 1; i >= 0; i--)
11933 devlink_trap_group_unregister(devlink, &groups[i]);
11935 EXPORT_SYMBOL_GPL(devl_trap_groups_unregister);
11938 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
11939 * @devlink: devlink.
11940 * @groups: Packet trap groups.
11941 * @groups_count: Count of provided packet trap groups.
11943 * Context: Takes and release devlink->lock <mutex>.
11945 void devlink_trap_groups_unregister(struct devlink *devlink,
11946 const struct devlink_trap_group *groups,
11947 size_t groups_count)
11949 devl_lock(devlink);
11950 devl_trap_groups_unregister(devlink, groups, groups_count);
11951 devl_unlock(devlink);
11953 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
11956 devlink_trap_policer_notify(struct devlink *devlink,
11957 const struct devlink_trap_policer_item *policer_item,
11958 enum devlink_command cmd)
11960 struct sk_buff *msg;
11963 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
11964 cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
11965 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11968 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11972 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
11979 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11980 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11984 devlink_trap_policer_register(struct devlink *devlink,
11985 const struct devlink_trap_policer *policer)
11987 struct devlink_trap_policer_item *policer_item;
11990 if (devlink_trap_policer_item_lookup(devlink, policer->id))
11993 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
11997 policer_item->policer = policer;
11998 policer_item->rate = policer->init_rate;
11999 policer_item->burst = policer->init_burst;
12001 if (devlink->ops->trap_policer_init) {
12002 err = devlink->ops->trap_policer_init(devlink, policer);
12004 goto err_policer_init;
12007 list_add_tail(&policer_item->list, &devlink->trap_policer_list);
12008 devlink_trap_policer_notify(devlink, policer_item,
12009 DEVLINK_CMD_TRAP_POLICER_NEW);
12014 kfree(policer_item);
12019 devlink_trap_policer_unregister(struct devlink *devlink,
12020 const struct devlink_trap_policer *policer)
12022 struct devlink_trap_policer_item *policer_item;
12024 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
12025 if (WARN_ON_ONCE(!policer_item))
12028 devlink_trap_policer_notify(devlink, policer_item,
12029 DEVLINK_CMD_TRAP_POLICER_DEL);
12030 list_del(&policer_item->list);
12031 if (devlink->ops->trap_policer_fini)
12032 devlink->ops->trap_policer_fini(devlink, policer);
12033 kfree(policer_item);
12037 * devl_trap_policers_register - Register packet trap policers with devlink.
12038 * @devlink: devlink.
12039 * @policers: Packet trap policers.
12040 * @policers_count: Count of provided packet trap policers.
12042 * Return: Non-zero value on failure.
12045 devl_trap_policers_register(struct devlink *devlink,
12046 const struct devlink_trap_policer *policers,
12047 size_t policers_count)
12051 devl_assert_locked(devlink);
12052 for (i = 0; i < policers_count; i++) {
12053 const struct devlink_trap_policer *policer = &policers[i];
12055 if (WARN_ON(policer->id == 0 ||
12056 policer->max_rate < policer->min_rate ||
12057 policer->max_burst < policer->min_burst)) {
12059 goto err_trap_policer_verify;
12062 err = devlink_trap_policer_register(devlink, policer);
12064 goto err_trap_policer_register;
12068 err_trap_policer_register:
12069 err_trap_policer_verify:
12070 for (i--; i >= 0; i--)
12071 devlink_trap_policer_unregister(devlink, &policers[i]);
12074 EXPORT_SYMBOL_GPL(devl_trap_policers_register);
12077 * devl_trap_policers_unregister - Unregister packet trap policers from devlink.
12078 * @devlink: devlink.
12079 * @policers: Packet trap policers.
12080 * @policers_count: Count of provided packet trap policers.
12083 devl_trap_policers_unregister(struct devlink *devlink,
12084 const struct devlink_trap_policer *policers,
12085 size_t policers_count)
12089 devl_assert_locked(devlink);
12090 for (i = policers_count - 1; i >= 0; i--)
12091 devlink_trap_policer_unregister(devlink, &policers[i]);
12093 EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
12095 static void __devlink_compat_running_version(struct devlink *devlink,
12096 char *buf, size_t len)
12098 struct devlink_info_req req = {};
12099 const struct nlattr *nlattr;
12100 struct sk_buff *msg;
12103 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12108 err = devlink->ops->info_get(devlink, &req, NULL);
12112 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
12113 const struct nlattr *kv;
12116 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
12119 nla_for_each_nested(kv, nlattr, rem_kv) {
12120 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
12123 strlcat(buf, nla_data(kv), len);
12124 strlcat(buf, " ", len);
12131 void devlink_compat_running_version(struct devlink *devlink,
12132 char *buf, size_t len)
12134 if (!devlink->ops->info_get)
12137 devl_lock(devlink);
12138 if (devl_is_registered(devlink))
12139 __devlink_compat_running_version(devlink, buf, len);
12140 devl_unlock(devlink);
12143 int devlink_compat_flash_update(struct devlink *devlink, const char *file_name)
12145 struct devlink_flash_update_params params = {};
12148 devl_lock(devlink);
12149 if (!devl_is_registered(devlink)) {
12154 if (!devlink->ops->flash_update) {
12159 ret = request_firmware(¶ms.fw, file_name, devlink->dev);
12163 devlink_flash_update_begin_notify(devlink);
12164 ret = devlink->ops->flash_update(devlink, ¶ms, NULL);
12165 devlink_flash_update_end_notify(devlink);
12167 release_firmware(params.fw);
12169 devl_unlock(devlink);
12174 int devlink_compat_phys_port_name_get(struct net_device *dev,
12175 char *name, size_t len)
12177 struct devlink_port *devlink_port;
12179 /* RTNL mutex is held here which ensures that devlink_port
12180 * instance cannot disappear in the middle. No need to take
12181 * any devlink lock as only permanent values are accessed.
12185 devlink_port = dev->devlink_port;
12187 return -EOPNOTSUPP;
12189 return __devlink_port_phys_port_name_get(devlink_port, name, len);
12192 int devlink_compat_switch_id_get(struct net_device *dev,
12193 struct netdev_phys_item_id *ppid)
12195 struct devlink_port *devlink_port;
12197 /* Caller must hold RTNL mutex or reference to dev, which ensures that
12198 * devlink_port instance cannot disappear in the middle. No need to take
12199 * any devlink lock as only permanent values are accessed.
12201 devlink_port = dev->devlink_port;
12202 if (!devlink_port || !devlink_port->switch_port)
12203 return -EOPNOTSUPP;
12205 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));