devlink: move devlink reload notifications back in between _down() and _up() calls
[linux-block.git] / net / devlink / leftover.c
... / ...
CommitLineData
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * net/core/devlink.c - Network physical/parent device Netlink interface
4 *
5 * Heavily inspired by net/wireless/
6 * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
7 * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
8 */
9
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>
29#include <net/sock.h>
30#include <net/devlink.h>
31#define CREATE_TRACE_POINTS
32#include <trace/events/devlink.h>
33
34#include "devl_internal.h"
35
36struct devlink_linecard {
37 struct list_head list;
38 struct devlink *devlink;
39 unsigned int index;
40 const struct devlink_linecard_ops *ops;
41 void *priv;
42 enum devlink_linecard_state state;
43 struct mutex state_lock; /* Protects state */
44 const char *type;
45 struct devlink_linecard_type *types;
46 unsigned int types_count;
47 struct devlink *nested_devlink;
48};
49
50/**
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
60 * @list: parent list
61 * @resource_list: list of child resources
62 * @occ_get: occupancy getter callback
63 * @occ_get_priv: occupancy getter callback priv
64 */
65struct devlink_resource {
66 const char *name;
67 u64 id;
68 u64 size;
69 u64 size_new;
70 bool size_valid;
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;
76 void *occ_get_priv;
77};
78
79static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
80 {
81 .name = "destination mac",
82 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
83 .bitwidth = 48,
84 },
85};
86
87struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
88 .name = "ethernet",
89 .id = DEVLINK_DPIPE_HEADER_ETHERNET,
90 .fields = devlink_dpipe_fields_ethernet,
91 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
92 .global = true,
93};
94EXPORT_SYMBOL_GPL(devlink_dpipe_header_ethernet);
95
96static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
97 {
98 .name = "destination ip",
99 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
100 .bitwidth = 32,
101 },
102};
103
104struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
105 .name = "ipv4",
106 .id = DEVLINK_DPIPE_HEADER_IPV4,
107 .fields = devlink_dpipe_fields_ipv4,
108 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
109 .global = true,
110};
111EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv4);
112
113static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
114 {
115 .name = "destination ip",
116 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
117 .bitwidth = 128,
118 },
119};
120
121struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
122 .name = "ipv6",
123 .id = DEVLINK_DPIPE_HEADER_IPV6,
124 .fields = devlink_dpipe_fields_ipv6,
125 .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
126 .global = true,
127};
128EXPORT_SYMBOL_GPL(devlink_dpipe_header_ipv6);
129
130EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
131EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
132EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_trap_report);
133
134#define DEVLINK_PORT_FN_CAPS_VALID_MASK \
135 (_BITUL(__DEVLINK_PORT_FN_ATTR_CAPS_MAX) - 1)
136
137static 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),
144};
145
146static const struct nla_policy devlink_selftest_nl_policy[DEVLINK_ATTR_SELFTEST_ID_MAX + 1] = {
147 [DEVLINK_ATTR_SELFTEST_ID_FLASH] = { .type = NLA_FLAG },
148};
149
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)
156
157static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
158 unsigned int port_index)
159{
160 return xa_load(&devlink->ports, port_index);
161}
162
163static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
164 struct nlattr **attrs)
165{
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;
169
170 devlink_port = devlink_port_get_by_index(devlink, port_index);
171 if (!devlink_port)
172 return ERR_PTR(-ENODEV);
173 return devlink_port;
174 }
175 return ERR_PTR(-EINVAL);
176}
177
178struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
179 struct genl_info *info)
180{
181 return devlink_port_get_from_attrs(devlink, info->attrs);
182}
183
184static inline bool
185devlink_rate_is_leaf(struct devlink_rate *devlink_rate)
186{
187 return devlink_rate->type == DEVLINK_RATE_TYPE_LEAF;
188}
189
190static inline bool
191devlink_rate_is_node(struct devlink_rate *devlink_rate)
192{
193 return devlink_rate->type == DEVLINK_RATE_TYPE_NODE;
194}
195
196static struct devlink_rate *
197devlink_rate_leaf_get_from_info(struct devlink *devlink, struct genl_info *info)
198{
199 struct devlink_rate *devlink_rate;
200 struct devlink_port *devlink_port;
201
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);
207}
208
209static struct devlink_rate *
210devlink_rate_node_get_by_name(struct devlink *devlink, const char *node_name)
211{
212 static struct devlink_rate *devlink_rate;
213
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))
217 return devlink_rate;
218 }
219 return ERR_PTR(-ENODEV);
220}
221
222static struct devlink_rate *
223devlink_rate_node_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
224{
225 const char *rate_node_name;
226 size_t len;
227
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);
235
236 return devlink_rate_node_get_by_name(devlink, rate_node_name);
237}
238
239struct devlink_rate *
240devlink_rate_node_get_from_info(struct devlink *devlink, struct genl_info *info)
241{
242 return devlink_rate_node_get_from_attrs(devlink, info->attrs);
243}
244
245struct devlink_rate *
246devlink_rate_get_from_info(struct devlink *devlink, struct genl_info *info)
247{
248 struct nlattr **attrs = info->attrs;
249
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);
254 else
255 return ERR_PTR(-EINVAL);
256}
257
258static struct devlink_linecard *
259devlink_linecard_get_by_index(struct devlink *devlink,
260 unsigned int linecard_index)
261{
262 struct devlink_linecard *devlink_linecard;
263
264 list_for_each_entry(devlink_linecard, &devlink->linecard_list, list) {
265 if (devlink_linecard->index == linecard_index)
266 return devlink_linecard;
267 }
268 return NULL;
269}
270
271static bool devlink_linecard_index_exists(struct devlink *devlink,
272 unsigned int linecard_index)
273{
274 return devlink_linecard_get_by_index(devlink, linecard_index);
275}
276
277static struct devlink_linecard *
278devlink_linecard_get_from_attrs(struct devlink *devlink, struct nlattr **attrs)
279{
280 if (attrs[DEVLINK_ATTR_LINECARD_INDEX]) {
281 u32 linecard_index = nla_get_u32(attrs[DEVLINK_ATTR_LINECARD_INDEX]);
282 struct devlink_linecard *linecard;
283
284 linecard = devlink_linecard_get_by_index(devlink, linecard_index);
285 if (!linecard)
286 return ERR_PTR(-ENODEV);
287 return linecard;
288 }
289 return ERR_PTR(-EINVAL);
290}
291
292struct devlink_linecard *
293devlink_linecard_get_from_info(struct devlink *devlink, struct genl_info *info)
294{
295 return devlink_linecard_get_from_attrs(devlink, info->attrs);
296}
297
298struct devlink_sb {
299 struct list_head list;
300 unsigned int index;
301 u32 size;
302 u16 ingress_pools_count;
303 u16 egress_pools_count;
304 u16 ingress_tc_count;
305 u16 egress_tc_count;
306};
307
308static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
309{
310 return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
311}
312
313static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
314 unsigned int sb_index)
315{
316 struct devlink_sb *devlink_sb;
317
318 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
319 if (devlink_sb->index == sb_index)
320 return devlink_sb;
321 }
322 return NULL;
323}
324
325static bool devlink_sb_index_exists(struct devlink *devlink,
326 unsigned int sb_index)
327{
328 return devlink_sb_get_by_index(devlink, sb_index);
329}
330
331static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
332 struct nlattr **attrs)
333{
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;
337
338 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
339 if (!devlink_sb)
340 return ERR_PTR(-ENODEV);
341 return devlink_sb;
342 }
343 return ERR_PTR(-EINVAL);
344}
345
346static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
347 struct genl_info *info)
348{
349 return devlink_sb_get_from_attrs(devlink, info->attrs);
350}
351
352static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
353 struct nlattr **attrs,
354 u16 *p_pool_index)
355{
356 u16 val;
357
358 if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
359 return -EINVAL;
360
361 val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
362 if (val >= devlink_sb_pool_count(devlink_sb))
363 return -EINVAL;
364 *p_pool_index = val;
365 return 0;
366}
367
368static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
369 struct genl_info *info,
370 u16 *p_pool_index)
371{
372 return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
373 p_pool_index);
374}
375
376static int
377devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
378 enum devlink_sb_pool_type *p_pool_type)
379{
380 u8 val;
381
382 if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
383 return -EINVAL;
384
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)
388 return -EINVAL;
389 *p_pool_type = val;
390 return 0;
391}
392
393static int
394devlink_sb_pool_type_get_from_info(struct genl_info *info,
395 enum devlink_sb_pool_type *p_pool_type)
396{
397 return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
398}
399
400static int
401devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
402 enum devlink_sb_threshold_type *p_th_type)
403{
404 u8 val;
405
406 if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
407 return -EINVAL;
408
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)
412 return -EINVAL;
413 *p_th_type = val;
414 return 0;
415}
416
417static int
418devlink_sb_th_type_get_from_info(struct genl_info *info,
419 enum devlink_sb_threshold_type *p_th_type)
420{
421 return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
422}
423
424static int
425devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
426 struct nlattr **attrs,
427 enum devlink_sb_pool_type pool_type,
428 u16 *p_tc_index)
429{
430 u16 val;
431
432 if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
433 return -EINVAL;
434
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)
438 return -EINVAL;
439 if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
440 val >= devlink_sb->egress_tc_count)
441 return -EINVAL;
442 *p_tc_index = val;
443 return 0;
444}
445
446static void devlink_port_fn_cap_fill(struct nla_bitfield32 *caps,
447 u32 cap, bool is_enable)
448{
449 caps->selector |= cap;
450 if (is_enable)
451 caps->value |= cap;
452}
453
454static 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)
458{
459 bool is_enable;
460 int err;
461
462 if (!ops->port_fn_roce_get)
463 return 0;
464
465 err = ops->port_fn_roce_get(devlink_port, &is_enable, extack);
466 if (err) {
467 if (err == -EOPNOTSUPP)
468 return 0;
469 return err;
470 }
471
472 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_ROCE, is_enable);
473 return 0;
474}
475
476static 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)
480{
481 bool is_enable;
482 int err;
483
484 if (!ops->port_fn_migratable_get ||
485 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_PCI_VF)
486 return 0;
487
488 err = ops->port_fn_migratable_get(devlink_port, &is_enable, extack);
489 if (err) {
490 if (err == -EOPNOTSUPP)
491 return 0;
492 return err;
493 }
494
495 devlink_port_fn_cap_fill(caps, DEVLINK_PORT_FN_CAP_MIGRATABLE, is_enable);
496 return 0;
497}
498
499static int devlink_port_fn_caps_fill(const struct devlink_ops *ops,
500 struct devlink_port *devlink_port,
501 struct sk_buff *msg,
502 struct netlink_ext_ack *extack,
503 bool *msg_updated)
504{
505 struct nla_bitfield32 caps = {};
506 int err;
507
508 err = devlink_port_fn_roce_fill(ops, devlink_port, &caps, extack);
509 if (err)
510 return err;
511
512 err = devlink_port_fn_migratable_fill(ops, devlink_port, &caps, extack);
513 if (err)
514 return err;
515
516 if (!caps.selector)
517 return 0;
518 err = nla_put_bitfield32(msg, DEVLINK_PORT_FN_ATTR_CAPS, caps.value,
519 caps.selector);
520 if (err)
521 return err;
522
523 *msg_updated = true;
524 return 0;
525}
526
527static int
528devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
529 struct genl_info *info,
530 enum devlink_sb_pool_type pool_type,
531 u16 *p_tc_index)
532{
533 return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
534 pool_type, p_tc_index);
535}
536
537struct devlink_region {
538 struct devlink *devlink;
539 struct devlink_port *port;
540 struct list_head list;
541 union {
542 const struct devlink_region_ops *ops;
543 const struct devlink_port_region_ops *port_ops;
544 };
545 struct mutex snapshot_lock; /* protects snapshot_list,
546 * max_snapshots and cur_snapshots
547 * consistency.
548 */
549 struct list_head snapshot_list;
550 u32 max_snapshots;
551 u32 cur_snapshots;
552 u64 size;
553};
554
555struct devlink_snapshot {
556 struct list_head list;
557 struct devlink_region *region;
558 u8 *data;
559 u32 id;
560};
561
562static struct devlink_region *
563devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
564{
565 struct devlink_region *region;
566
567 list_for_each_entry(region, &devlink->region_list, list)
568 if (!strcmp(region->ops->name, region_name))
569 return region;
570
571 return NULL;
572}
573
574static struct devlink_region *
575devlink_port_region_get_by_name(struct devlink_port *port,
576 const char *region_name)
577{
578 struct devlink_region *region;
579
580 list_for_each_entry(region, &port->region_list, list)
581 if (!strcmp(region->ops->name, region_name))
582 return region;
583
584 return NULL;
585}
586
587static struct devlink_snapshot *
588devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
589{
590 struct devlink_snapshot *snapshot;
591
592 list_for_each_entry(snapshot, &region->snapshot_list, list)
593 if (snapshot->id == id)
594 return snapshot;
595
596 return NULL;
597}
598
599static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
600{
601 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
602 return -EMSGSIZE;
603 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
604 return -EMSGSIZE;
605 return 0;
606}
607
608static int devlink_nl_put_nested_handle(struct sk_buff *msg, struct devlink *devlink)
609{
610 struct nlattr *nested_attr;
611
612 nested_attr = nla_nest_start(msg, DEVLINK_ATTR_NESTED_DEVLINK);
613 if (!nested_attr)
614 return -EMSGSIZE;
615 if (devlink_nl_put_handle(msg, devlink))
616 goto nla_put_failure;
617
618 nla_nest_end(msg, nested_attr);
619 return 0;
620
621nla_put_failure:
622 nla_nest_cancel(msg, nested_attr);
623 return -EMSGSIZE;
624}
625
626int devlink_nl_port_handle_fill(struct sk_buff *msg, struct devlink_port *devlink_port)
627{
628 if (devlink_nl_put_handle(msg, devlink_port->devlink))
629 return -EMSGSIZE;
630 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
631 return -EMSGSIZE;
632 return 0;
633}
634
635size_t devlink_nl_port_handle_size(struct devlink_port *devlink_port)
636{
637 struct devlink *devlink = devlink_port->devlink;
638
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 */
642}
643
644struct devlink_reload_combination {
645 enum devlink_reload_action action;
646 enum devlink_reload_limit limit;
647};
648
649static const struct devlink_reload_combination devlink_reload_invalid_combinations[] = {
650 {
651 /* can't reinitialize driver with no down time */
652 .action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT,
653 .limit = DEVLINK_RELOAD_LIMIT_NO_RESET,
654 },
655};
656
657static bool
658devlink_reload_combination_is_invalid(enum devlink_reload_action action,
659 enum devlink_reload_limit limit)
660{
661 int i;
662
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)
666 return true;
667 return false;
668}
669
670static bool
671devlink_reload_action_is_supported(struct devlink *devlink, enum devlink_reload_action action)
672{
673 return test_bit(action, &devlink->ops->reload_actions);
674}
675
676static bool
677devlink_reload_limit_is_supported(struct devlink *devlink, enum devlink_reload_limit limit)
678{
679 return test_bit(limit, &devlink->ops->reload_limits);
680}
681
682static int devlink_reload_stat_put(struct sk_buff *msg,
683 enum devlink_reload_limit limit, u32 value)
684{
685 struct nlattr *reload_stats_entry;
686
687 reload_stats_entry = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS_ENTRY);
688 if (!reload_stats_entry)
689 return -EMSGSIZE;
690
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);
695 return 0;
696
697nla_put_failure:
698 nla_nest_cancel(msg, reload_stats_entry);
699 return -EMSGSIZE;
700}
701
702static int devlink_reload_stats_put(struct sk_buff *msg, struct devlink *devlink, bool is_remote)
703{
704 struct nlattr *reload_stats_attr, *act_info, *act_stats;
705 int i, j, stat_idx;
706 u32 value;
707
708 if (!is_remote)
709 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_STATS);
710 else
711 reload_stats_attr = nla_nest_start(msg, DEVLINK_ATTR_REMOTE_RELOAD_STATS);
712
713 if (!reload_stats_attr)
714 return -EMSGSIZE;
715
716 for (i = 0; i <= DEVLINK_RELOAD_ACTION_MAX; i++) {
717 if ((!is_remote &&
718 !devlink_reload_action_is_supported(devlink, i)) ||
719 i == DEVLINK_RELOAD_ACTION_UNSPEC)
720 continue;
721 act_info = nla_nest_start(msg, DEVLINK_ATTR_RELOAD_ACTION_INFO);
722 if (!act_info)
723 goto nla_put_failure;
724
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);
728 if (!act_stats)
729 goto action_info_nest_cancel;
730
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
735 * limit.
736 */
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))
740 continue;
741
742 stat_idx = j * __DEVLINK_RELOAD_ACTION_MAX + i;
743 if (!is_remote)
744 value = devlink->stats.reload_stats[stat_idx];
745 else
746 value = devlink->stats.remote_reload_stats[stat_idx];
747 if (devlink_reload_stat_put(msg, j, value))
748 goto action_stats_nest_cancel;
749 }
750 nla_nest_end(msg, act_stats);
751 nla_nest_end(msg, act_info);
752 }
753 nla_nest_end(msg, reload_stats_attr);
754 return 0;
755
756action_stats_nest_cancel:
757 nla_nest_cancel(msg, act_stats);
758action_info_nest_cancel:
759 nla_nest_cancel(msg, act_info);
760nla_put_failure:
761 nla_nest_cancel(msg, reload_stats_attr);
762 return -EMSGSIZE;
763}
764
765static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
766 enum devlink_command cmd, u32 portid,
767 u32 seq, int flags)
768{
769 struct nlattr *dev_stats;
770 void *hdr;
771
772 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
773 if (!hdr)
774 return -EMSGSIZE;
775
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;
780
781 dev_stats = nla_nest_start(msg, DEVLINK_ATTR_DEV_STATS);
782 if (!dev_stats)
783 goto nla_put_failure;
784
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;
789
790 nla_nest_end(msg, dev_stats);
791 genlmsg_end(msg, hdr);
792 return 0;
793
794dev_stats_nest_cancel:
795 nla_nest_cancel(msg, dev_stats);
796nla_put_failure:
797 genlmsg_cancel(msg, hdr);
798 return -EMSGSIZE;
799}
800
801static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
802{
803 struct sk_buff *msg;
804 int err;
805
806 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
807 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
808
809 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
810 if (!msg)
811 return;
812
813 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
814 if (err) {
815 nlmsg_free(msg);
816 return;
817 }
818
819 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
820 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
821}
822
823static int devlink_nl_port_attrs_put(struct sk_buff *msg,
824 struct devlink_port *devlink_port)
825{
826 struct devlink_port_attrs *attrs = &devlink_port->attrs;
827
828 if (!devlink_port->attrs_set)
829 return 0;
830 if (attrs->lanes) {
831 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_LANES, attrs->lanes))
832 return -EMSGSIZE;
833 }
834 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_SPLITTABLE, attrs->splittable))
835 return -EMSGSIZE;
836 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
837 return -EMSGSIZE;
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))
843 return -EMSGSIZE;
844 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_pf.external))
845 return -EMSGSIZE;
846 break;
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))
852 return -EMSGSIZE;
853 if (nla_put_u8(msg, DEVLINK_ATTR_PORT_EXTERNAL, attrs->pci_vf.external))
854 return -EMSGSIZE;
855 break;
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,
860 attrs->pci_sf.pf) ||
861 nla_put_u32(msg, DEVLINK_ATTR_PORT_PCI_SF_NUMBER,
862 attrs->pci_sf.sf))
863 return -EMSGSIZE;
864 break;
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))
870 return -EMSGSIZE;
871 if (!attrs->split)
872 return 0;
873 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
874 attrs->phys.port_number))
875 return -EMSGSIZE;
876 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
877 attrs->phys.split_subport_number))
878 return -EMSGSIZE;
879 break;
880 default:
881 break;
882 }
883 return 0;
884}
885
886static int devlink_port_fn_hw_addr_fill(const struct devlink_ops *ops,
887 struct devlink_port *port,
888 struct sk_buff *msg,
889 struct netlink_ext_ack *extack,
890 bool *msg_updated)
891{
892 u8 hw_addr[MAX_ADDR_LEN];
893 int hw_addr_len;
894 int err;
895
896 if (!ops->port_function_hw_addr_get)
897 return 0;
898
899 err = ops->port_function_hw_addr_get(port, hw_addr, &hw_addr_len,
900 extack);
901 if (err) {
902 if (err == -EOPNOTSUPP)
903 return 0;
904 return err;
905 }
906 err = nla_put(msg, DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR, hw_addr_len, hw_addr);
907 if (err)
908 return err;
909 *msg_updated = true;
910 return 0;
911}
912
913static 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)
917{
918 struct devlink *devlink = devlink_rate->devlink;
919 void *hdr;
920
921 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
922 if (!hdr)
923 return -EMSGSIZE;
924
925 if (devlink_nl_put_handle(msg, devlink))
926 goto nla_put_failure;
927
928 if (nla_put_u16(msg, DEVLINK_ATTR_RATE_TYPE, devlink_rate->type))
929 goto nla_put_failure;
930
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,
937 devlink_rate->name))
938 goto nla_put_failure;
939 }
940
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;
944
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;
948
949 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_PRIORITY,
950 devlink_rate->tx_priority))
951 goto nla_put_failure;
952
953 if (nla_put_u32(msg, DEVLINK_ATTR_RATE_TX_WEIGHT,
954 devlink_rate->tx_weight))
955 goto nla_put_failure;
956
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;
961
962 genlmsg_end(msg, hdr);
963 return 0;
964
965nla_put_failure:
966 genlmsg_cancel(msg, hdr);
967 return -EMSGSIZE;
968}
969
970static bool
971devlink_port_fn_state_valid(enum devlink_port_fn_state state)
972{
973 return state == DEVLINK_PORT_FN_STATE_INACTIVE ||
974 state == DEVLINK_PORT_FN_STATE_ACTIVE;
975}
976
977static bool
978devlink_port_fn_opstate_valid(enum devlink_port_fn_opstate opstate)
979{
980 return opstate == DEVLINK_PORT_FN_OPSTATE_DETACHED ||
981 opstate == DEVLINK_PORT_FN_OPSTATE_ATTACHED;
982}
983
984static int devlink_port_fn_state_fill(const struct devlink_ops *ops,
985 struct devlink_port *port,
986 struct sk_buff *msg,
987 struct netlink_ext_ack *extack,
988 bool *msg_updated)
989{
990 enum devlink_port_fn_opstate opstate;
991 enum devlink_port_fn_state state;
992 int err;
993
994 if (!ops->port_fn_state_get)
995 return 0;
996
997 err = ops->port_fn_state_get(port, &state, &opstate, extack);
998 if (err) {
999 if (err == -EOPNOTSUPP)
1000 return 0;
1001 return err;
1002 }
1003 if (!devlink_port_fn_state_valid(state)) {
1004 WARN_ON_ONCE(1);
1005 NL_SET_ERR_MSG_MOD(extack, "Invalid state read from driver");
1006 return -EINVAL;
1007 }
1008 if (!devlink_port_fn_opstate_valid(opstate)) {
1009 WARN_ON_ONCE(1);
1010 NL_SET_ERR_MSG_MOD(extack,
1011 "Invalid operational state read from driver");
1012 return -EINVAL;
1013 }
1014 if (nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_STATE, state) ||
1015 nla_put_u8(msg, DEVLINK_PORT_FN_ATTR_OPSTATE, opstate))
1016 return -EMSGSIZE;
1017 *msg_updated = true;
1018 return 0;
1019}
1020
1021static int
1022devlink_port_fn_mig_set(struct devlink_port *devlink_port, bool enable,
1023 struct netlink_ext_ack *extack)
1024{
1025 const struct devlink_ops *ops = devlink_port->devlink->ops;
1026
1027 return ops->port_fn_migratable_set(devlink_port, enable, extack);
1028}
1029
1030static int
1031devlink_port_fn_roce_set(struct devlink_port *devlink_port, bool enable,
1032 struct netlink_ext_ack *extack)
1033{
1034 const struct devlink_ops *ops = devlink_port->devlink->ops;
1035
1036 return ops->port_fn_roce_set(devlink_port, enable, extack);
1037}
1038
1039static int devlink_port_fn_caps_set(struct devlink_port *devlink_port,
1040 const struct nlattr *attr,
1041 struct netlink_ext_ack *extack)
1042{
1043 struct nla_bitfield32 caps;
1044 u32 caps_value;
1045 int err;
1046
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,
1052 extack);
1053 if (err)
1054 return err;
1055 }
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,
1059 extack);
1060 if (err)
1061 return err;
1062 }
1063 return 0;
1064}
1065
1066static int
1067devlink_nl_port_function_attrs_put(struct sk_buff *msg, struct devlink_port *port,
1068 struct netlink_ext_ack *extack)
1069{
1070 const struct devlink_ops *ops;
1071 struct nlattr *function_attr;
1072 bool msg_updated = false;
1073 int err;
1074
1075 function_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PORT_FUNCTION);
1076 if (!function_attr)
1077 return -EMSGSIZE;
1078
1079 ops = port->devlink->ops;
1080 err = devlink_port_fn_hw_addr_fill(ops, port, msg, extack,
1081 &msg_updated);
1082 if (err)
1083 goto out;
1084 err = devlink_port_fn_caps_fill(ops, port, msg, extack,
1085 &msg_updated);
1086 if (err)
1087 goto out;
1088 err = devlink_port_fn_state_fill(ops, port, msg, extack, &msg_updated);
1089out:
1090 if (err || !msg_updated)
1091 nla_nest_cancel(msg, function_attr);
1092 else
1093 nla_nest_end(msg, function_attr);
1094 return err;
1095}
1096
1097static 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)
1101{
1102 struct devlink *devlink = devlink_port->devlink;
1103 void *hdr;
1104
1105 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1106 if (!hdr)
1107 return -EMSGSIZE;
1108
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;
1113
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;
1128 }
1129 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
1130 struct ib_device *ibdev = devlink_port->type_ib.ibdev;
1131
1132 if (ibdev &&
1133 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
1134 ibdev->name))
1135 goto nla_put_failure_type_locked;
1136 }
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;
1146
1147 genlmsg_end(msg, hdr);
1148 return 0;
1149
1150nla_put_failure_type_locked:
1151 spin_unlock_bh(&devlink_port->type_lock);
1152nla_put_failure:
1153 genlmsg_cancel(msg, hdr);
1154 return -EMSGSIZE;
1155}
1156
1157static void devlink_port_notify(struct devlink_port *devlink_port,
1158 enum devlink_command cmd)
1159{
1160 struct devlink *devlink = devlink_port->devlink;
1161 struct sk_buff *msg;
1162 int err;
1163
1164 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
1165
1166 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1167 return;
1168
1169 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1170 if (!msg)
1171 return;
1172
1173 err = devlink_nl_port_fill(msg, devlink_port, cmd, 0, 0, 0, NULL);
1174 if (err) {
1175 nlmsg_free(msg);
1176 return;
1177 }
1178
1179 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1180 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1181}
1182
1183static void devlink_rate_notify(struct devlink_rate *devlink_rate,
1184 enum devlink_command cmd)
1185{
1186 struct devlink *devlink = devlink_rate->devlink;
1187 struct sk_buff *msg;
1188 int err;
1189
1190 WARN_ON(cmd != DEVLINK_CMD_RATE_NEW && cmd != DEVLINK_CMD_RATE_DEL);
1191
1192 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
1193 return;
1194
1195 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1196 if (!msg)
1197 return;
1198
1199 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, 0, 0, 0, NULL);
1200 if (err) {
1201 nlmsg_free(msg);
1202 return;
1203 }
1204
1205 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
1206 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
1207}
1208
1209static int
1210devlink_nl_cmd_rate_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1211 struct netlink_callback *cb)
1212{
1213 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1214 struct devlink_rate *devlink_rate;
1215 int idx = 0;
1216 int err = 0;
1217
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;
1221
1222 if (idx < state->idx) {
1223 idx++;
1224 continue;
1225 }
1226 err = devlink_nl_rate_fill(msg, devlink_rate, cmd, id,
1227 cb->nlh->nlmsg_seq,
1228 NLM_F_MULTI, NULL);
1229 if (err) {
1230 state->idx = idx;
1231 break;
1232 }
1233 idx++;
1234 }
1235
1236 return err;
1237}
1238
1239const struct devlink_gen_cmd devl_gen_rate_get = {
1240 .dump_one = devlink_nl_cmd_rate_get_dump_one,
1241};
1242
1243static int devlink_nl_cmd_rate_get_doit(struct sk_buff *skb,
1244 struct genl_info *info)
1245{
1246 struct devlink_rate *devlink_rate = info->user_ptr[1];
1247 struct sk_buff *msg;
1248 int err;
1249
1250 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1251 if (!msg)
1252 return -ENOMEM;
1253
1254 err = devlink_nl_rate_fill(msg, devlink_rate, DEVLINK_CMD_RATE_NEW,
1255 info->snd_portid, info->snd_seq, 0,
1256 info->extack);
1257 if (err) {
1258 nlmsg_free(msg);
1259 return err;
1260 }
1261
1262 return genlmsg_reply(msg, info);
1263}
1264
1265static bool
1266devlink_rate_is_parent_node(struct devlink_rate *devlink_rate,
1267 struct devlink_rate *parent)
1268{
1269 while (parent) {
1270 if (parent == devlink_rate)
1271 return true;
1272 parent = parent->parent;
1273 }
1274 return false;
1275}
1276
1277static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
1278{
1279 struct devlink *devlink = info->user_ptr[0];
1280 struct sk_buff *msg;
1281 int err;
1282
1283 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1284 if (!msg)
1285 return -ENOMEM;
1286
1287 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1288 info->snd_portid, info->snd_seq, 0);
1289 if (err) {
1290 nlmsg_free(msg);
1291 return err;
1292 }
1293
1294 return genlmsg_reply(msg, info);
1295}
1296
1297static int
1298devlink_nl_cmd_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1299 struct netlink_callback *cb)
1300{
1301 return devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
1302 NETLINK_CB(cb->skb).portid,
1303 cb->nlh->nlmsg_seq, NLM_F_MULTI);
1304}
1305
1306const struct devlink_gen_cmd devl_gen_inst = {
1307 .dump_one = devlink_nl_cmd_get_dump_one,
1308};
1309
1310static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
1311 struct genl_info *info)
1312{
1313 struct devlink_port *devlink_port = info->user_ptr[1];
1314 struct sk_buff *msg;
1315 int err;
1316
1317 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1318 if (!msg)
1319 return -ENOMEM;
1320
1321 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_PORT_NEW,
1322 info->snd_portid, info->snd_seq, 0,
1323 info->extack);
1324 if (err) {
1325 nlmsg_free(msg);
1326 return err;
1327 }
1328
1329 return genlmsg_reply(msg, info);
1330}
1331
1332static int
1333devlink_nl_cmd_port_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
1334 struct netlink_callback *cb)
1335{
1336 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
1337 struct devlink_port *devlink_port;
1338 unsigned long port_index;
1339 int idx = 0;
1340 int err = 0;
1341
1342 xa_for_each(&devlink->ports, port_index, devlink_port) {
1343 if (idx < state->idx) {
1344 idx++;
1345 continue;
1346 }
1347 err = devlink_nl_port_fill(msg, devlink_port,
1348 DEVLINK_CMD_NEW,
1349 NETLINK_CB(cb->skb).portid,
1350 cb->nlh->nlmsg_seq,
1351 NLM_F_MULTI, cb->extack);
1352 if (err) {
1353 state->idx = idx;
1354 break;
1355 }
1356 idx++;
1357 }
1358
1359 return err;
1360}
1361
1362const struct devlink_gen_cmd devl_gen_port = {
1363 .dump_one = devlink_nl_cmd_port_get_dump_one,
1364};
1365
1366static int devlink_port_type_set(struct devlink_port *devlink_port,
1367 enum devlink_port_type port_type)
1368
1369{
1370 int err;
1371
1372 if (!devlink_port->devlink->ops->port_type_set)
1373 return -EOPNOTSUPP;
1374
1375 if (port_type == devlink_port->type)
1376 return 0;
1377
1378 err = devlink_port->devlink->ops->port_type_set(devlink_port,
1379 port_type);
1380 if (err)
1381 return err;
1382
1383 devlink_port->desired_type = port_type;
1384 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1385 return 0;
1386}
1387
1388static int devlink_port_function_hw_addr_set(struct devlink_port *port,
1389 const struct nlattr *attr,
1390 struct netlink_ext_ack *extack)
1391{
1392 const struct devlink_ops *ops = port->devlink->ops;
1393 const u8 *hw_addr;
1394 int hw_addr_len;
1395
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");
1400 return -EINVAL;
1401 }
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");
1405 return -EINVAL;
1406 }
1407 if (!is_unicast_ether_addr(hw_addr)) {
1408 NL_SET_ERR_MSG_MOD(extack, "Non-unicast hardware address unsupported");
1409 return -EINVAL;
1410 }
1411 }
1412
1413 return ops->port_function_hw_addr_set(port, hw_addr, hw_addr_len,
1414 extack);
1415}
1416
1417static int devlink_port_fn_state_set(struct devlink_port *port,
1418 const struct nlattr *attr,
1419 struct netlink_ext_ack *extack)
1420{
1421 enum devlink_port_fn_state state;
1422 const struct devlink_ops *ops;
1423
1424 state = nla_get_u8(attr);
1425 ops = port->devlink->ops;
1426 return ops->port_fn_state_set(port, state, extack);
1427}
1428
1429static int devlink_port_function_validate(struct devlink_port *devlink_port,
1430 struct nlattr **tb,
1431 struct netlink_ext_ack *extack)
1432{
1433 const struct devlink_ops *ops = devlink_port->devlink->ops;
1434 struct nlattr *attr;
1435
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");
1440 return -EOPNOTSUPP;
1441 }
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");
1445 return -EOPNOTSUPP;
1446 }
1447 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1448 if (attr) {
1449 struct nla_bitfield32 caps;
1450
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");
1456 return -EOPNOTSUPP;
1457 }
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");
1462 return -EOPNOTSUPP;
1463 }
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");
1467 return -EOPNOTSUPP;
1468 }
1469 }
1470 }
1471 return 0;
1472}
1473
1474static int devlink_port_function_set(struct devlink_port *port,
1475 const struct nlattr *attr,
1476 struct netlink_ext_ack *extack)
1477{
1478 struct nlattr *tb[DEVLINK_PORT_FUNCTION_ATTR_MAX + 1];
1479 int err;
1480
1481 err = nla_parse_nested(tb, DEVLINK_PORT_FUNCTION_ATTR_MAX, attr,
1482 devlink_function_nl_policy, extack);
1483 if (err < 0) {
1484 NL_SET_ERR_MSG_MOD(extack, "Fail to parse port function attributes");
1485 return err;
1486 }
1487
1488 err = devlink_port_function_validate(port, tb, extack);
1489 if (err)
1490 return err;
1491
1492 attr = tb[DEVLINK_PORT_FUNCTION_ATTR_HW_ADDR];
1493 if (attr) {
1494 err = devlink_port_function_hw_addr_set(port, attr, extack);
1495 if (err)
1496 return err;
1497 }
1498
1499 attr = tb[DEVLINK_PORT_FN_ATTR_CAPS];
1500 if (attr) {
1501 err = devlink_port_fn_caps_set(port, attr, extack);
1502 if (err)
1503 return err;
1504 }
1505
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.
1509 */
1510 attr = tb[DEVLINK_PORT_FN_ATTR_STATE];
1511 if (attr)
1512 err = devlink_port_fn_state_set(port, attr, extack);
1513
1514 if (!err)
1515 devlink_port_notify(port, DEVLINK_CMD_PORT_NEW);
1516 return err;
1517}
1518
1519static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
1520 struct genl_info *info)
1521{
1522 struct devlink_port *devlink_port = info->user_ptr[1];
1523 int err;
1524
1525 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
1526 enum devlink_port_type port_type;
1527
1528 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
1529 err = devlink_port_type_set(devlink_port, port_type);
1530 if (err)
1531 return err;
1532 }
1533
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;
1537
1538 err = devlink_port_function_set(devlink_port, attr, extack);
1539 if (err)
1540 return err;
1541 }
1542
1543 return 0;
1544}
1545
1546static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
1547 struct genl_info *info)
1548{
1549 struct devlink_port *devlink_port = info->user_ptr[1];
1550 struct devlink *devlink = info->user_ptr[0];
1551 u32 count;
1552
1553 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_SPLIT_COUNT))
1554 return -EINVAL;
1555 if (!devlink->ops->port_split)
1556 return -EOPNOTSUPP;
1557
1558 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
1559
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");
1564 else
1565 NL_SET_ERR_MSG_MOD(info->extack, "Port cannot be split");
1566 return -EINVAL;
1567 }
1568
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");
1571 return -EINVAL;
1572 }
1573
1574 return devlink->ops->port_split(devlink, devlink_port, count,
1575 info->extack);
1576}
1577
1578static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
1579 struct genl_info *info)
1580{
1581 struct devlink_port *devlink_port = info->user_ptr[1];
1582 struct devlink *devlink = info->user_ptr[0];
1583
1584 if (!devlink->ops->port_unsplit)
1585 return -EOPNOTSUPP;
1586 return devlink->ops->port_unsplit(devlink, devlink_port, info->extack);
1587}
1588
1589static int devlink_port_new_notify(struct devlink *devlink,
1590 unsigned int port_index,
1591 struct genl_info *info)
1592{
1593 struct devlink_port *devlink_port;
1594 struct sk_buff *msg;
1595 int err;
1596
1597 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1598 if (!msg)
1599 return -ENOMEM;
1600
1601 lockdep_assert_held(&devlink->lock);
1602 devlink_port = devlink_port_get_by_index(devlink, port_index);
1603 if (!devlink_port) {
1604 err = -ENODEV;
1605 goto out;
1606 }
1607
1608 err = devlink_nl_port_fill(msg, devlink_port, DEVLINK_CMD_NEW,
1609 info->snd_portid, info->snd_seq, 0, NULL);
1610 if (err)
1611 goto out;
1612
1613 return genlmsg_reply(msg, info);
1614
1615out:
1616 nlmsg_free(msg);
1617 return err;
1618}
1619
1620static int devlink_nl_cmd_port_new_doit(struct sk_buff *skb,
1621 struct genl_info *info)
1622{
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;
1627 int err;
1628
1629 if (!devlink->ops->port_new || !devlink->ops->port_del)
1630 return -EOPNOTSUPP;
1631
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");
1635 return -EINVAL;
1636 }
1637 new_attrs.flavour = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_FLAVOUR]);
1638 new_attrs.pfnum =
1639 nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_PCI_PF_NUMBER]);
1640
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;
1646 }
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;
1651 }
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;
1656 }
1657
1658 err = devlink->ops->port_new(devlink, &new_attrs, extack,
1659 &new_port_index);
1660 if (err)
1661 return err;
1662
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);
1667 }
1668 return err;
1669}
1670
1671static int devlink_nl_cmd_port_del_doit(struct sk_buff *skb,
1672 struct genl_info *info)
1673{
1674 struct netlink_ext_ack *extack = info->extack;
1675 struct devlink *devlink = info->user_ptr[0];
1676 unsigned int port_index;
1677
1678 if (!devlink->ops->port_del)
1679 return -EOPNOTSUPP;
1680
1681 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PORT_INDEX)) {
1682 NL_SET_ERR_MSG_MOD(extack, "Port index is not specified");
1683 return -EINVAL;
1684 }
1685 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
1686
1687 return devlink->ops->port_del(devlink, port_index, extack);
1688}
1689
1690static int
1691devlink_nl_rate_parent_node_set(struct devlink_rate *devlink_rate,
1692 struct genl_info *info,
1693 struct nlattr *nla_parent)
1694{
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;
1701
1702 parent = devlink_rate->parent;
1703
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,
1708 info->extack);
1709 else if (devlink_rate_is_node(devlink_rate))
1710 err = ops->rate_node_parent_set(devlink_rate, NULL,
1711 devlink_rate->priv, NULL,
1712 info->extack);
1713 if (err)
1714 return err;
1715
1716 refcount_dec(&parent->refcnt);
1717 devlink_rate->parent = NULL;
1718 } else if (len) {
1719 parent = devlink_rate_node_get_by_name(devlink, parent_name);
1720 if (IS_ERR(parent))
1721 return -ENODEV;
1722
1723 if (parent == devlink_rate) {
1724 NL_SET_ERR_MSG_MOD(info->extack, "Parent to self is not allowed");
1725 return -EINVAL;
1726 }
1727
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.");
1731 return -EEXIST;
1732 }
1733
1734 if (devlink_rate_is_leaf(devlink_rate))
1735 err = ops->rate_leaf_parent_set(devlink_rate, parent,
1736 devlink_rate->priv, parent->priv,
1737 info->extack);
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,
1741 info->extack);
1742 if (err)
1743 return err;
1744
1745 if (devlink_rate->parent)
1746 /* we're reassigning to other parent in this case */
1747 refcount_dec(&devlink_rate->parent->refcnt);
1748
1749 refcount_inc(&parent->refcnt);
1750 devlink_rate->parent = parent;
1751 }
1752
1753 return 0;
1754}
1755
1756static int devlink_nl_rate_set(struct devlink_rate *devlink_rate,
1757 const struct devlink_ops *ops,
1758 struct genl_info *info)
1759{
1760 struct nlattr *nla_parent, **attrs = info->attrs;
1761 int err = -EOPNOTSUPP;
1762 u32 priority;
1763 u32 weight;
1764 u64 rate;
1765
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);
1774 if (err)
1775 return err;
1776 devlink_rate->tx_share = rate;
1777 }
1778
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);
1787 if (err)
1788 return err;
1789 devlink_rate->tx_max = rate;
1790 }
1791
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);
1800
1801 if (err)
1802 return err;
1803 devlink_rate->tx_priority = priority;
1804 }
1805
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);
1814
1815 if (err)
1816 return err;
1817 devlink_rate->tx_weight = weight;
1818 }
1819
1820 nla_parent = attrs[DEVLINK_ATTR_RATE_PARENT_NODE_NAME];
1821 if (nla_parent) {
1822 err = devlink_nl_rate_parent_node_set(devlink_rate, info,
1823 nla_parent);
1824 if (err)
1825 return err;
1826 }
1827
1828 return 0;
1829}
1830
1831static bool devlink_rate_set_ops_supported(const struct devlink_ops *ops,
1832 struct genl_info *info,
1833 enum devlink_rate_type type)
1834{
1835 struct nlattr **attrs = info->attrs;
1836
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");
1840 return false;
1841 }
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");
1844 return false;
1845 }
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");
1849 return false;
1850 }
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");
1855 return false;
1856 }
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");
1861 return false;
1862 }
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");
1866 return false;
1867 }
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");
1870 return false;
1871 }
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");
1875 return false;
1876 }
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");
1881 return false;
1882 }
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");
1887 return false;
1888 }
1889 } else {
1890 WARN(1, "Unknown type of rate object");
1891 return false;
1892 }
1893
1894 return true;
1895}
1896
1897static int devlink_nl_cmd_rate_set_doit(struct sk_buff *skb,
1898 struct genl_info *info)
1899{
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;
1903 int err;
1904
1905 if (!ops || !devlink_rate_set_ops_supported(ops, info, devlink_rate->type))
1906 return -EOPNOTSUPP;
1907
1908 err = devlink_nl_rate_set(devlink_rate, ops, info);
1909
1910 if (!err)
1911 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
1912 return err;
1913}
1914
1915static int devlink_nl_cmd_rate_new_doit(struct sk_buff *skb,
1916 struct genl_info *info)
1917{
1918 struct devlink *devlink = info->user_ptr[0];
1919 struct devlink_rate *rate_node;
1920 const struct devlink_ops *ops;
1921 int err;
1922
1923 ops = devlink->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");
1926 return -EOPNOTSUPP;
1927 }
1928
1929 if (!devlink_rate_set_ops_supported(ops, info, DEVLINK_RATE_TYPE_NODE))
1930 return -EOPNOTSUPP;
1931
1932 rate_node = devlink_rate_node_get_from_attrs(devlink, info->attrs);
1933 if (!IS_ERR(rate_node))
1934 return -EEXIST;
1935 else if (rate_node == ERR_PTR(-EINVAL))
1936 return -EINVAL;
1937
1938 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
1939 if (!rate_node)
1940 return -ENOMEM;
1941
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) {
1946 err = -ENOMEM;
1947 goto err_strdup;
1948 }
1949
1950 err = ops->rate_node_new(rate_node, &rate_node->priv, info->extack);
1951 if (err)
1952 goto err_node_new;
1953
1954 err = devlink_nl_rate_set(rate_node, ops, info);
1955 if (err)
1956 goto err_rate_set;
1957
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);
1961 return 0;
1962
1963err_rate_set:
1964 ops->rate_node_del(rate_node, rate_node->priv, info->extack);
1965err_node_new:
1966 kfree(rate_node->name);
1967err_strdup:
1968 kfree(rate_node);
1969 return err;
1970}
1971
1972static int devlink_nl_cmd_rate_del_doit(struct sk_buff *skb,
1973 struct genl_info *info)
1974{
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;
1978 int err;
1979
1980 if (refcount_read(&rate_node->refcnt) > 1) {
1981 NL_SET_ERR_MSG_MOD(info->extack, "Node has children. Cannot delete node.");
1982 return -EBUSY;
1983 }
1984
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);
1991 kfree(rate_node);
1992 return err;
1993}
1994
1995struct devlink_linecard_type {
1996 const char *type;
1997 const void *priv;
1998};
1999
2000static 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,
2004 u32 seq, int flags,
2005 struct netlink_ext_ack *extack)
2006{
2007 struct devlink_linecard_type *linecard_type;
2008 struct nlattr *attr;
2009 void *hdr;
2010 int i;
2011
2012 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2013 if (!hdr)
2014 return -EMSGSIZE;
2015
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;
2025
2026 if (linecard->types_count) {
2027 attr = nla_nest_start(msg,
2028 DEVLINK_ATTR_LINECARD_SUPPORTED_TYPES);
2029 if (!attr)
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;
2037 }
2038 }
2039 nla_nest_end(msg, attr);
2040 }
2041
2042 if (linecard->nested_devlink &&
2043 devlink_nl_put_nested_handle(msg, linecard->nested_devlink))
2044 goto nla_put_failure;
2045
2046 genlmsg_end(msg, hdr);
2047 return 0;
2048
2049nla_put_failure:
2050 genlmsg_cancel(msg, hdr);
2051 return -EMSGSIZE;
2052}
2053
2054static void devlink_linecard_notify(struct devlink_linecard *linecard,
2055 enum devlink_command cmd)
2056{
2057 struct devlink *devlink = linecard->devlink;
2058 struct sk_buff *msg;
2059 int err;
2060
2061 WARN_ON(cmd != DEVLINK_CMD_LINECARD_NEW &&
2062 cmd != DEVLINK_CMD_LINECARD_DEL);
2063
2064 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
2065 return;
2066
2067 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2068 if (!msg)
2069 return;
2070
2071 err = devlink_nl_linecard_fill(msg, devlink, linecard, cmd, 0, 0, 0,
2072 NULL);
2073 if (err) {
2074 nlmsg_free(msg);
2075 return;
2076 }
2077
2078 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2079 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
2080}
2081
2082static int devlink_nl_cmd_linecard_get_doit(struct sk_buff *skb,
2083 struct genl_info *info)
2084{
2085 struct devlink_linecard *linecard = info->user_ptr[1];
2086 struct devlink *devlink = linecard->devlink;
2087 struct sk_buff *msg;
2088 int err;
2089
2090 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2091 if (!msg)
2092 return -ENOMEM;
2093
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,
2098 info->extack);
2099 mutex_unlock(&linecard->state_lock);
2100 if (err) {
2101 nlmsg_free(msg);
2102 return err;
2103 }
2104
2105 return genlmsg_reply(msg, info);
2106}
2107
2108static int devlink_nl_cmd_linecard_get_dump_one(struct sk_buff *msg,
2109 struct devlink *devlink,
2110 struct netlink_callback *cb)
2111{
2112 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2113 struct devlink_linecard *linecard;
2114 int idx = 0;
2115 int err = 0;
2116
2117 list_for_each_entry(linecard, &devlink->linecard_list, list) {
2118 if (idx < state->idx) {
2119 idx++;
2120 continue;
2121 }
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,
2126 cb->nlh->nlmsg_seq,
2127 NLM_F_MULTI,
2128 cb->extack);
2129 mutex_unlock(&linecard->state_lock);
2130 if (err) {
2131 state->idx = idx;
2132 break;
2133 }
2134 idx++;
2135 }
2136
2137 return err;
2138}
2139
2140const struct devlink_gen_cmd devl_gen_linecard = {
2141 .dump_one = devlink_nl_cmd_linecard_get_dump_one,
2142};
2143
2144static struct devlink_linecard_type *
2145devlink_linecard_type_lookup(struct devlink_linecard *linecard,
2146 const char *type)
2147{
2148 struct devlink_linecard_type *linecard_type;
2149 int i;
2150
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;
2155 }
2156 return NULL;
2157}
2158
2159static int devlink_linecard_type_set(struct devlink_linecard *linecard,
2160 const char *type,
2161 struct netlink_ext_ack *extack)
2162{
2163 const struct devlink_linecard_ops *ops = linecard->ops;
2164 struct devlink_linecard_type *linecard_type;
2165 int err;
2166
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");
2170 err = -EBUSY;
2171 goto out;
2172 }
2173 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2174 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2175 err = -EBUSY;
2176 goto out;
2177 }
2178
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");
2182 err = -EINVAL;
2183 goto out;
2184 }
2185
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");
2189 err = -EBUSY;
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.
2193 */
2194 if (ops->same_provision &&
2195 ops->same_provision(linecard, linecard->priv,
2196 linecard_type->type,
2197 linecard_type->priv))
2198 err = 0;
2199 goto out;
2200 }
2201
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);
2208 if (err) {
2209 /* Provisioning failed. Assume the linecard is unprovisioned
2210 * for future operations.
2211 */
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);
2217 }
2218 return err;
2219
2220out:
2221 mutex_unlock(&linecard->state_lock);
2222 return err;
2223}
2224
2225static int devlink_linecard_type_unset(struct devlink_linecard *linecard,
2226 struct netlink_ext_ack *extack)
2227{
2228 int err;
2229
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");
2233 err = -EBUSY;
2234 goto out;
2235 }
2236 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONING) {
2237 NL_SET_ERR_MSG_MOD(extack, "Line card is currently being unprovisioned");
2238 err = -EBUSY;
2239 goto out;
2240 }
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);
2245 err = 0;
2246 goto out;
2247 }
2248
2249 if (linecard->state == DEVLINK_LINECARD_STATE_UNPROVISIONED) {
2250 NL_SET_ERR_MSG_MOD(extack, "Line card is not provisioned");
2251 err = 0;
2252 goto out;
2253 }
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,
2258 extack);
2259 if (err) {
2260 /* Unprovisioning failed. Assume the linecard is unprovisioned
2261 * for future operations.
2262 */
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);
2268 }
2269 return err;
2270
2271out:
2272 mutex_unlock(&linecard->state_lock);
2273 return err;
2274}
2275
2276static int devlink_nl_cmd_linecard_set_doit(struct sk_buff *skb,
2277 struct genl_info *info)
2278{
2279 struct devlink_linecard *linecard = info->user_ptr[1];
2280 struct netlink_ext_ack *extack = info->extack;
2281 int err;
2282
2283 if (info->attrs[DEVLINK_ATTR_LINECARD_TYPE]) {
2284 const char *type;
2285
2286 type = nla_data(info->attrs[DEVLINK_ATTR_LINECARD_TYPE]);
2287 if (strcmp(type, "")) {
2288 err = devlink_linecard_type_set(linecard, type, extack);
2289 if (err)
2290 return err;
2291 } else {
2292 err = devlink_linecard_type_unset(linecard, extack);
2293 if (err)
2294 return err;
2295 }
2296 }
2297
2298 return 0;
2299}
2300
2301static 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,
2304 u32 seq, int flags)
2305{
2306 void *hdr;
2307
2308 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2309 if (!hdr)
2310 return -EMSGSIZE;
2311
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;
2330
2331 genlmsg_end(msg, hdr);
2332 return 0;
2333
2334nla_put_failure:
2335 genlmsg_cancel(msg, hdr);
2336 return -EMSGSIZE;
2337}
2338
2339static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
2340 struct genl_info *info)
2341{
2342 struct devlink *devlink = info->user_ptr[0];
2343 struct devlink_sb *devlink_sb;
2344 struct sk_buff *msg;
2345 int err;
2346
2347 devlink_sb = devlink_sb_get_from_info(devlink, info);
2348 if (IS_ERR(devlink_sb))
2349 return PTR_ERR(devlink_sb);
2350
2351 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2352 if (!msg)
2353 return -ENOMEM;
2354
2355 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2356 DEVLINK_CMD_SB_NEW,
2357 info->snd_portid, info->snd_seq, 0);
2358 if (err) {
2359 nlmsg_free(msg);
2360 return err;
2361 }
2362
2363 return genlmsg_reply(msg, info);
2364}
2365
2366static int
2367devlink_nl_cmd_sb_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
2368 struct netlink_callback *cb)
2369{
2370 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2371 struct devlink_sb *devlink_sb;
2372 int idx = 0;
2373 int err = 0;
2374
2375 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
2376 if (idx < state->idx) {
2377 idx++;
2378 continue;
2379 }
2380 err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
2381 DEVLINK_CMD_SB_NEW,
2382 NETLINK_CB(cb->skb).portid,
2383 cb->nlh->nlmsg_seq,
2384 NLM_F_MULTI);
2385 if (err) {
2386 state->idx = idx;
2387 break;
2388 }
2389 idx++;
2390 }
2391
2392 return err;
2393}
2394
2395const struct devlink_gen_cmd devl_gen_sb = {
2396 .dump_one = devlink_nl_cmd_sb_get_dump_one,
2397};
2398
2399static 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)
2403{
2404 struct devlink_sb_pool_info pool_info;
2405 void *hdr;
2406 int err;
2407
2408 err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
2409 pool_index, &pool_info);
2410 if (err)
2411 return err;
2412
2413 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2414 if (!hdr)
2415 return -EMSGSIZE;
2416
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;
2433
2434 genlmsg_end(msg, hdr);
2435 return 0;
2436
2437nla_put_failure:
2438 genlmsg_cancel(msg, hdr);
2439 return -EMSGSIZE;
2440}
2441
2442static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
2443 struct genl_info *info)
2444{
2445 struct devlink *devlink = info->user_ptr[0];
2446 struct devlink_sb *devlink_sb;
2447 struct sk_buff *msg;
2448 u16 pool_index;
2449 int err;
2450
2451 devlink_sb = devlink_sb_get_from_info(devlink, info);
2452 if (IS_ERR(devlink_sb))
2453 return PTR_ERR(devlink_sb);
2454
2455 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2456 &pool_index);
2457 if (err)
2458 return err;
2459
2460 if (!devlink->ops->sb_pool_get)
2461 return -EOPNOTSUPP;
2462
2463 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2464 if (!msg)
2465 return -ENOMEM;
2466
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);
2470 if (err) {
2471 nlmsg_free(msg);
2472 return err;
2473 }
2474
2475 return genlmsg_reply(msg, info);
2476}
2477
2478static 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)
2482{
2483 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2484 u16 pool_index;
2485 int err;
2486
2487 for (pool_index = 0; pool_index < pool_count; pool_index++) {
2488 if (*p_idx < start) {
2489 (*p_idx)++;
2490 continue;
2491 }
2492 err = devlink_nl_sb_pool_fill(msg, devlink,
2493 devlink_sb,
2494 pool_index,
2495 DEVLINK_CMD_SB_POOL_NEW,
2496 portid, seq, NLM_F_MULTI);
2497 if (err)
2498 return err;
2499 (*p_idx)++;
2500 }
2501 return 0;
2502}
2503
2504static int
2505devlink_nl_cmd_sb_pool_get_dump_one(struct sk_buff *msg,
2506 struct devlink *devlink,
2507 struct netlink_callback *cb)
2508{
2509 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2510 struct devlink_sb *devlink_sb;
2511 int err = 0;
2512 int idx = 0;
2513
2514 if (!devlink->ops->sb_pool_get)
2515 return 0;
2516
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) {
2523 err = 0;
2524 } else if (err) {
2525 state->idx = idx;
2526 break;
2527 }
2528 }
2529
2530 return err;
2531}
2532
2533const struct devlink_gen_cmd devl_gen_sb_pool = {
2534 .dump_one = devlink_nl_cmd_sb_pool_get_dump_one,
2535};
2536
2537static 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)
2541
2542{
2543 const struct devlink_ops *ops = devlink->ops;
2544
2545 if (ops->sb_pool_set)
2546 return ops->sb_pool_set(devlink, sb_index, pool_index,
2547 size, threshold_type, extack);
2548 return -EOPNOTSUPP;
2549}
2550
2551static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
2552 struct genl_info *info)
2553{
2554 struct devlink *devlink = info->user_ptr[0];
2555 enum devlink_sb_threshold_type threshold_type;
2556 struct devlink_sb *devlink_sb;
2557 u16 pool_index;
2558 u32 size;
2559 int err;
2560
2561 devlink_sb = devlink_sb_get_from_info(devlink, info);
2562 if (IS_ERR(devlink_sb))
2563 return PTR_ERR(devlink_sb);
2564
2565 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2566 &pool_index);
2567 if (err)
2568 return err;
2569
2570 err = devlink_sb_th_type_get_from_info(info, &threshold_type);
2571 if (err)
2572 return err;
2573
2574 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_POOL_SIZE))
2575 return -EINVAL;
2576
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,
2580 info->extack);
2581}
2582
2583static 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,
2587 u16 pool_index,
2588 enum devlink_command cmd,
2589 u32 portid, u32 seq, int flags)
2590{
2591 const struct devlink_ops *ops = devlink->ops;
2592 u32 threshold;
2593 void *hdr;
2594 int err;
2595
2596 err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
2597 pool_index, &threshold);
2598 if (err)
2599 return err;
2600
2601 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2602 if (!hdr)
2603 return -EMSGSIZE;
2604
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;
2615
2616 if (ops->sb_occ_port_pool_get) {
2617 u32 cur;
2618 u32 max;
2619
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;
2624 if (!err) {
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;
2629 }
2630 }
2631
2632 genlmsg_end(msg, hdr);
2633 return 0;
2634
2635nla_put_failure:
2636 err = -EMSGSIZE;
2637sb_occ_get_failure:
2638 genlmsg_cancel(msg, hdr);
2639 return err;
2640}
2641
2642static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
2643 struct genl_info *info)
2644{
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;
2649 u16 pool_index;
2650 int err;
2651
2652 devlink_sb = devlink_sb_get_from_info(devlink, info);
2653 if (IS_ERR(devlink_sb))
2654 return PTR_ERR(devlink_sb);
2655
2656 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2657 &pool_index);
2658 if (err)
2659 return err;
2660
2661 if (!devlink->ops->sb_port_pool_get)
2662 return -EOPNOTSUPP;
2663
2664 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2665 if (!msg)
2666 return -ENOMEM;
2667
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);
2672 if (err) {
2673 nlmsg_free(msg);
2674 return err;
2675 }
2676
2677 return genlmsg_reply(msg, info);
2678}
2679
2680static 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)
2684{
2685 struct devlink_port *devlink_port;
2686 u16 pool_count = devlink_sb_pool_count(devlink_sb);
2687 unsigned long port_index;
2688 u16 pool_index;
2689 int err;
2690
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) {
2694 (*p_idx)++;
2695 continue;
2696 }
2697 err = devlink_nl_sb_port_pool_fill(msg, devlink,
2698 devlink_port,
2699 devlink_sb,
2700 pool_index,
2701 DEVLINK_CMD_SB_PORT_POOL_NEW,
2702 portid, seq,
2703 NLM_F_MULTI);
2704 if (err)
2705 return err;
2706 (*p_idx)++;
2707 }
2708 }
2709 return 0;
2710}
2711
2712static int
2713devlink_nl_cmd_sb_port_pool_get_dump_one(struct sk_buff *msg,
2714 struct devlink *devlink,
2715 struct netlink_callback *cb)
2716{
2717 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2718 struct devlink_sb *devlink_sb;
2719 int idx = 0;
2720 int err = 0;
2721
2722 if (!devlink->ops->sb_port_pool_get)
2723 return 0;
2724
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) {
2731 err = 0;
2732 } else if (err) {
2733 state->idx = idx;
2734 break;
2735 }
2736 }
2737
2738 return err;
2739}
2740
2741const struct devlink_gen_cmd devl_gen_sb_port_pool = {
2742 .dump_one = devlink_nl_cmd_sb_port_pool_get_dump_one,
2743};
2744
2745static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
2746 unsigned int sb_index, u16 pool_index,
2747 u32 threshold,
2748 struct netlink_ext_ack *extack)
2749
2750{
2751 const struct devlink_ops *ops = devlink_port->devlink->ops;
2752
2753 if (ops->sb_port_pool_set)
2754 return ops->sb_port_pool_set(devlink_port, sb_index,
2755 pool_index, threshold, extack);
2756 return -EOPNOTSUPP;
2757}
2758
2759static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
2760 struct genl_info *info)
2761{
2762 struct devlink_port *devlink_port = info->user_ptr[1];
2763 struct devlink *devlink = info->user_ptr[0];
2764 struct devlink_sb *devlink_sb;
2765 u16 pool_index;
2766 u32 threshold;
2767 int err;
2768
2769 devlink_sb = devlink_sb_get_from_info(devlink, info);
2770 if (IS_ERR(devlink_sb))
2771 return PTR_ERR(devlink_sb);
2772
2773 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
2774 &pool_index);
2775 if (err)
2776 return err;
2777
2778 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
2779 return -EINVAL;
2780
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);
2784}
2785
2786static int
2787devlink_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)
2793{
2794 const struct devlink_ops *ops = devlink->ops;
2795 u16 pool_index;
2796 u32 threshold;
2797 void *hdr;
2798 int err;
2799
2800 err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
2801 tc_index, pool_type,
2802 &pool_index, &threshold);
2803 if (err)
2804 return err;
2805
2806 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2807 if (!hdr)
2808 return -EMSGSIZE;
2809
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;
2824
2825 if (ops->sb_occ_tc_port_bind_get) {
2826 u32 cur;
2827 u32 max;
2828
2829 err = ops->sb_occ_tc_port_bind_get(devlink_port,
2830 devlink_sb->index,
2831 tc_index, pool_type,
2832 &cur, &max);
2833 if (err && err != -EOPNOTSUPP)
2834 return err;
2835 if (!err) {
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;
2840 }
2841 }
2842
2843 genlmsg_end(msg, hdr);
2844 return 0;
2845
2846nla_put_failure:
2847 genlmsg_cancel(msg, hdr);
2848 return -EMSGSIZE;
2849}
2850
2851static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
2852 struct genl_info *info)
2853{
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;
2859 u16 tc_index;
2860 int err;
2861
2862 devlink_sb = devlink_sb_get_from_info(devlink, info);
2863 if (IS_ERR(devlink_sb))
2864 return PTR_ERR(devlink_sb);
2865
2866 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
2867 if (err)
2868 return err;
2869
2870 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
2871 pool_type, &tc_index);
2872 if (err)
2873 return err;
2874
2875 if (!devlink->ops->sb_tc_pool_bind_get)
2876 return -EOPNOTSUPP;
2877
2878 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2879 if (!msg)
2880 return -ENOMEM;
2881
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,
2885 info->snd_portid,
2886 info->snd_seq, 0);
2887 if (err) {
2888 nlmsg_free(msg);
2889 return err;
2890 }
2891
2892 return genlmsg_reply(msg, info);
2893}
2894
2895static 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)
2900{
2901 struct devlink_port *devlink_port;
2902 unsigned long port_index;
2903 u16 tc_index;
2904 int err;
2905
2906 xa_for_each(&devlink->ports, port_index, devlink_port) {
2907 for (tc_index = 0;
2908 tc_index < devlink_sb->ingress_tc_count; tc_index++) {
2909 if (*p_idx < start) {
2910 (*p_idx)++;
2911 continue;
2912 }
2913 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2914 devlink_port,
2915 devlink_sb,
2916 tc_index,
2917 DEVLINK_SB_POOL_TYPE_INGRESS,
2918 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2919 portid, seq,
2920 NLM_F_MULTI);
2921 if (err)
2922 return err;
2923 (*p_idx)++;
2924 }
2925 for (tc_index = 0;
2926 tc_index < devlink_sb->egress_tc_count; tc_index++) {
2927 if (*p_idx < start) {
2928 (*p_idx)++;
2929 continue;
2930 }
2931 err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
2932 devlink_port,
2933 devlink_sb,
2934 tc_index,
2935 DEVLINK_SB_POOL_TYPE_EGRESS,
2936 DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
2937 portid, seq,
2938 NLM_F_MULTI);
2939 if (err)
2940 return err;
2941 (*p_idx)++;
2942 }
2943 }
2944 return 0;
2945}
2946
2947static int
2948devlink_nl_cmd_sb_tc_pool_bind_get_dump_one(struct sk_buff *msg,
2949 struct devlink *devlink,
2950 struct netlink_callback *cb)
2951{
2952 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
2953 struct devlink_sb *devlink_sb;
2954 int idx = 0;
2955 int err = 0;
2956
2957 if (!devlink->ops->sb_tc_pool_bind_get)
2958 return 0;
2959
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) {
2966 err = 0;
2967 } else if (err) {
2968 state->idx = idx;
2969 break;
2970 }
2971 }
2972
2973 return err;
2974}
2975
2976const struct devlink_gen_cmd devl_gen_sb_tc_pool_bind = {
2977 .dump_one = devlink_nl_cmd_sb_tc_pool_bind_get_dump_one,
2978};
2979
2980static 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)
2985
2986{
2987 const struct devlink_ops *ops = devlink_port->devlink->ops;
2988
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);
2993 return -EOPNOTSUPP;
2994}
2995
2996static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
2997 struct genl_info *info)
2998{
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;
3003 u16 tc_index;
3004 u16 pool_index;
3005 u32 threshold;
3006 int err;
3007
3008 devlink_sb = devlink_sb_get_from_info(devlink, info);
3009 if (IS_ERR(devlink_sb))
3010 return PTR_ERR(devlink_sb);
3011
3012 err = devlink_sb_pool_type_get_from_info(info, &pool_type);
3013 if (err)
3014 return err;
3015
3016 err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
3017 pool_type, &tc_index);
3018 if (err)
3019 return err;
3020
3021 err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
3022 &pool_index);
3023 if (err)
3024 return err;
3025
3026 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SB_THRESHOLD))
3027 return -EINVAL;
3028
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);
3033}
3034
3035static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
3036 struct genl_info *info)
3037{
3038 struct devlink *devlink = info->user_ptr[0];
3039 const struct devlink_ops *ops = devlink->ops;
3040 struct devlink_sb *devlink_sb;
3041
3042 devlink_sb = devlink_sb_get_from_info(devlink, info);
3043 if (IS_ERR(devlink_sb))
3044 return PTR_ERR(devlink_sb);
3045
3046 if (ops->sb_occ_snapshot)
3047 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
3048 return -EOPNOTSUPP;
3049}
3050
3051static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
3052 struct genl_info *info)
3053{
3054 struct devlink *devlink = info->user_ptr[0];
3055 const struct devlink_ops *ops = devlink->ops;
3056 struct devlink_sb *devlink_sb;
3057
3058 devlink_sb = devlink_sb_get_from_info(devlink, info);
3059 if (IS_ERR(devlink_sb))
3060 return PTR_ERR(devlink_sb);
3061
3062 if (ops->sb_occ_max_clear)
3063 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
3064 return -EOPNOTSUPP;
3065}
3066
3067static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
3068 enum devlink_command cmd, u32 portid,
3069 u32 seq, int flags)
3070{
3071 const struct devlink_ops *ops = devlink->ops;
3072 enum devlink_eswitch_encap_mode encap_mode;
3073 u8 inline_mode;
3074 void *hdr;
3075 int err = 0;
3076 u16 mode;
3077
3078 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3079 if (!hdr)
3080 return -EMSGSIZE;
3081
3082 err = devlink_nl_put_handle(msg, devlink);
3083 if (err)
3084 goto nla_put_failure;
3085
3086 if (ops->eswitch_mode_get) {
3087 err = ops->eswitch_mode_get(devlink, &mode);
3088 if (err)
3089 goto nla_put_failure;
3090 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
3091 if (err)
3092 goto nla_put_failure;
3093 }
3094
3095 if (ops->eswitch_inline_mode_get) {
3096 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
3097 if (err)
3098 goto nla_put_failure;
3099 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
3100 inline_mode);
3101 if (err)
3102 goto nla_put_failure;
3103 }
3104
3105 if (ops->eswitch_encap_mode_get) {
3106 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
3107 if (err)
3108 goto nla_put_failure;
3109 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
3110 if (err)
3111 goto nla_put_failure;
3112 }
3113
3114 genlmsg_end(msg, hdr);
3115 return 0;
3116
3117nla_put_failure:
3118 genlmsg_cancel(msg, hdr);
3119 return err;
3120}
3121
3122static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
3123 struct genl_info *info)
3124{
3125 struct devlink *devlink = info->user_ptr[0];
3126 struct sk_buff *msg;
3127 int err;
3128
3129 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3130 if (!msg)
3131 return -ENOMEM;
3132
3133 err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
3134 info->snd_portid, info->snd_seq, 0);
3135
3136 if (err) {
3137 nlmsg_free(msg);
3138 return err;
3139 }
3140
3141 return genlmsg_reply(msg, info);
3142}
3143
3144static int devlink_rate_nodes_check(struct devlink *devlink, u16 mode,
3145 struct netlink_ext_ack *extack)
3146{
3147 struct devlink_rate *devlink_rate;
3148
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.");
3152 return -EBUSY;
3153 }
3154 return 0;
3155}
3156
3157static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
3158 struct genl_info *info)
3159{
3160 struct devlink *devlink = info->user_ptr[0];
3161 const struct devlink_ops *ops = devlink->ops;
3162 enum devlink_eswitch_encap_mode encap_mode;
3163 u8 inline_mode;
3164 int err = 0;
3165 u16 mode;
3166
3167 if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
3168 if (!ops->eswitch_mode_set)
3169 return -EOPNOTSUPP;
3170 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
3171 err = devlink_rate_nodes_check(devlink, mode, info->extack);
3172 if (err)
3173 return err;
3174 err = ops->eswitch_mode_set(devlink, mode, info->extack);
3175 if (err)
3176 return err;
3177 }
3178
3179 if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
3180 if (!ops->eswitch_inline_mode_set)
3181 return -EOPNOTSUPP;
3182 inline_mode = nla_get_u8(
3183 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
3184 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
3185 info->extack);
3186 if (err)
3187 return err;
3188 }
3189
3190 if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
3191 if (!ops->eswitch_encap_mode_set)
3192 return -EOPNOTSUPP;
3193 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
3194 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
3195 info->extack);
3196 if (err)
3197 return err;
3198 }
3199
3200 return 0;
3201}
3202
3203int devlink_dpipe_match_put(struct sk_buff *skb,
3204 struct devlink_dpipe_match *match)
3205{
3206 struct devlink_dpipe_header *header = match->header;
3207 struct devlink_dpipe_field *field = &header->fields[match->field_id];
3208 struct nlattr *match_attr;
3209
3210 match_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_MATCH);
3211 if (!match_attr)
3212 return -EMSGSIZE;
3213
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;
3220
3221 nla_nest_end(skb, match_attr);
3222 return 0;
3223
3224nla_put_failure:
3225 nla_nest_cancel(skb, match_attr);
3226 return -EMSGSIZE;
3227}
3228EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
3229
3230static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
3231 struct sk_buff *skb)
3232{
3233 struct nlattr *matches_attr;
3234
3235 matches_attr = nla_nest_start_noflag(skb,
3236 DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
3237 if (!matches_attr)
3238 return -EMSGSIZE;
3239
3240 if (table->table_ops->matches_dump(table->priv, skb))
3241 goto nla_put_failure;
3242
3243 nla_nest_end(skb, matches_attr);
3244 return 0;
3245
3246nla_put_failure:
3247 nla_nest_cancel(skb, matches_attr);
3248 return -EMSGSIZE;
3249}
3250
3251int devlink_dpipe_action_put(struct sk_buff *skb,
3252 struct devlink_dpipe_action *action)
3253{
3254 struct devlink_dpipe_header *header = action->header;
3255 struct devlink_dpipe_field *field = &header->fields[action->field_id];
3256 struct nlattr *action_attr;
3257
3258 action_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ACTION);
3259 if (!action_attr)
3260 return -EMSGSIZE;
3261
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;
3268
3269 nla_nest_end(skb, action_attr);
3270 return 0;
3271
3272nla_put_failure:
3273 nla_nest_cancel(skb, action_attr);
3274 return -EMSGSIZE;
3275}
3276EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
3277
3278static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
3279 struct sk_buff *skb)
3280{
3281 struct nlattr *actions_attr;
3282
3283 actions_attr = nla_nest_start_noflag(skb,
3284 DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
3285 if (!actions_attr)
3286 return -EMSGSIZE;
3287
3288 if (table->table_ops->actions_dump(table->priv, skb))
3289 goto nla_put_failure;
3290
3291 nla_nest_end(skb, actions_attr);
3292 return 0;
3293
3294nla_put_failure:
3295 nla_nest_cancel(skb, actions_attr);
3296 return -EMSGSIZE;
3297}
3298
3299static int devlink_dpipe_table_put(struct sk_buff *skb,
3300 struct devlink_dpipe_table *table)
3301{
3302 struct nlattr *table_attr;
3303 u64 table_size;
3304
3305 table_size = table->table_ops->size_get(table->priv);
3306 table_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_TABLE);
3307 if (!table_attr)
3308 return -EMSGSIZE;
3309
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,
3312 DEVLINK_ATTR_PAD))
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;
3317
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;
3324 }
3325 if (devlink_dpipe_matches_put(table, skb))
3326 goto nla_put_failure;
3327
3328 if (devlink_dpipe_actions_put(table, skb))
3329 goto nla_put_failure;
3330
3331 nla_nest_end(skb, table_attr);
3332 return 0;
3333
3334nla_put_failure:
3335 nla_nest_cancel(skb, table_attr);
3336 return -EMSGSIZE;
3337}
3338
3339static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
3340 struct genl_info *info)
3341{
3342 int err;
3343
3344 if (*pskb) {
3345 err = genlmsg_reply(*pskb, info);
3346 if (err)
3347 return err;
3348 }
3349 *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
3350 if (!*pskb)
3351 return -ENOMEM;
3352 return 0;
3353}
3354
3355static 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)
3359{
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;
3365 bool incomplete;
3366 void *hdr;
3367 int i;
3368 int err;
3369
3370 table = list_first_entry(dpipe_tables,
3371 struct devlink_dpipe_table, list);
3372start_again:
3373 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3374 if (err)
3375 return err;
3376
3377 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3378 &devlink_nl_family, NLM_F_MULTI, cmd);
3379 if (!hdr) {
3380 nlmsg_free(skb);
3381 return -EMSGSIZE;
3382 }
3383
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);
3387 if (!tables_attr)
3388 goto nla_put_failure;
3389
3390 i = 0;
3391 incomplete = false;
3392 list_for_each_entry_from(table, dpipe_tables, list) {
3393 if (!table_name) {
3394 err = devlink_dpipe_table_put(skb, table);
3395 if (err) {
3396 if (!i)
3397 goto err_table_put;
3398 incomplete = true;
3399 break;
3400 }
3401 } else {
3402 if (!strcmp(table->name, table_name)) {
3403 err = devlink_dpipe_table_put(skb, table);
3404 if (err)
3405 break;
3406 }
3407 }
3408 i++;
3409 }
3410
3411 nla_nest_end(skb, tables_attr);
3412 genlmsg_end(skb, hdr);
3413 if (incomplete)
3414 goto start_again;
3415
3416send_done:
3417 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3418 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3419 if (!nlh) {
3420 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3421 if (err)
3422 return err;
3423 goto send_done;
3424 }
3425
3426 return genlmsg_reply(skb, info);
3427
3428nla_put_failure:
3429 err = -EMSGSIZE;
3430err_table_put:
3431 nlmsg_free(skb);
3432 return err;
3433}
3434
3435static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
3436 struct genl_info *info)
3437{
3438 struct devlink *devlink = info->user_ptr[0];
3439 const char *table_name = NULL;
3440
3441 if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
3442 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
3443
3444 return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
3445 &devlink->dpipe_table_list,
3446 table_name);
3447}
3448
3449static int devlink_dpipe_value_put(struct sk_buff *skb,
3450 struct devlink_dpipe_value *value)
3451{
3452 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
3453 value->value_size, value->value))
3454 return -EMSGSIZE;
3455 if (value->mask)
3456 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
3457 value->value_size, value->mask))
3458 return -EMSGSIZE;
3459 if (value->mapping_valid)
3460 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
3461 value->mapping_value))
3462 return -EMSGSIZE;
3463 return 0;
3464}
3465
3466static int devlink_dpipe_action_value_put(struct sk_buff *skb,
3467 struct devlink_dpipe_value *value)
3468{
3469 if (!value->action)
3470 return -EINVAL;
3471 if (devlink_dpipe_action_put(skb, value->action))
3472 return -EMSGSIZE;
3473 if (devlink_dpipe_value_put(skb, value))
3474 return -EMSGSIZE;
3475 return 0;
3476}
3477
3478static int devlink_dpipe_action_values_put(struct sk_buff *skb,
3479 struct devlink_dpipe_value *values,
3480 unsigned int values_count)
3481{
3482 struct nlattr *action_attr;
3483 int i;
3484 int err;
3485
3486 for (i = 0; i < values_count; i++) {
3487 action_attr = nla_nest_start_noflag(skb,
3488 DEVLINK_ATTR_DPIPE_ACTION_VALUE);
3489 if (!action_attr)
3490 return -EMSGSIZE;
3491 err = devlink_dpipe_action_value_put(skb, &values[i]);
3492 if (err)
3493 goto err_action_value_put;
3494 nla_nest_end(skb, action_attr);
3495 }
3496 return 0;
3497
3498err_action_value_put:
3499 nla_nest_cancel(skb, action_attr);
3500 return err;
3501}
3502
3503static int devlink_dpipe_match_value_put(struct sk_buff *skb,
3504 struct devlink_dpipe_value *value)
3505{
3506 if (!value->match)
3507 return -EINVAL;
3508 if (devlink_dpipe_match_put(skb, value->match))
3509 return -EMSGSIZE;
3510 if (devlink_dpipe_value_put(skb, value))
3511 return -EMSGSIZE;
3512 return 0;
3513}
3514
3515static int devlink_dpipe_match_values_put(struct sk_buff *skb,
3516 struct devlink_dpipe_value *values,
3517 unsigned int values_count)
3518{
3519 struct nlattr *match_attr;
3520 int i;
3521 int err;
3522
3523 for (i = 0; i < values_count; i++) {
3524 match_attr = nla_nest_start_noflag(skb,
3525 DEVLINK_ATTR_DPIPE_MATCH_VALUE);
3526 if (!match_attr)
3527 return -EMSGSIZE;
3528 err = devlink_dpipe_match_value_put(skb, &values[i]);
3529 if (err)
3530 goto err_match_value_put;
3531 nla_nest_end(skb, match_attr);
3532 }
3533 return 0;
3534
3535err_match_value_put:
3536 nla_nest_cancel(skb, match_attr);
3537 return err;
3538}
3539
3540static int devlink_dpipe_entry_put(struct sk_buff *skb,
3541 struct devlink_dpipe_entry *entry)
3542{
3543 struct nlattr *entry_attr, *matches_attr, *actions_attr;
3544 int err;
3545
3546 entry_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_ENTRY);
3547 if (!entry_attr)
3548 return -EMSGSIZE;
3549
3550 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
3551 DEVLINK_ATTR_PAD))
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;
3557
3558 matches_attr = nla_nest_start_noflag(skb,
3559 DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
3560 if (!matches_attr)
3561 goto nla_put_failure;
3562
3563 err = devlink_dpipe_match_values_put(skb, entry->match_values,
3564 entry->match_values_count);
3565 if (err) {
3566 nla_nest_cancel(skb, matches_attr);
3567 goto err_match_values_put;
3568 }
3569 nla_nest_end(skb, matches_attr);
3570
3571 actions_attr = nla_nest_start_noflag(skb,
3572 DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
3573 if (!actions_attr)
3574 goto nla_put_failure;
3575
3576 err = devlink_dpipe_action_values_put(skb, entry->action_values,
3577 entry->action_values_count);
3578 if (err) {
3579 nla_nest_cancel(skb, actions_attr);
3580 goto err_action_values_put;
3581 }
3582 nla_nest_end(skb, actions_attr);
3583
3584 nla_nest_end(skb, entry_attr);
3585 return 0;
3586
3587nla_put_failure:
3588 err = -EMSGSIZE;
3589err_match_values_put:
3590err_action_values_put:
3591 nla_nest_cancel(skb, entry_attr);
3592 return err;
3593}
3594
3595static struct devlink_dpipe_table *
3596devlink_dpipe_table_find(struct list_head *dpipe_tables,
3597 const char *table_name, struct devlink *devlink)
3598{
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))
3603 return table;
3604 }
3605 return NULL;
3606}
3607
3608int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
3609{
3610 struct devlink *devlink;
3611 int err;
3612
3613 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
3614 dump_ctx->info);
3615 if (err)
3616 return err;
3617
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,
3622 dump_ctx->cmd);
3623 if (!dump_ctx->hdr)
3624 goto nla_put_failure;
3625
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;
3633 return 0;
3634
3635nla_put_failure:
3636 nlmsg_free(dump_ctx->skb);
3637 return -EMSGSIZE;
3638}
3639EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
3640
3641int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
3642 struct devlink_dpipe_entry *entry)
3643{
3644 return devlink_dpipe_entry_put(dump_ctx->skb, entry);
3645}
3646EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
3647
3648int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
3649{
3650 nla_nest_end(dump_ctx->skb, dump_ctx->nest);
3651 genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
3652 return 0;
3653}
3654EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
3655
3656void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
3657
3658{
3659 unsigned int value_count, value_index;
3660 struct devlink_dpipe_value *value;
3661
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);
3667 }
3668
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);
3674 }
3675}
3676EXPORT_SYMBOL_GPL(devlink_dpipe_entry_clear);
3677
3678static int devlink_dpipe_entries_fill(struct genl_info *info,
3679 enum devlink_command cmd, int flags,
3680 struct devlink_dpipe_table *table)
3681{
3682 struct devlink_dpipe_dump_ctx dump_ctx;
3683 struct nlmsghdr *nlh;
3684 int err;
3685
3686 dump_ctx.skb = NULL;
3687 dump_ctx.cmd = cmd;
3688 dump_ctx.info = info;
3689
3690 err = table->table_ops->entries_dump(table->priv,
3691 table->counters_enabled,
3692 &dump_ctx);
3693 if (err)
3694 return err;
3695
3696send_done:
3697 nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
3698 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3699 if (!nlh) {
3700 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
3701 if (err)
3702 return err;
3703 goto send_done;
3704 }
3705 return genlmsg_reply(dump_ctx.skb, info);
3706}
3707
3708static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
3709 struct genl_info *info)
3710{
3711 struct devlink *devlink = info->user_ptr[0];
3712 struct devlink_dpipe_table *table;
3713 const char *table_name;
3714
3715 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_DPIPE_TABLE_NAME))
3716 return -EINVAL;
3717
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);
3721 if (!table)
3722 return -EINVAL;
3723
3724 if (!table->table_ops->entries_dump)
3725 return -EINVAL;
3726
3727 return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
3728 0, table);
3729}
3730
3731static int devlink_dpipe_fields_put(struct sk_buff *skb,
3732 const struct devlink_dpipe_header *header)
3733{
3734 struct devlink_dpipe_field *field;
3735 struct nlattr *field_attr;
3736 int i;
3737
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);
3742 if (!field_attr)
3743 return -EMSGSIZE;
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);
3750 }
3751 return 0;
3752
3753nla_put_failure:
3754 nla_nest_cancel(skb, field_attr);
3755 return -EMSGSIZE;
3756}
3757
3758static int devlink_dpipe_header_put(struct sk_buff *skb,
3759 struct devlink_dpipe_header *header)
3760{
3761 struct nlattr *fields_attr, *header_attr;
3762 int err;
3763
3764 header_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_DPIPE_HEADER);
3765 if (!header_attr)
3766 return -EMSGSIZE;
3767
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;
3772
3773 fields_attr = nla_nest_start_noflag(skb,
3774 DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
3775 if (!fields_attr)
3776 goto nla_put_failure;
3777
3778 err = devlink_dpipe_fields_put(skb, header);
3779 if (err) {
3780 nla_nest_cancel(skb, fields_attr);
3781 goto nla_put_failure;
3782 }
3783 nla_nest_end(skb, fields_attr);
3784 nla_nest_end(skb, header_attr);
3785 return 0;
3786
3787nla_put_failure:
3788 err = -EMSGSIZE;
3789 nla_nest_cancel(skb, header_attr);
3790 return err;
3791}
3792
3793static int devlink_dpipe_headers_fill(struct genl_info *info,
3794 enum devlink_command cmd, int flags,
3795 struct devlink_dpipe_headers *
3796 dpipe_headers)
3797{
3798 struct devlink *devlink = info->user_ptr[0];
3799 struct nlattr *headers_attr;
3800 struct sk_buff *skb = NULL;
3801 struct nlmsghdr *nlh;
3802 void *hdr;
3803 int i, j;
3804 int err;
3805
3806 i = 0;
3807start_again:
3808 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3809 if (err)
3810 return err;
3811
3812 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
3813 &devlink_nl_family, NLM_F_MULTI, cmd);
3814 if (!hdr) {
3815 nlmsg_free(skb);
3816 return -EMSGSIZE;
3817 }
3818
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);
3822 if (!headers_attr)
3823 goto nla_put_failure;
3824
3825 j = 0;
3826 for (; i < dpipe_headers->headers_count; i++) {
3827 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
3828 if (err) {
3829 if (!j)
3830 goto err_table_put;
3831 break;
3832 }
3833 j++;
3834 }
3835 nla_nest_end(skb, headers_attr);
3836 genlmsg_end(skb, hdr);
3837 if (i != dpipe_headers->headers_count)
3838 goto start_again;
3839
3840send_done:
3841 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
3842 NLMSG_DONE, 0, flags | NLM_F_MULTI);
3843 if (!nlh) {
3844 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
3845 if (err)
3846 return err;
3847 goto send_done;
3848 }
3849 return genlmsg_reply(skb, info);
3850
3851nla_put_failure:
3852 err = -EMSGSIZE;
3853err_table_put:
3854 nlmsg_free(skb);
3855 return err;
3856}
3857
3858static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
3859 struct genl_info *info)
3860{
3861 struct devlink *devlink = info->user_ptr[0];
3862
3863 if (!devlink->dpipe_headers)
3864 return -EOPNOTSUPP;
3865 return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
3866 0, devlink->dpipe_headers);
3867}
3868
3869static int devlink_dpipe_table_counters_set(struct devlink *devlink,
3870 const char *table_name,
3871 bool enable)
3872{
3873 struct devlink_dpipe_table *table;
3874
3875 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
3876 table_name, devlink);
3877 if (!table)
3878 return -EINVAL;
3879
3880 if (table->counter_control_extern)
3881 return -EOPNOTSUPP;
3882
3883 if (!(table->counters_enabled ^ enable))
3884 return 0;
3885
3886 table->counters_enabled = enable;
3887 if (table->table_ops->counters_set_update)
3888 table->table_ops->counters_set_update(table->priv, enable);
3889 return 0;
3890}
3891
3892static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
3893 struct genl_info *info)
3894{
3895 struct devlink *devlink = info->user_ptr[0];
3896 const char *table_name;
3897 bool counters_enable;
3898
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))
3902 return -EINVAL;
3903
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]);
3906
3907 return devlink_dpipe_table_counters_set(devlink, table_name,
3908 counters_enable);
3909}
3910
3911static struct devlink_resource *
3912devlink_resource_find(struct devlink *devlink,
3913 struct devlink_resource *resource, u64 resource_id)
3914{
3915 struct list_head *resource_list;
3916
3917 if (resource)
3918 resource_list = &resource->resource_list;
3919 else
3920 resource_list = &devlink->resource_list;
3921
3922 list_for_each_entry(resource, resource_list, list) {
3923 struct devlink_resource *child_resource;
3924
3925 if (resource->id == resource_id)
3926 return resource;
3927
3928 child_resource = devlink_resource_find(devlink, resource,
3929 resource_id);
3930 if (child_resource)
3931 return child_resource;
3932 }
3933 return NULL;
3934}
3935
3936static void
3937devlink_resource_validate_children(struct devlink_resource *resource)
3938{
3939 struct devlink_resource *child_resource;
3940 bool size_valid = true;
3941 u64 parts_size = 0;
3942
3943 if (list_empty(&resource->resource_list))
3944 goto out;
3945
3946 list_for_each_entry(child_resource, &resource->resource_list, list)
3947 parts_size += child_resource->size_new;
3948
3949 if (parts_size > resource->size_new)
3950 size_valid = false;
3951out:
3952 resource->size_valid = size_valid;
3953}
3954
3955static int
3956devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
3957 struct netlink_ext_ack *extack)
3958{
3959 u64 reminder;
3960 int err = 0;
3961
3962 if (size > resource->size_params.size_max) {
3963 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
3964 err = -EINVAL;
3965 }
3966
3967 if (size < resource->size_params.size_min) {
3968 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
3969 err = -EINVAL;
3970 }
3971
3972 div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
3973 if (reminder) {
3974 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
3975 err = -EINVAL;
3976 }
3977
3978 return err;
3979}
3980
3981static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
3982 struct genl_info *info)
3983{
3984 struct devlink *devlink = info->user_ptr[0];
3985 struct devlink_resource *resource;
3986 u64 resource_id;
3987 u64 size;
3988 int err;
3989
3990 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_ID) ||
3991 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_RESOURCE_SIZE))
3992 return -EINVAL;
3993 resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
3994
3995 resource = devlink_resource_find(devlink, NULL, resource_id);
3996 if (!resource)
3997 return -EINVAL;
3998
3999 size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
4000 err = devlink_resource_validate_size(resource, size, info->extack);
4001 if (err)
4002 return err;
4003
4004 resource->size_new = size;
4005 devlink_resource_validate_children(resource);
4006 if (resource->parent)
4007 devlink_resource_validate_children(resource->parent);
4008 return 0;
4009}
4010
4011static int
4012devlink_resource_size_params_put(struct devlink_resource *resource,
4013 struct sk_buff *skb)
4014{
4015 struct devlink_resource_size_params *size_params;
4016
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))
4025 return -EMSGSIZE;
4026 return 0;
4027}
4028
4029static int devlink_resource_occ_put(struct devlink_resource *resource,
4030 struct sk_buff *skb)
4031{
4032 if (!resource->occ_get)
4033 return 0;
4034 return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
4035 resource->occ_get(resource->occ_get_priv),
4036 DEVLINK_ATTR_PAD);
4037}
4038
4039static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
4040 struct devlink_resource *resource)
4041{
4042 struct devlink_resource *child_resource;
4043 struct nlattr *child_resource_attr;
4044 struct nlattr *resource_attr;
4045
4046 resource_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_RESOURCE);
4047 if (!resource_attr)
4048 return -EMSGSIZE;
4049
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,
4054 DEVLINK_ATTR_PAD))
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))
4065 goto out;
4066
4067 if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
4068 resource->size_valid))
4069 goto nla_put_failure;
4070
4071 child_resource_attr = nla_nest_start_noflag(skb,
4072 DEVLINK_ATTR_RESOURCE_LIST);
4073 if (!child_resource_attr)
4074 goto nla_put_failure;
4075
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;
4079 }
4080
4081 nla_nest_end(skb, child_resource_attr);
4082out:
4083 nla_nest_end(skb, resource_attr);
4084 return 0;
4085
4086resource_put_failure:
4087 nla_nest_cancel(skb, child_resource_attr);
4088nla_put_failure:
4089 nla_nest_cancel(skb, resource_attr);
4090 return -EMSGSIZE;
4091}
4092
4093static int devlink_resource_fill(struct genl_info *info,
4094 enum devlink_command cmd, int flags)
4095{
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;
4101 bool incomplete;
4102 void *hdr;
4103 int i;
4104 int err;
4105
4106 resource = list_first_entry(&devlink->resource_list,
4107 struct devlink_resource, list);
4108start_again:
4109 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4110 if (err)
4111 return err;
4112
4113 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4114 &devlink_nl_family, NLM_F_MULTI, cmd);
4115 if (!hdr) {
4116 nlmsg_free(skb);
4117 return -EMSGSIZE;
4118 }
4119
4120 if (devlink_nl_put_handle(skb, devlink))
4121 goto nla_put_failure;
4122
4123 resources_attr = nla_nest_start_noflag(skb,
4124 DEVLINK_ATTR_RESOURCE_LIST);
4125 if (!resources_attr)
4126 goto nla_put_failure;
4127
4128 incomplete = false;
4129 i = 0;
4130 list_for_each_entry_from(resource, &devlink->resource_list, list) {
4131 err = devlink_resource_put(devlink, skb, resource);
4132 if (err) {
4133 if (!i)
4134 goto err_resource_put;
4135 incomplete = true;
4136 break;
4137 }
4138 i++;
4139 }
4140 nla_nest_end(skb, resources_attr);
4141 genlmsg_end(skb, hdr);
4142 if (incomplete)
4143 goto start_again;
4144send_done:
4145 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4146 NLMSG_DONE, 0, flags | NLM_F_MULTI);
4147 if (!nlh) {
4148 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
4149 if (err)
4150 return err;
4151 goto send_done;
4152 }
4153 return genlmsg_reply(skb, info);
4154
4155nla_put_failure:
4156 err = -EMSGSIZE;
4157err_resource_put:
4158 nlmsg_free(skb);
4159 return err;
4160}
4161
4162static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
4163 struct genl_info *info)
4164{
4165 struct devlink *devlink = info->user_ptr[0];
4166
4167 if (list_empty(&devlink->resource_list))
4168 return -EOPNOTSUPP;
4169
4170 return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
4171}
4172
4173static int
4174devlink_resources_validate(struct devlink *devlink,
4175 struct devlink_resource *resource,
4176 struct genl_info *info)
4177{
4178 struct list_head *resource_list;
4179 int err = 0;
4180
4181 if (resource)
4182 resource_list = &resource->resource_list;
4183 else
4184 resource_list = &devlink->resource_list;
4185
4186 list_for_each_entry(resource, resource_list, list) {
4187 if (!resource->size_valid)
4188 return -EINVAL;
4189 err = devlink_resources_validate(devlink, resource, info);
4190 if (err)
4191 return err;
4192 }
4193 return err;
4194}
4195
4196static struct net *devlink_netns_get(struct sk_buff *skb,
4197 struct genl_info *info)
4198{
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];
4202 struct net *net;
4203
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);
4207 }
4208
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));
4216 if (!net)
4217 net = ERR_PTR(-EINVAL);
4218 } else {
4219 WARN_ON(1);
4220 net = ERR_PTR(-EINVAL);
4221 }
4222 if (IS_ERR(net)) {
4223 NL_SET_ERR_MSG_MOD(info->extack, "Unknown network namespace");
4224 return ERR_PTR(-EINVAL);
4225 }
4226 if (!netlink_ns_capable(skb, net->user_ns, CAP_NET_ADMIN)) {
4227 put_net(net);
4228 return ERR_PTR(-EPERM);
4229 }
4230 return net;
4231}
4232
4233static void devlink_param_notify(struct devlink *devlink,
4234 unsigned int port_index,
4235 struct devlink_param_item *param_item,
4236 enum devlink_command cmd);
4237
4238static void devlink_reload_netns_change(struct devlink *devlink,
4239 struct net *curr_net,
4240 struct net *dest_net)
4241{
4242 struct devlink_param_item *param_item;
4243
4244 /* Userspace needs to be notified about devlink objects
4245 * removed from original and entering new network namespace.
4246 * The rest of the devlink objects are re-created during
4247 * reload process so the notifications are generated separatelly.
4248 */
4249
4250 list_for_each_entry(param_item, &devlink->param_list, list)
4251 devlink_param_notify(devlink, 0, param_item,
4252 DEVLINK_CMD_PARAM_DEL);
4253 devlink_notify(devlink, DEVLINK_CMD_DEL);
4254
4255 move_netdevice_notifier_net(curr_net, dest_net,
4256 &devlink->netdevice_nb);
4257 write_pnet(&devlink->_net, dest_net);
4258
4259 devlink_notify(devlink, DEVLINK_CMD_NEW);
4260 list_for_each_entry(param_item, &devlink->param_list, list)
4261 devlink_param_notify(devlink, 0, param_item,
4262 DEVLINK_CMD_PARAM_NEW);
4263}
4264
4265static void devlink_reload_failed_set(struct devlink *devlink,
4266 bool reload_failed)
4267{
4268 if (devlink->reload_failed == reload_failed)
4269 return;
4270 devlink->reload_failed = reload_failed;
4271 devlink_notify(devlink, DEVLINK_CMD_NEW);
4272}
4273
4274bool devlink_is_reload_failed(const struct devlink *devlink)
4275{
4276 return devlink->reload_failed;
4277}
4278EXPORT_SYMBOL_GPL(devlink_is_reload_failed);
4279
4280static void
4281__devlink_reload_stats_update(struct devlink *devlink, u32 *reload_stats,
4282 enum devlink_reload_limit limit, u32 actions_performed)
4283{
4284 unsigned long actions = actions_performed;
4285 int stat_idx;
4286 int action;
4287
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]++;
4291 }
4292 devlink_notify(devlink, DEVLINK_CMD_NEW);
4293}
4294
4295static void
4296devlink_reload_stats_update(struct devlink *devlink, enum devlink_reload_limit limit,
4297 u32 actions_performed)
4298{
4299 __devlink_reload_stats_update(devlink, devlink->stats.reload_stats, limit,
4300 actions_performed);
4301}
4302
4303/**
4304 * devlink_remote_reload_actions_performed - Update devlink on reload actions
4305 * performed which are not a direct result of devlink reload call.
4306 *
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.
4312 *
4313 * @devlink: devlink
4314 * @limit: reload limit
4315 * @actions_performed: bitmask of actions performed
4316 */
4317void devlink_remote_reload_actions_performed(struct devlink *devlink,
4318 enum devlink_reload_limit limit,
4319 u32 actions_performed)
4320{
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))
4325 return;
4326
4327 __devlink_reload_stats_update(devlink, devlink->stats.remote_reload_stats, limit,
4328 actions_performed);
4329}
4330EXPORT_SYMBOL_GPL(devlink_remote_reload_actions_performed);
4331
4332int 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)
4336{
4337 u32 remote_reload_stats[DEVLINK_RELOAD_STATS_ARRAY_SIZE];
4338 struct net *curr_net;
4339 int err;
4340
4341 memcpy(remote_reload_stats, devlink->stats.remote_reload_stats,
4342 sizeof(remote_reload_stats));
4343
4344 err = devlink->ops->reload_down(devlink, !!dest_net, action, limit, extack);
4345 if (err)
4346 return err;
4347
4348 curr_net = devlink_net(devlink);
4349 if (dest_net && !net_eq(dest_net, curr_net))
4350 devlink_reload_netns_change(devlink, curr_net, dest_net);
4351
4352 err = devlink->ops->reload_up(devlink, action, limit, actions_performed, extack);
4353 devlink_reload_failed_set(devlink, !!err);
4354 if (err)
4355 return err;
4356
4357 WARN_ON(!(*actions_performed & BIT(action)));
4358 /* Catch driver on updating the remote action within devlink reload */
4359 WARN_ON(memcmp(remote_reload_stats, devlink->stats.remote_reload_stats,
4360 sizeof(remote_reload_stats)));
4361 devlink_reload_stats_update(devlink, limit, *actions_performed);
4362 return 0;
4363}
4364
4365static int
4366devlink_nl_reload_actions_performed_snd(struct devlink *devlink, u32 actions_performed,
4367 enum devlink_command cmd, struct genl_info *info)
4368{
4369 struct sk_buff *msg;
4370 void *hdr;
4371
4372 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4373 if (!msg)
4374 return -ENOMEM;
4375
4376 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq, &devlink_nl_family, 0, cmd);
4377 if (!hdr)
4378 goto free_msg;
4379
4380 if (devlink_nl_put_handle(msg, devlink))
4381 goto nla_put_failure;
4382
4383 if (nla_put_bitfield32(msg, DEVLINK_ATTR_RELOAD_ACTIONS_PERFORMED, actions_performed,
4384 actions_performed))
4385 goto nla_put_failure;
4386 genlmsg_end(msg, hdr);
4387
4388 return genlmsg_reply(msg, info);
4389
4390nla_put_failure:
4391 genlmsg_cancel(msg, hdr);
4392free_msg:
4393 nlmsg_free(msg);
4394 return -EMSGSIZE;
4395}
4396
4397static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
4398{
4399 struct devlink *devlink = info->user_ptr[0];
4400 enum devlink_reload_action action;
4401 enum devlink_reload_limit limit;
4402 struct net *dest_net = NULL;
4403 u32 actions_performed;
4404 int err;
4405
4406 if (!(devlink->features & DEVLINK_F_RELOAD))
4407 return -EOPNOTSUPP;
4408
4409 err = devlink_resources_validate(devlink, NULL, info);
4410 if (err) {
4411 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
4412 return err;
4413 }
4414
4415 if (info->attrs[DEVLINK_ATTR_RELOAD_ACTION])
4416 action = nla_get_u8(info->attrs[DEVLINK_ATTR_RELOAD_ACTION]);
4417 else
4418 action = DEVLINK_RELOAD_ACTION_DRIVER_REINIT;
4419
4420 if (!devlink_reload_action_is_supported(devlink, action)) {
4421 NL_SET_ERR_MSG_MOD(info->extack,
4422 "Requested reload action is not supported by the driver");
4423 return -EOPNOTSUPP;
4424 }
4425
4426 limit = DEVLINK_RELOAD_LIMIT_UNSPEC;
4427 if (info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]) {
4428 struct nla_bitfield32 limits;
4429 u32 limits_selected;
4430
4431 limits = nla_get_bitfield32(info->attrs[DEVLINK_ATTR_RELOAD_LIMITS]);
4432 limits_selected = limits.value & limits.selector;
4433 if (!limits_selected) {
4434 NL_SET_ERR_MSG_MOD(info->extack, "Invalid limit selected");
4435 return -EINVAL;
4436 }
4437 for (limit = 0 ; limit <= DEVLINK_RELOAD_LIMIT_MAX ; limit++)
4438 if (limits_selected & BIT(limit))
4439 break;
4440 /* UAPI enables multiselection, but currently it is not used */
4441 if (limits_selected != BIT(limit)) {
4442 NL_SET_ERR_MSG_MOD(info->extack,
4443 "Multiselection of limit is not supported");
4444 return -EOPNOTSUPP;
4445 }
4446 if (!devlink_reload_limit_is_supported(devlink, limit)) {
4447 NL_SET_ERR_MSG_MOD(info->extack,
4448 "Requested limit is not supported by the driver");
4449 return -EOPNOTSUPP;
4450 }
4451 if (devlink_reload_combination_is_invalid(action, limit)) {
4452 NL_SET_ERR_MSG_MOD(info->extack,
4453 "Requested limit is invalid for this action");
4454 return -EINVAL;
4455 }
4456 }
4457 if (info->attrs[DEVLINK_ATTR_NETNS_PID] ||
4458 info->attrs[DEVLINK_ATTR_NETNS_FD] ||
4459 info->attrs[DEVLINK_ATTR_NETNS_ID]) {
4460 dest_net = devlink_netns_get(skb, info);
4461 if (IS_ERR(dest_net))
4462 return PTR_ERR(dest_net);
4463 }
4464
4465 err = devlink_reload(devlink, dest_net, action, limit, &actions_performed, info->extack);
4466
4467 if (dest_net)
4468 put_net(dest_net);
4469
4470 if (err)
4471 return err;
4472 /* For backward compatibility generate reply only if attributes used by user */
4473 if (!info->attrs[DEVLINK_ATTR_RELOAD_ACTION] && !info->attrs[DEVLINK_ATTR_RELOAD_LIMITS])
4474 return 0;
4475
4476 return devlink_nl_reload_actions_performed_snd(devlink, actions_performed,
4477 DEVLINK_CMD_RELOAD, info);
4478}
4479
4480static int devlink_nl_flash_update_fill(struct sk_buff *msg,
4481 struct devlink *devlink,
4482 enum devlink_command cmd,
4483 struct devlink_flash_notify *params)
4484{
4485 void *hdr;
4486
4487 hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
4488 if (!hdr)
4489 return -EMSGSIZE;
4490
4491 if (devlink_nl_put_handle(msg, devlink))
4492 goto nla_put_failure;
4493
4494 if (cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS)
4495 goto out;
4496
4497 if (params->status_msg &&
4498 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_MSG,
4499 params->status_msg))
4500 goto nla_put_failure;
4501 if (params->component &&
4502 nla_put_string(msg, DEVLINK_ATTR_FLASH_UPDATE_COMPONENT,
4503 params->component))
4504 goto nla_put_failure;
4505 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_DONE,
4506 params->done, DEVLINK_ATTR_PAD))
4507 goto nla_put_failure;
4508 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TOTAL,
4509 params->total, DEVLINK_ATTR_PAD))
4510 goto nla_put_failure;
4511 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_FLASH_UPDATE_STATUS_TIMEOUT,
4512 params->timeout, DEVLINK_ATTR_PAD))
4513 goto nla_put_failure;
4514
4515out:
4516 genlmsg_end(msg, hdr);
4517 return 0;
4518
4519nla_put_failure:
4520 genlmsg_cancel(msg, hdr);
4521 return -EMSGSIZE;
4522}
4523
4524static void __devlink_flash_update_notify(struct devlink *devlink,
4525 enum devlink_command cmd,
4526 struct devlink_flash_notify *params)
4527{
4528 struct sk_buff *msg;
4529 int err;
4530
4531 WARN_ON(cmd != DEVLINK_CMD_FLASH_UPDATE &&
4532 cmd != DEVLINK_CMD_FLASH_UPDATE_END &&
4533 cmd != DEVLINK_CMD_FLASH_UPDATE_STATUS);
4534
4535 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
4536 return;
4537
4538 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4539 if (!msg)
4540 return;
4541
4542 err = devlink_nl_flash_update_fill(msg, devlink, cmd, params);
4543 if (err)
4544 goto out_free_msg;
4545
4546 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
4547 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
4548 return;
4549
4550out_free_msg:
4551 nlmsg_free(msg);
4552}
4553
4554static void devlink_flash_update_begin_notify(struct devlink *devlink)
4555{
4556 struct devlink_flash_notify params = {};
4557
4558 __devlink_flash_update_notify(devlink,
4559 DEVLINK_CMD_FLASH_UPDATE,
4560 &params);
4561}
4562
4563static void devlink_flash_update_end_notify(struct devlink *devlink)
4564{
4565 struct devlink_flash_notify params = {};
4566
4567 __devlink_flash_update_notify(devlink,
4568 DEVLINK_CMD_FLASH_UPDATE_END,
4569 &params);
4570}
4571
4572void devlink_flash_update_status_notify(struct devlink *devlink,
4573 const char *status_msg,
4574 const char *component,
4575 unsigned long done,
4576 unsigned long total)
4577{
4578 struct devlink_flash_notify params = {
4579 .status_msg = status_msg,
4580 .component = component,
4581 .done = done,
4582 .total = total,
4583 };
4584
4585 __devlink_flash_update_notify(devlink,
4586 DEVLINK_CMD_FLASH_UPDATE_STATUS,
4587 &params);
4588}
4589EXPORT_SYMBOL_GPL(devlink_flash_update_status_notify);
4590
4591void devlink_flash_update_timeout_notify(struct devlink *devlink,
4592 const char *status_msg,
4593 const char *component,
4594 unsigned long timeout)
4595{
4596 struct devlink_flash_notify params = {
4597 .status_msg = status_msg,
4598 .component = component,
4599 .timeout = timeout,
4600 };
4601
4602 __devlink_flash_update_notify(devlink,
4603 DEVLINK_CMD_FLASH_UPDATE_STATUS,
4604 &params);
4605}
4606EXPORT_SYMBOL_GPL(devlink_flash_update_timeout_notify);
4607
4608struct devlink_info_req {
4609 struct sk_buff *msg;
4610 void (*version_cb)(const char *version_name,
4611 enum devlink_info_version_type version_type,
4612 void *version_cb_priv);
4613 void *version_cb_priv;
4614};
4615
4616struct devlink_flash_component_lookup_ctx {
4617 const char *lookup_name;
4618 bool lookup_name_found;
4619};
4620
4621static void
4622devlink_flash_component_lookup_cb(const char *version_name,
4623 enum devlink_info_version_type version_type,
4624 void *version_cb_priv)
4625{
4626 struct devlink_flash_component_lookup_ctx *lookup_ctx = version_cb_priv;
4627
4628 if (version_type != DEVLINK_INFO_VERSION_TYPE_COMPONENT ||
4629 lookup_ctx->lookup_name_found)
4630 return;
4631
4632 lookup_ctx->lookup_name_found =
4633 !strcmp(lookup_ctx->lookup_name, version_name);
4634}
4635
4636static int devlink_flash_component_get(struct devlink *devlink,
4637 struct nlattr *nla_component,
4638 const char **p_component,
4639 struct netlink_ext_ack *extack)
4640{
4641 struct devlink_flash_component_lookup_ctx lookup_ctx = {};
4642 struct devlink_info_req req = {};
4643 const char *component;
4644 int ret;
4645
4646 if (!nla_component)
4647 return 0;
4648
4649 component = nla_data(nla_component);
4650
4651 if (!devlink->ops->info_get) {
4652 NL_SET_ERR_MSG_ATTR(extack, nla_component,
4653 "component update is not supported by this device");
4654 return -EOPNOTSUPP;
4655 }
4656
4657 lookup_ctx.lookup_name = component;
4658 req.version_cb = devlink_flash_component_lookup_cb;
4659 req.version_cb_priv = &lookup_ctx;
4660
4661 ret = devlink->ops->info_get(devlink, &req, NULL);
4662 if (ret)
4663 return ret;
4664
4665 if (!lookup_ctx.lookup_name_found) {
4666 NL_SET_ERR_MSG_ATTR(extack, nla_component,
4667 "selected component is not supported by this device");
4668 return -EINVAL;
4669 }
4670 *p_component = component;
4671 return 0;
4672}
4673
4674static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
4675 struct genl_info *info)
4676{
4677 struct nlattr *nla_overwrite_mask, *nla_file_name;
4678 struct devlink_flash_update_params params = {};
4679 struct devlink *devlink = info->user_ptr[0];
4680 const char *file_name;
4681 u32 supported_params;
4682 int ret;
4683
4684 if (!devlink->ops->flash_update)
4685 return -EOPNOTSUPP;
4686
4687 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME))
4688 return -EINVAL;
4689
4690 ret = devlink_flash_component_get(devlink,
4691 info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT],
4692 &params.component, info->extack);
4693 if (ret)
4694 return ret;
4695
4696 supported_params = devlink->ops->supported_flash_update_params;
4697
4698 nla_overwrite_mask = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_OVERWRITE_MASK];
4699 if (nla_overwrite_mask) {
4700 struct nla_bitfield32 sections;
4701
4702 if (!(supported_params & DEVLINK_SUPPORT_FLASH_UPDATE_OVERWRITE_MASK)) {
4703 NL_SET_ERR_MSG_ATTR(info->extack, nla_overwrite_mask,
4704 "overwrite settings are not supported by this device");
4705 return -EOPNOTSUPP;
4706 }
4707 sections = nla_get_bitfield32(nla_overwrite_mask);
4708 params.overwrite_mask = sections.value & sections.selector;
4709 }
4710
4711 nla_file_name = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME];
4712 file_name = nla_data(nla_file_name);
4713 ret = request_firmware(&params.fw, file_name, devlink->dev);
4714 if (ret) {
4715 NL_SET_ERR_MSG_ATTR(info->extack, nla_file_name, "failed to locate the requested firmware file");
4716 return ret;
4717 }
4718
4719 devlink_flash_update_begin_notify(devlink);
4720 ret = devlink->ops->flash_update(devlink, &params, info->extack);
4721 devlink_flash_update_end_notify(devlink);
4722
4723 release_firmware(params.fw);
4724
4725 return ret;
4726}
4727
4728static int
4729devlink_nl_selftests_fill(struct sk_buff *msg, struct devlink *devlink,
4730 u32 portid, u32 seq, int flags,
4731 struct netlink_ext_ack *extack)
4732{
4733 struct nlattr *selftests;
4734 void *hdr;
4735 int err;
4736 int i;
4737
4738 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags,
4739 DEVLINK_CMD_SELFTESTS_GET);
4740 if (!hdr)
4741 return -EMSGSIZE;
4742
4743 err = -EMSGSIZE;
4744 if (devlink_nl_put_handle(msg, devlink))
4745 goto err_cancel_msg;
4746
4747 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
4748 if (!selftests)
4749 goto err_cancel_msg;
4750
4751 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
4752 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
4753 if (devlink->ops->selftest_check(devlink, i, extack)) {
4754 err = nla_put_flag(msg, i);
4755 if (err)
4756 goto err_cancel_msg;
4757 }
4758 }
4759
4760 nla_nest_end(msg, selftests);
4761 genlmsg_end(msg, hdr);
4762 return 0;
4763
4764err_cancel_msg:
4765 genlmsg_cancel(msg, hdr);
4766 return err;
4767}
4768
4769static int devlink_nl_cmd_selftests_get_doit(struct sk_buff *skb,
4770 struct genl_info *info)
4771{
4772 struct devlink *devlink = info->user_ptr[0];
4773 struct sk_buff *msg;
4774 int err;
4775
4776 if (!devlink->ops->selftest_check)
4777 return -EOPNOTSUPP;
4778
4779 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4780 if (!msg)
4781 return -ENOMEM;
4782
4783 err = devlink_nl_selftests_fill(msg, devlink, info->snd_portid,
4784 info->snd_seq, 0, info->extack);
4785 if (err) {
4786 nlmsg_free(msg);
4787 return err;
4788 }
4789
4790 return genlmsg_reply(msg, info);
4791}
4792
4793static int
4794devlink_nl_cmd_selftests_get_dump_one(struct sk_buff *msg,
4795 struct devlink *devlink,
4796 struct netlink_callback *cb)
4797{
4798 if (!devlink->ops->selftest_check)
4799 return 0;
4800
4801 return devlink_nl_selftests_fill(msg, devlink,
4802 NETLINK_CB(cb->skb).portid,
4803 cb->nlh->nlmsg_seq, NLM_F_MULTI,
4804 cb->extack);
4805}
4806
4807const struct devlink_gen_cmd devl_gen_selftests = {
4808 .dump_one = devlink_nl_cmd_selftests_get_dump_one,
4809};
4810
4811static int devlink_selftest_result_put(struct sk_buff *skb, unsigned int id,
4812 enum devlink_selftest_status test_status)
4813{
4814 struct nlattr *result_attr;
4815
4816 result_attr = nla_nest_start(skb, DEVLINK_ATTR_SELFTEST_RESULT);
4817 if (!result_attr)
4818 return -EMSGSIZE;
4819
4820 if (nla_put_u32(skb, DEVLINK_ATTR_SELFTEST_RESULT_ID, id) ||
4821 nla_put_u8(skb, DEVLINK_ATTR_SELFTEST_RESULT_STATUS,
4822 test_status))
4823 goto nla_put_failure;
4824
4825 nla_nest_end(skb, result_attr);
4826 return 0;
4827
4828nla_put_failure:
4829 nla_nest_cancel(skb, result_attr);
4830 return -EMSGSIZE;
4831}
4832
4833static int devlink_nl_cmd_selftests_run(struct sk_buff *skb,
4834 struct genl_info *info)
4835{
4836 struct nlattr *tb[DEVLINK_ATTR_SELFTEST_ID_MAX + 1];
4837 struct devlink *devlink = info->user_ptr[0];
4838 struct nlattr *attrs, *selftests;
4839 struct sk_buff *msg;
4840 void *hdr;
4841 int err;
4842 int i;
4843
4844 if (!devlink->ops->selftest_run || !devlink->ops->selftest_check)
4845 return -EOPNOTSUPP;
4846
4847 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_SELFTESTS))
4848 return -EINVAL;
4849
4850 attrs = info->attrs[DEVLINK_ATTR_SELFTESTS];
4851
4852 err = nla_parse_nested(tb, DEVLINK_ATTR_SELFTEST_ID_MAX, attrs,
4853 devlink_selftest_nl_policy, info->extack);
4854 if (err < 0)
4855 return err;
4856
4857 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4858 if (!msg)
4859 return -ENOMEM;
4860
4861 err = -EMSGSIZE;
4862 hdr = genlmsg_put(msg, info->snd_portid, info->snd_seq,
4863 &devlink_nl_family, 0, DEVLINK_CMD_SELFTESTS_RUN);
4864 if (!hdr)
4865 goto free_msg;
4866
4867 if (devlink_nl_put_handle(msg, devlink))
4868 goto genlmsg_cancel;
4869
4870 selftests = nla_nest_start(msg, DEVLINK_ATTR_SELFTESTS);
4871 if (!selftests)
4872 goto genlmsg_cancel;
4873
4874 for (i = DEVLINK_ATTR_SELFTEST_ID_UNSPEC + 1;
4875 i <= DEVLINK_ATTR_SELFTEST_ID_MAX; i++) {
4876 enum devlink_selftest_status test_status;
4877
4878 if (nla_get_flag(tb[i])) {
4879 if (!devlink->ops->selftest_check(devlink, i,
4880 info->extack)) {
4881 if (devlink_selftest_result_put(msg, i,
4882 DEVLINK_SELFTEST_STATUS_SKIP))
4883 goto selftests_nest_cancel;
4884 continue;
4885 }
4886
4887 test_status = devlink->ops->selftest_run(devlink, i,
4888 info->extack);
4889 if (devlink_selftest_result_put(msg, i, test_status))
4890 goto selftests_nest_cancel;
4891 }
4892 }
4893
4894 nla_nest_end(msg, selftests);
4895 genlmsg_end(msg, hdr);
4896 return genlmsg_reply(msg, info);
4897
4898selftests_nest_cancel:
4899 nla_nest_cancel(msg, selftests);
4900genlmsg_cancel:
4901 genlmsg_cancel(msg, hdr);
4902free_msg:
4903 nlmsg_free(msg);
4904 return err;
4905}
4906
4907static const struct devlink_param devlink_param_generic[] = {
4908 {
4909 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
4910 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
4911 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
4912 },
4913 {
4914 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
4915 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
4916 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
4917 },
4918 {
4919 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
4920 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
4921 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
4922 },
4923 {
4924 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
4925 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
4926 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
4927 },
4928 {
4929 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
4930 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
4931 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
4932 },
4933 {
4934 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
4935 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
4936 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
4937 },
4938 {
4939 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
4940 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
4941 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
4942 },
4943 {
4944 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
4945 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
4946 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
4947 },
4948 {
4949 .id = DEVLINK_PARAM_GENERIC_ID_RESET_DEV_ON_DRV_PROBE,
4950 .name = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_NAME,
4951 .type = DEVLINK_PARAM_GENERIC_RESET_DEV_ON_DRV_PROBE_TYPE,
4952 },
4953 {
4954 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ROCE,
4955 .name = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_NAME,
4956 .type = DEVLINK_PARAM_GENERIC_ENABLE_ROCE_TYPE,
4957 },
4958 {
4959 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_REMOTE_DEV_RESET,
4960 .name = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_NAME,
4961 .type = DEVLINK_PARAM_GENERIC_ENABLE_REMOTE_DEV_RESET_TYPE,
4962 },
4963 {
4964 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_ETH,
4965 .name = DEVLINK_PARAM_GENERIC_ENABLE_ETH_NAME,
4966 .type = DEVLINK_PARAM_GENERIC_ENABLE_ETH_TYPE,
4967 },
4968 {
4969 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_RDMA,
4970 .name = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_NAME,
4971 .type = DEVLINK_PARAM_GENERIC_ENABLE_RDMA_TYPE,
4972 },
4973 {
4974 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_VNET,
4975 .name = DEVLINK_PARAM_GENERIC_ENABLE_VNET_NAME,
4976 .type = DEVLINK_PARAM_GENERIC_ENABLE_VNET_TYPE,
4977 },
4978 {
4979 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_IWARP,
4980 .name = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_NAME,
4981 .type = DEVLINK_PARAM_GENERIC_ENABLE_IWARP_TYPE,
4982 },
4983 {
4984 .id = DEVLINK_PARAM_GENERIC_ID_IO_EQ_SIZE,
4985 .name = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_NAME,
4986 .type = DEVLINK_PARAM_GENERIC_IO_EQ_SIZE_TYPE,
4987 },
4988 {
4989 .id = DEVLINK_PARAM_GENERIC_ID_EVENT_EQ_SIZE,
4990 .name = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_NAME,
4991 .type = DEVLINK_PARAM_GENERIC_EVENT_EQ_SIZE_TYPE,
4992 },
4993};
4994
4995static int devlink_param_generic_verify(const struct devlink_param *param)
4996{
4997 /* verify it match generic parameter by id and name */
4998 if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
4999 return -EINVAL;
5000 if (strcmp(param->name, devlink_param_generic[param->id].name))
5001 return -ENOENT;
5002
5003 WARN_ON(param->type != devlink_param_generic[param->id].type);
5004
5005 return 0;
5006}
5007
5008static int devlink_param_driver_verify(const struct devlink_param *param)
5009{
5010 int i;
5011
5012 if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
5013 return -EINVAL;
5014 /* verify no such name in generic params */
5015 for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
5016 if (!strcmp(param->name, devlink_param_generic[i].name))
5017 return -EEXIST;
5018
5019 return 0;
5020}
5021
5022static struct devlink_param_item *
5023devlink_param_find_by_name(struct list_head *param_list,
5024 const char *param_name)
5025{
5026 struct devlink_param_item *param_item;
5027
5028 list_for_each_entry(param_item, param_list, list)
5029 if (!strcmp(param_item->param->name, param_name))
5030 return param_item;
5031 return NULL;
5032}
5033
5034static struct devlink_param_item *
5035devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
5036{
5037 struct devlink_param_item *param_item;
5038
5039 list_for_each_entry(param_item, param_list, list)
5040 if (param_item->param->id == param_id)
5041 return param_item;
5042 return NULL;
5043}
5044
5045static bool
5046devlink_param_cmode_is_supported(const struct devlink_param *param,
5047 enum devlink_param_cmode cmode)
5048{
5049 return test_bit(cmode, &param->supported_cmodes);
5050}
5051
5052static int devlink_param_get(struct devlink *devlink,
5053 const struct devlink_param *param,
5054 struct devlink_param_gset_ctx *ctx)
5055{
5056 if (!param->get || devlink->reload_failed)
5057 return -EOPNOTSUPP;
5058 return param->get(devlink, param->id, ctx);
5059}
5060
5061static int devlink_param_set(struct devlink *devlink,
5062 const struct devlink_param *param,
5063 struct devlink_param_gset_ctx *ctx)
5064{
5065 if (!param->set || devlink->reload_failed)
5066 return -EOPNOTSUPP;
5067 return param->set(devlink, param->id, ctx);
5068}
5069
5070static int
5071devlink_param_type_to_nla_type(enum devlink_param_type param_type)
5072{
5073 switch (param_type) {
5074 case DEVLINK_PARAM_TYPE_U8:
5075 return NLA_U8;
5076 case DEVLINK_PARAM_TYPE_U16:
5077 return NLA_U16;
5078 case DEVLINK_PARAM_TYPE_U32:
5079 return NLA_U32;
5080 case DEVLINK_PARAM_TYPE_STRING:
5081 return NLA_STRING;
5082 case DEVLINK_PARAM_TYPE_BOOL:
5083 return NLA_FLAG;
5084 default:
5085 return -EINVAL;
5086 }
5087}
5088
5089static int
5090devlink_nl_param_value_fill_one(struct sk_buff *msg,
5091 enum devlink_param_type type,
5092 enum devlink_param_cmode cmode,
5093 union devlink_param_value val)
5094{
5095 struct nlattr *param_value_attr;
5096
5097 param_value_attr = nla_nest_start_noflag(msg,
5098 DEVLINK_ATTR_PARAM_VALUE);
5099 if (!param_value_attr)
5100 goto nla_put_failure;
5101
5102 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
5103 goto value_nest_cancel;
5104
5105 switch (type) {
5106 case DEVLINK_PARAM_TYPE_U8:
5107 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
5108 goto value_nest_cancel;
5109 break;
5110 case DEVLINK_PARAM_TYPE_U16:
5111 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
5112 goto value_nest_cancel;
5113 break;
5114 case DEVLINK_PARAM_TYPE_U32:
5115 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
5116 goto value_nest_cancel;
5117 break;
5118 case DEVLINK_PARAM_TYPE_STRING:
5119 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
5120 val.vstr))
5121 goto value_nest_cancel;
5122 break;
5123 case DEVLINK_PARAM_TYPE_BOOL:
5124 if (val.vbool &&
5125 nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
5126 goto value_nest_cancel;
5127 break;
5128 }
5129
5130 nla_nest_end(msg, param_value_attr);
5131 return 0;
5132
5133value_nest_cancel:
5134 nla_nest_cancel(msg, param_value_attr);
5135nla_put_failure:
5136 return -EMSGSIZE;
5137}
5138
5139static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
5140 unsigned int port_index,
5141 struct devlink_param_item *param_item,
5142 enum devlink_command cmd,
5143 u32 portid, u32 seq, int flags)
5144{
5145 union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
5146 bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
5147 const struct devlink_param *param = param_item->param;
5148 struct devlink_param_gset_ctx ctx;
5149 struct nlattr *param_values_list;
5150 struct nlattr *param_attr;
5151 int nla_type;
5152 void *hdr;
5153 int err;
5154 int i;
5155
5156 /* Get value from driver part to driverinit configuration mode */
5157 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5158 if (!devlink_param_cmode_is_supported(param, i))
5159 continue;
5160 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5161 if (!param_item->driverinit_value_valid)
5162 return -EOPNOTSUPP;
5163 param_value[i] = param_item->driverinit_value;
5164 } else {
5165 ctx.cmode = i;
5166 err = devlink_param_get(devlink, param, &ctx);
5167 if (err)
5168 return err;
5169 param_value[i] = ctx.val;
5170 }
5171 param_value_set[i] = true;
5172 }
5173
5174 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5175 if (!hdr)
5176 return -EMSGSIZE;
5177
5178 if (devlink_nl_put_handle(msg, devlink))
5179 goto genlmsg_cancel;
5180
5181 if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
5182 cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
5183 cmd == DEVLINK_CMD_PORT_PARAM_DEL)
5184 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
5185 goto genlmsg_cancel;
5186
5187 param_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_PARAM);
5188 if (!param_attr)
5189 goto genlmsg_cancel;
5190 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
5191 goto param_nest_cancel;
5192 if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
5193 goto param_nest_cancel;
5194
5195 nla_type = devlink_param_type_to_nla_type(param->type);
5196 if (nla_type < 0)
5197 goto param_nest_cancel;
5198 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
5199 goto param_nest_cancel;
5200
5201 param_values_list = nla_nest_start_noflag(msg,
5202 DEVLINK_ATTR_PARAM_VALUES_LIST);
5203 if (!param_values_list)
5204 goto param_nest_cancel;
5205
5206 for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
5207 if (!param_value_set[i])
5208 continue;
5209 err = devlink_nl_param_value_fill_one(msg, param->type,
5210 i, param_value[i]);
5211 if (err)
5212 goto values_list_nest_cancel;
5213 }
5214
5215 nla_nest_end(msg, param_values_list);
5216 nla_nest_end(msg, param_attr);
5217 genlmsg_end(msg, hdr);
5218 return 0;
5219
5220values_list_nest_cancel:
5221 nla_nest_end(msg, param_values_list);
5222param_nest_cancel:
5223 nla_nest_cancel(msg, param_attr);
5224genlmsg_cancel:
5225 genlmsg_cancel(msg, hdr);
5226 return -EMSGSIZE;
5227}
5228
5229static void devlink_param_notify(struct devlink *devlink,
5230 unsigned int port_index,
5231 struct devlink_param_item *param_item,
5232 enum devlink_command cmd)
5233{
5234 struct sk_buff *msg;
5235 int err;
5236
5237 WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
5238 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
5239 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
5240
5241 /* devlink_notify_register() / devlink_notify_unregister()
5242 * will replay the notifications if the params are added/removed
5243 * outside of the lifetime of the instance.
5244 */
5245 if (!devl_is_registered(devlink))
5246 return;
5247
5248 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5249 if (!msg)
5250 return;
5251 err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
5252 0, 0, 0);
5253 if (err) {
5254 nlmsg_free(msg);
5255 return;
5256 }
5257
5258 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
5259 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5260}
5261
5262static int
5263devlink_nl_cmd_param_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
5264 struct netlink_callback *cb)
5265{
5266 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5267 struct devlink_param_item *param_item;
5268 int idx = 0;
5269 int err = 0;
5270
5271 list_for_each_entry(param_item, &devlink->param_list, list) {
5272 if (idx < state->idx) {
5273 idx++;
5274 continue;
5275 }
5276 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5277 DEVLINK_CMD_PARAM_GET,
5278 NETLINK_CB(cb->skb).portid,
5279 cb->nlh->nlmsg_seq,
5280 NLM_F_MULTI);
5281 if (err == -EOPNOTSUPP) {
5282 err = 0;
5283 } else if (err) {
5284 state->idx = idx;
5285 break;
5286 }
5287 idx++;
5288 }
5289
5290 return err;
5291}
5292
5293const struct devlink_gen_cmd devl_gen_param = {
5294 .dump_one = devlink_nl_cmd_param_get_dump_one,
5295};
5296
5297static int
5298devlink_param_type_get_from_info(struct genl_info *info,
5299 enum devlink_param_type *param_type)
5300{
5301 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_TYPE))
5302 return -EINVAL;
5303
5304 switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
5305 case NLA_U8:
5306 *param_type = DEVLINK_PARAM_TYPE_U8;
5307 break;
5308 case NLA_U16:
5309 *param_type = DEVLINK_PARAM_TYPE_U16;
5310 break;
5311 case NLA_U32:
5312 *param_type = DEVLINK_PARAM_TYPE_U32;
5313 break;
5314 case NLA_STRING:
5315 *param_type = DEVLINK_PARAM_TYPE_STRING;
5316 break;
5317 case NLA_FLAG:
5318 *param_type = DEVLINK_PARAM_TYPE_BOOL;
5319 break;
5320 default:
5321 return -EINVAL;
5322 }
5323
5324 return 0;
5325}
5326
5327static int
5328devlink_param_value_get_from_info(const struct devlink_param *param,
5329 struct genl_info *info,
5330 union devlink_param_value *value)
5331{
5332 struct nlattr *param_data;
5333 int len;
5334
5335 param_data = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA];
5336
5337 if (param->type != DEVLINK_PARAM_TYPE_BOOL && !param_data)
5338 return -EINVAL;
5339
5340 switch (param->type) {
5341 case DEVLINK_PARAM_TYPE_U8:
5342 if (nla_len(param_data) != sizeof(u8))
5343 return -EINVAL;
5344 value->vu8 = nla_get_u8(param_data);
5345 break;
5346 case DEVLINK_PARAM_TYPE_U16:
5347 if (nla_len(param_data) != sizeof(u16))
5348 return -EINVAL;
5349 value->vu16 = nla_get_u16(param_data);
5350 break;
5351 case DEVLINK_PARAM_TYPE_U32:
5352 if (nla_len(param_data) != sizeof(u32))
5353 return -EINVAL;
5354 value->vu32 = nla_get_u32(param_data);
5355 break;
5356 case DEVLINK_PARAM_TYPE_STRING:
5357 len = strnlen(nla_data(param_data), nla_len(param_data));
5358 if (len == nla_len(param_data) ||
5359 len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
5360 return -EINVAL;
5361 strcpy(value->vstr, nla_data(param_data));
5362 break;
5363 case DEVLINK_PARAM_TYPE_BOOL:
5364 if (param_data && nla_len(param_data))
5365 return -EINVAL;
5366 value->vbool = nla_get_flag(param_data);
5367 break;
5368 }
5369 return 0;
5370}
5371
5372static struct devlink_param_item *
5373devlink_param_get_from_info(struct list_head *param_list,
5374 struct genl_info *info)
5375{
5376 char *param_name;
5377
5378 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_NAME))
5379 return NULL;
5380
5381 param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
5382 return devlink_param_find_by_name(param_list, param_name);
5383}
5384
5385static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
5386 struct genl_info *info)
5387{
5388 struct devlink *devlink = info->user_ptr[0];
5389 struct devlink_param_item *param_item;
5390 struct sk_buff *msg;
5391 int err;
5392
5393 param_item = devlink_param_get_from_info(&devlink->param_list, info);
5394 if (!param_item)
5395 return -EINVAL;
5396
5397 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5398 if (!msg)
5399 return -ENOMEM;
5400
5401 err = devlink_nl_param_fill(msg, devlink, 0, param_item,
5402 DEVLINK_CMD_PARAM_GET,
5403 info->snd_portid, info->snd_seq, 0);
5404 if (err) {
5405 nlmsg_free(msg);
5406 return err;
5407 }
5408
5409 return genlmsg_reply(msg, info);
5410}
5411
5412static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
5413 unsigned int port_index,
5414 struct list_head *param_list,
5415 struct genl_info *info,
5416 enum devlink_command cmd)
5417{
5418 enum devlink_param_type param_type;
5419 struct devlink_param_gset_ctx ctx;
5420 enum devlink_param_cmode cmode;
5421 struct devlink_param_item *param_item;
5422 const struct devlink_param *param;
5423 union devlink_param_value value;
5424 int err = 0;
5425
5426 param_item = devlink_param_get_from_info(param_list, info);
5427 if (!param_item)
5428 return -EINVAL;
5429 param = param_item->param;
5430 err = devlink_param_type_get_from_info(info, &param_type);
5431 if (err)
5432 return err;
5433 if (param_type != param->type)
5434 return -EINVAL;
5435 err = devlink_param_value_get_from_info(param, info, &value);
5436 if (err)
5437 return err;
5438 if (param->validate) {
5439 err = param->validate(devlink, param->id, value, info->extack);
5440 if (err)
5441 return err;
5442 }
5443
5444 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_PARAM_VALUE_CMODE))
5445 return -EINVAL;
5446 cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
5447 if (!devlink_param_cmode_is_supported(param, cmode))
5448 return -EOPNOTSUPP;
5449
5450 if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
5451 if (param->type == DEVLINK_PARAM_TYPE_STRING)
5452 strcpy(param_item->driverinit_value.vstr, value.vstr);
5453 else
5454 param_item->driverinit_value = value;
5455 param_item->driverinit_value_valid = true;
5456 } else {
5457 if (!param->set)
5458 return -EOPNOTSUPP;
5459 ctx.val = value;
5460 ctx.cmode = cmode;
5461 err = devlink_param_set(devlink, param, &ctx);
5462 if (err)
5463 return err;
5464 }
5465
5466 devlink_param_notify(devlink, port_index, param_item, cmd);
5467 return 0;
5468}
5469
5470static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
5471 struct genl_info *info)
5472{
5473 struct devlink *devlink = info->user_ptr[0];
5474
5475 return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
5476 info, DEVLINK_CMD_PARAM_NEW);
5477}
5478
5479static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
5480 struct netlink_callback *cb)
5481{
5482 NL_SET_ERR_MSG_MOD(cb->extack, "Port params are not supported");
5483 return msg->len;
5484}
5485
5486static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
5487 struct genl_info *info)
5488{
5489 NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
5490 return -EINVAL;
5491}
5492
5493static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
5494 struct genl_info *info)
5495{
5496 NL_SET_ERR_MSG_MOD(info->extack, "Port params are not supported");
5497 return -EINVAL;
5498}
5499
5500static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
5501 struct devlink *devlink,
5502 struct devlink_snapshot *snapshot)
5503{
5504 struct nlattr *snap_attr;
5505 int err;
5506
5507 snap_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
5508 if (!snap_attr)
5509 return -EINVAL;
5510
5511 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
5512 if (err)
5513 goto nla_put_failure;
5514
5515 nla_nest_end(msg, snap_attr);
5516 return 0;
5517
5518nla_put_failure:
5519 nla_nest_cancel(msg, snap_attr);
5520 return err;
5521}
5522
5523static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
5524 struct devlink *devlink,
5525 struct devlink_region *region)
5526{
5527 struct devlink_snapshot *snapshot;
5528 struct nlattr *snapshots_attr;
5529 int err;
5530
5531 snapshots_attr = nla_nest_start_noflag(msg,
5532 DEVLINK_ATTR_REGION_SNAPSHOTS);
5533 if (!snapshots_attr)
5534 return -EINVAL;
5535
5536 list_for_each_entry(snapshot, &region->snapshot_list, list) {
5537 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
5538 if (err)
5539 goto nla_put_failure;
5540 }
5541
5542 nla_nest_end(msg, snapshots_attr);
5543 return 0;
5544
5545nla_put_failure:
5546 nla_nest_cancel(msg, snapshots_attr);
5547 return err;
5548}
5549
5550static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
5551 enum devlink_command cmd, u32 portid,
5552 u32 seq, int flags,
5553 struct devlink_region *region)
5554{
5555 void *hdr;
5556 int err;
5557
5558 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
5559 if (!hdr)
5560 return -EMSGSIZE;
5561
5562 err = devlink_nl_put_handle(msg, devlink);
5563 if (err)
5564 goto nla_put_failure;
5565
5566 if (region->port) {
5567 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5568 region->port->index);
5569 if (err)
5570 goto nla_put_failure;
5571 }
5572
5573 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->ops->name);
5574 if (err)
5575 goto nla_put_failure;
5576
5577 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5578 region->size,
5579 DEVLINK_ATTR_PAD);
5580 if (err)
5581 goto nla_put_failure;
5582
5583 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_MAX_SNAPSHOTS,
5584 region->max_snapshots);
5585 if (err)
5586 goto nla_put_failure;
5587
5588 err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
5589 if (err)
5590 goto nla_put_failure;
5591
5592 genlmsg_end(msg, hdr);
5593 return 0;
5594
5595nla_put_failure:
5596 genlmsg_cancel(msg, hdr);
5597 return err;
5598}
5599
5600static struct sk_buff *
5601devlink_nl_region_notify_build(struct devlink_region *region,
5602 struct devlink_snapshot *snapshot,
5603 enum devlink_command cmd, u32 portid, u32 seq)
5604{
5605 struct devlink *devlink = region->devlink;
5606 struct sk_buff *msg;
5607 void *hdr;
5608 int err;
5609
5610
5611 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5612 if (!msg)
5613 return ERR_PTR(-ENOMEM);
5614
5615 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, 0, cmd);
5616 if (!hdr) {
5617 err = -EMSGSIZE;
5618 goto out_free_msg;
5619 }
5620
5621 err = devlink_nl_put_handle(msg, devlink);
5622 if (err)
5623 goto out_cancel_msg;
5624
5625 if (region->port) {
5626 err = nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX,
5627 region->port->index);
5628 if (err)
5629 goto out_cancel_msg;
5630 }
5631
5632 err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
5633 region->ops->name);
5634 if (err)
5635 goto out_cancel_msg;
5636
5637 if (snapshot) {
5638 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
5639 snapshot->id);
5640 if (err)
5641 goto out_cancel_msg;
5642 } else {
5643 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
5644 region->size, DEVLINK_ATTR_PAD);
5645 if (err)
5646 goto out_cancel_msg;
5647 }
5648 genlmsg_end(msg, hdr);
5649
5650 return msg;
5651
5652out_cancel_msg:
5653 genlmsg_cancel(msg, hdr);
5654out_free_msg:
5655 nlmsg_free(msg);
5656 return ERR_PTR(err);
5657}
5658
5659static void devlink_nl_region_notify(struct devlink_region *region,
5660 struct devlink_snapshot *snapshot,
5661 enum devlink_command cmd)
5662{
5663 struct devlink *devlink = region->devlink;
5664 struct sk_buff *msg;
5665
5666 WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
5667 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
5668 return;
5669
5670 msg = devlink_nl_region_notify_build(region, snapshot, cmd, 0, 0);
5671 if (IS_ERR(msg))
5672 return;
5673
5674 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
5675 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
5676}
5677
5678/**
5679 * __devlink_snapshot_id_increment - Increment number of snapshots using an id
5680 * @devlink: devlink instance
5681 * @id: the snapshot id
5682 *
5683 * Track when a new snapshot begins using an id. Load the count for the
5684 * given id from the snapshot xarray, increment it, and store it back.
5685 *
5686 * Called when a new snapshot is created with the given id.
5687 *
5688 * The id *must* have been previously allocated by
5689 * devlink_region_snapshot_id_get().
5690 *
5691 * Returns 0 on success, or an error on failure.
5692 */
5693static int __devlink_snapshot_id_increment(struct devlink *devlink, u32 id)
5694{
5695 unsigned long count;
5696 void *p;
5697 int err;
5698
5699 xa_lock(&devlink->snapshot_ids);
5700 p = xa_load(&devlink->snapshot_ids, id);
5701 if (WARN_ON(!p)) {
5702 err = -EINVAL;
5703 goto unlock;
5704 }
5705
5706 if (WARN_ON(!xa_is_value(p))) {
5707 err = -EINVAL;
5708 goto unlock;
5709 }
5710
5711 count = xa_to_value(p);
5712 count++;
5713
5714 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5715 GFP_ATOMIC));
5716unlock:
5717 xa_unlock(&devlink->snapshot_ids);
5718 return err;
5719}
5720
5721/**
5722 * __devlink_snapshot_id_decrement - Decrease number of snapshots using an id
5723 * @devlink: devlink instance
5724 * @id: the snapshot id
5725 *
5726 * Track when a snapshot is deleted and stops using an id. Load the count
5727 * for the given id from the snapshot xarray, decrement it, and store it
5728 * back.
5729 *
5730 * If the count reaches zero, erase this id from the xarray, freeing it
5731 * up for future re-use by devlink_region_snapshot_id_get().
5732 *
5733 * Called when a snapshot using the given id is deleted, and when the
5734 * initial allocator of the id is finished using it.
5735 */
5736static void __devlink_snapshot_id_decrement(struct devlink *devlink, u32 id)
5737{
5738 unsigned long count;
5739 void *p;
5740
5741 xa_lock(&devlink->snapshot_ids);
5742 p = xa_load(&devlink->snapshot_ids, id);
5743 if (WARN_ON(!p))
5744 goto unlock;
5745
5746 if (WARN_ON(!xa_is_value(p)))
5747 goto unlock;
5748
5749 count = xa_to_value(p);
5750
5751 if (count > 1) {
5752 count--;
5753 __xa_store(&devlink->snapshot_ids, id, xa_mk_value(count),
5754 GFP_ATOMIC);
5755 } else {
5756 /* If this was the last user, we can erase this id */
5757 __xa_erase(&devlink->snapshot_ids, id);
5758 }
5759unlock:
5760 xa_unlock(&devlink->snapshot_ids);
5761}
5762
5763/**
5764 * __devlink_snapshot_id_insert - Insert a specific snapshot ID
5765 * @devlink: devlink instance
5766 * @id: the snapshot id
5767 *
5768 * Mark the given snapshot id as used by inserting a zero value into the
5769 * snapshot xarray.
5770 *
5771 * This must be called while holding the devlink instance lock. Unlike
5772 * devlink_snapshot_id_get, the initial reference count is zero, not one.
5773 * It is expected that the id will immediately be used before
5774 * releasing the devlink instance lock.
5775 *
5776 * Returns zero on success, or an error code if the snapshot id could not
5777 * be inserted.
5778 */
5779static int __devlink_snapshot_id_insert(struct devlink *devlink, u32 id)
5780{
5781 int err;
5782
5783 xa_lock(&devlink->snapshot_ids);
5784 if (xa_load(&devlink->snapshot_ids, id)) {
5785 xa_unlock(&devlink->snapshot_ids);
5786 return -EEXIST;
5787 }
5788 err = xa_err(__xa_store(&devlink->snapshot_ids, id, xa_mk_value(0),
5789 GFP_ATOMIC));
5790 xa_unlock(&devlink->snapshot_ids);
5791 return err;
5792}
5793
5794/**
5795 * __devlink_region_snapshot_id_get - get snapshot ID
5796 * @devlink: devlink instance
5797 * @id: storage to return snapshot id
5798 *
5799 * Allocates a new snapshot id. Returns zero on success, or a negative
5800 * error on failure. Must be called while holding the devlink instance
5801 * lock.
5802 *
5803 * Snapshot IDs are tracked using an xarray which stores the number of
5804 * users of the snapshot id.
5805 *
5806 * Note that the caller of this function counts as a 'user', in order to
5807 * avoid race conditions. The caller must release its hold on the
5808 * snapshot by using devlink_region_snapshot_id_put.
5809 */
5810static int __devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
5811{
5812 return xa_alloc(&devlink->snapshot_ids, id, xa_mk_value(1),
5813 xa_limit_32b, GFP_KERNEL);
5814}
5815
5816/**
5817 * __devlink_region_snapshot_create - create a new snapshot
5818 * This will add a new snapshot of a region. The snapshot
5819 * will be stored on the region struct and can be accessed
5820 * from devlink. This is useful for future analyses of snapshots.
5821 * Multiple snapshots can be created on a region.
5822 * The @snapshot_id should be obtained using the getter function.
5823 *
5824 * Must be called only while holding the region snapshot lock.
5825 *
5826 * @region: devlink region of the snapshot
5827 * @data: snapshot data
5828 * @snapshot_id: snapshot id to be created
5829 */
5830static int
5831__devlink_region_snapshot_create(struct devlink_region *region,
5832 u8 *data, u32 snapshot_id)
5833{
5834 struct devlink *devlink = region->devlink;
5835 struct devlink_snapshot *snapshot;
5836 int err;
5837
5838 lockdep_assert_held(&region->snapshot_lock);
5839
5840 /* check if region can hold one more snapshot */
5841 if (region->cur_snapshots == region->max_snapshots)
5842 return -ENOSPC;
5843
5844 if (devlink_region_snapshot_get_by_id(region, snapshot_id))
5845 return -EEXIST;
5846
5847 snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
5848 if (!snapshot)
5849 return -ENOMEM;
5850
5851 err = __devlink_snapshot_id_increment(devlink, snapshot_id);
5852 if (err)
5853 goto err_snapshot_id_increment;
5854
5855 snapshot->id = snapshot_id;
5856 snapshot->region = region;
5857 snapshot->data = data;
5858
5859 list_add_tail(&snapshot->list, &region->snapshot_list);
5860
5861 region->cur_snapshots++;
5862
5863 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
5864 return 0;
5865
5866err_snapshot_id_increment:
5867 kfree(snapshot);
5868 return err;
5869}
5870
5871static void devlink_region_snapshot_del(struct devlink_region *region,
5872 struct devlink_snapshot *snapshot)
5873{
5874 struct devlink *devlink = region->devlink;
5875
5876 lockdep_assert_held(&region->snapshot_lock);
5877
5878 devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
5879 region->cur_snapshots--;
5880 list_del(&snapshot->list);
5881 region->ops->destructor(snapshot->data);
5882 __devlink_snapshot_id_decrement(devlink, snapshot->id);
5883 kfree(snapshot);
5884}
5885
5886static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
5887 struct genl_info *info)
5888{
5889 struct devlink *devlink = info->user_ptr[0];
5890 struct devlink_port *port = NULL;
5891 struct devlink_region *region;
5892 const char *region_name;
5893 struct sk_buff *msg;
5894 unsigned int index;
5895 int err;
5896
5897 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME))
5898 return -EINVAL;
5899
5900 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
5901 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
5902
5903 port = devlink_port_get_by_index(devlink, index);
5904 if (!port)
5905 return -ENODEV;
5906 }
5907
5908 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
5909 if (port)
5910 region = devlink_port_region_get_by_name(port, region_name);
5911 else
5912 region = devlink_region_get_by_name(devlink, region_name);
5913
5914 if (!region)
5915 return -EINVAL;
5916
5917 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
5918 if (!msg)
5919 return -ENOMEM;
5920
5921 err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
5922 info->snd_portid, info->snd_seq, 0,
5923 region);
5924 if (err) {
5925 nlmsg_free(msg);
5926 return err;
5927 }
5928
5929 return genlmsg_reply(msg, info);
5930}
5931
5932static int devlink_nl_cmd_region_get_port_dumpit(struct sk_buff *msg,
5933 struct netlink_callback *cb,
5934 struct devlink_port *port,
5935 int *idx,
5936 int start)
5937{
5938 struct devlink_region *region;
5939 int err = 0;
5940
5941 list_for_each_entry(region, &port->region_list, list) {
5942 if (*idx < start) {
5943 (*idx)++;
5944 continue;
5945 }
5946 err = devlink_nl_region_fill(msg, port->devlink,
5947 DEVLINK_CMD_REGION_GET,
5948 NETLINK_CB(cb->skb).portid,
5949 cb->nlh->nlmsg_seq,
5950 NLM_F_MULTI, region);
5951 if (err)
5952 goto out;
5953 (*idx)++;
5954 }
5955
5956out:
5957 return err;
5958}
5959
5960static int
5961devlink_nl_cmd_region_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
5962 struct netlink_callback *cb)
5963{
5964 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
5965 struct devlink_region *region;
5966 struct devlink_port *port;
5967 unsigned long port_index;
5968 int idx = 0;
5969 int err;
5970
5971 list_for_each_entry(region, &devlink->region_list, list) {
5972 if (idx < state->idx) {
5973 idx++;
5974 continue;
5975 }
5976 err = devlink_nl_region_fill(msg, devlink,
5977 DEVLINK_CMD_REGION_GET,
5978 NETLINK_CB(cb->skb).portid,
5979 cb->nlh->nlmsg_seq,
5980 NLM_F_MULTI, region);
5981 if (err) {
5982 state->idx = idx;
5983 return err;
5984 }
5985 idx++;
5986 }
5987
5988 xa_for_each(&devlink->ports, port_index, port) {
5989 err = devlink_nl_cmd_region_get_port_dumpit(msg, cb, port, &idx,
5990 state->idx);
5991 if (err) {
5992 state->idx = idx;
5993 return err;
5994 }
5995 }
5996
5997 return 0;
5998}
5999
6000const struct devlink_gen_cmd devl_gen_region = {
6001 .dump_one = devlink_nl_cmd_region_get_dump_one,
6002};
6003
6004static int devlink_nl_cmd_region_del(struct sk_buff *skb,
6005 struct genl_info *info)
6006{
6007 struct devlink *devlink = info->user_ptr[0];
6008 struct devlink_snapshot *snapshot;
6009 struct devlink_port *port = NULL;
6010 struct devlink_region *region;
6011 const char *region_name;
6012 unsigned int index;
6013 u32 snapshot_id;
6014
6015 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME) ||
6016 GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_SNAPSHOT_ID))
6017 return -EINVAL;
6018
6019 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6020 snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
6021
6022 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6023 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6024
6025 port = devlink_port_get_by_index(devlink, index);
6026 if (!port)
6027 return -ENODEV;
6028 }
6029
6030 if (port)
6031 region = devlink_port_region_get_by_name(port, region_name);
6032 else
6033 region = devlink_region_get_by_name(devlink, region_name);
6034
6035 if (!region)
6036 return -EINVAL;
6037
6038 mutex_lock(&region->snapshot_lock);
6039 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6040 if (!snapshot) {
6041 mutex_unlock(&region->snapshot_lock);
6042 return -EINVAL;
6043 }
6044
6045 devlink_region_snapshot_del(region, snapshot);
6046 mutex_unlock(&region->snapshot_lock);
6047 return 0;
6048}
6049
6050static int
6051devlink_nl_cmd_region_new(struct sk_buff *skb, struct genl_info *info)
6052{
6053 struct devlink *devlink = info->user_ptr[0];
6054 struct devlink_snapshot *snapshot;
6055 struct devlink_port *port = NULL;
6056 struct nlattr *snapshot_id_attr;
6057 struct devlink_region *region;
6058 const char *region_name;
6059 unsigned int index;
6060 u32 snapshot_id;
6061 u8 *data;
6062 int err;
6063
6064 if (GENL_REQ_ATTR_CHECK(info, DEVLINK_ATTR_REGION_NAME)) {
6065 NL_SET_ERR_MSG_MOD(info->extack, "No region name provided");
6066 return -EINVAL;
6067 }
6068
6069 region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
6070
6071 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6072 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6073
6074 port = devlink_port_get_by_index(devlink, index);
6075 if (!port)
6076 return -ENODEV;
6077 }
6078
6079 if (port)
6080 region = devlink_port_region_get_by_name(port, region_name);
6081 else
6082 region = devlink_region_get_by_name(devlink, region_name);
6083
6084 if (!region) {
6085 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not exist");
6086 return -EINVAL;
6087 }
6088
6089 if (!region->ops->snapshot) {
6090 NL_SET_ERR_MSG_MOD(info->extack, "The requested region does not support taking an immediate snapshot");
6091 return -EOPNOTSUPP;
6092 }
6093
6094 mutex_lock(&region->snapshot_lock);
6095
6096 if (region->cur_snapshots == region->max_snapshots) {
6097 NL_SET_ERR_MSG_MOD(info->extack, "The region has reached the maximum number of stored snapshots");
6098 err = -ENOSPC;
6099 goto unlock;
6100 }
6101
6102 snapshot_id_attr = info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
6103 if (snapshot_id_attr) {
6104 snapshot_id = nla_get_u32(snapshot_id_attr);
6105
6106 if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
6107 NL_SET_ERR_MSG_MOD(info->extack, "The requested snapshot id is already in use");
6108 err = -EEXIST;
6109 goto unlock;
6110 }
6111
6112 err = __devlink_snapshot_id_insert(devlink, snapshot_id);
6113 if (err)
6114 goto unlock;
6115 } else {
6116 err = __devlink_region_snapshot_id_get(devlink, &snapshot_id);
6117 if (err) {
6118 NL_SET_ERR_MSG_MOD(info->extack, "Failed to allocate a new snapshot id");
6119 goto unlock;
6120 }
6121 }
6122
6123 if (port)
6124 err = region->port_ops->snapshot(port, region->port_ops,
6125 info->extack, &data);
6126 else
6127 err = region->ops->snapshot(devlink, region->ops,
6128 info->extack, &data);
6129 if (err)
6130 goto err_snapshot_capture;
6131
6132 err = __devlink_region_snapshot_create(region, data, snapshot_id);
6133 if (err)
6134 goto err_snapshot_create;
6135
6136 if (!snapshot_id_attr) {
6137 struct sk_buff *msg;
6138
6139 snapshot = devlink_region_snapshot_get_by_id(region,
6140 snapshot_id);
6141 if (WARN_ON(!snapshot)) {
6142 err = -EINVAL;
6143 goto unlock;
6144 }
6145
6146 msg = devlink_nl_region_notify_build(region, snapshot,
6147 DEVLINK_CMD_REGION_NEW,
6148 info->snd_portid,
6149 info->snd_seq);
6150 err = PTR_ERR_OR_ZERO(msg);
6151 if (err)
6152 goto err_notify;
6153
6154 err = genlmsg_reply(msg, info);
6155 if (err)
6156 goto err_notify;
6157 }
6158
6159 mutex_unlock(&region->snapshot_lock);
6160 return 0;
6161
6162err_snapshot_create:
6163 region->ops->destructor(data);
6164err_snapshot_capture:
6165 __devlink_snapshot_id_decrement(devlink, snapshot_id);
6166 mutex_unlock(&region->snapshot_lock);
6167 return err;
6168
6169err_notify:
6170 devlink_region_snapshot_del(region, snapshot);
6171unlock:
6172 mutex_unlock(&region->snapshot_lock);
6173 return err;
6174}
6175
6176static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
6177 u8 *chunk, u32 chunk_size,
6178 u64 addr)
6179{
6180 struct nlattr *chunk_attr;
6181 int err;
6182
6183 chunk_attr = nla_nest_start_noflag(msg, DEVLINK_ATTR_REGION_CHUNK);
6184 if (!chunk_attr)
6185 return -EINVAL;
6186
6187 err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
6188 if (err)
6189 goto nla_put_failure;
6190
6191 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
6192 DEVLINK_ATTR_PAD);
6193 if (err)
6194 goto nla_put_failure;
6195
6196 nla_nest_end(msg, chunk_attr);
6197 return 0;
6198
6199nla_put_failure:
6200 nla_nest_cancel(msg, chunk_attr);
6201 return err;
6202}
6203
6204#define DEVLINK_REGION_READ_CHUNK_SIZE 256
6205
6206typedef int devlink_chunk_fill_t(void *cb_priv, u8 *chunk, u32 chunk_size,
6207 u64 curr_offset,
6208 struct netlink_ext_ack *extack);
6209
6210static int
6211devlink_nl_region_read_fill(struct sk_buff *skb, devlink_chunk_fill_t *cb,
6212 void *cb_priv, u64 start_offset, u64 end_offset,
6213 u64 *new_offset, struct netlink_ext_ack *extack)
6214{
6215 u64 curr_offset = start_offset;
6216 int err = 0;
6217 u8 *data;
6218
6219 /* Allocate and re-use a single buffer */
6220 data = kmalloc(DEVLINK_REGION_READ_CHUNK_SIZE, GFP_KERNEL);
6221 if (!data)
6222 return -ENOMEM;
6223
6224 *new_offset = start_offset;
6225
6226 while (curr_offset < end_offset) {
6227 u32 data_size;
6228
6229 data_size = min_t(u32, end_offset - curr_offset,
6230 DEVLINK_REGION_READ_CHUNK_SIZE);
6231
6232 err = cb(cb_priv, data, data_size, curr_offset, extack);
6233 if (err)
6234 break;
6235
6236 err = devlink_nl_cmd_region_read_chunk_fill(skb, data, data_size, curr_offset);
6237 if (err)
6238 break;
6239
6240 curr_offset += data_size;
6241 }
6242 *new_offset = curr_offset;
6243
6244 kfree(data);
6245
6246 return err;
6247}
6248
6249static int
6250devlink_region_snapshot_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
6251 u64 curr_offset,
6252 struct netlink_ext_ack __always_unused *extack)
6253{
6254 struct devlink_snapshot *snapshot = cb_priv;
6255
6256 memcpy(chunk, &snapshot->data[curr_offset], chunk_size);
6257
6258 return 0;
6259}
6260
6261static int
6262devlink_region_port_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
6263 u64 curr_offset, struct netlink_ext_ack *extack)
6264{
6265 struct devlink_region *region = cb_priv;
6266
6267 return region->port_ops->read(region->port, region->port_ops, extack,
6268 curr_offset, chunk_size, chunk);
6269}
6270
6271static int
6272devlink_region_direct_fill(void *cb_priv, u8 *chunk, u32 chunk_size,
6273 u64 curr_offset, struct netlink_ext_ack *extack)
6274{
6275 struct devlink_region *region = cb_priv;
6276
6277 return region->ops->read(region->devlink, region->ops, extack,
6278 curr_offset, chunk_size, chunk);
6279}
6280
6281static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
6282 struct netlink_callback *cb)
6283{
6284 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
6285 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
6286 struct nlattr *chunks_attr, *region_attr, *snapshot_attr;
6287 u64 ret_offset, start_offset, end_offset = U64_MAX;
6288 struct nlattr **attrs = info->attrs;
6289 struct devlink_port *port = NULL;
6290 devlink_chunk_fill_t *region_cb;
6291 struct devlink_region *region;
6292 const char *region_name;
6293 struct devlink *devlink;
6294 unsigned int index;
6295 void *region_cb_priv;
6296 void *hdr;
6297 int err;
6298
6299 start_offset = state->start_offset;
6300
6301 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
6302 if (IS_ERR(devlink))
6303 return PTR_ERR(devlink);
6304
6305 if (!attrs[DEVLINK_ATTR_REGION_NAME]) {
6306 NL_SET_ERR_MSG(cb->extack, "No region name provided");
6307 err = -EINVAL;
6308 goto out_unlock;
6309 }
6310
6311 if (info->attrs[DEVLINK_ATTR_PORT_INDEX]) {
6312 index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
6313
6314 port = devlink_port_get_by_index(devlink, index);
6315 if (!port) {
6316 err = -ENODEV;
6317 goto out_unlock;
6318 }
6319 }
6320
6321 region_attr = attrs[DEVLINK_ATTR_REGION_NAME];
6322 region_name = nla_data(region_attr);
6323
6324 if (port)
6325 region = devlink_port_region_get_by_name(port, region_name);
6326 else
6327 region = devlink_region_get_by_name(devlink, region_name);
6328
6329 if (!region) {
6330 NL_SET_ERR_MSG_ATTR(cb->extack, region_attr, "Requested region does not exist");
6331 err = -EINVAL;
6332 goto out_unlock;
6333 }
6334
6335 snapshot_attr = attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID];
6336 if (!snapshot_attr) {
6337 if (!nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
6338 NL_SET_ERR_MSG(cb->extack, "No snapshot id provided");
6339 err = -EINVAL;
6340 goto out_unlock;
6341 }
6342
6343 if (!region->ops->read) {
6344 NL_SET_ERR_MSG(cb->extack, "Requested region does not support direct read");
6345 err = -EOPNOTSUPP;
6346 goto out_unlock;
6347 }
6348
6349 if (port)
6350 region_cb = &devlink_region_port_direct_fill;
6351 else
6352 region_cb = &devlink_region_direct_fill;
6353 region_cb_priv = region;
6354 } else {
6355 struct devlink_snapshot *snapshot;
6356 u32 snapshot_id;
6357
6358 if (nla_get_flag(attrs[DEVLINK_ATTR_REGION_DIRECT])) {
6359 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Direct region read does not use snapshot");
6360 err = -EINVAL;
6361 goto out_unlock;
6362 }
6363
6364 snapshot_id = nla_get_u32(snapshot_attr);
6365 snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
6366 if (!snapshot) {
6367 NL_SET_ERR_MSG_ATTR(cb->extack, snapshot_attr, "Requested snapshot does not exist");
6368 err = -EINVAL;
6369 goto out_unlock;
6370 }
6371 region_cb = &devlink_region_snapshot_fill;
6372 region_cb_priv = snapshot;
6373 }
6374
6375 if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
6376 attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
6377 if (!start_offset)
6378 start_offset =
6379 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6380
6381 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
6382 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
6383 }
6384
6385 if (end_offset > region->size)
6386 end_offset = region->size;
6387
6388 /* return 0 if there is no further data to read */
6389 if (start_offset == end_offset) {
6390 err = 0;
6391 goto out_unlock;
6392 }
6393
6394 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
6395 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
6396 DEVLINK_CMD_REGION_READ);
6397 if (!hdr) {
6398 err = -EMSGSIZE;
6399 goto out_unlock;
6400 }
6401
6402 err = devlink_nl_put_handle(skb, devlink);
6403 if (err)
6404 goto nla_put_failure;
6405
6406 if (region->port) {
6407 err = nla_put_u32(skb, DEVLINK_ATTR_PORT_INDEX,
6408 region->port->index);
6409 if (err)
6410 goto nla_put_failure;
6411 }
6412
6413 err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
6414 if (err)
6415 goto nla_put_failure;
6416
6417 chunks_attr = nla_nest_start_noflag(skb, DEVLINK_ATTR_REGION_CHUNKS);
6418 if (!chunks_attr) {
6419 err = -EMSGSIZE;
6420 goto nla_put_failure;
6421 }
6422
6423 err = devlink_nl_region_read_fill(skb, region_cb, region_cb_priv,
6424 start_offset, end_offset, &ret_offset,
6425 cb->extack);
6426
6427 if (err && err != -EMSGSIZE)
6428 goto nla_put_failure;
6429
6430 /* Check if there was any progress done to prevent infinite loop */
6431 if (ret_offset == start_offset) {
6432 err = -EINVAL;
6433 goto nla_put_failure;
6434 }
6435
6436 state->start_offset = ret_offset;
6437
6438 nla_nest_end(skb, chunks_attr);
6439 genlmsg_end(skb, hdr);
6440 devl_unlock(devlink);
6441 devlink_put(devlink);
6442 return skb->len;
6443
6444nla_put_failure:
6445 genlmsg_cancel(skb, hdr);
6446out_unlock:
6447 devl_unlock(devlink);
6448 devlink_put(devlink);
6449 return err;
6450}
6451
6452int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
6453{
6454 if (!req->msg)
6455 return 0;
6456 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
6457}
6458EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
6459
6460int devlink_info_board_serial_number_put(struct devlink_info_req *req,
6461 const char *bsn)
6462{
6463 if (!req->msg)
6464 return 0;
6465 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_BOARD_SERIAL_NUMBER,
6466 bsn);
6467}
6468EXPORT_SYMBOL_GPL(devlink_info_board_serial_number_put);
6469
6470static int devlink_info_version_put(struct devlink_info_req *req, int attr,
6471 const char *version_name,
6472 const char *version_value,
6473 enum devlink_info_version_type version_type)
6474{
6475 struct nlattr *nest;
6476 int err;
6477
6478 if (req->version_cb)
6479 req->version_cb(version_name, version_type,
6480 req->version_cb_priv);
6481
6482 if (!req->msg)
6483 return 0;
6484
6485 nest = nla_nest_start_noflag(req->msg, attr);
6486 if (!nest)
6487 return -EMSGSIZE;
6488
6489 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
6490 version_name);
6491 if (err)
6492 goto nla_put_failure;
6493
6494 err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
6495 version_value);
6496 if (err)
6497 goto nla_put_failure;
6498
6499 nla_nest_end(req->msg, nest);
6500
6501 return 0;
6502
6503nla_put_failure:
6504 nla_nest_cancel(req->msg, nest);
6505 return err;
6506}
6507
6508int devlink_info_version_fixed_put(struct devlink_info_req *req,
6509 const char *version_name,
6510 const char *version_value)
6511{
6512 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
6513 version_name, version_value,
6514 DEVLINK_INFO_VERSION_TYPE_NONE);
6515}
6516EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
6517
6518int devlink_info_version_stored_put(struct devlink_info_req *req,
6519 const char *version_name,
6520 const char *version_value)
6521{
6522 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
6523 version_name, version_value,
6524 DEVLINK_INFO_VERSION_TYPE_NONE);
6525}
6526EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
6527
6528int devlink_info_version_stored_put_ext(struct devlink_info_req *req,
6529 const char *version_name,
6530 const char *version_value,
6531 enum devlink_info_version_type version_type)
6532{
6533 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
6534 version_name, version_value,
6535 version_type);
6536}
6537EXPORT_SYMBOL_GPL(devlink_info_version_stored_put_ext);
6538
6539int devlink_info_version_running_put(struct devlink_info_req *req,
6540 const char *version_name,
6541 const char *version_value)
6542{
6543 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
6544 version_name, version_value,
6545 DEVLINK_INFO_VERSION_TYPE_NONE);
6546}
6547EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
6548
6549int devlink_info_version_running_put_ext(struct devlink_info_req *req,
6550 const char *version_name,
6551 const char *version_value,
6552 enum devlink_info_version_type version_type)
6553{
6554 return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
6555 version_name, version_value,
6556 version_type);
6557}
6558EXPORT_SYMBOL_GPL(devlink_info_version_running_put_ext);
6559
6560static int devlink_nl_driver_info_get(struct device_driver *drv,
6561 struct devlink_info_req *req)
6562{
6563 if (!drv)
6564 return 0;
6565
6566 if (drv->name[0])
6567 return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME,
6568 drv->name);
6569
6570 return 0;
6571}
6572
6573static int
6574devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
6575 enum devlink_command cmd, u32 portid,
6576 u32 seq, int flags, struct netlink_ext_ack *extack)
6577{
6578 struct device *dev = devlink_to_dev(devlink);
6579 struct devlink_info_req req = {};
6580 void *hdr;
6581 int err;
6582
6583 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
6584 if (!hdr)
6585 return -EMSGSIZE;
6586
6587 err = -EMSGSIZE;
6588 if (devlink_nl_put_handle(msg, devlink))
6589 goto err_cancel_msg;
6590
6591 req.msg = msg;
6592 if (devlink->ops->info_get) {
6593 err = devlink->ops->info_get(devlink, &req, extack);
6594 if (err)
6595 goto err_cancel_msg;
6596 }
6597
6598 err = devlink_nl_driver_info_get(dev->driver, &req);
6599 if (err)
6600 goto err_cancel_msg;
6601
6602 genlmsg_end(msg, hdr);
6603 return 0;
6604
6605err_cancel_msg:
6606 genlmsg_cancel(msg, hdr);
6607 return err;
6608}
6609
6610static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
6611 struct genl_info *info)
6612{
6613 struct devlink *devlink = info->user_ptr[0];
6614 struct sk_buff *msg;
6615 int err;
6616
6617 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6618 if (!msg)
6619 return -ENOMEM;
6620
6621 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6622 info->snd_portid, info->snd_seq, 0,
6623 info->extack);
6624 if (err) {
6625 nlmsg_free(msg);
6626 return err;
6627 }
6628
6629 return genlmsg_reply(msg, info);
6630}
6631
6632static int
6633devlink_nl_cmd_info_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
6634 struct netlink_callback *cb)
6635{
6636 int err;
6637
6638 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
6639 NETLINK_CB(cb->skb).portid,
6640 cb->nlh->nlmsg_seq, NLM_F_MULTI,
6641 cb->extack);
6642 if (err == -EOPNOTSUPP)
6643 err = 0;
6644 return err;
6645}
6646
6647const struct devlink_gen_cmd devl_gen_info = {
6648 .dump_one = devlink_nl_cmd_info_get_dump_one,
6649};
6650
6651struct devlink_fmsg_item {
6652 struct list_head list;
6653 int attrtype;
6654 u8 nla_type;
6655 u16 len;
6656 int value[];
6657};
6658
6659struct devlink_fmsg {
6660 struct list_head item_list;
6661 bool putting_binary; /* This flag forces enclosing of binary data
6662 * in an array brackets. It forces using
6663 * of designated API:
6664 * devlink_fmsg_binary_pair_nest_start()
6665 * devlink_fmsg_binary_pair_nest_end()
6666 */
6667};
6668
6669static struct devlink_fmsg *devlink_fmsg_alloc(void)
6670{
6671 struct devlink_fmsg *fmsg;
6672
6673 fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
6674 if (!fmsg)
6675 return NULL;
6676
6677 INIT_LIST_HEAD(&fmsg->item_list);
6678
6679 return fmsg;
6680}
6681
6682static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
6683{
6684 struct devlink_fmsg_item *item, *tmp;
6685
6686 list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
6687 list_del(&item->list);
6688 kfree(item);
6689 }
6690 kfree(fmsg);
6691}
6692
6693static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
6694 int attrtype)
6695{
6696 struct devlink_fmsg_item *item;
6697
6698 item = kzalloc(sizeof(*item), GFP_KERNEL);
6699 if (!item)
6700 return -ENOMEM;
6701
6702 item->attrtype = attrtype;
6703 list_add_tail(&item->list, &fmsg->item_list);
6704
6705 return 0;
6706}
6707
6708int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
6709{
6710 if (fmsg->putting_binary)
6711 return -EINVAL;
6712
6713 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
6714}
6715EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
6716
6717static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
6718{
6719 if (fmsg->putting_binary)
6720 return -EINVAL;
6721
6722 return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
6723}
6724
6725int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
6726{
6727 if (fmsg->putting_binary)
6728 return -EINVAL;
6729
6730 return devlink_fmsg_nest_end(fmsg);
6731}
6732EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
6733
6734#define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
6735
6736static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
6737{
6738 struct devlink_fmsg_item *item;
6739
6740 if (fmsg->putting_binary)
6741 return -EINVAL;
6742
6743 if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
6744 return -EMSGSIZE;
6745
6746 item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
6747 if (!item)
6748 return -ENOMEM;
6749
6750 item->nla_type = NLA_NUL_STRING;
6751 item->len = strlen(name) + 1;
6752 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
6753 memcpy(&item->value, name, item->len);
6754 list_add_tail(&item->list, &fmsg->item_list);
6755
6756 return 0;
6757}
6758
6759int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
6760{
6761 int err;
6762
6763 if (fmsg->putting_binary)
6764 return -EINVAL;
6765
6766 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
6767 if (err)
6768 return err;
6769
6770 err = devlink_fmsg_put_name(fmsg, name);
6771 if (err)
6772 return err;
6773
6774 return 0;
6775}
6776EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
6777
6778int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
6779{
6780 if (fmsg->putting_binary)
6781 return -EINVAL;
6782
6783 return devlink_fmsg_nest_end(fmsg);
6784}
6785EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
6786
6787int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
6788 const char *name)
6789{
6790 int err;
6791
6792 if (fmsg->putting_binary)
6793 return -EINVAL;
6794
6795 err = devlink_fmsg_pair_nest_start(fmsg, name);
6796 if (err)
6797 return err;
6798
6799 err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
6800 if (err)
6801 return err;
6802
6803 return 0;
6804}
6805EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
6806
6807int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
6808{
6809 int err;
6810
6811 if (fmsg->putting_binary)
6812 return -EINVAL;
6813
6814 err = devlink_fmsg_nest_end(fmsg);
6815 if (err)
6816 return err;
6817
6818 err = devlink_fmsg_nest_end(fmsg);
6819 if (err)
6820 return err;
6821
6822 return 0;
6823}
6824EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
6825
6826int devlink_fmsg_binary_pair_nest_start(struct devlink_fmsg *fmsg,
6827 const char *name)
6828{
6829 int err;
6830
6831 err = devlink_fmsg_arr_pair_nest_start(fmsg, name);
6832 if (err)
6833 return err;
6834
6835 fmsg->putting_binary = true;
6836 return err;
6837}
6838EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_start);
6839
6840int devlink_fmsg_binary_pair_nest_end(struct devlink_fmsg *fmsg)
6841{
6842 if (!fmsg->putting_binary)
6843 return -EINVAL;
6844
6845 fmsg->putting_binary = false;
6846 return devlink_fmsg_arr_pair_nest_end(fmsg);
6847}
6848EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_nest_end);
6849
6850static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
6851 const void *value, u16 value_len,
6852 u8 value_nla_type)
6853{
6854 struct devlink_fmsg_item *item;
6855
6856 if (value_len > DEVLINK_FMSG_MAX_SIZE)
6857 return -EMSGSIZE;
6858
6859 item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
6860 if (!item)
6861 return -ENOMEM;
6862
6863 item->nla_type = value_nla_type;
6864 item->len = value_len;
6865 item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
6866 memcpy(&item->value, value, item->len);
6867 list_add_tail(&item->list, &fmsg->item_list);
6868
6869 return 0;
6870}
6871
6872static int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
6873{
6874 if (fmsg->putting_binary)
6875 return -EINVAL;
6876
6877 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
6878}
6879
6880static int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
6881{
6882 if (fmsg->putting_binary)
6883 return -EINVAL;
6884
6885 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
6886}
6887
6888int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
6889{
6890 if (fmsg->putting_binary)
6891 return -EINVAL;
6892
6893 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
6894}
6895EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
6896
6897static int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
6898{
6899 if (fmsg->putting_binary)
6900 return -EINVAL;
6901
6902 return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
6903}
6904
6905int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
6906{
6907 if (fmsg->putting_binary)
6908 return -EINVAL;
6909
6910 return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
6911 NLA_NUL_STRING);
6912}
6913EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
6914
6915int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
6916 u16 value_len)
6917{
6918 if (!fmsg->putting_binary)
6919 return -EINVAL;
6920
6921 return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
6922}
6923EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
6924
6925int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
6926 bool value)
6927{
6928 int err;
6929
6930 err = devlink_fmsg_pair_nest_start(fmsg, name);
6931 if (err)
6932 return err;
6933
6934 err = devlink_fmsg_bool_put(fmsg, value);
6935 if (err)
6936 return err;
6937
6938 err = devlink_fmsg_pair_nest_end(fmsg);
6939 if (err)
6940 return err;
6941
6942 return 0;
6943}
6944EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
6945
6946int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
6947 u8 value)
6948{
6949 int err;
6950
6951 err = devlink_fmsg_pair_nest_start(fmsg, name);
6952 if (err)
6953 return err;
6954
6955 err = devlink_fmsg_u8_put(fmsg, value);
6956 if (err)
6957 return err;
6958
6959 err = devlink_fmsg_pair_nest_end(fmsg);
6960 if (err)
6961 return err;
6962
6963 return 0;
6964}
6965EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
6966
6967int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
6968 u32 value)
6969{
6970 int err;
6971
6972 err = devlink_fmsg_pair_nest_start(fmsg, name);
6973 if (err)
6974 return err;
6975
6976 err = devlink_fmsg_u32_put(fmsg, value);
6977 if (err)
6978 return err;
6979
6980 err = devlink_fmsg_pair_nest_end(fmsg);
6981 if (err)
6982 return err;
6983
6984 return 0;
6985}
6986EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
6987
6988int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
6989 u64 value)
6990{
6991 int err;
6992
6993 err = devlink_fmsg_pair_nest_start(fmsg, name);
6994 if (err)
6995 return err;
6996
6997 err = devlink_fmsg_u64_put(fmsg, value);
6998 if (err)
6999 return err;
7000
7001 err = devlink_fmsg_pair_nest_end(fmsg);
7002 if (err)
7003 return err;
7004
7005 return 0;
7006}
7007EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
7008
7009int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
7010 const char *value)
7011{
7012 int err;
7013
7014 err = devlink_fmsg_pair_nest_start(fmsg, name);
7015 if (err)
7016 return err;
7017
7018 err = devlink_fmsg_string_put(fmsg, value);
7019 if (err)
7020 return err;
7021
7022 err = devlink_fmsg_pair_nest_end(fmsg);
7023 if (err)
7024 return err;
7025
7026 return 0;
7027}
7028EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
7029
7030int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
7031 const void *value, u32 value_len)
7032{
7033 u32 data_size;
7034 int end_err;
7035 u32 offset;
7036 int err;
7037
7038 err = devlink_fmsg_binary_pair_nest_start(fmsg, name);
7039 if (err)
7040 return err;
7041
7042 for (offset = 0; offset < value_len; offset += data_size) {
7043 data_size = value_len - offset;
7044 if (data_size > DEVLINK_FMSG_MAX_SIZE)
7045 data_size = DEVLINK_FMSG_MAX_SIZE;
7046 err = devlink_fmsg_binary_put(fmsg, value + offset, data_size);
7047 if (err)
7048 break;
7049 /* Exit from loop with a break (instead of
7050 * return) to make sure putting_binary is turned off in
7051 * devlink_fmsg_binary_pair_nest_end
7052 */
7053 }
7054
7055 end_err = devlink_fmsg_binary_pair_nest_end(fmsg);
7056 if (end_err)
7057 err = end_err;
7058
7059 return err;
7060}
7061EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
7062
7063static int
7064devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
7065{
7066 switch (msg->nla_type) {
7067 case NLA_FLAG:
7068 case NLA_U8:
7069 case NLA_U32:
7070 case NLA_U64:
7071 case NLA_NUL_STRING:
7072 case NLA_BINARY:
7073 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
7074 msg->nla_type);
7075 default:
7076 return -EINVAL;
7077 }
7078}
7079
7080static int
7081devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
7082{
7083 int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
7084 u8 tmp;
7085
7086 switch (msg->nla_type) {
7087 case NLA_FLAG:
7088 /* Always provide flag data, regardless of its value */
7089 tmp = *(bool *) msg->value;
7090
7091 return nla_put_u8(skb, attrtype, tmp);
7092 case NLA_U8:
7093 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
7094 case NLA_U32:
7095 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
7096 case NLA_U64:
7097 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
7098 DEVLINK_ATTR_PAD);
7099 case NLA_NUL_STRING:
7100 return nla_put_string(skb, attrtype, (char *) &msg->value);
7101 case NLA_BINARY:
7102 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
7103 default:
7104 return -EINVAL;
7105 }
7106}
7107
7108static int
7109devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7110 int *start)
7111{
7112 struct devlink_fmsg_item *item;
7113 struct nlattr *fmsg_nlattr;
7114 int err = 0;
7115 int i = 0;
7116
7117 fmsg_nlattr = nla_nest_start_noflag(skb, DEVLINK_ATTR_FMSG);
7118 if (!fmsg_nlattr)
7119 return -EMSGSIZE;
7120
7121 list_for_each_entry(item, &fmsg->item_list, list) {
7122 if (i < *start) {
7123 i++;
7124 continue;
7125 }
7126
7127 switch (item->attrtype) {
7128 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
7129 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
7130 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
7131 case DEVLINK_ATTR_FMSG_NEST_END:
7132 err = nla_put_flag(skb, item->attrtype);
7133 break;
7134 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
7135 err = devlink_fmsg_item_fill_type(item, skb);
7136 if (err)
7137 break;
7138 err = devlink_fmsg_item_fill_data(item, skb);
7139 break;
7140 case DEVLINK_ATTR_FMSG_OBJ_NAME:
7141 err = nla_put_string(skb, item->attrtype,
7142 (char *) &item->value);
7143 break;
7144 default:
7145 err = -EINVAL;
7146 break;
7147 }
7148 if (!err)
7149 *start = ++i;
7150 else
7151 break;
7152 }
7153
7154 nla_nest_end(skb, fmsg_nlattr);
7155 return err;
7156}
7157
7158static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
7159 struct genl_info *info,
7160 enum devlink_command cmd, int flags)
7161{
7162 struct nlmsghdr *nlh;
7163 struct sk_buff *skb;
7164 bool last = false;
7165 int index = 0;
7166 void *hdr;
7167 int err;
7168
7169 while (!last) {
7170 int tmp_index = index;
7171
7172 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7173 if (!skb)
7174 return -ENOMEM;
7175
7176 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
7177 &devlink_nl_family, flags | NLM_F_MULTI, cmd);
7178 if (!hdr) {
7179 err = -EMSGSIZE;
7180 goto nla_put_failure;
7181 }
7182
7183 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7184 if (!err)
7185 last = true;
7186 else if (err != -EMSGSIZE || tmp_index == index)
7187 goto nla_put_failure;
7188
7189 genlmsg_end(skb, hdr);
7190 err = genlmsg_reply(skb, info);
7191 if (err)
7192 return err;
7193 }
7194
7195 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
7196 if (!skb)
7197 return -ENOMEM;
7198 nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
7199 NLMSG_DONE, 0, flags | NLM_F_MULTI);
7200 if (!nlh) {
7201 err = -EMSGSIZE;
7202 goto nla_put_failure;
7203 }
7204
7205 return genlmsg_reply(skb, info);
7206
7207nla_put_failure:
7208 nlmsg_free(skb);
7209 return err;
7210}
7211
7212static int devlink_fmsg_dumpit(struct devlink_fmsg *fmsg, struct sk_buff *skb,
7213 struct netlink_callback *cb,
7214 enum devlink_command cmd)
7215{
7216 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7217 int index = state->idx;
7218 int tmp_index = index;
7219 void *hdr;
7220 int err;
7221
7222 hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
7223 &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI, cmd);
7224 if (!hdr) {
7225 err = -EMSGSIZE;
7226 goto nla_put_failure;
7227 }
7228
7229 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
7230 if ((err && err != -EMSGSIZE) || tmp_index == index)
7231 goto nla_put_failure;
7232
7233 state->idx = index;
7234 genlmsg_end(skb, hdr);
7235 return skb->len;
7236
7237nla_put_failure:
7238 genlmsg_cancel(skb, hdr);
7239 return err;
7240}
7241
7242struct devlink_health_reporter {
7243 struct list_head list;
7244 void *priv;
7245 const struct devlink_health_reporter_ops *ops;
7246 struct devlink *devlink;
7247 struct devlink_port *devlink_port;
7248 struct devlink_fmsg *dump_fmsg;
7249 struct mutex dump_lock; /* lock parallel read/write from dump buffers */
7250 u64 graceful_period;
7251 bool auto_recover;
7252 bool auto_dump;
7253 u8 health_state;
7254 u64 dump_ts;
7255 u64 dump_real_ts;
7256 u64 error_count;
7257 u64 recovery_count;
7258 u64 last_recovery_ts;
7259};
7260
7261void *
7262devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
7263{
7264 return reporter->priv;
7265}
7266EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
7267
7268static struct devlink_health_reporter *
7269__devlink_health_reporter_find_by_name(struct list_head *reporter_list,
7270 const char *reporter_name)
7271{
7272 struct devlink_health_reporter *reporter;
7273
7274 list_for_each_entry(reporter, reporter_list, list)
7275 if (!strcmp(reporter->ops->name, reporter_name))
7276 return reporter;
7277 return NULL;
7278}
7279
7280static struct devlink_health_reporter *
7281devlink_health_reporter_find_by_name(struct devlink *devlink,
7282 const char *reporter_name)
7283{
7284 return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
7285 reporter_name);
7286}
7287
7288static struct devlink_health_reporter *
7289devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
7290 const char *reporter_name)
7291{
7292 return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
7293 reporter_name);
7294}
7295
7296static struct devlink_health_reporter *
7297__devlink_health_reporter_create(struct devlink *devlink,
7298 const struct devlink_health_reporter_ops *ops,
7299 u64 graceful_period, void *priv)
7300{
7301 struct devlink_health_reporter *reporter;
7302
7303 if (WARN_ON(graceful_period && !ops->recover))
7304 return ERR_PTR(-EINVAL);
7305
7306 reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
7307 if (!reporter)
7308 return ERR_PTR(-ENOMEM);
7309
7310 reporter->priv = priv;
7311 reporter->ops = ops;
7312 reporter->devlink = devlink;
7313 reporter->graceful_period = graceful_period;
7314 reporter->auto_recover = !!ops->recover;
7315 reporter->auto_dump = !!ops->dump;
7316 mutex_init(&reporter->dump_lock);
7317 return reporter;
7318}
7319
7320/**
7321 * devl_port_health_reporter_create - create devlink health reporter for
7322 * specified port instance
7323 *
7324 * @port: devlink_port which should contain the new reporter
7325 * @ops: ops
7326 * @graceful_period: to avoid recovery loops, in msecs
7327 * @priv: priv
7328 */
7329struct devlink_health_reporter *
7330devl_port_health_reporter_create(struct devlink_port *port,
7331 const struct devlink_health_reporter_ops *ops,
7332 u64 graceful_period, void *priv)
7333{
7334 struct devlink_health_reporter *reporter;
7335
7336 devl_assert_locked(port->devlink);
7337
7338 if (__devlink_health_reporter_find_by_name(&port->reporter_list,
7339 ops->name))
7340 return ERR_PTR(-EEXIST);
7341
7342 reporter = __devlink_health_reporter_create(port->devlink, ops,
7343 graceful_period, priv);
7344 if (IS_ERR(reporter))
7345 return reporter;
7346
7347 reporter->devlink_port = port;
7348 list_add_tail(&reporter->list, &port->reporter_list);
7349 return reporter;
7350}
7351EXPORT_SYMBOL_GPL(devl_port_health_reporter_create);
7352
7353struct devlink_health_reporter *
7354devlink_port_health_reporter_create(struct devlink_port *port,
7355 const struct devlink_health_reporter_ops *ops,
7356 u64 graceful_period, void *priv)
7357{
7358 struct devlink_health_reporter *reporter;
7359 struct devlink *devlink = port->devlink;
7360
7361 devl_lock(devlink);
7362 reporter = devl_port_health_reporter_create(port, ops,
7363 graceful_period, priv);
7364 devl_unlock(devlink);
7365 return reporter;
7366}
7367EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
7368
7369/**
7370 * devl_health_reporter_create - create devlink health reporter
7371 *
7372 * @devlink: devlink
7373 * @ops: ops
7374 * @graceful_period: to avoid recovery loops, in msecs
7375 * @priv: priv
7376 */
7377struct devlink_health_reporter *
7378devl_health_reporter_create(struct devlink *devlink,
7379 const struct devlink_health_reporter_ops *ops,
7380 u64 graceful_period, void *priv)
7381{
7382 struct devlink_health_reporter *reporter;
7383
7384 devl_assert_locked(devlink);
7385
7386 if (devlink_health_reporter_find_by_name(devlink, ops->name))
7387 return ERR_PTR(-EEXIST);
7388
7389 reporter = __devlink_health_reporter_create(devlink, ops,
7390 graceful_period, priv);
7391 if (IS_ERR(reporter))
7392 return reporter;
7393
7394 list_add_tail(&reporter->list, &devlink->reporter_list);
7395 return reporter;
7396}
7397EXPORT_SYMBOL_GPL(devl_health_reporter_create);
7398
7399struct devlink_health_reporter *
7400devlink_health_reporter_create(struct devlink *devlink,
7401 const struct devlink_health_reporter_ops *ops,
7402 u64 graceful_period, void *priv)
7403{
7404 struct devlink_health_reporter *reporter;
7405
7406 devl_lock(devlink);
7407 reporter = devl_health_reporter_create(devlink, ops,
7408 graceful_period, priv);
7409 devl_unlock(devlink);
7410 return reporter;
7411}
7412EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
7413
7414static void
7415devlink_health_reporter_free(struct devlink_health_reporter *reporter)
7416{
7417 mutex_destroy(&reporter->dump_lock);
7418 if (reporter->dump_fmsg)
7419 devlink_fmsg_free(reporter->dump_fmsg);
7420 kfree(reporter);
7421}
7422
7423/**
7424 * devl_health_reporter_destroy - destroy devlink health reporter
7425 *
7426 * @reporter: devlink health reporter to destroy
7427 */
7428void
7429devl_health_reporter_destroy(struct devlink_health_reporter *reporter)
7430{
7431 devl_assert_locked(reporter->devlink);
7432
7433 list_del(&reporter->list);
7434 devlink_health_reporter_free(reporter);
7435}
7436EXPORT_SYMBOL_GPL(devl_health_reporter_destroy);
7437
7438void
7439devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
7440{
7441 struct devlink *devlink = reporter->devlink;
7442
7443 devl_lock(devlink);
7444 devl_health_reporter_destroy(reporter);
7445 devl_unlock(devlink);
7446}
7447EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
7448
7449static int
7450devlink_nl_health_reporter_fill(struct sk_buff *msg,
7451 struct devlink_health_reporter *reporter,
7452 enum devlink_command cmd, u32 portid,
7453 u32 seq, int flags)
7454{
7455 struct devlink *devlink = reporter->devlink;
7456 struct nlattr *reporter_attr;
7457 void *hdr;
7458
7459 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7460 if (!hdr)
7461 return -EMSGSIZE;
7462
7463 if (devlink_nl_put_handle(msg, devlink))
7464 goto genlmsg_cancel;
7465
7466 if (reporter->devlink_port) {
7467 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
7468 goto genlmsg_cancel;
7469 }
7470 reporter_attr = nla_nest_start_noflag(msg,
7471 DEVLINK_ATTR_HEALTH_REPORTER);
7472 if (!reporter_attr)
7473 goto genlmsg_cancel;
7474 if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
7475 reporter->ops->name))
7476 goto reporter_nest_cancel;
7477 if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
7478 reporter->health_state))
7479 goto reporter_nest_cancel;
7480 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
7481 reporter->error_count, DEVLINK_ATTR_PAD))
7482 goto reporter_nest_cancel;
7483 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
7484 reporter->recovery_count, DEVLINK_ATTR_PAD))
7485 goto reporter_nest_cancel;
7486 if (reporter->ops->recover &&
7487 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
7488 reporter->graceful_period,
7489 DEVLINK_ATTR_PAD))
7490 goto reporter_nest_cancel;
7491 if (reporter->ops->recover &&
7492 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
7493 reporter->auto_recover))
7494 goto reporter_nest_cancel;
7495 if (reporter->dump_fmsg &&
7496 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
7497 jiffies_to_msecs(reporter->dump_ts),
7498 DEVLINK_ATTR_PAD))
7499 goto reporter_nest_cancel;
7500 if (reporter->dump_fmsg &&
7501 nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
7502 reporter->dump_real_ts, DEVLINK_ATTR_PAD))
7503 goto reporter_nest_cancel;
7504 if (reporter->ops->dump &&
7505 nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
7506 reporter->auto_dump))
7507 goto reporter_nest_cancel;
7508
7509 nla_nest_end(msg, reporter_attr);
7510 genlmsg_end(msg, hdr);
7511 return 0;
7512
7513reporter_nest_cancel:
7514 nla_nest_end(msg, reporter_attr);
7515genlmsg_cancel:
7516 genlmsg_cancel(msg, hdr);
7517 return -EMSGSIZE;
7518}
7519
7520static void devlink_recover_notify(struct devlink_health_reporter *reporter,
7521 enum devlink_command cmd)
7522{
7523 struct devlink *devlink = reporter->devlink;
7524 struct sk_buff *msg;
7525 int err;
7526
7527 WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7528 WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
7529
7530 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7531 if (!msg)
7532 return;
7533
7534 err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0);
7535 if (err) {
7536 nlmsg_free(msg);
7537 return;
7538 }
7539
7540 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
7541 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7542}
7543
7544void
7545devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
7546{
7547 reporter->recovery_count++;
7548 reporter->last_recovery_ts = jiffies;
7549}
7550EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
7551
7552static int
7553devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
7554 void *priv_ctx, struct netlink_ext_ack *extack)
7555{
7556 int err;
7557
7558 if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
7559 return 0;
7560
7561 if (!reporter->ops->recover)
7562 return -EOPNOTSUPP;
7563
7564 err = reporter->ops->recover(reporter, priv_ctx, extack);
7565 if (err)
7566 return err;
7567
7568 devlink_health_reporter_recovery_done(reporter);
7569 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
7570 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7571
7572 return 0;
7573}
7574
7575static void
7576devlink_health_dump_clear(struct devlink_health_reporter *reporter)
7577{
7578 if (!reporter->dump_fmsg)
7579 return;
7580 devlink_fmsg_free(reporter->dump_fmsg);
7581 reporter->dump_fmsg = NULL;
7582}
7583
7584static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
7585 void *priv_ctx,
7586 struct netlink_ext_ack *extack)
7587{
7588 int err;
7589
7590 if (!reporter->ops->dump)
7591 return 0;
7592
7593 if (reporter->dump_fmsg)
7594 return 0;
7595
7596 reporter->dump_fmsg = devlink_fmsg_alloc();
7597 if (!reporter->dump_fmsg) {
7598 err = -ENOMEM;
7599 return err;
7600 }
7601
7602 err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
7603 if (err)
7604 goto dump_err;
7605
7606 err = reporter->ops->dump(reporter, reporter->dump_fmsg,
7607 priv_ctx, extack);
7608 if (err)
7609 goto dump_err;
7610
7611 err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
7612 if (err)
7613 goto dump_err;
7614
7615 reporter->dump_ts = jiffies;
7616 reporter->dump_real_ts = ktime_get_real_ns();
7617
7618 return 0;
7619
7620dump_err:
7621 devlink_health_dump_clear(reporter);
7622 return err;
7623}
7624
7625int devlink_health_report(struct devlink_health_reporter *reporter,
7626 const char *msg, void *priv_ctx)
7627{
7628 enum devlink_health_reporter_state prev_health_state;
7629 struct devlink *devlink = reporter->devlink;
7630 unsigned long recover_ts_threshold;
7631 int ret;
7632
7633 /* write a log message of the current error */
7634 WARN_ON(!msg);
7635 trace_devlink_health_report(devlink, reporter->ops->name, msg);
7636 reporter->error_count++;
7637 prev_health_state = reporter->health_state;
7638 reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
7639 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7640
7641 /* abort if the previous error wasn't recovered */
7642 recover_ts_threshold = reporter->last_recovery_ts +
7643 msecs_to_jiffies(reporter->graceful_period);
7644 if (reporter->auto_recover &&
7645 (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
7646 (reporter->last_recovery_ts && reporter->recovery_count &&
7647 time_is_after_jiffies(recover_ts_threshold)))) {
7648 trace_devlink_health_recover_aborted(devlink,
7649 reporter->ops->name,
7650 reporter->health_state,
7651 jiffies -
7652 reporter->last_recovery_ts);
7653 return -ECANCELED;
7654 }
7655
7656 if (reporter->auto_dump) {
7657 mutex_lock(&reporter->dump_lock);
7658 /* store current dump of current error, for later analysis */
7659 devlink_health_do_dump(reporter, priv_ctx, NULL);
7660 mutex_unlock(&reporter->dump_lock);
7661 }
7662
7663 if (!reporter->auto_recover)
7664 return 0;
7665
7666 devl_lock(devlink);
7667 ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL);
7668 devl_unlock(devlink);
7669
7670 return ret;
7671}
7672EXPORT_SYMBOL_GPL(devlink_health_report);
7673
7674static struct devlink_health_reporter *
7675devlink_health_reporter_get_from_attrs(struct devlink *devlink,
7676 struct nlattr **attrs)
7677{
7678 struct devlink_port *devlink_port;
7679 char *reporter_name;
7680
7681 if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
7682 return NULL;
7683
7684 reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
7685 devlink_port = devlink_port_get_from_attrs(devlink, attrs);
7686 if (IS_ERR(devlink_port))
7687 return devlink_health_reporter_find_by_name(devlink,
7688 reporter_name);
7689 else
7690 return devlink_port_health_reporter_find_by_name(devlink_port,
7691 reporter_name);
7692}
7693
7694static struct devlink_health_reporter *
7695devlink_health_reporter_get_from_info(struct devlink *devlink,
7696 struct genl_info *info)
7697{
7698 return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
7699}
7700
7701static struct devlink_health_reporter *
7702devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
7703{
7704 const struct genl_dumpit_info *info = genl_dumpit_info(cb);
7705 struct devlink_health_reporter *reporter;
7706 struct nlattr **attrs = info->attrs;
7707 struct devlink *devlink;
7708
7709 devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
7710 if (IS_ERR(devlink))
7711 return NULL;
7712 devl_unlock(devlink);
7713
7714 reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
7715 devlink_put(devlink);
7716 return reporter;
7717}
7718
7719void
7720devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
7721 enum devlink_health_reporter_state state)
7722{
7723 if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
7724 state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
7725 return;
7726
7727 if (reporter->health_state == state)
7728 return;
7729
7730 reporter->health_state = state;
7731 trace_devlink_health_reporter_state_update(reporter->devlink,
7732 reporter->ops->name, state);
7733 devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7734}
7735EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
7736
7737static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
7738 struct genl_info *info)
7739{
7740 struct devlink *devlink = info->user_ptr[0];
7741 struct devlink_health_reporter *reporter;
7742 struct sk_buff *msg;
7743 int err;
7744
7745 reporter = devlink_health_reporter_get_from_info(devlink, info);
7746 if (!reporter)
7747 return -EINVAL;
7748
7749 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7750 if (!msg)
7751 return -ENOMEM;
7752
7753 err = devlink_nl_health_reporter_fill(msg, reporter,
7754 DEVLINK_CMD_HEALTH_REPORTER_GET,
7755 info->snd_portid, info->snd_seq,
7756 0);
7757 if (err) {
7758 nlmsg_free(msg);
7759 return err;
7760 }
7761
7762 return genlmsg_reply(msg, info);
7763}
7764
7765static int
7766devlink_nl_cmd_health_reporter_get_dump_one(struct sk_buff *msg,
7767 struct devlink *devlink,
7768 struct netlink_callback *cb)
7769{
7770 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7771 struct devlink_health_reporter *reporter;
7772 struct devlink_port *port;
7773 unsigned long port_index;
7774 int idx = 0;
7775 int err;
7776
7777 list_for_each_entry(reporter, &devlink->reporter_list, list) {
7778 if (idx < state->idx) {
7779 idx++;
7780 continue;
7781 }
7782 err = devlink_nl_health_reporter_fill(msg, reporter,
7783 DEVLINK_CMD_HEALTH_REPORTER_GET,
7784 NETLINK_CB(cb->skb).portid,
7785 cb->nlh->nlmsg_seq,
7786 NLM_F_MULTI);
7787 if (err) {
7788 state->idx = idx;
7789 return err;
7790 }
7791 idx++;
7792 }
7793 xa_for_each(&devlink->ports, port_index, port) {
7794 list_for_each_entry(reporter, &port->reporter_list, list) {
7795 if (idx < state->idx) {
7796 idx++;
7797 continue;
7798 }
7799 err = devlink_nl_health_reporter_fill(msg, reporter,
7800 DEVLINK_CMD_HEALTH_REPORTER_GET,
7801 NETLINK_CB(cb->skb).portid,
7802 cb->nlh->nlmsg_seq,
7803 NLM_F_MULTI);
7804 if (err) {
7805 state->idx = idx;
7806 return err;
7807 }
7808 idx++;
7809 }
7810 }
7811
7812 return 0;
7813}
7814
7815const struct devlink_gen_cmd devl_gen_health_reporter = {
7816 .dump_one = devlink_nl_cmd_health_reporter_get_dump_one,
7817};
7818
7819static int
7820devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
7821 struct genl_info *info)
7822{
7823 struct devlink *devlink = info->user_ptr[0];
7824 struct devlink_health_reporter *reporter;
7825
7826 reporter = devlink_health_reporter_get_from_info(devlink, info);
7827 if (!reporter)
7828 return -EINVAL;
7829
7830 if (!reporter->ops->recover &&
7831 (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
7832 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]))
7833 return -EOPNOTSUPP;
7834
7835 if (!reporter->ops->dump &&
7836 info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
7837 return -EOPNOTSUPP;
7838
7839 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
7840 reporter->graceful_period =
7841 nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
7842
7843 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
7844 reporter->auto_recover =
7845 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
7846
7847 if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
7848 reporter->auto_dump =
7849 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
7850
7851 return 0;
7852}
7853
7854static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
7855 struct genl_info *info)
7856{
7857 struct devlink *devlink = info->user_ptr[0];
7858 struct devlink_health_reporter *reporter;
7859
7860 reporter = devlink_health_reporter_get_from_info(devlink, info);
7861 if (!reporter)
7862 return -EINVAL;
7863
7864 return devlink_health_reporter_recover(reporter, NULL, info->extack);
7865}
7866
7867static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
7868 struct genl_info *info)
7869{
7870 struct devlink *devlink = info->user_ptr[0];
7871 struct devlink_health_reporter *reporter;
7872 struct devlink_fmsg *fmsg;
7873 int err;
7874
7875 reporter = devlink_health_reporter_get_from_info(devlink, info);
7876 if (!reporter)
7877 return -EINVAL;
7878
7879 if (!reporter->ops->diagnose)
7880 return -EOPNOTSUPP;
7881
7882 fmsg = devlink_fmsg_alloc();
7883 if (!fmsg)
7884 return -ENOMEM;
7885
7886 err = devlink_fmsg_obj_nest_start(fmsg);
7887 if (err)
7888 return err;
7889
7890 err = reporter->ops->diagnose(reporter, fmsg, info->extack);
7891 if (err)
7892 return err;
7893
7894 err = devlink_fmsg_obj_nest_end(fmsg);
7895 if (err)
7896 return err;
7897
7898 return devlink_fmsg_snd(fmsg, info,
7899 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
7900}
7901
7902static int
7903devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
7904 struct netlink_callback *cb)
7905{
7906 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7907 struct devlink_health_reporter *reporter;
7908 int err;
7909
7910 reporter = devlink_health_reporter_get_from_cb(cb);
7911 if (!reporter)
7912 return -EINVAL;
7913
7914 if (!reporter->ops->dump)
7915 return -EOPNOTSUPP;
7916
7917 mutex_lock(&reporter->dump_lock);
7918 if (!state->idx) {
7919 err = devlink_health_do_dump(reporter, NULL, cb->extack);
7920 if (err)
7921 goto unlock;
7922 state->dump_ts = reporter->dump_ts;
7923 }
7924 if (!reporter->dump_fmsg || state->dump_ts != reporter->dump_ts) {
7925 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
7926 err = -EAGAIN;
7927 goto unlock;
7928 }
7929
7930 err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
7931 DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
7932unlock:
7933 mutex_unlock(&reporter->dump_lock);
7934 return err;
7935}
7936
7937static int
7938devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
7939 struct genl_info *info)
7940{
7941 struct devlink *devlink = info->user_ptr[0];
7942 struct devlink_health_reporter *reporter;
7943
7944 reporter = devlink_health_reporter_get_from_info(devlink, info);
7945 if (!reporter)
7946 return -EINVAL;
7947
7948 if (!reporter->ops->dump)
7949 return -EOPNOTSUPP;
7950
7951 mutex_lock(&reporter->dump_lock);
7952 devlink_health_dump_clear(reporter);
7953 mutex_unlock(&reporter->dump_lock);
7954 return 0;
7955}
7956
7957static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
7958 struct genl_info *info)
7959{
7960 struct devlink *devlink = info->user_ptr[0];
7961 struct devlink_health_reporter *reporter;
7962
7963 reporter = devlink_health_reporter_get_from_info(devlink, info);
7964 if (!reporter)
7965 return -EINVAL;
7966
7967 if (!reporter->ops->test)
7968 return -EOPNOTSUPP;
7969
7970 return reporter->ops->test(reporter, info->extack);
7971}
7972
7973struct devlink_stats {
7974 u64_stats_t rx_bytes;
7975 u64_stats_t rx_packets;
7976 struct u64_stats_sync syncp;
7977};
7978
7979/**
7980 * struct devlink_trap_policer_item - Packet trap policer attributes.
7981 * @policer: Immutable packet trap policer attributes.
7982 * @rate: Rate in packets / sec.
7983 * @burst: Burst size in packets.
7984 * @list: trap_policer_list member.
7985 *
7986 * Describes packet trap policer attributes. Created by devlink during trap
7987 * policer registration.
7988 */
7989struct devlink_trap_policer_item {
7990 const struct devlink_trap_policer *policer;
7991 u64 rate;
7992 u64 burst;
7993 struct list_head list;
7994};
7995
7996/**
7997 * struct devlink_trap_group_item - Packet trap group attributes.
7998 * @group: Immutable packet trap group attributes.
7999 * @policer_item: Associated policer item. Can be NULL.
8000 * @list: trap_group_list member.
8001 * @stats: Trap group statistics.
8002 *
8003 * Describes packet trap group attributes. Created by devlink during trap
8004 * group registration.
8005 */
8006struct devlink_trap_group_item {
8007 const struct devlink_trap_group *group;
8008 struct devlink_trap_policer_item *policer_item;
8009 struct list_head list;
8010 struct devlink_stats __percpu *stats;
8011};
8012
8013/**
8014 * struct devlink_trap_item - Packet trap attributes.
8015 * @trap: Immutable packet trap attributes.
8016 * @group_item: Associated group item.
8017 * @list: trap_list member.
8018 * @action: Trap action.
8019 * @stats: Trap statistics.
8020 * @priv: Driver private information.
8021 *
8022 * Describes both mutable and immutable packet trap attributes. Created by
8023 * devlink during trap registration and used for all trap related operations.
8024 */
8025struct devlink_trap_item {
8026 const struct devlink_trap *trap;
8027 struct devlink_trap_group_item *group_item;
8028 struct list_head list;
8029 enum devlink_trap_action action;
8030 struct devlink_stats __percpu *stats;
8031 void *priv;
8032};
8033
8034static struct devlink_trap_policer_item *
8035devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
8036{
8037 struct devlink_trap_policer_item *policer_item;
8038
8039 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
8040 if (policer_item->policer->id == id)
8041 return policer_item;
8042 }
8043
8044 return NULL;
8045}
8046
8047static struct devlink_trap_item *
8048devlink_trap_item_lookup(struct devlink *devlink, const char *name)
8049{
8050 struct devlink_trap_item *trap_item;
8051
8052 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8053 if (!strcmp(trap_item->trap->name, name))
8054 return trap_item;
8055 }
8056
8057 return NULL;
8058}
8059
8060static struct devlink_trap_item *
8061devlink_trap_item_get_from_info(struct devlink *devlink,
8062 struct genl_info *info)
8063{
8064 struct nlattr *attr;
8065
8066 if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
8067 return NULL;
8068 attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
8069
8070 return devlink_trap_item_lookup(devlink, nla_data(attr));
8071}
8072
8073static int
8074devlink_trap_action_get_from_info(struct genl_info *info,
8075 enum devlink_trap_action *p_trap_action)
8076{
8077 u8 val;
8078
8079 val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
8080 switch (val) {
8081 case DEVLINK_TRAP_ACTION_DROP:
8082 case DEVLINK_TRAP_ACTION_TRAP:
8083 case DEVLINK_TRAP_ACTION_MIRROR:
8084 *p_trap_action = val;
8085 break;
8086 default:
8087 return -EINVAL;
8088 }
8089
8090 return 0;
8091}
8092
8093static int devlink_trap_metadata_put(struct sk_buff *msg,
8094 const struct devlink_trap *trap)
8095{
8096 struct nlattr *attr;
8097
8098 attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
8099 if (!attr)
8100 return -EMSGSIZE;
8101
8102 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
8103 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
8104 goto nla_put_failure;
8105 if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
8106 nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
8107 goto nla_put_failure;
8108
8109 nla_nest_end(msg, attr);
8110
8111 return 0;
8112
8113nla_put_failure:
8114 nla_nest_cancel(msg, attr);
8115 return -EMSGSIZE;
8116}
8117
8118static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
8119 struct devlink_stats *stats)
8120{
8121 int i;
8122
8123 memset(stats, 0, sizeof(*stats));
8124 for_each_possible_cpu(i) {
8125 struct devlink_stats *cpu_stats;
8126 u64 rx_packets, rx_bytes;
8127 unsigned int start;
8128
8129 cpu_stats = per_cpu_ptr(trap_stats, i);
8130 do {
8131 start = u64_stats_fetch_begin(&cpu_stats->syncp);
8132 rx_packets = u64_stats_read(&cpu_stats->rx_packets);
8133 rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
8134 } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
8135
8136 u64_stats_add(&stats->rx_packets, rx_packets);
8137 u64_stats_add(&stats->rx_bytes, rx_bytes);
8138 }
8139}
8140
8141static int
8142devlink_trap_group_stats_put(struct sk_buff *msg,
8143 struct devlink_stats __percpu *trap_stats)
8144{
8145 struct devlink_stats stats;
8146 struct nlattr *attr;
8147
8148 devlink_trap_stats_read(trap_stats, &stats);
8149
8150 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8151 if (!attr)
8152 return -EMSGSIZE;
8153
8154 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8155 u64_stats_read(&stats.rx_packets),
8156 DEVLINK_ATTR_PAD))
8157 goto nla_put_failure;
8158
8159 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8160 u64_stats_read(&stats.rx_bytes),
8161 DEVLINK_ATTR_PAD))
8162 goto nla_put_failure;
8163
8164 nla_nest_end(msg, attr);
8165
8166 return 0;
8167
8168nla_put_failure:
8169 nla_nest_cancel(msg, attr);
8170 return -EMSGSIZE;
8171}
8172
8173static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink,
8174 const struct devlink_trap_item *trap_item)
8175{
8176 struct devlink_stats stats;
8177 struct nlattr *attr;
8178 u64 drops = 0;
8179 int err;
8180
8181 if (devlink->ops->trap_drop_counter_get) {
8182 err = devlink->ops->trap_drop_counter_get(devlink,
8183 trap_item->trap,
8184 &drops);
8185 if (err)
8186 return err;
8187 }
8188
8189 devlink_trap_stats_read(trap_item->stats, &stats);
8190
8191 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8192 if (!attr)
8193 return -EMSGSIZE;
8194
8195 if (devlink->ops->trap_drop_counter_get &&
8196 nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8197 DEVLINK_ATTR_PAD))
8198 goto nla_put_failure;
8199
8200 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8201 u64_stats_read(&stats.rx_packets),
8202 DEVLINK_ATTR_PAD))
8203 goto nla_put_failure;
8204
8205 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8206 u64_stats_read(&stats.rx_bytes),
8207 DEVLINK_ATTR_PAD))
8208 goto nla_put_failure;
8209
8210 nla_nest_end(msg, attr);
8211
8212 return 0;
8213
8214nla_put_failure:
8215 nla_nest_cancel(msg, attr);
8216 return -EMSGSIZE;
8217}
8218
8219static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
8220 const struct devlink_trap_item *trap_item,
8221 enum devlink_command cmd, u32 portid, u32 seq,
8222 int flags)
8223{
8224 struct devlink_trap_group_item *group_item = trap_item->group_item;
8225 void *hdr;
8226 int err;
8227
8228 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8229 if (!hdr)
8230 return -EMSGSIZE;
8231
8232 if (devlink_nl_put_handle(msg, devlink))
8233 goto nla_put_failure;
8234
8235 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8236 group_item->group->name))
8237 goto nla_put_failure;
8238
8239 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
8240 goto nla_put_failure;
8241
8242 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
8243 goto nla_put_failure;
8244
8245 if (trap_item->trap->generic &&
8246 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8247 goto nla_put_failure;
8248
8249 if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
8250 goto nla_put_failure;
8251
8252 err = devlink_trap_metadata_put(msg, trap_item->trap);
8253 if (err)
8254 goto nla_put_failure;
8255
8256 err = devlink_trap_stats_put(msg, devlink, trap_item);
8257 if (err)
8258 goto nla_put_failure;
8259
8260 genlmsg_end(msg, hdr);
8261
8262 return 0;
8263
8264nla_put_failure:
8265 genlmsg_cancel(msg, hdr);
8266 return -EMSGSIZE;
8267}
8268
8269static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
8270 struct genl_info *info)
8271{
8272 struct netlink_ext_ack *extack = info->extack;
8273 struct devlink *devlink = info->user_ptr[0];
8274 struct devlink_trap_item *trap_item;
8275 struct sk_buff *msg;
8276 int err;
8277
8278 if (list_empty(&devlink->trap_list))
8279 return -EOPNOTSUPP;
8280
8281 trap_item = devlink_trap_item_get_from_info(devlink, info);
8282 if (!trap_item) {
8283 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8284 return -ENOENT;
8285 }
8286
8287 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8288 if (!msg)
8289 return -ENOMEM;
8290
8291 err = devlink_nl_trap_fill(msg, devlink, trap_item,
8292 DEVLINK_CMD_TRAP_NEW, info->snd_portid,
8293 info->snd_seq, 0);
8294 if (err)
8295 goto err_trap_fill;
8296
8297 return genlmsg_reply(msg, info);
8298
8299err_trap_fill:
8300 nlmsg_free(msg);
8301 return err;
8302}
8303
8304static int
8305devlink_nl_cmd_trap_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
8306 struct netlink_callback *cb)
8307{
8308 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8309 struct devlink_trap_item *trap_item;
8310 int idx = 0;
8311 int err = 0;
8312
8313 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8314 if (idx < state->idx) {
8315 idx++;
8316 continue;
8317 }
8318 err = devlink_nl_trap_fill(msg, devlink, trap_item,
8319 DEVLINK_CMD_TRAP_NEW,
8320 NETLINK_CB(cb->skb).portid,
8321 cb->nlh->nlmsg_seq,
8322 NLM_F_MULTI);
8323 if (err) {
8324 state->idx = idx;
8325 break;
8326 }
8327 idx++;
8328 }
8329
8330 return err;
8331}
8332
8333const struct devlink_gen_cmd devl_gen_trap = {
8334 .dump_one = devlink_nl_cmd_trap_get_dump_one,
8335};
8336
8337static int __devlink_trap_action_set(struct devlink *devlink,
8338 struct devlink_trap_item *trap_item,
8339 enum devlink_trap_action trap_action,
8340 struct netlink_ext_ack *extack)
8341{
8342 int err;
8343
8344 if (trap_item->action != trap_action &&
8345 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
8346 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
8347 return 0;
8348 }
8349
8350 err = devlink->ops->trap_action_set(devlink, trap_item->trap,
8351 trap_action, extack);
8352 if (err)
8353 return err;
8354
8355 trap_item->action = trap_action;
8356
8357 return 0;
8358}
8359
8360static int devlink_trap_action_set(struct devlink *devlink,
8361 struct devlink_trap_item *trap_item,
8362 struct genl_info *info)
8363{
8364 enum devlink_trap_action trap_action;
8365 int err;
8366
8367 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8368 return 0;
8369
8370 err = devlink_trap_action_get_from_info(info, &trap_action);
8371 if (err) {
8372 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8373 return -EINVAL;
8374 }
8375
8376 return __devlink_trap_action_set(devlink, trap_item, trap_action,
8377 info->extack);
8378}
8379
8380static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
8381 struct genl_info *info)
8382{
8383 struct netlink_ext_ack *extack = info->extack;
8384 struct devlink *devlink = info->user_ptr[0];
8385 struct devlink_trap_item *trap_item;
8386
8387 if (list_empty(&devlink->trap_list))
8388 return -EOPNOTSUPP;
8389
8390 trap_item = devlink_trap_item_get_from_info(devlink, info);
8391 if (!trap_item) {
8392 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8393 return -ENOENT;
8394 }
8395
8396 return devlink_trap_action_set(devlink, trap_item, info);
8397}
8398
8399static struct devlink_trap_group_item *
8400devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
8401{
8402 struct devlink_trap_group_item *group_item;
8403
8404 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8405 if (!strcmp(group_item->group->name, name))
8406 return group_item;
8407 }
8408
8409 return NULL;
8410}
8411
8412static struct devlink_trap_group_item *
8413devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
8414{
8415 struct devlink_trap_group_item *group_item;
8416
8417 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8418 if (group_item->group->id == id)
8419 return group_item;
8420 }
8421
8422 return NULL;
8423}
8424
8425static struct devlink_trap_group_item *
8426devlink_trap_group_item_get_from_info(struct devlink *devlink,
8427 struct genl_info *info)
8428{
8429 char *name;
8430
8431 if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
8432 return NULL;
8433 name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
8434
8435 return devlink_trap_group_item_lookup(devlink, name);
8436}
8437
8438static int
8439devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
8440 const struct devlink_trap_group_item *group_item,
8441 enum devlink_command cmd, u32 portid, u32 seq,
8442 int flags)
8443{
8444 void *hdr;
8445 int err;
8446
8447 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8448 if (!hdr)
8449 return -EMSGSIZE;
8450
8451 if (devlink_nl_put_handle(msg, devlink))
8452 goto nla_put_failure;
8453
8454 if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8455 group_item->group->name))
8456 goto nla_put_failure;
8457
8458 if (group_item->group->generic &&
8459 nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8460 goto nla_put_failure;
8461
8462 if (group_item->policer_item &&
8463 nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8464 group_item->policer_item->policer->id))
8465 goto nla_put_failure;
8466
8467 err = devlink_trap_group_stats_put(msg, group_item->stats);
8468 if (err)
8469 goto nla_put_failure;
8470
8471 genlmsg_end(msg, hdr);
8472
8473 return 0;
8474
8475nla_put_failure:
8476 genlmsg_cancel(msg, hdr);
8477 return -EMSGSIZE;
8478}
8479
8480static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
8481 struct genl_info *info)
8482{
8483 struct netlink_ext_ack *extack = info->extack;
8484 struct devlink *devlink = info->user_ptr[0];
8485 struct devlink_trap_group_item *group_item;
8486 struct sk_buff *msg;
8487 int err;
8488
8489 if (list_empty(&devlink->trap_group_list))
8490 return -EOPNOTSUPP;
8491
8492 group_item = devlink_trap_group_item_get_from_info(devlink, info);
8493 if (!group_item) {
8494 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8495 return -ENOENT;
8496 }
8497
8498 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8499 if (!msg)
8500 return -ENOMEM;
8501
8502 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
8503 DEVLINK_CMD_TRAP_GROUP_NEW,
8504 info->snd_portid, info->snd_seq, 0);
8505 if (err)
8506 goto err_trap_group_fill;
8507
8508 return genlmsg_reply(msg, info);
8509
8510err_trap_group_fill:
8511 nlmsg_free(msg);
8512 return err;
8513}
8514
8515static int
8516devlink_nl_cmd_trap_group_get_dump_one(struct sk_buff *msg,
8517 struct devlink *devlink,
8518 struct netlink_callback *cb)
8519{
8520 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8521 struct devlink_trap_group_item *group_item;
8522 int idx = 0;
8523 int err = 0;
8524
8525
8526 list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8527 if (idx < state->idx) {
8528 idx++;
8529 continue;
8530 }
8531 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
8532 DEVLINK_CMD_TRAP_GROUP_NEW,
8533 NETLINK_CB(cb->skb).portid,
8534 cb->nlh->nlmsg_seq,
8535 NLM_F_MULTI);
8536 if (err) {
8537 state->idx = idx;
8538 break;
8539 }
8540 idx++;
8541 }
8542
8543 return err;
8544}
8545
8546const struct devlink_gen_cmd devl_gen_trap_group = {
8547 .dump_one = devlink_nl_cmd_trap_group_get_dump_one,
8548};
8549
8550static int
8551__devlink_trap_group_action_set(struct devlink *devlink,
8552 struct devlink_trap_group_item *group_item,
8553 enum devlink_trap_action trap_action,
8554 struct netlink_ext_ack *extack)
8555{
8556 const char *group_name = group_item->group->name;
8557 struct devlink_trap_item *trap_item;
8558 int err;
8559
8560 if (devlink->ops->trap_group_action_set) {
8561 err = devlink->ops->trap_group_action_set(devlink, group_item->group,
8562 trap_action, extack);
8563 if (err)
8564 return err;
8565
8566 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8567 if (strcmp(trap_item->group_item->group->name, group_name))
8568 continue;
8569 if (trap_item->action != trap_action &&
8570 trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
8571 continue;
8572 trap_item->action = trap_action;
8573 }
8574
8575 return 0;
8576 }
8577
8578 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8579 if (strcmp(trap_item->group_item->group->name, group_name))
8580 continue;
8581 err = __devlink_trap_action_set(devlink, trap_item,
8582 trap_action, extack);
8583 if (err)
8584 return err;
8585 }
8586
8587 return 0;
8588}
8589
8590static int
8591devlink_trap_group_action_set(struct devlink *devlink,
8592 struct devlink_trap_group_item *group_item,
8593 struct genl_info *info, bool *p_modified)
8594{
8595 enum devlink_trap_action trap_action;
8596 int err;
8597
8598 if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8599 return 0;
8600
8601 err = devlink_trap_action_get_from_info(info, &trap_action);
8602 if (err) {
8603 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8604 return -EINVAL;
8605 }
8606
8607 err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
8608 info->extack);
8609 if (err)
8610 return err;
8611
8612 *p_modified = true;
8613
8614 return 0;
8615}
8616
8617static int devlink_trap_group_set(struct devlink *devlink,
8618 struct devlink_trap_group_item *group_item,
8619 struct genl_info *info)
8620{
8621 struct devlink_trap_policer_item *policer_item;
8622 struct netlink_ext_ack *extack = info->extack;
8623 const struct devlink_trap_policer *policer;
8624 struct nlattr **attrs = info->attrs;
8625 u32 policer_id;
8626 int err;
8627
8628 if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8629 return 0;
8630
8631 if (!devlink->ops->trap_group_set)
8632 return -EOPNOTSUPP;
8633
8634 policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8635 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
8636 if (policer_id && !policer_item) {
8637 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8638 return -ENOENT;
8639 }
8640 policer = policer_item ? policer_item->policer : NULL;
8641
8642 err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
8643 extack);
8644 if (err)
8645 return err;
8646
8647 group_item->policer_item = policer_item;
8648
8649 return 0;
8650}
8651
8652static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
8653 struct genl_info *info)
8654{
8655 struct netlink_ext_ack *extack = info->extack;
8656 struct devlink *devlink = info->user_ptr[0];
8657 struct devlink_trap_group_item *group_item;
8658 bool modified = false;
8659 int err;
8660
8661 if (list_empty(&devlink->trap_group_list))
8662 return -EOPNOTSUPP;
8663
8664 group_item = devlink_trap_group_item_get_from_info(devlink, info);
8665 if (!group_item) {
8666 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8667 return -ENOENT;
8668 }
8669
8670 err = devlink_trap_group_action_set(devlink, group_item, info,
8671 &modified);
8672 if (err)
8673 return err;
8674
8675 err = devlink_trap_group_set(devlink, group_item, info);
8676 if (err)
8677 goto err_trap_group_set;
8678
8679 return 0;
8680
8681err_trap_group_set:
8682 if (modified)
8683 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
8684 return err;
8685}
8686
8687static struct devlink_trap_policer_item *
8688devlink_trap_policer_item_get_from_info(struct devlink *devlink,
8689 struct genl_info *info)
8690{
8691 u32 id;
8692
8693 if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8694 return NULL;
8695 id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8696
8697 return devlink_trap_policer_item_lookup(devlink, id);
8698}
8699
8700static int
8701devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
8702 const struct devlink_trap_policer *policer)
8703{
8704 struct nlattr *attr;
8705 u64 drops;
8706 int err;
8707
8708 if (!devlink->ops->trap_policer_counter_get)
8709 return 0;
8710
8711 err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
8712 if (err)
8713 return err;
8714
8715 attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8716 if (!attr)
8717 return -EMSGSIZE;
8718
8719 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8720 DEVLINK_ATTR_PAD))
8721 goto nla_put_failure;
8722
8723 nla_nest_end(msg, attr);
8724
8725 return 0;
8726
8727nla_put_failure:
8728 nla_nest_cancel(msg, attr);
8729 return -EMSGSIZE;
8730}
8731
8732static int
8733devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
8734 const struct devlink_trap_policer_item *policer_item,
8735 enum devlink_command cmd, u32 portid, u32 seq,
8736 int flags)
8737{
8738 void *hdr;
8739 int err;
8740
8741 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8742 if (!hdr)
8743 return -EMSGSIZE;
8744
8745 if (devlink_nl_put_handle(msg, devlink))
8746 goto nla_put_failure;
8747
8748 if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8749 policer_item->policer->id))
8750 goto nla_put_failure;
8751
8752 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
8753 policer_item->rate, DEVLINK_ATTR_PAD))
8754 goto nla_put_failure;
8755
8756 if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
8757 policer_item->burst, DEVLINK_ATTR_PAD))
8758 goto nla_put_failure;
8759
8760 err = devlink_trap_policer_stats_put(msg, devlink,
8761 policer_item->policer);
8762 if (err)
8763 goto nla_put_failure;
8764
8765 genlmsg_end(msg, hdr);
8766
8767 return 0;
8768
8769nla_put_failure:
8770 genlmsg_cancel(msg, hdr);
8771 return -EMSGSIZE;
8772}
8773
8774static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
8775 struct genl_info *info)
8776{
8777 struct devlink_trap_policer_item *policer_item;
8778 struct netlink_ext_ack *extack = info->extack;
8779 struct devlink *devlink = info->user_ptr[0];
8780 struct sk_buff *msg;
8781 int err;
8782
8783 if (list_empty(&devlink->trap_policer_list))
8784 return -EOPNOTSUPP;
8785
8786 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8787 if (!policer_item) {
8788 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8789 return -ENOENT;
8790 }
8791
8792 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8793 if (!msg)
8794 return -ENOMEM;
8795
8796 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
8797 DEVLINK_CMD_TRAP_POLICER_NEW,
8798 info->snd_portid, info->snd_seq, 0);
8799 if (err)
8800 goto err_trap_policer_fill;
8801
8802 return genlmsg_reply(msg, info);
8803
8804err_trap_policer_fill:
8805 nlmsg_free(msg);
8806 return err;
8807}
8808
8809static int
8810devlink_nl_cmd_trap_policer_get_dump_one(struct sk_buff *msg,
8811 struct devlink *devlink,
8812 struct netlink_callback *cb)
8813{
8814 struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8815 struct devlink_trap_policer_item *policer_item;
8816 int idx = 0;
8817 int err = 0;
8818
8819 list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
8820 if (idx < state->idx) {
8821 idx++;
8822 continue;
8823 }
8824 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
8825 DEVLINK_CMD_TRAP_POLICER_NEW,
8826 NETLINK_CB(cb->skb).portid,
8827 cb->nlh->nlmsg_seq,
8828 NLM_F_MULTI);
8829 if (err) {
8830 state->idx = idx;
8831 break;
8832 }
8833 idx++;
8834 }
8835
8836 return err;
8837}
8838
8839const struct devlink_gen_cmd devl_gen_trap_policer = {
8840 .dump_one = devlink_nl_cmd_trap_policer_get_dump_one,
8841};
8842
8843static int
8844devlink_trap_policer_set(struct devlink *devlink,
8845 struct devlink_trap_policer_item *policer_item,
8846 struct genl_info *info)
8847{
8848 struct netlink_ext_ack *extack = info->extack;
8849 struct nlattr **attrs = info->attrs;
8850 u64 rate, burst;
8851 int err;
8852
8853 rate = policer_item->rate;
8854 burst = policer_item->burst;
8855
8856 if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
8857 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
8858
8859 if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
8860 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
8861
8862 if (rate < policer_item->policer->min_rate) {
8863 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
8864 return -EINVAL;
8865 }
8866
8867 if (rate > policer_item->policer->max_rate) {
8868 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
8869 return -EINVAL;
8870 }
8871
8872 if (burst < policer_item->policer->min_burst) {
8873 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
8874 return -EINVAL;
8875 }
8876
8877 if (burst > policer_item->policer->max_burst) {
8878 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
8879 return -EINVAL;
8880 }
8881
8882 err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
8883 rate, burst, info->extack);
8884 if (err)
8885 return err;
8886
8887 policer_item->rate = rate;
8888 policer_item->burst = burst;
8889
8890 return 0;
8891}
8892
8893static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
8894 struct genl_info *info)
8895{
8896 struct devlink_trap_policer_item *policer_item;
8897 struct netlink_ext_ack *extack = info->extack;
8898 struct devlink *devlink = info->user_ptr[0];
8899
8900 if (list_empty(&devlink->trap_policer_list))
8901 return -EOPNOTSUPP;
8902
8903 if (!devlink->ops->trap_policer_set)
8904 return -EOPNOTSUPP;
8905
8906 policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8907 if (!policer_item) {
8908 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8909 return -ENOENT;
8910 }
8911
8912 return devlink_trap_policer_set(devlink, policer_item, info);
8913}
8914
8915const struct genl_small_ops devlink_nl_ops[56] = {
8916 {
8917 .cmd = DEVLINK_CMD_GET,
8918 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8919 .doit = devlink_nl_cmd_get_doit,
8920 .dumpit = devlink_nl_instance_iter_dump,
8921 /* can be retrieved by unprivileged users */
8922 },
8923 {
8924 .cmd = DEVLINK_CMD_PORT_GET,
8925 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8926 .doit = devlink_nl_cmd_port_get_doit,
8927 .dumpit = devlink_nl_instance_iter_dump,
8928 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8929 /* can be retrieved by unprivileged users */
8930 },
8931 {
8932 .cmd = DEVLINK_CMD_PORT_SET,
8933 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8934 .doit = devlink_nl_cmd_port_set_doit,
8935 .flags = GENL_ADMIN_PERM,
8936 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8937 },
8938 {
8939 .cmd = DEVLINK_CMD_RATE_GET,
8940 .doit = devlink_nl_cmd_rate_get_doit,
8941 .dumpit = devlink_nl_instance_iter_dump,
8942 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
8943 /* can be retrieved by unprivileged users */
8944 },
8945 {
8946 .cmd = DEVLINK_CMD_RATE_SET,
8947 .doit = devlink_nl_cmd_rate_set_doit,
8948 .flags = GENL_ADMIN_PERM,
8949 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
8950 },
8951 {
8952 .cmd = DEVLINK_CMD_RATE_NEW,
8953 .doit = devlink_nl_cmd_rate_new_doit,
8954 .flags = GENL_ADMIN_PERM,
8955 },
8956 {
8957 .cmd = DEVLINK_CMD_RATE_DEL,
8958 .doit = devlink_nl_cmd_rate_del_doit,
8959 .flags = GENL_ADMIN_PERM,
8960 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE,
8961 },
8962 {
8963 .cmd = DEVLINK_CMD_PORT_SPLIT,
8964 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8965 .doit = devlink_nl_cmd_port_split_doit,
8966 .flags = GENL_ADMIN_PERM,
8967 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8968 },
8969 {
8970 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
8971 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8972 .doit = devlink_nl_cmd_port_unsplit_doit,
8973 .flags = GENL_ADMIN_PERM,
8974 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8975 },
8976 {
8977 .cmd = DEVLINK_CMD_PORT_NEW,
8978 .doit = devlink_nl_cmd_port_new_doit,
8979 .flags = GENL_ADMIN_PERM,
8980 },
8981 {
8982 .cmd = DEVLINK_CMD_PORT_DEL,
8983 .doit = devlink_nl_cmd_port_del_doit,
8984 .flags = GENL_ADMIN_PERM,
8985 },
8986 {
8987 .cmd = DEVLINK_CMD_LINECARD_GET,
8988 .doit = devlink_nl_cmd_linecard_get_doit,
8989 .dumpit = devlink_nl_instance_iter_dump,
8990 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
8991 /* can be retrieved by unprivileged users */
8992 },
8993 {
8994 .cmd = DEVLINK_CMD_LINECARD_SET,
8995 .doit = devlink_nl_cmd_linecard_set_doit,
8996 .flags = GENL_ADMIN_PERM,
8997 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
8998 },
8999 {
9000 .cmd = DEVLINK_CMD_SB_GET,
9001 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9002 .doit = devlink_nl_cmd_sb_get_doit,
9003 .dumpit = devlink_nl_instance_iter_dump,
9004 /* can be retrieved by unprivileged users */
9005 },
9006 {
9007 .cmd = DEVLINK_CMD_SB_POOL_GET,
9008 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9009 .doit = devlink_nl_cmd_sb_pool_get_doit,
9010 .dumpit = devlink_nl_instance_iter_dump,
9011 /* can be retrieved by unprivileged users */
9012 },
9013 {
9014 .cmd = DEVLINK_CMD_SB_POOL_SET,
9015 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9016 .doit = devlink_nl_cmd_sb_pool_set_doit,
9017 .flags = GENL_ADMIN_PERM,
9018 },
9019 {
9020 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
9021 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9022 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
9023 .dumpit = devlink_nl_instance_iter_dump,
9024 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9025 /* can be retrieved by unprivileged users */
9026 },
9027 {
9028 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
9029 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9030 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
9031 .flags = GENL_ADMIN_PERM,
9032 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9033 },
9034 {
9035 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
9036 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9037 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
9038 .dumpit = devlink_nl_instance_iter_dump,
9039 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9040 /* can be retrieved by unprivileged users */
9041 },
9042 {
9043 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
9044 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9045 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
9046 .flags = GENL_ADMIN_PERM,
9047 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9048 },
9049 {
9050 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
9051 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9052 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
9053 .flags = GENL_ADMIN_PERM,
9054 },
9055 {
9056 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
9057 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9058 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
9059 .flags = GENL_ADMIN_PERM,
9060 },
9061 {
9062 .cmd = DEVLINK_CMD_ESWITCH_GET,
9063 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9064 .doit = devlink_nl_cmd_eswitch_get_doit,
9065 .flags = GENL_ADMIN_PERM,
9066 },
9067 {
9068 .cmd = DEVLINK_CMD_ESWITCH_SET,
9069 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9070 .doit = devlink_nl_cmd_eswitch_set_doit,
9071 .flags = GENL_ADMIN_PERM,
9072 },
9073 {
9074 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
9075 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9076 .doit = devlink_nl_cmd_dpipe_table_get,
9077 /* can be retrieved by unprivileged users */
9078 },
9079 {
9080 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
9081 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9082 .doit = devlink_nl_cmd_dpipe_entries_get,
9083 /* can be retrieved by unprivileged users */
9084 },
9085 {
9086 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
9087 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9088 .doit = devlink_nl_cmd_dpipe_headers_get,
9089 /* can be retrieved by unprivileged users */
9090 },
9091 {
9092 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
9093 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9094 .doit = devlink_nl_cmd_dpipe_table_counters_set,
9095 .flags = GENL_ADMIN_PERM,
9096 },
9097 {
9098 .cmd = DEVLINK_CMD_RESOURCE_SET,
9099 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9100 .doit = devlink_nl_cmd_resource_set,
9101 .flags = GENL_ADMIN_PERM,
9102 },
9103 {
9104 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
9105 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9106 .doit = devlink_nl_cmd_resource_dump,
9107 /* can be retrieved by unprivileged users */
9108 },
9109 {
9110 .cmd = DEVLINK_CMD_RELOAD,
9111 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9112 .doit = devlink_nl_cmd_reload,
9113 .flags = GENL_ADMIN_PERM,
9114 },
9115 {
9116 .cmd = DEVLINK_CMD_PARAM_GET,
9117 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9118 .doit = devlink_nl_cmd_param_get_doit,
9119 .dumpit = devlink_nl_instance_iter_dump,
9120 /* can be retrieved by unprivileged users */
9121 },
9122 {
9123 .cmd = DEVLINK_CMD_PARAM_SET,
9124 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9125 .doit = devlink_nl_cmd_param_set_doit,
9126 .flags = GENL_ADMIN_PERM,
9127 },
9128 {
9129 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
9130 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9131 .doit = devlink_nl_cmd_port_param_get_doit,
9132 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
9133 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9134 /* can be retrieved by unprivileged users */
9135 },
9136 {
9137 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
9138 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9139 .doit = devlink_nl_cmd_port_param_set_doit,
9140 .flags = GENL_ADMIN_PERM,
9141 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9142 },
9143 {
9144 .cmd = DEVLINK_CMD_REGION_GET,
9145 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9146 .doit = devlink_nl_cmd_region_get_doit,
9147 .dumpit = devlink_nl_instance_iter_dump,
9148 .flags = GENL_ADMIN_PERM,
9149 },
9150 {
9151 .cmd = DEVLINK_CMD_REGION_NEW,
9152 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9153 .doit = devlink_nl_cmd_region_new,
9154 .flags = GENL_ADMIN_PERM,
9155 },
9156 {
9157 .cmd = DEVLINK_CMD_REGION_DEL,
9158 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9159 .doit = devlink_nl_cmd_region_del,
9160 .flags = GENL_ADMIN_PERM,
9161 },
9162 {
9163 .cmd = DEVLINK_CMD_REGION_READ,
9164 .validate = GENL_DONT_VALIDATE_STRICT |
9165 GENL_DONT_VALIDATE_DUMP_STRICT,
9166 .dumpit = devlink_nl_cmd_region_read_dumpit,
9167 .flags = GENL_ADMIN_PERM,
9168 },
9169 {
9170 .cmd = DEVLINK_CMD_INFO_GET,
9171 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9172 .doit = devlink_nl_cmd_info_get_doit,
9173 .dumpit = devlink_nl_instance_iter_dump,
9174 /* can be retrieved by unprivileged users */
9175 },
9176 {
9177 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
9178 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9179 .doit = devlink_nl_cmd_health_reporter_get_doit,
9180 .dumpit = devlink_nl_instance_iter_dump,
9181 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9182 /* can be retrieved by unprivileged users */
9183 },
9184 {
9185 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
9186 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9187 .doit = devlink_nl_cmd_health_reporter_set_doit,
9188 .flags = GENL_ADMIN_PERM,
9189 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9190 },
9191 {
9192 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
9193 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9194 .doit = devlink_nl_cmd_health_reporter_recover_doit,
9195 .flags = GENL_ADMIN_PERM,
9196 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9197 },
9198 {
9199 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
9200 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9201 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
9202 .flags = GENL_ADMIN_PERM,
9203 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9204 },
9205 {
9206 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
9207 .validate = GENL_DONT_VALIDATE_STRICT |
9208 GENL_DONT_VALIDATE_DUMP_STRICT,
9209 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
9210 .flags = GENL_ADMIN_PERM,
9211 },
9212 {
9213 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
9214 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9215 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
9216 .flags = GENL_ADMIN_PERM,
9217 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9218 },
9219 {
9220 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
9221 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9222 .doit = devlink_nl_cmd_health_reporter_test_doit,
9223 .flags = GENL_ADMIN_PERM,
9224 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9225 },
9226 {
9227 .cmd = DEVLINK_CMD_FLASH_UPDATE,
9228 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9229 .doit = devlink_nl_cmd_flash_update,
9230 .flags = GENL_ADMIN_PERM,
9231 },
9232 {
9233 .cmd = DEVLINK_CMD_TRAP_GET,
9234 .doit = devlink_nl_cmd_trap_get_doit,
9235 .dumpit = devlink_nl_instance_iter_dump,
9236 /* can be retrieved by unprivileged users */
9237 },
9238 {
9239 .cmd = DEVLINK_CMD_TRAP_SET,
9240 .doit = devlink_nl_cmd_trap_set_doit,
9241 .flags = GENL_ADMIN_PERM,
9242 },
9243 {
9244 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
9245 .doit = devlink_nl_cmd_trap_group_get_doit,
9246 .dumpit = devlink_nl_instance_iter_dump,
9247 /* can be retrieved by unprivileged users */
9248 },
9249 {
9250 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
9251 .doit = devlink_nl_cmd_trap_group_set_doit,
9252 .flags = GENL_ADMIN_PERM,
9253 },
9254 {
9255 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
9256 .doit = devlink_nl_cmd_trap_policer_get_doit,
9257 .dumpit = devlink_nl_instance_iter_dump,
9258 /* can be retrieved by unprivileged users */
9259 },
9260 {
9261 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
9262 .doit = devlink_nl_cmd_trap_policer_set_doit,
9263 .flags = GENL_ADMIN_PERM,
9264 },
9265 {
9266 .cmd = DEVLINK_CMD_SELFTESTS_GET,
9267 .doit = devlink_nl_cmd_selftests_get_doit,
9268 .dumpit = devlink_nl_instance_iter_dump,
9269 /* can be retrieved by unprivileged users */
9270 },
9271 {
9272 .cmd = DEVLINK_CMD_SELFTESTS_RUN,
9273 .doit = devlink_nl_cmd_selftests_run,
9274 .flags = GENL_ADMIN_PERM,
9275 },
9276 /* -- No new ops here! Use split ops going forward! -- */
9277};
9278
9279bool devlink_reload_actions_valid(const struct devlink_ops *ops)
9280{
9281 const struct devlink_reload_combination *comb;
9282 int i;
9283
9284 if (!devlink_reload_supported(ops)) {
9285 if (WARN_ON(ops->reload_actions))
9286 return false;
9287 return true;
9288 }
9289
9290 if (WARN_ON(!ops->reload_actions ||
9291 ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
9292 ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
9293 return false;
9294
9295 if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
9296 ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
9297 return false;
9298
9299 for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++) {
9300 comb = &devlink_reload_invalid_combinations[i];
9301 if (ops->reload_actions == BIT(comb->action) &&
9302 ops->reload_limits == BIT(comb->limit))
9303 return false;
9304 }
9305 return true;
9306}
9307
9308static void
9309devlink_trap_policer_notify(struct devlink *devlink,
9310 const struct devlink_trap_policer_item *policer_item,
9311 enum devlink_command cmd);
9312static void
9313devlink_trap_group_notify(struct devlink *devlink,
9314 const struct devlink_trap_group_item *group_item,
9315 enum devlink_command cmd);
9316static void devlink_trap_notify(struct devlink *devlink,
9317 const struct devlink_trap_item *trap_item,
9318 enum devlink_command cmd);
9319
9320void devlink_notify_register(struct devlink *devlink)
9321{
9322 struct devlink_trap_policer_item *policer_item;
9323 struct devlink_trap_group_item *group_item;
9324 struct devlink_param_item *param_item;
9325 struct devlink_trap_item *trap_item;
9326 struct devlink_port *devlink_port;
9327 struct devlink_linecard *linecard;
9328 struct devlink_rate *rate_node;
9329 struct devlink_region *region;
9330 unsigned long port_index;
9331
9332 devlink_notify(devlink, DEVLINK_CMD_NEW);
9333 list_for_each_entry(linecard, &devlink->linecard_list, list)
9334 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
9335
9336 xa_for_each(&devlink->ports, port_index, devlink_port)
9337 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9338
9339 list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
9340 devlink_trap_policer_notify(devlink, policer_item,
9341 DEVLINK_CMD_TRAP_POLICER_NEW);
9342
9343 list_for_each_entry(group_item, &devlink->trap_group_list, list)
9344 devlink_trap_group_notify(devlink, group_item,
9345 DEVLINK_CMD_TRAP_GROUP_NEW);
9346
9347 list_for_each_entry(trap_item, &devlink->trap_list, list)
9348 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
9349
9350 list_for_each_entry(rate_node, &devlink->rate_list, list)
9351 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
9352
9353 list_for_each_entry(region, &devlink->region_list, list)
9354 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9355
9356 list_for_each_entry(param_item, &devlink->param_list, list)
9357 devlink_param_notify(devlink, 0, param_item,
9358 DEVLINK_CMD_PARAM_NEW);
9359}
9360
9361void devlink_notify_unregister(struct devlink *devlink)
9362{
9363 struct devlink_trap_policer_item *policer_item;
9364 struct devlink_trap_group_item *group_item;
9365 struct devlink_param_item *param_item;
9366 struct devlink_trap_item *trap_item;
9367 struct devlink_port *devlink_port;
9368 struct devlink_rate *rate_node;
9369 struct devlink_region *region;
9370 unsigned long port_index;
9371
9372 list_for_each_entry_reverse(param_item, &devlink->param_list, list)
9373 devlink_param_notify(devlink, 0, param_item,
9374 DEVLINK_CMD_PARAM_DEL);
9375
9376 list_for_each_entry_reverse(region, &devlink->region_list, list)
9377 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
9378
9379 list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
9380 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
9381
9382 list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
9383 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
9384
9385 list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
9386 devlink_trap_group_notify(devlink, group_item,
9387 DEVLINK_CMD_TRAP_GROUP_DEL);
9388 list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
9389 list)
9390 devlink_trap_policer_notify(devlink, policer_item,
9391 DEVLINK_CMD_TRAP_POLICER_DEL);
9392
9393 xa_for_each(&devlink->ports, port_index, devlink_port)
9394 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9395 devlink_notify(devlink, DEVLINK_CMD_DEL);
9396}
9397
9398static void devlink_port_type_warn(struct work_struct *work)
9399{
9400 WARN(true, "Type was not set for devlink port.");
9401}
9402
9403static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
9404{
9405 /* Ignore CPU and DSA flavours. */
9406 return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
9407 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
9408 devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
9409}
9410
9411#define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
9412
9413static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
9414{
9415 if (!devlink_port_type_should_warn(devlink_port))
9416 return;
9417 /* Schedule a work to WARN in case driver does not set port
9418 * type within timeout.
9419 */
9420 schedule_delayed_work(&devlink_port->type_warn_dw,
9421 DEVLINK_PORT_TYPE_WARN_TIMEOUT);
9422}
9423
9424static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
9425{
9426 if (!devlink_port_type_should_warn(devlink_port))
9427 return;
9428 cancel_delayed_work_sync(&devlink_port->type_warn_dw);
9429}
9430
9431/**
9432 * devlink_port_init() - Init devlink port
9433 *
9434 * @devlink: devlink
9435 * @devlink_port: devlink port
9436 *
9437 * Initialize essencial stuff that is needed for functions
9438 * that may be called before devlink port registration.
9439 * Call to this function is optional and not needed
9440 * in case the driver does not use such functions.
9441 */
9442void devlink_port_init(struct devlink *devlink,
9443 struct devlink_port *devlink_port)
9444{
9445 if (devlink_port->initialized)
9446 return;
9447 devlink_port->devlink = devlink;
9448 INIT_LIST_HEAD(&devlink_port->region_list);
9449 devlink_port->initialized = true;
9450}
9451EXPORT_SYMBOL_GPL(devlink_port_init);
9452
9453/**
9454 * devlink_port_fini() - Deinitialize devlink port
9455 *
9456 * @devlink_port: devlink port
9457 *
9458 * Deinitialize essencial stuff that is in use for functions
9459 * that may be called after devlink port unregistration.
9460 * Call to this function is optional and not needed
9461 * in case the driver does not use such functions.
9462 */
9463void devlink_port_fini(struct devlink_port *devlink_port)
9464{
9465 WARN_ON(!list_empty(&devlink_port->region_list));
9466}
9467EXPORT_SYMBOL_GPL(devlink_port_fini);
9468
9469/**
9470 * devl_port_register() - Register devlink port
9471 *
9472 * @devlink: devlink
9473 * @devlink_port: devlink port
9474 * @port_index: driver-specific numerical identifier of the port
9475 *
9476 * Register devlink port with provided port index. User can use
9477 * any indexing, even hw-related one. devlink_port structure
9478 * is convenient to be embedded inside user driver private structure.
9479 * Note that the caller should take care of zeroing the devlink_port
9480 * structure.
9481 */
9482int devl_port_register(struct devlink *devlink,
9483 struct devlink_port *devlink_port,
9484 unsigned int port_index)
9485{
9486 int err;
9487
9488 devl_assert_locked(devlink);
9489
9490 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9491
9492 devlink_port_init(devlink, devlink_port);
9493 devlink_port->registered = true;
9494 devlink_port->index = port_index;
9495 spin_lock_init(&devlink_port->type_lock);
9496 INIT_LIST_HEAD(&devlink_port->reporter_list);
9497 err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL);
9498 if (err)
9499 return err;
9500
9501 INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
9502 devlink_port_type_warn_schedule(devlink_port);
9503 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9504 return 0;
9505}
9506EXPORT_SYMBOL_GPL(devl_port_register);
9507
9508/**
9509 * devlink_port_register - Register devlink port
9510 *
9511 * @devlink: devlink
9512 * @devlink_port: devlink port
9513 * @port_index: driver-specific numerical identifier of the port
9514 *
9515 * Register devlink port with provided port index. User can use
9516 * any indexing, even hw-related one. devlink_port structure
9517 * is convenient to be embedded inside user driver private structure.
9518 * Note that the caller should take care of zeroing the devlink_port
9519 * structure.
9520 *
9521 * Context: Takes and release devlink->lock <mutex>.
9522 */
9523int devlink_port_register(struct devlink *devlink,
9524 struct devlink_port *devlink_port,
9525 unsigned int port_index)
9526{
9527 int err;
9528
9529 devl_lock(devlink);
9530 err = devl_port_register(devlink, devlink_port, port_index);
9531 devl_unlock(devlink);
9532 return err;
9533}
9534EXPORT_SYMBOL_GPL(devlink_port_register);
9535
9536/**
9537 * devl_port_unregister() - Unregister devlink port
9538 *
9539 * @devlink_port: devlink port
9540 */
9541void devl_port_unregister(struct devlink_port *devlink_port)
9542{
9543 lockdep_assert_held(&devlink_port->devlink->lock);
9544 WARN_ON(devlink_port->type != DEVLINK_PORT_TYPE_NOTSET);
9545
9546 devlink_port_type_warn_cancel(devlink_port);
9547 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9548 xa_erase(&devlink_port->devlink->ports, devlink_port->index);
9549 WARN_ON(!list_empty(&devlink_port->reporter_list));
9550 devlink_port->registered = false;
9551}
9552EXPORT_SYMBOL_GPL(devl_port_unregister);
9553
9554/**
9555 * devlink_port_unregister - Unregister devlink port
9556 *
9557 * @devlink_port: devlink port
9558 *
9559 * Context: Takes and release devlink->lock <mutex>.
9560 */
9561void devlink_port_unregister(struct devlink_port *devlink_port)
9562{
9563 struct devlink *devlink = devlink_port->devlink;
9564
9565 devl_lock(devlink);
9566 devl_port_unregister(devlink_port);
9567 devl_unlock(devlink);
9568}
9569EXPORT_SYMBOL_GPL(devlink_port_unregister);
9570
9571static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
9572 struct net_device *netdev)
9573{
9574 const struct net_device_ops *ops = netdev->netdev_ops;
9575
9576 /* If driver registers devlink port, it should set devlink port
9577 * attributes accordingly so the compat functions are called
9578 * and the original ops are not used.
9579 */
9580 if (ops->ndo_get_phys_port_name) {
9581 /* Some drivers use the same set of ndos for netdevs
9582 * that have devlink_port registered and also for
9583 * those who don't. Make sure that ndo_get_phys_port_name
9584 * returns -EOPNOTSUPP here in case it is defined.
9585 * Warn if not.
9586 */
9587 char name[IFNAMSIZ];
9588 int err;
9589
9590 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
9591 WARN_ON(err != -EOPNOTSUPP);
9592 }
9593 if (ops->ndo_get_port_parent_id) {
9594 /* Some drivers use the same set of ndos for netdevs
9595 * that have devlink_port registered and also for
9596 * those who don't. Make sure that ndo_get_port_parent_id
9597 * returns -EOPNOTSUPP here in case it is defined.
9598 * Warn if not.
9599 */
9600 struct netdev_phys_item_id ppid;
9601 int err;
9602
9603 err = ops->ndo_get_port_parent_id(netdev, &ppid);
9604 WARN_ON(err != -EOPNOTSUPP);
9605 }
9606}
9607
9608static void __devlink_port_type_set(struct devlink_port *devlink_port,
9609 enum devlink_port_type type,
9610 void *type_dev)
9611{
9612 struct net_device *netdev = type_dev;
9613
9614 ASSERT_DEVLINK_PORT_REGISTERED(devlink_port);
9615
9616 if (type == DEVLINK_PORT_TYPE_NOTSET) {
9617 devlink_port_type_warn_schedule(devlink_port);
9618 } else {
9619 devlink_port_type_warn_cancel(devlink_port);
9620 if (type == DEVLINK_PORT_TYPE_ETH && netdev)
9621 devlink_port_type_netdev_checks(devlink_port, netdev);
9622 }
9623
9624 spin_lock_bh(&devlink_port->type_lock);
9625 devlink_port->type = type;
9626 switch (type) {
9627 case DEVLINK_PORT_TYPE_ETH:
9628 devlink_port->type_eth.netdev = netdev;
9629 if (netdev) {
9630 ASSERT_RTNL();
9631 devlink_port->type_eth.ifindex = netdev->ifindex;
9632 BUILD_BUG_ON(sizeof(devlink_port->type_eth.ifname) !=
9633 sizeof(netdev->name));
9634 strcpy(devlink_port->type_eth.ifname, netdev->name);
9635 }
9636 break;
9637 case DEVLINK_PORT_TYPE_IB:
9638 devlink_port->type_ib.ibdev = type_dev;
9639 break;
9640 default:
9641 break;
9642 }
9643 spin_unlock_bh(&devlink_port->type_lock);
9644 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9645}
9646
9647/**
9648 * devlink_port_type_eth_set - Set port type to Ethernet
9649 *
9650 * @devlink_port: devlink port
9651 *
9652 * If driver is calling this, most likely it is doing something wrong.
9653 */
9654void devlink_port_type_eth_set(struct devlink_port *devlink_port)
9655{
9656 dev_warn(devlink_port->devlink->dev,
9657 "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
9658 devlink_port->index);
9659 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL);
9660}
9661EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
9662
9663/**
9664 * devlink_port_type_ib_set - Set port type to InfiniBand
9665 *
9666 * @devlink_port: devlink port
9667 * @ibdev: related IB device
9668 */
9669void devlink_port_type_ib_set(struct devlink_port *devlink_port,
9670 struct ib_device *ibdev)
9671{
9672 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
9673}
9674EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
9675
9676/**
9677 * devlink_port_type_clear - Clear port type
9678 *
9679 * @devlink_port: devlink port
9680 *
9681 * If driver is calling this for clearing Ethernet type, most likely
9682 * it is doing something wrong.
9683 */
9684void devlink_port_type_clear(struct devlink_port *devlink_port)
9685{
9686 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH)
9687 dev_warn(devlink_port->devlink->dev,
9688 "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n",
9689 devlink_port->index);
9690 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
9691}
9692EXPORT_SYMBOL_GPL(devlink_port_type_clear);
9693
9694int devlink_port_netdevice_event(struct notifier_block *nb,
9695 unsigned long event, void *ptr)
9696{
9697 struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
9698 struct devlink_port *devlink_port = netdev->devlink_port;
9699 struct devlink *devlink;
9700
9701 devlink = container_of(nb, struct devlink, netdevice_nb);
9702
9703 if (!devlink_port || devlink_port->devlink != devlink)
9704 return NOTIFY_OK;
9705
9706 switch (event) {
9707 case NETDEV_POST_INIT:
9708 /* Set the type but not netdev pointer. It is going to be set
9709 * later on by NETDEV_REGISTER event. Happens once during
9710 * netdevice register
9711 */
9712 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH,
9713 NULL);
9714 break;
9715 case NETDEV_REGISTER:
9716 case NETDEV_CHANGENAME:
9717 /* Set the netdev on top of previously set type. Note this
9718 * event happens also during net namespace change so here
9719 * we take into account netdev pointer appearing in this
9720 * namespace.
9721 */
9722 __devlink_port_type_set(devlink_port, devlink_port->type,
9723 netdev);
9724 break;
9725 case NETDEV_UNREGISTER:
9726 /* Clear netdev pointer, but not the type. This event happens
9727 * also during net namespace change so we need to clear
9728 * pointer to netdev that is going to another net namespace.
9729 */
9730 __devlink_port_type_set(devlink_port, devlink_port->type,
9731 NULL);
9732 break;
9733 case NETDEV_PRE_UNINIT:
9734 /* Clear the type and the netdev pointer. Happens one during
9735 * netdevice unregister.
9736 */
9737 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET,
9738 NULL);
9739 break;
9740 }
9741
9742 return NOTIFY_OK;
9743}
9744
9745static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
9746 enum devlink_port_flavour flavour)
9747{
9748 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9749
9750 devlink_port->attrs_set = true;
9751 attrs->flavour = flavour;
9752 if (attrs->switch_id.id_len) {
9753 devlink_port->switch_port = true;
9754 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
9755 attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
9756 } else {
9757 devlink_port->switch_port = false;
9758 }
9759 return 0;
9760}
9761
9762/**
9763 * devlink_port_attrs_set - Set port attributes
9764 *
9765 * @devlink_port: devlink port
9766 * @attrs: devlink port attrs
9767 */
9768void devlink_port_attrs_set(struct devlink_port *devlink_port,
9769 struct devlink_port_attrs *attrs)
9770{
9771 int ret;
9772
9773 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9774
9775 devlink_port->attrs = *attrs;
9776 ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
9777 if (ret)
9778 return;
9779 WARN_ON(attrs->splittable && attrs->split);
9780}
9781EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
9782
9783/**
9784 * devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
9785 *
9786 * @devlink_port: devlink port
9787 * @controller: associated controller number for the devlink port instance
9788 * @pf: associated PF for the devlink port instance
9789 * @external: indicates if the port is for an external controller
9790 */
9791void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
9792 u16 pf, bool external)
9793{
9794 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9795 int ret;
9796
9797 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9798
9799 ret = __devlink_port_attrs_set(devlink_port,
9800 DEVLINK_PORT_FLAVOUR_PCI_PF);
9801 if (ret)
9802 return;
9803 attrs->pci_pf.controller = controller;
9804 attrs->pci_pf.pf = pf;
9805 attrs->pci_pf.external = external;
9806}
9807EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
9808
9809/**
9810 * devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
9811 *
9812 * @devlink_port: devlink port
9813 * @controller: associated controller number for the devlink port instance
9814 * @pf: associated PF for the devlink port instance
9815 * @vf: associated VF of a PF for the devlink port instance
9816 * @external: indicates if the port is for an external controller
9817 */
9818void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
9819 u16 pf, u16 vf, bool external)
9820{
9821 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9822 int ret;
9823
9824 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9825
9826 ret = __devlink_port_attrs_set(devlink_port,
9827 DEVLINK_PORT_FLAVOUR_PCI_VF);
9828 if (ret)
9829 return;
9830 attrs->pci_vf.controller = controller;
9831 attrs->pci_vf.pf = pf;
9832 attrs->pci_vf.vf = vf;
9833 attrs->pci_vf.external = external;
9834}
9835EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
9836
9837/**
9838 * devlink_port_attrs_pci_sf_set - Set PCI SF port attributes
9839 *
9840 * @devlink_port: devlink port
9841 * @controller: associated controller number for the devlink port instance
9842 * @pf: associated PF for the devlink port instance
9843 * @sf: associated SF of a PF for the devlink port instance
9844 * @external: indicates if the port is for an external controller
9845 */
9846void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller,
9847 u16 pf, u32 sf, bool external)
9848{
9849 struct devlink_port_attrs *attrs = &devlink_port->attrs;
9850 int ret;
9851
9852 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9853
9854 ret = __devlink_port_attrs_set(devlink_port,
9855 DEVLINK_PORT_FLAVOUR_PCI_SF);
9856 if (ret)
9857 return;
9858 attrs->pci_sf.controller = controller;
9859 attrs->pci_sf.pf = pf;
9860 attrs->pci_sf.sf = sf;
9861 attrs->pci_sf.external = external;
9862}
9863EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
9864
9865/**
9866 * devl_rate_node_create - create devlink rate node
9867 * @devlink: devlink instance
9868 * @priv: driver private data
9869 * @node_name: name of the resulting node
9870 * @parent: parent devlink_rate struct
9871 *
9872 * Create devlink rate object of type node
9873 */
9874struct devlink_rate *
9875devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
9876 struct devlink_rate *parent)
9877{
9878 struct devlink_rate *rate_node;
9879
9880 rate_node = devlink_rate_node_get_by_name(devlink, node_name);
9881 if (!IS_ERR(rate_node))
9882 return ERR_PTR(-EEXIST);
9883
9884 rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
9885 if (!rate_node)
9886 return ERR_PTR(-ENOMEM);
9887
9888 if (parent) {
9889 rate_node->parent = parent;
9890 refcount_inc(&rate_node->parent->refcnt);
9891 }
9892
9893 rate_node->type = DEVLINK_RATE_TYPE_NODE;
9894 rate_node->devlink = devlink;
9895 rate_node->priv = priv;
9896
9897 rate_node->name = kstrdup(node_name, GFP_KERNEL);
9898 if (!rate_node->name) {
9899 kfree(rate_node);
9900 return ERR_PTR(-ENOMEM);
9901 }
9902
9903 refcount_set(&rate_node->refcnt, 1);
9904 list_add(&rate_node->list, &devlink->rate_list);
9905 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
9906 return rate_node;
9907}
9908EXPORT_SYMBOL_GPL(devl_rate_node_create);
9909
9910/**
9911 * devl_rate_leaf_create - create devlink rate leaf
9912 * @devlink_port: devlink port object to create rate object on
9913 * @priv: driver private data
9914 * @parent: parent devlink_rate struct
9915 *
9916 * Create devlink rate object of type leaf on provided @devlink_port.
9917 */
9918int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv,
9919 struct devlink_rate *parent)
9920{
9921 struct devlink *devlink = devlink_port->devlink;
9922 struct devlink_rate *devlink_rate;
9923
9924 devl_assert_locked(devlink_port->devlink);
9925
9926 if (WARN_ON(devlink_port->devlink_rate))
9927 return -EBUSY;
9928
9929 devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL);
9930 if (!devlink_rate)
9931 return -ENOMEM;
9932
9933 if (parent) {
9934 devlink_rate->parent = parent;
9935 refcount_inc(&devlink_rate->parent->refcnt);
9936 }
9937
9938 devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
9939 devlink_rate->devlink = devlink;
9940 devlink_rate->devlink_port = devlink_port;
9941 devlink_rate->priv = priv;
9942 list_add_tail(&devlink_rate->list, &devlink->rate_list);
9943 devlink_port->devlink_rate = devlink_rate;
9944 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
9945
9946 return 0;
9947}
9948EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
9949
9950/**
9951 * devl_rate_leaf_destroy - destroy devlink rate leaf
9952 *
9953 * @devlink_port: devlink port linked to the rate object
9954 *
9955 * Destroy the devlink rate object of type leaf on provided @devlink_port.
9956 */
9957void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
9958{
9959 struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
9960
9961 devl_assert_locked(devlink_port->devlink);
9962 if (!devlink_rate)
9963 return;
9964
9965 devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
9966 if (devlink_rate->parent)
9967 refcount_dec(&devlink_rate->parent->refcnt);
9968 list_del(&devlink_rate->list);
9969 devlink_port->devlink_rate = NULL;
9970 kfree(devlink_rate);
9971}
9972EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
9973
9974/**
9975 * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
9976 * @devlink: devlink instance
9977 *
9978 * Unset parent for all rate objects and destroy all rate nodes
9979 * on specified device.
9980 */
9981void devl_rate_nodes_destroy(struct devlink *devlink)
9982{
9983 static struct devlink_rate *devlink_rate, *tmp;
9984 const struct devlink_ops *ops = devlink->ops;
9985
9986 devl_assert_locked(devlink);
9987
9988 list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
9989 if (!devlink_rate->parent)
9990 continue;
9991
9992 refcount_dec(&devlink_rate->parent->refcnt);
9993 if (devlink_rate_is_leaf(devlink_rate))
9994 ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
9995 NULL, NULL);
9996 else if (devlink_rate_is_node(devlink_rate))
9997 ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
9998 NULL, NULL);
9999 }
10000 list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
10001 if (devlink_rate_is_node(devlink_rate)) {
10002 ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
10003 list_del(&devlink_rate->list);
10004 kfree(devlink_rate->name);
10005 kfree(devlink_rate);
10006 }
10007 }
10008}
10009EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);
10010
10011/**
10012 * devlink_port_linecard_set - Link port with a linecard
10013 *
10014 * @devlink_port: devlink port
10015 * @linecard: devlink linecard
10016 */
10017void devlink_port_linecard_set(struct devlink_port *devlink_port,
10018 struct devlink_linecard *linecard)
10019{
10020 ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10021
10022 devlink_port->linecard = linecard;
10023}
10024EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
10025
10026static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
10027 char *name, size_t len)
10028{
10029 struct devlink_port_attrs *attrs = &devlink_port->attrs;
10030 int n = 0;
10031
10032 if (!devlink_port->attrs_set)
10033 return -EOPNOTSUPP;
10034
10035 switch (attrs->flavour) {
10036 case DEVLINK_PORT_FLAVOUR_PHYSICAL:
10037 if (devlink_port->linecard)
10038 n = snprintf(name, len, "l%u",
10039 devlink_port->linecard->index);
10040 if (n < len)
10041 n += snprintf(name + n, len - n, "p%u",
10042 attrs->phys.port_number);
10043 if (n < len && attrs->split)
10044 n += snprintf(name + n, len - n, "s%u",
10045 attrs->phys.split_subport_number);
10046 break;
10047 case DEVLINK_PORT_FLAVOUR_CPU:
10048 case DEVLINK_PORT_FLAVOUR_DSA:
10049 case DEVLINK_PORT_FLAVOUR_UNUSED:
10050 /* As CPU and DSA ports do not have a netdevice associated
10051 * case should not ever happen.
10052 */
10053 WARN_ON(1);
10054 return -EINVAL;
10055 case DEVLINK_PORT_FLAVOUR_PCI_PF:
10056 if (attrs->pci_pf.external) {
10057 n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
10058 if (n >= len)
10059 return -EINVAL;
10060 len -= n;
10061 name += n;
10062 }
10063 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
10064 break;
10065 case DEVLINK_PORT_FLAVOUR_PCI_VF:
10066 if (attrs->pci_vf.external) {
10067 n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
10068 if (n >= len)
10069 return -EINVAL;
10070 len -= n;
10071 name += n;
10072 }
10073 n = snprintf(name, len, "pf%uvf%u",
10074 attrs->pci_vf.pf, attrs->pci_vf.vf);
10075 break;
10076 case DEVLINK_PORT_FLAVOUR_PCI_SF:
10077 if (attrs->pci_sf.external) {
10078 n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
10079 if (n >= len)
10080 return -EINVAL;
10081 len -= n;
10082 name += n;
10083 }
10084 n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf,
10085 attrs->pci_sf.sf);
10086 break;
10087 case DEVLINK_PORT_FLAVOUR_VIRTUAL:
10088 return -EOPNOTSUPP;
10089 }
10090
10091 if (n >= len)
10092 return -EINVAL;
10093
10094 return 0;
10095}
10096
10097static int devlink_linecard_types_init(struct devlink_linecard *linecard)
10098{
10099 struct devlink_linecard_type *linecard_type;
10100 unsigned int count;
10101 int i;
10102
10103 count = linecard->ops->types_count(linecard, linecard->priv);
10104 linecard->types = kmalloc_array(count, sizeof(*linecard_type),
10105 GFP_KERNEL);
10106 if (!linecard->types)
10107 return -ENOMEM;
10108 linecard->types_count = count;
10109
10110 for (i = 0; i < count; i++) {
10111 linecard_type = &linecard->types[i];
10112 linecard->ops->types_get(linecard, linecard->priv, i,
10113 &linecard_type->type,
10114 &linecard_type->priv);
10115 }
10116 return 0;
10117}
10118
10119static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
10120{
10121 kfree(linecard->types);
10122}
10123
10124/**
10125 * devl_linecard_create - Create devlink linecard
10126 *
10127 * @devlink: devlink
10128 * @linecard_index: driver-specific numerical identifier of the linecard
10129 * @ops: linecards ops
10130 * @priv: user priv pointer
10131 *
10132 * Create devlink linecard instance with provided linecard index.
10133 * Caller can use any indexing, even hw-related one.
10134 *
10135 * Return: Line card structure or an ERR_PTR() encoded error code.
10136 */
10137struct devlink_linecard *
10138devl_linecard_create(struct devlink *devlink, unsigned int linecard_index,
10139 const struct devlink_linecard_ops *ops, void *priv)
10140{
10141 struct devlink_linecard *linecard;
10142 int err;
10143
10144 if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
10145 !ops->types_count || !ops->types_get))
10146 return ERR_PTR(-EINVAL);
10147
10148 if (devlink_linecard_index_exists(devlink, linecard_index))
10149 return ERR_PTR(-EEXIST);
10150
10151 linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
10152 if (!linecard)
10153 return ERR_PTR(-ENOMEM);
10154
10155 linecard->devlink = devlink;
10156 linecard->index = linecard_index;
10157 linecard->ops = ops;
10158 linecard->priv = priv;
10159 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10160 mutex_init(&linecard->state_lock);
10161
10162 err = devlink_linecard_types_init(linecard);
10163 if (err) {
10164 mutex_destroy(&linecard->state_lock);
10165 kfree(linecard);
10166 return ERR_PTR(err);
10167 }
10168
10169 list_add_tail(&linecard->list, &devlink->linecard_list);
10170 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10171 return linecard;
10172}
10173EXPORT_SYMBOL_GPL(devl_linecard_create);
10174
10175/**
10176 * devl_linecard_destroy - Destroy devlink linecard
10177 *
10178 * @linecard: devlink linecard
10179 */
10180void devl_linecard_destroy(struct devlink_linecard *linecard)
10181{
10182 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
10183 list_del(&linecard->list);
10184 devlink_linecard_types_fini(linecard);
10185 mutex_destroy(&linecard->state_lock);
10186 kfree(linecard);
10187}
10188EXPORT_SYMBOL_GPL(devl_linecard_destroy);
10189
10190/**
10191 * devlink_linecard_provision_set - Set provisioning on linecard
10192 *
10193 * @linecard: devlink linecard
10194 * @type: linecard type
10195 *
10196 * This is either called directly from the provision() op call or
10197 * as a result of the provision() op call asynchronously.
10198 */
10199void devlink_linecard_provision_set(struct devlink_linecard *linecard,
10200 const char *type)
10201{
10202 mutex_lock(&linecard->state_lock);
10203 WARN_ON(linecard->type && strcmp(linecard->type, type));
10204 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10205 linecard->type = type;
10206 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10207 mutex_unlock(&linecard->state_lock);
10208}
10209EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
10210
10211/**
10212 * devlink_linecard_provision_clear - Clear provisioning on linecard
10213 *
10214 * @linecard: devlink linecard
10215 *
10216 * This is either called directly from the unprovision() op call or
10217 * as a result of the unprovision() op call asynchronously.
10218 */
10219void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
10220{
10221 mutex_lock(&linecard->state_lock);
10222 WARN_ON(linecard->nested_devlink);
10223 linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10224 linecard->type = NULL;
10225 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10226 mutex_unlock(&linecard->state_lock);
10227}
10228EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
10229
10230/**
10231 * devlink_linecard_provision_fail - Fail provisioning on linecard
10232 *
10233 * @linecard: devlink linecard
10234 *
10235 * This is either called directly from the provision() op call or
10236 * as a result of the provision() op call asynchronously.
10237 */
10238void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
10239{
10240 mutex_lock(&linecard->state_lock);
10241 WARN_ON(linecard->nested_devlink);
10242 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
10243 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10244 mutex_unlock(&linecard->state_lock);
10245}
10246EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
10247
10248/**
10249 * devlink_linecard_activate - Set linecard active
10250 *
10251 * @linecard: devlink linecard
10252 */
10253void devlink_linecard_activate(struct devlink_linecard *linecard)
10254{
10255 mutex_lock(&linecard->state_lock);
10256 WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
10257 linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
10258 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10259 mutex_unlock(&linecard->state_lock);
10260}
10261EXPORT_SYMBOL_GPL(devlink_linecard_activate);
10262
10263/**
10264 * devlink_linecard_deactivate - Set linecard inactive
10265 *
10266 * @linecard: devlink linecard
10267 */
10268void devlink_linecard_deactivate(struct devlink_linecard *linecard)
10269{
10270 mutex_lock(&linecard->state_lock);
10271 switch (linecard->state) {
10272 case DEVLINK_LINECARD_STATE_ACTIVE:
10273 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10274 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10275 break;
10276 case DEVLINK_LINECARD_STATE_UNPROVISIONING:
10277 /* Line card is being deactivated as part
10278 * of unprovisioning flow.
10279 */
10280 break;
10281 default:
10282 WARN_ON(1);
10283 break;
10284 }
10285 mutex_unlock(&linecard->state_lock);
10286}
10287EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
10288
10289/**
10290 * devlink_linecard_nested_dl_set - Attach/detach nested devlink
10291 * instance to linecard.
10292 *
10293 * @linecard: devlink linecard
10294 * @nested_devlink: devlink instance to attach or NULL to detach
10295 */
10296void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
10297 struct devlink *nested_devlink)
10298{
10299 mutex_lock(&linecard->state_lock);
10300 linecard->nested_devlink = nested_devlink;
10301 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10302 mutex_unlock(&linecard->state_lock);
10303}
10304EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
10305
10306int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
10307 u32 size, u16 ingress_pools_count,
10308 u16 egress_pools_count, u16 ingress_tc_count,
10309 u16 egress_tc_count)
10310{
10311 struct devlink_sb *devlink_sb;
10312
10313 lockdep_assert_held(&devlink->lock);
10314
10315 if (devlink_sb_index_exists(devlink, sb_index))
10316 return -EEXIST;
10317
10318 devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
10319 if (!devlink_sb)
10320 return -ENOMEM;
10321 devlink_sb->index = sb_index;
10322 devlink_sb->size = size;
10323 devlink_sb->ingress_pools_count = ingress_pools_count;
10324 devlink_sb->egress_pools_count = egress_pools_count;
10325 devlink_sb->ingress_tc_count = ingress_tc_count;
10326 devlink_sb->egress_tc_count = egress_tc_count;
10327 list_add_tail(&devlink_sb->list, &devlink->sb_list);
10328 return 0;
10329}
10330EXPORT_SYMBOL_GPL(devl_sb_register);
10331
10332int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
10333 u32 size, u16 ingress_pools_count,
10334 u16 egress_pools_count, u16 ingress_tc_count,
10335 u16 egress_tc_count)
10336{
10337 int err;
10338
10339 devl_lock(devlink);
10340 err = devl_sb_register(devlink, sb_index, size, ingress_pools_count,
10341 egress_pools_count, ingress_tc_count,
10342 egress_tc_count);
10343 devl_unlock(devlink);
10344 return err;
10345}
10346EXPORT_SYMBOL_GPL(devlink_sb_register);
10347
10348void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10349{
10350 struct devlink_sb *devlink_sb;
10351
10352 lockdep_assert_held(&devlink->lock);
10353
10354 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
10355 WARN_ON(!devlink_sb);
10356 list_del(&devlink_sb->list);
10357 kfree(devlink_sb);
10358}
10359EXPORT_SYMBOL_GPL(devl_sb_unregister);
10360
10361void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10362{
10363 devl_lock(devlink);
10364 devl_sb_unregister(devlink, sb_index);
10365 devl_unlock(devlink);
10366}
10367EXPORT_SYMBOL_GPL(devlink_sb_unregister);
10368
10369/**
10370 * devl_dpipe_headers_register - register dpipe headers
10371 *
10372 * @devlink: devlink
10373 * @dpipe_headers: dpipe header array
10374 *
10375 * Register the headers supported by hardware.
10376 */
10377void devl_dpipe_headers_register(struct devlink *devlink,
10378 struct devlink_dpipe_headers *dpipe_headers)
10379{
10380 lockdep_assert_held(&devlink->lock);
10381
10382 devlink->dpipe_headers = dpipe_headers;
10383}
10384EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
10385
10386/**
10387 * devl_dpipe_headers_unregister - unregister dpipe headers
10388 *
10389 * @devlink: devlink
10390 *
10391 * Unregister the headers supported by hardware.
10392 */
10393void devl_dpipe_headers_unregister(struct devlink *devlink)
10394{
10395 lockdep_assert_held(&devlink->lock);
10396
10397 devlink->dpipe_headers = NULL;
10398}
10399EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
10400
10401/**
10402 * devlink_dpipe_table_counter_enabled - check if counter allocation
10403 * required
10404 * @devlink: devlink
10405 * @table_name: tables name
10406 *
10407 * Used by driver to check if counter allocation is required.
10408 * After counter allocation is turned on the table entries
10409 * are updated to include counter statistics.
10410 *
10411 * After that point on the driver must respect the counter
10412 * state so that each entry added to the table is added
10413 * with a counter.
10414 */
10415bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
10416 const char *table_name)
10417{
10418 struct devlink_dpipe_table *table;
10419 bool enabled;
10420
10421 rcu_read_lock();
10422 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10423 table_name, devlink);
10424 enabled = false;
10425 if (table)
10426 enabled = table->counters_enabled;
10427 rcu_read_unlock();
10428 return enabled;
10429}
10430EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
10431
10432/**
10433 * devl_dpipe_table_register - register dpipe table
10434 *
10435 * @devlink: devlink
10436 * @table_name: table name
10437 * @table_ops: table ops
10438 * @priv: priv
10439 * @counter_control_extern: external control for counters
10440 */
10441int devl_dpipe_table_register(struct devlink *devlink,
10442 const char *table_name,
10443 struct devlink_dpipe_table_ops *table_ops,
10444 void *priv, bool counter_control_extern)
10445{
10446 struct devlink_dpipe_table *table;
10447
10448 lockdep_assert_held(&devlink->lock);
10449
10450 if (WARN_ON(!table_ops->size_get))
10451 return -EINVAL;
10452
10453 if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
10454 devlink))
10455 return -EEXIST;
10456
10457 table = kzalloc(sizeof(*table), GFP_KERNEL);
10458 if (!table)
10459 return -ENOMEM;
10460
10461 table->name = table_name;
10462 table->table_ops = table_ops;
10463 table->priv = priv;
10464 table->counter_control_extern = counter_control_extern;
10465
10466 list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
10467
10468 return 0;
10469}
10470EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
10471
10472/**
10473 * devl_dpipe_table_unregister - unregister dpipe table
10474 *
10475 * @devlink: devlink
10476 * @table_name: table name
10477 */
10478void devl_dpipe_table_unregister(struct devlink *devlink,
10479 const char *table_name)
10480{
10481 struct devlink_dpipe_table *table;
10482
10483 lockdep_assert_held(&devlink->lock);
10484
10485 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10486 table_name, devlink);
10487 if (!table)
10488 return;
10489 list_del_rcu(&table->list);
10490 kfree_rcu(table, rcu);
10491}
10492EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
10493
10494/**
10495 * devl_resource_register - devlink resource register
10496 *
10497 * @devlink: devlink
10498 * @resource_name: resource's name
10499 * @resource_size: resource's size
10500 * @resource_id: resource's id
10501 * @parent_resource_id: resource's parent id
10502 * @size_params: size parameters
10503 *
10504 * Generic resources should reuse the same names across drivers.
10505 * Please see the generic resources list at:
10506 * Documentation/networking/devlink/devlink-resource.rst
10507 */
10508int devl_resource_register(struct devlink *devlink,
10509 const char *resource_name,
10510 u64 resource_size,
10511 u64 resource_id,
10512 u64 parent_resource_id,
10513 const struct devlink_resource_size_params *size_params)
10514{
10515 struct devlink_resource *resource;
10516 struct list_head *resource_list;
10517 bool top_hierarchy;
10518
10519 lockdep_assert_held(&devlink->lock);
10520
10521 top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
10522
10523 resource = devlink_resource_find(devlink, NULL, resource_id);
10524 if (resource)
10525 return -EINVAL;
10526
10527 resource = kzalloc(sizeof(*resource), GFP_KERNEL);
10528 if (!resource)
10529 return -ENOMEM;
10530
10531 if (top_hierarchy) {
10532 resource_list = &devlink->resource_list;
10533 } else {
10534 struct devlink_resource *parent_resource;
10535
10536 parent_resource = devlink_resource_find(devlink, NULL,
10537 parent_resource_id);
10538 if (parent_resource) {
10539 resource_list = &parent_resource->resource_list;
10540 resource->parent = parent_resource;
10541 } else {
10542 kfree(resource);
10543 return -EINVAL;
10544 }
10545 }
10546
10547 resource->name = resource_name;
10548 resource->size = resource_size;
10549 resource->size_new = resource_size;
10550 resource->id = resource_id;
10551 resource->size_valid = true;
10552 memcpy(&resource->size_params, size_params,
10553 sizeof(resource->size_params));
10554 INIT_LIST_HEAD(&resource->resource_list);
10555 list_add_tail(&resource->list, resource_list);
10556
10557 return 0;
10558}
10559EXPORT_SYMBOL_GPL(devl_resource_register);
10560
10561/**
10562 * devlink_resource_register - devlink resource register
10563 *
10564 * @devlink: devlink
10565 * @resource_name: resource's name
10566 * @resource_size: resource's size
10567 * @resource_id: resource's id
10568 * @parent_resource_id: resource's parent id
10569 * @size_params: size parameters
10570 *
10571 * Generic resources should reuse the same names across drivers.
10572 * Please see the generic resources list at:
10573 * Documentation/networking/devlink/devlink-resource.rst
10574 *
10575 * Context: Takes and release devlink->lock <mutex>.
10576 */
10577int devlink_resource_register(struct devlink *devlink,
10578 const char *resource_name,
10579 u64 resource_size,
10580 u64 resource_id,
10581 u64 parent_resource_id,
10582 const struct devlink_resource_size_params *size_params)
10583{
10584 int err;
10585
10586 devl_lock(devlink);
10587 err = devl_resource_register(devlink, resource_name, resource_size,
10588 resource_id, parent_resource_id, size_params);
10589 devl_unlock(devlink);
10590 return err;
10591}
10592EXPORT_SYMBOL_GPL(devlink_resource_register);
10593
10594static void devlink_resource_unregister(struct devlink *devlink,
10595 struct devlink_resource *resource)
10596{
10597 struct devlink_resource *tmp, *child_resource;
10598
10599 list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
10600 list) {
10601 devlink_resource_unregister(devlink, child_resource);
10602 list_del(&child_resource->list);
10603 kfree(child_resource);
10604 }
10605}
10606
10607/**
10608 * devl_resources_unregister - free all resources
10609 *
10610 * @devlink: devlink
10611 */
10612void devl_resources_unregister(struct devlink *devlink)
10613{
10614 struct devlink_resource *tmp, *child_resource;
10615
10616 lockdep_assert_held(&devlink->lock);
10617
10618 list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
10619 list) {
10620 devlink_resource_unregister(devlink, child_resource);
10621 list_del(&child_resource->list);
10622 kfree(child_resource);
10623 }
10624}
10625EXPORT_SYMBOL_GPL(devl_resources_unregister);
10626
10627/**
10628 * devlink_resources_unregister - free all resources
10629 *
10630 * @devlink: devlink
10631 *
10632 * Context: Takes and release devlink->lock <mutex>.
10633 */
10634void devlink_resources_unregister(struct devlink *devlink)
10635{
10636 devl_lock(devlink);
10637 devl_resources_unregister(devlink);
10638 devl_unlock(devlink);
10639}
10640EXPORT_SYMBOL_GPL(devlink_resources_unregister);
10641
10642/**
10643 * devl_resource_size_get - get and update size
10644 *
10645 * @devlink: devlink
10646 * @resource_id: the requested resource id
10647 * @p_resource_size: ptr to update
10648 */
10649int devl_resource_size_get(struct devlink *devlink,
10650 u64 resource_id,
10651 u64 *p_resource_size)
10652{
10653 struct devlink_resource *resource;
10654
10655 lockdep_assert_held(&devlink->lock);
10656
10657 resource = devlink_resource_find(devlink, NULL, resource_id);
10658 if (!resource)
10659 return -EINVAL;
10660 *p_resource_size = resource->size_new;
10661 resource->size = resource->size_new;
10662 return 0;
10663}
10664EXPORT_SYMBOL_GPL(devl_resource_size_get);
10665
10666/**
10667 * devl_dpipe_table_resource_set - set the resource id
10668 *
10669 * @devlink: devlink
10670 * @table_name: table name
10671 * @resource_id: resource id
10672 * @resource_units: number of resource's units consumed per table's entry
10673 */
10674int devl_dpipe_table_resource_set(struct devlink *devlink,
10675 const char *table_name, u64 resource_id,
10676 u64 resource_units)
10677{
10678 struct devlink_dpipe_table *table;
10679
10680 table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10681 table_name, devlink);
10682 if (!table)
10683 return -EINVAL;
10684
10685 table->resource_id = resource_id;
10686 table->resource_units = resource_units;
10687 table->resource_valid = true;
10688 return 0;
10689}
10690EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
10691
10692/**
10693 * devl_resource_occ_get_register - register occupancy getter
10694 *
10695 * @devlink: devlink
10696 * @resource_id: resource id
10697 * @occ_get: occupancy getter callback
10698 * @occ_get_priv: occupancy getter callback priv
10699 */
10700void devl_resource_occ_get_register(struct devlink *devlink,
10701 u64 resource_id,
10702 devlink_resource_occ_get_t *occ_get,
10703 void *occ_get_priv)
10704{
10705 struct devlink_resource *resource;
10706
10707 lockdep_assert_held(&devlink->lock);
10708
10709 resource = devlink_resource_find(devlink, NULL, resource_id);
10710 if (WARN_ON(!resource))
10711 return;
10712 WARN_ON(resource->occ_get);
10713
10714 resource->occ_get = occ_get;
10715 resource->occ_get_priv = occ_get_priv;
10716}
10717EXPORT_SYMBOL_GPL(devl_resource_occ_get_register);
10718
10719/**
10720 * devlink_resource_occ_get_register - register occupancy getter
10721 *
10722 * @devlink: devlink
10723 * @resource_id: resource id
10724 * @occ_get: occupancy getter callback
10725 * @occ_get_priv: occupancy getter callback priv
10726 *
10727 * Context: Takes and release devlink->lock <mutex>.
10728 */
10729void devlink_resource_occ_get_register(struct devlink *devlink,
10730 u64 resource_id,
10731 devlink_resource_occ_get_t *occ_get,
10732 void *occ_get_priv)
10733{
10734 devl_lock(devlink);
10735 devl_resource_occ_get_register(devlink, resource_id,
10736 occ_get, occ_get_priv);
10737 devl_unlock(devlink);
10738}
10739EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
10740
10741/**
10742 * devl_resource_occ_get_unregister - unregister occupancy getter
10743 *
10744 * @devlink: devlink
10745 * @resource_id: resource id
10746 */
10747void devl_resource_occ_get_unregister(struct devlink *devlink,
10748 u64 resource_id)
10749{
10750 struct devlink_resource *resource;
10751
10752 lockdep_assert_held(&devlink->lock);
10753
10754 resource = devlink_resource_find(devlink, NULL, resource_id);
10755 if (WARN_ON(!resource))
10756 return;
10757 WARN_ON(!resource->occ_get);
10758
10759 resource->occ_get = NULL;
10760 resource->occ_get_priv = NULL;
10761}
10762EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
10763
10764/**
10765 * devlink_resource_occ_get_unregister - unregister occupancy getter
10766 *
10767 * @devlink: devlink
10768 * @resource_id: resource id
10769 *
10770 * Context: Takes and release devlink->lock <mutex>.
10771 */
10772void devlink_resource_occ_get_unregister(struct devlink *devlink,
10773 u64 resource_id)
10774{
10775 devl_lock(devlink);
10776 devl_resource_occ_get_unregister(devlink, resource_id);
10777 devl_unlock(devlink);
10778}
10779EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
10780
10781static int devlink_param_verify(const struct devlink_param *param)
10782{
10783 if (!param || !param->name || !param->supported_cmodes)
10784 return -EINVAL;
10785 if (param->generic)
10786 return devlink_param_generic_verify(param);
10787 else
10788 return devlink_param_driver_verify(param);
10789}
10790
10791static int devlink_param_register(struct devlink *devlink,
10792 const struct devlink_param *param)
10793{
10794 struct devlink_param_item *param_item;
10795
10796 WARN_ON(devlink_param_verify(param));
10797 WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name));
10798
10799 if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
10800 WARN_ON(param->get || param->set);
10801 else
10802 WARN_ON(!param->get || !param->set);
10803
10804 param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
10805 if (!param_item)
10806 return -ENOMEM;
10807
10808 param_item->param = param;
10809
10810 list_add_tail(&param_item->list, &devlink->param_list);
10811 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
10812 return 0;
10813}
10814
10815static void devlink_param_unregister(struct devlink *devlink,
10816 const struct devlink_param *param)
10817{
10818 struct devlink_param_item *param_item;
10819
10820 param_item =
10821 devlink_param_find_by_name(&devlink->param_list, param->name);
10822 if (WARN_ON(!param_item))
10823 return;
10824 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL);
10825 list_del(&param_item->list);
10826 kfree(param_item);
10827}
10828
10829/**
10830 * devl_params_register - register configuration parameters
10831 *
10832 * @devlink: devlink
10833 * @params: configuration parameters array
10834 * @params_count: number of parameters provided
10835 *
10836 * Register the configuration parameters supported by the driver.
10837 */
10838int devl_params_register(struct devlink *devlink,
10839 const struct devlink_param *params,
10840 size_t params_count)
10841{
10842 const struct devlink_param *param = params;
10843 int i, err;
10844
10845 lockdep_assert_held(&devlink->lock);
10846
10847 for (i = 0; i < params_count; i++, param++) {
10848 err = devlink_param_register(devlink, param);
10849 if (err)
10850 goto rollback;
10851 }
10852 return 0;
10853
10854rollback:
10855 if (!i)
10856 return err;
10857
10858 for (param--; i > 0; i--, param--)
10859 devlink_param_unregister(devlink, param);
10860 return err;
10861}
10862EXPORT_SYMBOL_GPL(devl_params_register);
10863
10864int devlink_params_register(struct devlink *devlink,
10865 const struct devlink_param *params,
10866 size_t params_count)
10867{
10868 int err;
10869
10870 devl_lock(devlink);
10871 err = devl_params_register(devlink, params, params_count);
10872 devl_unlock(devlink);
10873 return err;
10874}
10875EXPORT_SYMBOL_GPL(devlink_params_register);
10876
10877/**
10878 * devl_params_unregister - unregister configuration parameters
10879 * @devlink: devlink
10880 * @params: configuration parameters to unregister
10881 * @params_count: number of parameters provided
10882 */
10883void devl_params_unregister(struct devlink *devlink,
10884 const struct devlink_param *params,
10885 size_t params_count)
10886{
10887 const struct devlink_param *param = params;
10888 int i;
10889
10890 lockdep_assert_held(&devlink->lock);
10891
10892 for (i = 0; i < params_count; i++, param++)
10893 devlink_param_unregister(devlink, param);
10894}
10895EXPORT_SYMBOL_GPL(devl_params_unregister);
10896
10897void devlink_params_unregister(struct devlink *devlink,
10898 const struct devlink_param *params,
10899 size_t params_count)
10900{
10901 devl_lock(devlink);
10902 devl_params_unregister(devlink, params, params_count);
10903 devl_unlock(devlink);
10904}
10905EXPORT_SYMBOL_GPL(devlink_params_unregister);
10906
10907/**
10908 * devl_param_driverinit_value_get - get configuration parameter
10909 * value for driver initializing
10910 *
10911 * @devlink: devlink
10912 * @param_id: parameter ID
10913 * @init_val: value of parameter in driverinit configuration mode
10914 *
10915 * This function should be used by the driver to get driverinit
10916 * configuration for initialization after reload command.
10917 */
10918int devl_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
10919 union devlink_param_value *init_val)
10920{
10921 struct devlink_param_item *param_item;
10922
10923 lockdep_assert_held(&devlink->lock);
10924
10925 if (WARN_ON(!devlink_reload_supported(devlink->ops)))
10926 return -EOPNOTSUPP;
10927
10928 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
10929 if (!param_item)
10930 return -EINVAL;
10931
10932 if (!param_item->driverinit_value_valid)
10933 return -EOPNOTSUPP;
10934
10935 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
10936 DEVLINK_PARAM_CMODE_DRIVERINIT)))
10937 return -EOPNOTSUPP;
10938
10939 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
10940 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
10941 else
10942 *init_val = param_item->driverinit_value;
10943
10944 return 0;
10945}
10946EXPORT_SYMBOL_GPL(devl_param_driverinit_value_get);
10947
10948/**
10949 * devl_param_driverinit_value_set - set value of configuration
10950 * parameter for driverinit
10951 * configuration mode
10952 *
10953 * @devlink: devlink
10954 * @param_id: parameter ID
10955 * @init_val: value of parameter to set for driverinit configuration mode
10956 *
10957 * This function should be used by the driver to set driverinit
10958 * configuration mode default value.
10959 */
10960void devl_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
10961 union devlink_param_value init_val)
10962{
10963 struct devlink_param_item *param_item;
10964
10965 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
10966 if (WARN_ON(!param_item))
10967 return;
10968
10969 if (WARN_ON(!devlink_param_cmode_is_supported(param_item->param,
10970 DEVLINK_PARAM_CMODE_DRIVERINIT)))
10971 return;
10972
10973 if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
10974 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
10975 else
10976 param_item->driverinit_value = init_val;
10977 param_item->driverinit_value_valid = true;
10978
10979 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
10980}
10981EXPORT_SYMBOL_GPL(devl_param_driverinit_value_set);
10982
10983/**
10984 * devl_param_value_changed - notify devlink on a parameter's value
10985 * change. Should be called by the driver
10986 * right after the change.
10987 *
10988 * @devlink: devlink
10989 * @param_id: parameter ID
10990 *
10991 * This function should be used by the driver to notify devlink on value
10992 * change, excluding driverinit configuration mode.
10993 * For driverinit configuration mode driver should use the function
10994 */
10995void devl_param_value_changed(struct devlink *devlink, u32 param_id)
10996{
10997 struct devlink_param_item *param_item;
10998
10999 param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11000 WARN_ON(!param_item);
11001
11002 devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
11003}
11004EXPORT_SYMBOL_GPL(devl_param_value_changed);
11005
11006/**
11007 * devl_region_create - create a new address region
11008 *
11009 * @devlink: devlink
11010 * @ops: region operations and name
11011 * @region_max_snapshots: Maximum supported number of snapshots for region
11012 * @region_size: size of region
11013 */
11014struct devlink_region *devl_region_create(struct devlink *devlink,
11015 const struct devlink_region_ops *ops,
11016 u32 region_max_snapshots,
11017 u64 region_size)
11018{
11019 struct devlink_region *region;
11020
11021 devl_assert_locked(devlink);
11022
11023 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11024 return ERR_PTR(-EINVAL);
11025
11026 if (devlink_region_get_by_name(devlink, ops->name))
11027 return ERR_PTR(-EEXIST);
11028
11029 region = kzalloc(sizeof(*region), GFP_KERNEL);
11030 if (!region)
11031 return ERR_PTR(-ENOMEM);
11032
11033 region->devlink = devlink;
11034 region->max_snapshots = region_max_snapshots;
11035 region->ops = ops;
11036 region->size = region_size;
11037 INIT_LIST_HEAD(&region->snapshot_list);
11038 mutex_init(&region->snapshot_lock);
11039 list_add_tail(&region->list, &devlink->region_list);
11040 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11041
11042 return region;
11043}
11044EXPORT_SYMBOL_GPL(devl_region_create);
11045
11046/**
11047 * devlink_region_create - create a new address region
11048 *
11049 * @devlink: devlink
11050 * @ops: region operations and name
11051 * @region_max_snapshots: Maximum supported number of snapshots for region
11052 * @region_size: size of region
11053 *
11054 * Context: Takes and release devlink->lock <mutex>.
11055 */
11056struct devlink_region *
11057devlink_region_create(struct devlink *devlink,
11058 const struct devlink_region_ops *ops,
11059 u32 region_max_snapshots, u64 region_size)
11060{
11061 struct devlink_region *region;
11062
11063 devl_lock(devlink);
11064 region = devl_region_create(devlink, ops, region_max_snapshots,
11065 region_size);
11066 devl_unlock(devlink);
11067 return region;
11068}
11069EXPORT_SYMBOL_GPL(devlink_region_create);
11070
11071/**
11072 * devlink_port_region_create - create a new address region for a port
11073 *
11074 * @port: devlink port
11075 * @ops: region operations and name
11076 * @region_max_snapshots: Maximum supported number of snapshots for region
11077 * @region_size: size of region
11078 *
11079 * Context: Takes and release devlink->lock <mutex>.
11080 */
11081struct devlink_region *
11082devlink_port_region_create(struct devlink_port *port,
11083 const struct devlink_port_region_ops *ops,
11084 u32 region_max_snapshots, u64 region_size)
11085{
11086 struct devlink *devlink = port->devlink;
11087 struct devlink_region *region;
11088 int err = 0;
11089
11090 ASSERT_DEVLINK_PORT_INITIALIZED(port);
11091
11092 if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11093 return ERR_PTR(-EINVAL);
11094
11095 devl_lock(devlink);
11096
11097 if (devlink_port_region_get_by_name(port, ops->name)) {
11098 err = -EEXIST;
11099 goto unlock;
11100 }
11101
11102 region = kzalloc(sizeof(*region), GFP_KERNEL);
11103 if (!region) {
11104 err = -ENOMEM;
11105 goto unlock;
11106 }
11107
11108 region->devlink = devlink;
11109 region->port = port;
11110 region->max_snapshots = region_max_snapshots;
11111 region->port_ops = ops;
11112 region->size = region_size;
11113 INIT_LIST_HEAD(&region->snapshot_list);
11114 mutex_init(&region->snapshot_lock);
11115 list_add_tail(&region->list, &port->region_list);
11116 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11117
11118 devl_unlock(devlink);
11119 return region;
11120
11121unlock:
11122 devl_unlock(devlink);
11123 return ERR_PTR(err);
11124}
11125EXPORT_SYMBOL_GPL(devlink_port_region_create);
11126
11127/**
11128 * devl_region_destroy - destroy address region
11129 *
11130 * @region: devlink region to destroy
11131 */
11132void devl_region_destroy(struct devlink_region *region)
11133{
11134 struct devlink *devlink = region->devlink;
11135 struct devlink_snapshot *snapshot, *ts;
11136
11137 devl_assert_locked(devlink);
11138
11139 /* Free all snapshots of region */
11140 mutex_lock(&region->snapshot_lock);
11141 list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
11142 devlink_region_snapshot_del(region, snapshot);
11143 mutex_unlock(&region->snapshot_lock);
11144
11145 list_del(&region->list);
11146 mutex_destroy(&region->snapshot_lock);
11147
11148 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
11149 kfree(region);
11150}
11151EXPORT_SYMBOL_GPL(devl_region_destroy);
11152
11153/**
11154 * devlink_region_destroy - destroy address region
11155 *
11156 * @region: devlink region to destroy
11157 *
11158 * Context: Takes and release devlink->lock <mutex>.
11159 */
11160void devlink_region_destroy(struct devlink_region *region)
11161{
11162 struct devlink *devlink = region->devlink;
11163
11164 devl_lock(devlink);
11165 devl_region_destroy(region);
11166 devl_unlock(devlink);
11167}
11168EXPORT_SYMBOL_GPL(devlink_region_destroy);
11169
11170/**
11171 * devlink_region_snapshot_id_get - get snapshot ID
11172 *
11173 * This callback should be called when adding a new snapshot,
11174 * Driver should use the same id for multiple snapshots taken
11175 * on multiple regions at the same time/by the same trigger.
11176 *
11177 * The caller of this function must use devlink_region_snapshot_id_put
11178 * when finished creating regions using this id.
11179 *
11180 * Returns zero on success, or a negative error code on failure.
11181 *
11182 * @devlink: devlink
11183 * @id: storage to return id
11184 */
11185int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
11186{
11187 return __devlink_region_snapshot_id_get(devlink, id);
11188}
11189EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
11190
11191/**
11192 * devlink_region_snapshot_id_put - put snapshot ID reference
11193 *
11194 * This should be called by a driver after finishing creating snapshots
11195 * with an id. Doing so ensures that the ID can later be released in the
11196 * event that all snapshots using it have been destroyed.
11197 *
11198 * @devlink: devlink
11199 * @id: id to release reference on
11200 */
11201void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
11202{
11203 __devlink_snapshot_id_decrement(devlink, id);
11204}
11205EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
11206
11207/**
11208 * devlink_region_snapshot_create - create a new snapshot
11209 * This will add a new snapshot of a region. The snapshot
11210 * will be stored on the region struct and can be accessed
11211 * from devlink. This is useful for future analyses of snapshots.
11212 * Multiple snapshots can be created on a region.
11213 * The @snapshot_id should be obtained using the getter function.
11214 *
11215 * @region: devlink region of the snapshot
11216 * @data: snapshot data
11217 * @snapshot_id: snapshot id to be created
11218 */
11219int devlink_region_snapshot_create(struct devlink_region *region,
11220 u8 *data, u32 snapshot_id)
11221{
11222 int err;
11223
11224 mutex_lock(&region->snapshot_lock);
11225 err = __devlink_region_snapshot_create(region, data, snapshot_id);
11226 mutex_unlock(&region->snapshot_lock);
11227 return err;
11228}
11229EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
11230
11231#define DEVLINK_TRAP(_id, _type) \
11232 { \
11233 .type = DEVLINK_TRAP_TYPE_##_type, \
11234 .id = DEVLINK_TRAP_GENERIC_ID_##_id, \
11235 .name = DEVLINK_TRAP_GENERIC_NAME_##_id, \
11236 }
11237
11238static const struct devlink_trap devlink_trap_generic[] = {
11239 DEVLINK_TRAP(SMAC_MC, DROP),
11240 DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
11241 DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
11242 DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
11243 DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
11244 DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
11245 DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
11246 DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
11247 DEVLINK_TRAP(TAIL_DROP, DROP),
11248 DEVLINK_TRAP(NON_IP_PACKET, DROP),
11249 DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
11250 DEVLINK_TRAP(DIP_LB, DROP),
11251 DEVLINK_TRAP(SIP_MC, DROP),
11252 DEVLINK_TRAP(SIP_LB, DROP),
11253 DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
11254 DEVLINK_TRAP(IPV4_SIP_BC, DROP),
11255 DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
11256 DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
11257 DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
11258 DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
11259 DEVLINK_TRAP(RPF, EXCEPTION),
11260 DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
11261 DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
11262 DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
11263 DEVLINK_TRAP(NON_ROUTABLE, DROP),
11264 DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
11265 DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
11266 DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
11267 DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
11268 DEVLINK_TRAP(STP, CONTROL),
11269 DEVLINK_TRAP(LACP, CONTROL),
11270 DEVLINK_TRAP(LLDP, CONTROL),
11271 DEVLINK_TRAP(IGMP_QUERY, CONTROL),
11272 DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
11273 DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
11274 DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
11275 DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
11276 DEVLINK_TRAP(MLD_QUERY, CONTROL),
11277 DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
11278 DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
11279 DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
11280 DEVLINK_TRAP(IPV4_DHCP, CONTROL),
11281 DEVLINK_TRAP(IPV6_DHCP, CONTROL),
11282 DEVLINK_TRAP(ARP_REQUEST, CONTROL),
11283 DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
11284 DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
11285 DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
11286 DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
11287 DEVLINK_TRAP(IPV4_BFD, CONTROL),
11288 DEVLINK_TRAP(IPV6_BFD, CONTROL),
11289 DEVLINK_TRAP(IPV4_OSPF, CONTROL),
11290 DEVLINK_TRAP(IPV6_OSPF, CONTROL),
11291 DEVLINK_TRAP(IPV4_BGP, CONTROL),
11292 DEVLINK_TRAP(IPV6_BGP, CONTROL),
11293 DEVLINK_TRAP(IPV4_VRRP, CONTROL),
11294 DEVLINK_TRAP(IPV6_VRRP, CONTROL),
11295 DEVLINK_TRAP(IPV4_PIM, CONTROL),
11296 DEVLINK_TRAP(IPV6_PIM, CONTROL),
11297 DEVLINK_TRAP(UC_LB, CONTROL),
11298 DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
11299 DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
11300 DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
11301 DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
11302 DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
11303 DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
11304 DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
11305 DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
11306 DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
11307 DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
11308 DEVLINK_TRAP(PTP_EVENT, CONTROL),
11309 DEVLINK_TRAP(PTP_GENERAL, CONTROL),
11310 DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
11311 DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
11312 DEVLINK_TRAP(EARLY_DROP, DROP),
11313 DEVLINK_TRAP(VXLAN_PARSING, DROP),
11314 DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
11315 DEVLINK_TRAP(VLAN_PARSING, DROP),
11316 DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
11317 DEVLINK_TRAP(MPLS_PARSING, DROP),
11318 DEVLINK_TRAP(ARP_PARSING, DROP),
11319 DEVLINK_TRAP(IP_1_PARSING, DROP),
11320 DEVLINK_TRAP(IP_N_PARSING, DROP),
11321 DEVLINK_TRAP(GRE_PARSING, DROP),
11322 DEVLINK_TRAP(UDP_PARSING, DROP),
11323 DEVLINK_TRAP(TCP_PARSING, DROP),
11324 DEVLINK_TRAP(IPSEC_PARSING, DROP),
11325 DEVLINK_TRAP(SCTP_PARSING, DROP),
11326 DEVLINK_TRAP(DCCP_PARSING, DROP),
11327 DEVLINK_TRAP(GTP_PARSING, DROP),
11328 DEVLINK_TRAP(ESP_PARSING, DROP),
11329 DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP),
11330 DEVLINK_TRAP(DMAC_FILTER, DROP),
11331 DEVLINK_TRAP(EAPOL, CONTROL),
11332 DEVLINK_TRAP(LOCKED_PORT, DROP),
11333};
11334
11335#define DEVLINK_TRAP_GROUP(_id) \
11336 { \
11337 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id, \
11338 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id, \
11339 }
11340
11341static const struct devlink_trap_group devlink_trap_group_generic[] = {
11342 DEVLINK_TRAP_GROUP(L2_DROPS),
11343 DEVLINK_TRAP_GROUP(L3_DROPS),
11344 DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
11345 DEVLINK_TRAP_GROUP(BUFFER_DROPS),
11346 DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
11347 DEVLINK_TRAP_GROUP(ACL_DROPS),
11348 DEVLINK_TRAP_GROUP(STP),
11349 DEVLINK_TRAP_GROUP(LACP),
11350 DEVLINK_TRAP_GROUP(LLDP),
11351 DEVLINK_TRAP_GROUP(MC_SNOOPING),
11352 DEVLINK_TRAP_GROUP(DHCP),
11353 DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
11354 DEVLINK_TRAP_GROUP(BFD),
11355 DEVLINK_TRAP_GROUP(OSPF),
11356 DEVLINK_TRAP_GROUP(BGP),
11357 DEVLINK_TRAP_GROUP(VRRP),
11358 DEVLINK_TRAP_GROUP(PIM),
11359 DEVLINK_TRAP_GROUP(UC_LB),
11360 DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
11361 DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
11362 DEVLINK_TRAP_GROUP(IPV6),
11363 DEVLINK_TRAP_GROUP(PTP_EVENT),
11364 DEVLINK_TRAP_GROUP(PTP_GENERAL),
11365 DEVLINK_TRAP_GROUP(ACL_SAMPLE),
11366 DEVLINK_TRAP_GROUP(ACL_TRAP),
11367 DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
11368 DEVLINK_TRAP_GROUP(EAPOL),
11369};
11370
11371static int devlink_trap_generic_verify(const struct devlink_trap *trap)
11372{
11373 if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
11374 return -EINVAL;
11375
11376 if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
11377 return -EINVAL;
11378
11379 if (trap->type != devlink_trap_generic[trap->id].type)
11380 return -EINVAL;
11381
11382 return 0;
11383}
11384
11385static int devlink_trap_driver_verify(const struct devlink_trap *trap)
11386{
11387 int i;
11388
11389 if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
11390 return -EINVAL;
11391
11392 for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
11393 if (!strcmp(trap->name, devlink_trap_generic[i].name))
11394 return -EEXIST;
11395 }
11396
11397 return 0;
11398}
11399
11400static int devlink_trap_verify(const struct devlink_trap *trap)
11401{
11402 if (!trap || !trap->name)
11403 return -EINVAL;
11404
11405 if (trap->generic)
11406 return devlink_trap_generic_verify(trap);
11407 else
11408 return devlink_trap_driver_verify(trap);
11409}
11410
11411static int
11412devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
11413{
11414 if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11415 return -EINVAL;
11416
11417 if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
11418 return -EINVAL;
11419
11420 return 0;
11421}
11422
11423static int
11424devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
11425{
11426 int i;
11427
11428 if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11429 return -EINVAL;
11430
11431 for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
11432 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
11433 return -EEXIST;
11434 }
11435
11436 return 0;
11437}
11438
11439static int devlink_trap_group_verify(const struct devlink_trap_group *group)
11440{
11441 if (group->generic)
11442 return devlink_trap_group_generic_verify(group);
11443 else
11444 return devlink_trap_group_driver_verify(group);
11445}
11446
11447static void
11448devlink_trap_group_notify(struct devlink *devlink,
11449 const struct devlink_trap_group_item *group_item,
11450 enum devlink_command cmd)
11451{
11452 struct sk_buff *msg;
11453 int err;
11454
11455 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
11456 cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
11457 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11458 return;
11459
11460 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11461 if (!msg)
11462 return;
11463
11464 err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
11465 0);
11466 if (err) {
11467 nlmsg_free(msg);
11468 return;
11469 }
11470
11471 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11472 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11473}
11474
11475static int
11476devlink_trap_item_group_link(struct devlink *devlink,
11477 struct devlink_trap_item *trap_item)
11478{
11479 u16 group_id = trap_item->trap->init_group_id;
11480 struct devlink_trap_group_item *group_item;
11481
11482 group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
11483 if (WARN_ON_ONCE(!group_item))
11484 return -EINVAL;
11485
11486 trap_item->group_item = group_item;
11487
11488 return 0;
11489}
11490
11491static void devlink_trap_notify(struct devlink *devlink,
11492 const struct devlink_trap_item *trap_item,
11493 enum devlink_command cmd)
11494{
11495 struct sk_buff *msg;
11496 int err;
11497
11498 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
11499 cmd != DEVLINK_CMD_TRAP_DEL);
11500 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11501 return;
11502
11503 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11504 if (!msg)
11505 return;
11506
11507 err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
11508 if (err) {
11509 nlmsg_free(msg);
11510 return;
11511 }
11512
11513 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11514 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11515}
11516
11517static int
11518devlink_trap_register(struct devlink *devlink,
11519 const struct devlink_trap *trap, void *priv)
11520{
11521 struct devlink_trap_item *trap_item;
11522 int err;
11523
11524 if (devlink_trap_item_lookup(devlink, trap->name))
11525 return -EEXIST;
11526
11527 trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
11528 if (!trap_item)
11529 return -ENOMEM;
11530
11531 trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11532 if (!trap_item->stats) {
11533 err = -ENOMEM;
11534 goto err_stats_alloc;
11535 }
11536
11537 trap_item->trap = trap;
11538 trap_item->action = trap->init_action;
11539 trap_item->priv = priv;
11540
11541 err = devlink_trap_item_group_link(devlink, trap_item);
11542 if (err)
11543 goto err_group_link;
11544
11545 err = devlink->ops->trap_init(devlink, trap, trap_item);
11546 if (err)
11547 goto err_trap_init;
11548
11549 list_add_tail(&trap_item->list, &devlink->trap_list);
11550 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
11551
11552 return 0;
11553
11554err_trap_init:
11555err_group_link:
11556 free_percpu(trap_item->stats);
11557err_stats_alloc:
11558 kfree(trap_item);
11559 return err;
11560}
11561
11562static void devlink_trap_unregister(struct devlink *devlink,
11563 const struct devlink_trap *trap)
11564{
11565 struct devlink_trap_item *trap_item;
11566
11567 trap_item = devlink_trap_item_lookup(devlink, trap->name);
11568 if (WARN_ON_ONCE(!trap_item))
11569 return;
11570
11571 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
11572 list_del(&trap_item->list);
11573 if (devlink->ops->trap_fini)
11574 devlink->ops->trap_fini(devlink, trap, trap_item);
11575 free_percpu(trap_item->stats);
11576 kfree(trap_item);
11577}
11578
11579static void devlink_trap_disable(struct devlink *devlink,
11580 const struct devlink_trap *trap)
11581{
11582 struct devlink_trap_item *trap_item;
11583
11584 trap_item = devlink_trap_item_lookup(devlink, trap->name);
11585 if (WARN_ON_ONCE(!trap_item))
11586 return;
11587
11588 devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
11589 NULL);
11590 trap_item->action = DEVLINK_TRAP_ACTION_DROP;
11591}
11592
11593/**
11594 * devl_traps_register - Register packet traps with devlink.
11595 * @devlink: devlink.
11596 * @traps: Packet traps.
11597 * @traps_count: Count of provided packet traps.
11598 * @priv: Driver private information.
11599 *
11600 * Return: Non-zero value on failure.
11601 */
11602int devl_traps_register(struct devlink *devlink,
11603 const struct devlink_trap *traps,
11604 size_t traps_count, void *priv)
11605{
11606 int i, err;
11607
11608 if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
11609 return -EINVAL;
11610
11611 devl_assert_locked(devlink);
11612 for (i = 0; i < traps_count; i++) {
11613 const struct devlink_trap *trap = &traps[i];
11614
11615 err = devlink_trap_verify(trap);
11616 if (err)
11617 goto err_trap_verify;
11618
11619 err = devlink_trap_register(devlink, trap, priv);
11620 if (err)
11621 goto err_trap_register;
11622 }
11623
11624 return 0;
11625
11626err_trap_register:
11627err_trap_verify:
11628 for (i--; i >= 0; i--)
11629 devlink_trap_unregister(devlink, &traps[i]);
11630 return err;
11631}
11632EXPORT_SYMBOL_GPL(devl_traps_register);
11633
11634/**
11635 * devlink_traps_register - Register packet traps with devlink.
11636 * @devlink: devlink.
11637 * @traps: Packet traps.
11638 * @traps_count: Count of provided packet traps.
11639 * @priv: Driver private information.
11640 *
11641 * Context: Takes and release devlink->lock <mutex>.
11642 *
11643 * Return: Non-zero value on failure.
11644 */
11645int devlink_traps_register(struct devlink *devlink,
11646 const struct devlink_trap *traps,
11647 size_t traps_count, void *priv)
11648{
11649 int err;
11650
11651 devl_lock(devlink);
11652 err = devl_traps_register(devlink, traps, traps_count, priv);
11653 devl_unlock(devlink);
11654 return err;
11655}
11656EXPORT_SYMBOL_GPL(devlink_traps_register);
11657
11658/**
11659 * devl_traps_unregister - Unregister packet traps from devlink.
11660 * @devlink: devlink.
11661 * @traps: Packet traps.
11662 * @traps_count: Count of provided packet traps.
11663 */
11664void devl_traps_unregister(struct devlink *devlink,
11665 const struct devlink_trap *traps,
11666 size_t traps_count)
11667{
11668 int i;
11669
11670 devl_assert_locked(devlink);
11671 /* Make sure we do not have any packets in-flight while unregistering
11672 * traps by disabling all of them and waiting for a grace period.
11673 */
11674 for (i = traps_count - 1; i >= 0; i--)
11675 devlink_trap_disable(devlink, &traps[i]);
11676 synchronize_rcu();
11677 for (i = traps_count - 1; i >= 0; i--)
11678 devlink_trap_unregister(devlink, &traps[i]);
11679}
11680EXPORT_SYMBOL_GPL(devl_traps_unregister);
11681
11682/**
11683 * devlink_traps_unregister - Unregister packet traps from devlink.
11684 * @devlink: devlink.
11685 * @traps: Packet traps.
11686 * @traps_count: Count of provided packet traps.
11687 *
11688 * Context: Takes and release devlink->lock <mutex>.
11689 */
11690void devlink_traps_unregister(struct devlink *devlink,
11691 const struct devlink_trap *traps,
11692 size_t traps_count)
11693{
11694 devl_lock(devlink);
11695 devl_traps_unregister(devlink, traps, traps_count);
11696 devl_unlock(devlink);
11697}
11698EXPORT_SYMBOL_GPL(devlink_traps_unregister);
11699
11700static void
11701devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
11702 size_t skb_len)
11703{
11704 struct devlink_stats *stats;
11705
11706 stats = this_cpu_ptr(trap_stats);
11707 u64_stats_update_begin(&stats->syncp);
11708 u64_stats_add(&stats->rx_bytes, skb_len);
11709 u64_stats_inc(&stats->rx_packets);
11710 u64_stats_update_end(&stats->syncp);
11711}
11712
11713static void
11714devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
11715 const struct devlink_trap_item *trap_item,
11716 struct devlink_port *in_devlink_port,
11717 const struct flow_action_cookie *fa_cookie)
11718{
11719 metadata->trap_name = trap_item->trap->name;
11720 metadata->trap_group_name = trap_item->group_item->group->name;
11721 metadata->fa_cookie = fa_cookie;
11722 metadata->trap_type = trap_item->trap->type;
11723
11724 spin_lock(&in_devlink_port->type_lock);
11725 if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
11726 metadata->input_dev = in_devlink_port->type_eth.netdev;
11727 spin_unlock(&in_devlink_port->type_lock);
11728}
11729
11730/**
11731 * devlink_trap_report - Report trapped packet to drop monitor.
11732 * @devlink: devlink.
11733 * @skb: Trapped packet.
11734 * @trap_ctx: Trap context.
11735 * @in_devlink_port: Input devlink port.
11736 * @fa_cookie: Flow action cookie. Could be NULL.
11737 */
11738void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
11739 void *trap_ctx, struct devlink_port *in_devlink_port,
11740 const struct flow_action_cookie *fa_cookie)
11741
11742{
11743 struct devlink_trap_item *trap_item = trap_ctx;
11744
11745 devlink_trap_stats_update(trap_item->stats, skb->len);
11746 devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
11747
11748 if (trace_devlink_trap_report_enabled()) {
11749 struct devlink_trap_metadata metadata = {};
11750
11751 devlink_trap_report_metadata_set(&metadata, trap_item,
11752 in_devlink_port, fa_cookie);
11753 trace_devlink_trap_report(devlink, skb, &metadata);
11754 }
11755}
11756EXPORT_SYMBOL_GPL(devlink_trap_report);
11757
11758/**
11759 * devlink_trap_ctx_priv - Trap context to driver private information.
11760 * @trap_ctx: Trap context.
11761 *
11762 * Return: Driver private information passed during registration.
11763 */
11764void *devlink_trap_ctx_priv(void *trap_ctx)
11765{
11766 struct devlink_trap_item *trap_item = trap_ctx;
11767
11768 return trap_item->priv;
11769}
11770EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
11771
11772static int
11773devlink_trap_group_item_policer_link(struct devlink *devlink,
11774 struct devlink_trap_group_item *group_item)
11775{
11776 u32 policer_id = group_item->group->init_policer_id;
11777 struct devlink_trap_policer_item *policer_item;
11778
11779 if (policer_id == 0)
11780 return 0;
11781
11782 policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
11783 if (WARN_ON_ONCE(!policer_item))
11784 return -EINVAL;
11785
11786 group_item->policer_item = policer_item;
11787
11788 return 0;
11789}
11790
11791static int
11792devlink_trap_group_register(struct devlink *devlink,
11793 const struct devlink_trap_group *group)
11794{
11795 struct devlink_trap_group_item *group_item;
11796 int err;
11797
11798 if (devlink_trap_group_item_lookup(devlink, group->name))
11799 return -EEXIST;
11800
11801 group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
11802 if (!group_item)
11803 return -ENOMEM;
11804
11805 group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11806 if (!group_item->stats) {
11807 err = -ENOMEM;
11808 goto err_stats_alloc;
11809 }
11810
11811 group_item->group = group;
11812
11813 err = devlink_trap_group_item_policer_link(devlink, group_item);
11814 if (err)
11815 goto err_policer_link;
11816
11817 if (devlink->ops->trap_group_init) {
11818 err = devlink->ops->trap_group_init(devlink, group);
11819 if (err)
11820 goto err_group_init;
11821 }
11822
11823 list_add_tail(&group_item->list, &devlink->trap_group_list);
11824 devlink_trap_group_notify(devlink, group_item,
11825 DEVLINK_CMD_TRAP_GROUP_NEW);
11826
11827 return 0;
11828
11829err_group_init:
11830err_policer_link:
11831 free_percpu(group_item->stats);
11832err_stats_alloc:
11833 kfree(group_item);
11834 return err;
11835}
11836
11837static void
11838devlink_trap_group_unregister(struct devlink *devlink,
11839 const struct devlink_trap_group *group)
11840{
11841 struct devlink_trap_group_item *group_item;
11842
11843 group_item = devlink_trap_group_item_lookup(devlink, group->name);
11844 if (WARN_ON_ONCE(!group_item))
11845 return;
11846
11847 devlink_trap_group_notify(devlink, group_item,
11848 DEVLINK_CMD_TRAP_GROUP_DEL);
11849 list_del(&group_item->list);
11850 free_percpu(group_item->stats);
11851 kfree(group_item);
11852}
11853
11854/**
11855 * devl_trap_groups_register - Register packet trap groups with devlink.
11856 * @devlink: devlink.
11857 * @groups: Packet trap groups.
11858 * @groups_count: Count of provided packet trap groups.
11859 *
11860 * Return: Non-zero value on failure.
11861 */
11862int devl_trap_groups_register(struct devlink *devlink,
11863 const struct devlink_trap_group *groups,
11864 size_t groups_count)
11865{
11866 int i, err;
11867
11868 devl_assert_locked(devlink);
11869 for (i = 0; i < groups_count; i++) {
11870 const struct devlink_trap_group *group = &groups[i];
11871
11872 err = devlink_trap_group_verify(group);
11873 if (err)
11874 goto err_trap_group_verify;
11875
11876 err = devlink_trap_group_register(devlink, group);
11877 if (err)
11878 goto err_trap_group_register;
11879 }
11880
11881 return 0;
11882
11883err_trap_group_register:
11884err_trap_group_verify:
11885 for (i--; i >= 0; i--)
11886 devlink_trap_group_unregister(devlink, &groups[i]);
11887 return err;
11888}
11889EXPORT_SYMBOL_GPL(devl_trap_groups_register);
11890
11891/**
11892 * devlink_trap_groups_register - Register packet trap groups with devlink.
11893 * @devlink: devlink.
11894 * @groups: Packet trap groups.
11895 * @groups_count: Count of provided packet trap groups.
11896 *
11897 * Context: Takes and release devlink->lock <mutex>.
11898 *
11899 * Return: Non-zero value on failure.
11900 */
11901int devlink_trap_groups_register(struct devlink *devlink,
11902 const struct devlink_trap_group *groups,
11903 size_t groups_count)
11904{
11905 int err;
11906
11907 devl_lock(devlink);
11908 err = devl_trap_groups_register(devlink, groups, groups_count);
11909 devl_unlock(devlink);
11910 return err;
11911}
11912EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
11913
11914/**
11915 * devl_trap_groups_unregister - Unregister packet trap groups from devlink.
11916 * @devlink: devlink.
11917 * @groups: Packet trap groups.
11918 * @groups_count: Count of provided packet trap groups.
11919 */
11920void devl_trap_groups_unregister(struct devlink *devlink,
11921 const struct devlink_trap_group *groups,
11922 size_t groups_count)
11923{
11924 int i;
11925
11926 devl_assert_locked(devlink);
11927 for (i = groups_count - 1; i >= 0; i--)
11928 devlink_trap_group_unregister(devlink, &groups[i]);
11929}
11930EXPORT_SYMBOL_GPL(devl_trap_groups_unregister);
11931
11932/**
11933 * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
11934 * @devlink: devlink.
11935 * @groups: Packet trap groups.
11936 * @groups_count: Count of provided packet trap groups.
11937 *
11938 * Context: Takes and release devlink->lock <mutex>.
11939 */
11940void devlink_trap_groups_unregister(struct devlink *devlink,
11941 const struct devlink_trap_group *groups,
11942 size_t groups_count)
11943{
11944 devl_lock(devlink);
11945 devl_trap_groups_unregister(devlink, groups, groups_count);
11946 devl_unlock(devlink);
11947}
11948EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
11949
11950static void
11951devlink_trap_policer_notify(struct devlink *devlink,
11952 const struct devlink_trap_policer_item *policer_item,
11953 enum devlink_command cmd)
11954{
11955 struct sk_buff *msg;
11956 int err;
11957
11958 WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
11959 cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
11960 if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11961 return;
11962
11963 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11964 if (!msg)
11965 return;
11966
11967 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
11968 0, 0);
11969 if (err) {
11970 nlmsg_free(msg);
11971 return;
11972 }
11973
11974 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11975 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11976}
11977
11978static int
11979devlink_trap_policer_register(struct devlink *devlink,
11980 const struct devlink_trap_policer *policer)
11981{
11982 struct devlink_trap_policer_item *policer_item;
11983 int err;
11984
11985 if (devlink_trap_policer_item_lookup(devlink, policer->id))
11986 return -EEXIST;
11987
11988 policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
11989 if (!policer_item)
11990 return -ENOMEM;
11991
11992 policer_item->policer = policer;
11993 policer_item->rate = policer->init_rate;
11994 policer_item->burst = policer->init_burst;
11995
11996 if (devlink->ops->trap_policer_init) {
11997 err = devlink->ops->trap_policer_init(devlink, policer);
11998 if (err)
11999 goto err_policer_init;
12000 }
12001
12002 list_add_tail(&policer_item->list, &devlink->trap_policer_list);
12003 devlink_trap_policer_notify(devlink, policer_item,
12004 DEVLINK_CMD_TRAP_POLICER_NEW);
12005
12006 return 0;
12007
12008err_policer_init:
12009 kfree(policer_item);
12010 return err;
12011}
12012
12013static void
12014devlink_trap_policer_unregister(struct devlink *devlink,
12015 const struct devlink_trap_policer *policer)
12016{
12017 struct devlink_trap_policer_item *policer_item;
12018
12019 policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
12020 if (WARN_ON_ONCE(!policer_item))
12021 return;
12022
12023 devlink_trap_policer_notify(devlink, policer_item,
12024 DEVLINK_CMD_TRAP_POLICER_DEL);
12025 list_del(&policer_item->list);
12026 if (devlink->ops->trap_policer_fini)
12027 devlink->ops->trap_policer_fini(devlink, policer);
12028 kfree(policer_item);
12029}
12030
12031/**
12032 * devl_trap_policers_register - Register packet trap policers with devlink.
12033 * @devlink: devlink.
12034 * @policers: Packet trap policers.
12035 * @policers_count: Count of provided packet trap policers.
12036 *
12037 * Return: Non-zero value on failure.
12038 */
12039int
12040devl_trap_policers_register(struct devlink *devlink,
12041 const struct devlink_trap_policer *policers,
12042 size_t policers_count)
12043{
12044 int i, err;
12045
12046 devl_assert_locked(devlink);
12047 for (i = 0; i < policers_count; i++) {
12048 const struct devlink_trap_policer *policer = &policers[i];
12049
12050 if (WARN_ON(policer->id == 0 ||
12051 policer->max_rate < policer->min_rate ||
12052 policer->max_burst < policer->min_burst)) {
12053 err = -EINVAL;
12054 goto err_trap_policer_verify;
12055 }
12056
12057 err = devlink_trap_policer_register(devlink, policer);
12058 if (err)
12059 goto err_trap_policer_register;
12060 }
12061 return 0;
12062
12063err_trap_policer_register:
12064err_trap_policer_verify:
12065 for (i--; i >= 0; i--)
12066 devlink_trap_policer_unregister(devlink, &policers[i]);
12067 return err;
12068}
12069EXPORT_SYMBOL_GPL(devl_trap_policers_register);
12070
12071/**
12072 * devl_trap_policers_unregister - Unregister packet trap policers from devlink.
12073 * @devlink: devlink.
12074 * @policers: Packet trap policers.
12075 * @policers_count: Count of provided packet trap policers.
12076 */
12077void
12078devl_trap_policers_unregister(struct devlink *devlink,
12079 const struct devlink_trap_policer *policers,
12080 size_t policers_count)
12081{
12082 int i;
12083
12084 devl_assert_locked(devlink);
12085 for (i = policers_count - 1; i >= 0; i--)
12086 devlink_trap_policer_unregister(devlink, &policers[i]);
12087}
12088EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
12089
12090static void __devlink_compat_running_version(struct devlink *devlink,
12091 char *buf, size_t len)
12092{
12093 struct devlink_info_req req = {};
12094 const struct nlattr *nlattr;
12095 struct sk_buff *msg;
12096 int rem, err;
12097
12098 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12099 if (!msg)
12100 return;
12101
12102 req.msg = msg;
12103 err = devlink->ops->info_get(devlink, &req, NULL);
12104 if (err)
12105 goto free_msg;
12106
12107 nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
12108 const struct nlattr *kv;
12109 int rem_kv;
12110
12111 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
12112 continue;
12113
12114 nla_for_each_nested(kv, nlattr, rem_kv) {
12115 if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
12116 continue;
12117
12118 strlcat(buf, nla_data(kv), len);
12119 strlcat(buf, " ", len);
12120 }
12121 }
12122free_msg:
12123 nlmsg_free(msg);
12124}
12125
12126void devlink_compat_running_version(struct devlink *devlink,
12127 char *buf, size_t len)
12128{
12129 if (!devlink->ops->info_get)
12130 return;
12131
12132 devl_lock(devlink);
12133 if (devl_is_registered(devlink))
12134 __devlink_compat_running_version(devlink, buf, len);
12135 devl_unlock(devlink);
12136}
12137
12138int devlink_compat_flash_update(struct devlink *devlink, const char *file_name)
12139{
12140 struct devlink_flash_update_params params = {};
12141 int ret;
12142
12143 devl_lock(devlink);
12144 if (!devl_is_registered(devlink)) {
12145 ret = -ENODEV;
12146 goto out_unlock;
12147 }
12148
12149 if (!devlink->ops->flash_update) {
12150 ret = -EOPNOTSUPP;
12151 goto out_unlock;
12152 }
12153
12154 ret = request_firmware(&params.fw, file_name, devlink->dev);
12155 if (ret)
12156 goto out_unlock;
12157
12158 devlink_flash_update_begin_notify(devlink);
12159 ret = devlink->ops->flash_update(devlink, &params, NULL);
12160 devlink_flash_update_end_notify(devlink);
12161
12162 release_firmware(params.fw);
12163out_unlock:
12164 devl_unlock(devlink);
12165
12166 return ret;
12167}
12168
12169int devlink_compat_phys_port_name_get(struct net_device *dev,
12170 char *name, size_t len)
12171{
12172 struct devlink_port *devlink_port;
12173
12174 /* RTNL mutex is held here which ensures that devlink_port
12175 * instance cannot disappear in the middle. No need to take
12176 * any devlink lock as only permanent values are accessed.
12177 */
12178 ASSERT_RTNL();
12179
12180 devlink_port = dev->devlink_port;
12181 if (!devlink_port)
12182 return -EOPNOTSUPP;
12183
12184 return __devlink_port_phys_port_name_get(devlink_port, name, len);
12185}
12186
12187int devlink_compat_switch_id_get(struct net_device *dev,
12188 struct netdev_phys_item_id *ppid)
12189{
12190 struct devlink_port *devlink_port;
12191
12192 /* Caller must hold RTNL mutex or reference to dev, which ensures that
12193 * devlink_port instance cannot disappear in the middle. No need to take
12194 * any devlink lock as only permanent values are accessed.
12195 */
12196 devlink_port = dev->devlink_port;
12197 if (!devlink_port || !devlink_port->switch_port)
12198 return -EOPNOTSUPP;
12199
12200 memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
12201
12202 return 0;
12203}