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