devlink: remove reporter reference counting
[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 };
7273
7274 void *
7275 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
7276 {
7277         return reporter->priv;
7278 }
7279 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
7280
7281 static struct devlink_health_reporter *
7282 __devlink_health_reporter_find_by_name(struct list_head *reporter_list,
7283                                        const char *reporter_name)
7284 {
7285         struct devlink_health_reporter *reporter;
7286
7287         list_for_each_entry(reporter, reporter_list, list)
7288                 if (!strcmp(reporter->ops->name, reporter_name))
7289                         return reporter;
7290         return NULL;
7291 }
7292
7293 static struct devlink_health_reporter *
7294 devlink_health_reporter_find_by_name(struct devlink *devlink,
7295                                      const char *reporter_name)
7296 {
7297         return __devlink_health_reporter_find_by_name(&devlink->reporter_list,
7298                                                       reporter_name);
7299 }
7300
7301 static struct devlink_health_reporter *
7302 devlink_port_health_reporter_find_by_name(struct devlink_port *devlink_port,
7303                                           const char *reporter_name)
7304 {
7305         return __devlink_health_reporter_find_by_name(&devlink_port->reporter_list,
7306                                                       reporter_name);
7307 }
7308
7309 static struct devlink_health_reporter *
7310 __devlink_health_reporter_create(struct devlink *devlink,
7311                                  const struct devlink_health_reporter_ops *ops,
7312                                  u64 graceful_period, void *priv)
7313 {
7314         struct devlink_health_reporter *reporter;
7315
7316         if (WARN_ON(graceful_period && !ops->recover))
7317                 return ERR_PTR(-EINVAL);
7318
7319         reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
7320         if (!reporter)
7321                 return ERR_PTR(-ENOMEM);
7322
7323         reporter->priv = priv;
7324         reporter->ops = ops;
7325         reporter->devlink = devlink;
7326         reporter->graceful_period = graceful_period;
7327         reporter->auto_recover = !!ops->recover;
7328         reporter->auto_dump = !!ops->dump;
7329         mutex_init(&reporter->dump_lock);
7330         return reporter;
7331 }
7332
7333 /**
7334  *      devl_port_health_reporter_create - create devlink health reporter for
7335  *                                         specified port instance
7336  *
7337  *      @port: devlink_port which should contain the new reporter
7338  *      @ops: ops
7339  *      @graceful_period: to avoid recovery loops, in msecs
7340  *      @priv: priv
7341  */
7342 struct devlink_health_reporter *
7343 devl_port_health_reporter_create(struct devlink_port *port,
7344                                  const struct devlink_health_reporter_ops *ops,
7345                                  u64 graceful_period, void *priv)
7346 {
7347         struct devlink_health_reporter *reporter;
7348
7349         devl_assert_locked(port->devlink);
7350
7351         if (__devlink_health_reporter_find_by_name(&port->reporter_list,
7352                                                    ops->name))
7353                 return ERR_PTR(-EEXIST);
7354
7355         reporter = __devlink_health_reporter_create(port->devlink, ops,
7356                                                     graceful_period, priv);
7357         if (IS_ERR(reporter))
7358                 return reporter;
7359
7360         reporter->devlink_port = port;
7361         list_add_tail(&reporter->list, &port->reporter_list);
7362         return reporter;
7363 }
7364 EXPORT_SYMBOL_GPL(devl_port_health_reporter_create);
7365
7366 struct devlink_health_reporter *
7367 devlink_port_health_reporter_create(struct devlink_port *port,
7368                                     const struct devlink_health_reporter_ops *ops,
7369                                     u64 graceful_period, void *priv)
7370 {
7371         struct devlink_health_reporter *reporter;
7372         struct devlink *devlink = port->devlink;
7373
7374         devl_lock(devlink);
7375         reporter = devl_port_health_reporter_create(port, ops,
7376                                                     graceful_period, priv);
7377         devl_unlock(devlink);
7378         return reporter;
7379 }
7380 EXPORT_SYMBOL_GPL(devlink_port_health_reporter_create);
7381
7382 /**
7383  *      devl_health_reporter_create - create devlink health reporter
7384  *
7385  *      @devlink: devlink
7386  *      @ops: ops
7387  *      @graceful_period: to avoid recovery loops, in msecs
7388  *      @priv: priv
7389  */
7390 struct devlink_health_reporter *
7391 devl_health_reporter_create(struct devlink *devlink,
7392                             const struct devlink_health_reporter_ops *ops,
7393                             u64 graceful_period, void *priv)
7394 {
7395         struct devlink_health_reporter *reporter;
7396
7397         devl_assert_locked(devlink);
7398
7399         if (devlink_health_reporter_find_by_name(devlink, ops->name))
7400                 return ERR_PTR(-EEXIST);
7401
7402         reporter = __devlink_health_reporter_create(devlink, ops,
7403                                                     graceful_period, priv);
7404         if (IS_ERR(reporter))
7405                 return reporter;
7406
7407         list_add_tail(&reporter->list, &devlink->reporter_list);
7408         return reporter;
7409 }
7410 EXPORT_SYMBOL_GPL(devl_health_reporter_create);
7411
7412 struct devlink_health_reporter *
7413 devlink_health_reporter_create(struct devlink *devlink,
7414                                const struct devlink_health_reporter_ops *ops,
7415                                u64 graceful_period, void *priv)
7416 {
7417         struct devlink_health_reporter *reporter;
7418
7419         devl_lock(devlink);
7420         reporter = devl_health_reporter_create(devlink, ops,
7421                                                graceful_period, priv);
7422         devl_unlock(devlink);
7423         return reporter;
7424 }
7425 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
7426
7427 static void
7428 devlink_health_reporter_free(struct devlink_health_reporter *reporter)
7429 {
7430         mutex_destroy(&reporter->dump_lock);
7431         if (reporter->dump_fmsg)
7432                 devlink_fmsg_free(reporter->dump_fmsg);
7433         kfree(reporter);
7434 }
7435
7436 /**
7437  *      devl_health_reporter_destroy - destroy devlink health reporter
7438  *
7439  *      @reporter: devlink health reporter to destroy
7440  */
7441 void
7442 devl_health_reporter_destroy(struct devlink_health_reporter *reporter)
7443 {
7444         devl_assert_locked(reporter->devlink);
7445
7446         list_del(&reporter->list);
7447         devlink_health_reporter_free(reporter);
7448 }
7449 EXPORT_SYMBOL_GPL(devl_health_reporter_destroy);
7450
7451 void
7452 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
7453 {
7454         struct devlink *devlink = reporter->devlink;
7455
7456         devl_lock(devlink);
7457         devl_health_reporter_destroy(reporter);
7458         devl_unlock(devlink);
7459 }
7460 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
7461
7462 static int
7463 devlink_nl_health_reporter_fill(struct sk_buff *msg,
7464                                 struct devlink_health_reporter *reporter,
7465                                 enum devlink_command cmd, u32 portid,
7466                                 u32 seq, int flags)
7467 {
7468         struct devlink *devlink = reporter->devlink;
7469         struct nlattr *reporter_attr;
7470         void *hdr;
7471
7472         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
7473         if (!hdr)
7474                 return -EMSGSIZE;
7475
7476         if (devlink_nl_put_handle(msg, devlink))
7477                 goto genlmsg_cancel;
7478
7479         if (reporter->devlink_port) {
7480                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, reporter->devlink_port->index))
7481                         goto genlmsg_cancel;
7482         }
7483         reporter_attr = nla_nest_start_noflag(msg,
7484                                               DEVLINK_ATTR_HEALTH_REPORTER);
7485         if (!reporter_attr)
7486                 goto genlmsg_cancel;
7487         if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
7488                            reporter->ops->name))
7489                 goto reporter_nest_cancel;
7490         if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
7491                        reporter->health_state))
7492                 goto reporter_nest_cancel;
7493         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
7494                               reporter->error_count, DEVLINK_ATTR_PAD))
7495                 goto reporter_nest_cancel;
7496         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
7497                               reporter->recovery_count, DEVLINK_ATTR_PAD))
7498                 goto reporter_nest_cancel;
7499         if (reporter->ops->recover &&
7500             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
7501                               reporter->graceful_period,
7502                               DEVLINK_ATTR_PAD))
7503                 goto reporter_nest_cancel;
7504         if (reporter->ops->recover &&
7505             nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
7506                        reporter->auto_recover))
7507                 goto reporter_nest_cancel;
7508         if (reporter->dump_fmsg &&
7509             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
7510                               jiffies_to_msecs(reporter->dump_ts),
7511                               DEVLINK_ATTR_PAD))
7512                 goto reporter_nest_cancel;
7513         if (reporter->dump_fmsg &&
7514             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS_NS,
7515                               reporter->dump_real_ts, DEVLINK_ATTR_PAD))
7516                 goto reporter_nest_cancel;
7517         if (reporter->ops->dump &&
7518             nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP,
7519                        reporter->auto_dump))
7520                 goto reporter_nest_cancel;
7521
7522         nla_nest_end(msg, reporter_attr);
7523         genlmsg_end(msg, hdr);
7524         return 0;
7525
7526 reporter_nest_cancel:
7527         nla_nest_end(msg, reporter_attr);
7528 genlmsg_cancel:
7529         genlmsg_cancel(msg, hdr);
7530         return -EMSGSIZE;
7531 }
7532
7533 static void devlink_recover_notify(struct devlink_health_reporter *reporter,
7534                                    enum devlink_command cmd)
7535 {
7536         struct devlink *devlink = reporter->devlink;
7537         struct sk_buff *msg;
7538         int err;
7539
7540         WARN_ON(cmd != DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7541         WARN_ON(!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED));
7542
7543         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7544         if (!msg)
7545                 return;
7546
7547         err = devlink_nl_health_reporter_fill(msg, reporter, cmd, 0, 0, 0);
7548         if (err) {
7549                 nlmsg_free(msg);
7550                 return;
7551         }
7552
7553         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink), msg,
7554                                 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
7555 }
7556
7557 void
7558 devlink_health_reporter_recovery_done(struct devlink_health_reporter *reporter)
7559 {
7560         reporter->recovery_count++;
7561         reporter->last_recovery_ts = jiffies;
7562 }
7563 EXPORT_SYMBOL_GPL(devlink_health_reporter_recovery_done);
7564
7565 static int
7566 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
7567                                 void *priv_ctx, struct netlink_ext_ack *extack)
7568 {
7569         int err;
7570
7571         if (reporter->health_state == DEVLINK_HEALTH_REPORTER_STATE_HEALTHY)
7572                 return 0;
7573
7574         if (!reporter->ops->recover)
7575                 return -EOPNOTSUPP;
7576
7577         err = reporter->ops->recover(reporter, priv_ctx, extack);
7578         if (err)
7579                 return err;
7580
7581         devlink_health_reporter_recovery_done(reporter);
7582         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
7583         devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7584
7585         return 0;
7586 }
7587
7588 static void
7589 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
7590 {
7591         if (!reporter->dump_fmsg)
7592                 return;
7593         devlink_fmsg_free(reporter->dump_fmsg);
7594         reporter->dump_fmsg = NULL;
7595 }
7596
7597 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
7598                                   void *priv_ctx,
7599                                   struct netlink_ext_ack *extack)
7600 {
7601         int err;
7602
7603         if (!reporter->ops->dump)
7604                 return 0;
7605
7606         if (reporter->dump_fmsg)
7607                 return 0;
7608
7609         reporter->dump_fmsg = devlink_fmsg_alloc();
7610         if (!reporter->dump_fmsg) {
7611                 err = -ENOMEM;
7612                 return err;
7613         }
7614
7615         err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
7616         if (err)
7617                 goto dump_err;
7618
7619         err = reporter->ops->dump(reporter, reporter->dump_fmsg,
7620                                   priv_ctx, extack);
7621         if (err)
7622                 goto dump_err;
7623
7624         err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
7625         if (err)
7626                 goto dump_err;
7627
7628         reporter->dump_ts = jiffies;
7629         reporter->dump_real_ts = ktime_get_real_ns();
7630
7631         return 0;
7632
7633 dump_err:
7634         devlink_health_dump_clear(reporter);
7635         return err;
7636 }
7637
7638 int devlink_health_report(struct devlink_health_reporter *reporter,
7639                           const char *msg, void *priv_ctx)
7640 {
7641         enum devlink_health_reporter_state prev_health_state;
7642         struct devlink *devlink = reporter->devlink;
7643         unsigned long recover_ts_threshold;
7644         int ret;
7645
7646         /* write a log message of the current error */
7647         WARN_ON(!msg);
7648         trace_devlink_health_report(devlink, reporter->ops->name, msg);
7649         reporter->error_count++;
7650         prev_health_state = reporter->health_state;
7651         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
7652         devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7653
7654         /* abort if the previous error wasn't recovered */
7655         recover_ts_threshold = reporter->last_recovery_ts +
7656                                msecs_to_jiffies(reporter->graceful_period);
7657         if (reporter->auto_recover &&
7658             (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
7659              (reporter->last_recovery_ts && reporter->recovery_count &&
7660               time_is_after_jiffies(recover_ts_threshold)))) {
7661                 trace_devlink_health_recover_aborted(devlink,
7662                                                      reporter->ops->name,
7663                                                      reporter->health_state,
7664                                                      jiffies -
7665                                                      reporter->last_recovery_ts);
7666                 return -ECANCELED;
7667         }
7668
7669         if (reporter->auto_dump) {
7670                 mutex_lock(&reporter->dump_lock);
7671                 /* store current dump of current error, for later analysis */
7672                 devlink_health_do_dump(reporter, priv_ctx, NULL);
7673                 mutex_unlock(&reporter->dump_lock);
7674         }
7675
7676         if (!reporter->auto_recover)
7677                 return 0;
7678
7679         devl_lock(devlink);
7680         ret = devlink_health_reporter_recover(reporter, priv_ctx, NULL);
7681         devl_unlock(devlink);
7682
7683         return ret;
7684 }
7685 EXPORT_SYMBOL_GPL(devlink_health_report);
7686
7687 static struct devlink_health_reporter *
7688 devlink_health_reporter_get_from_attrs(struct devlink *devlink,
7689                                        struct nlattr **attrs)
7690 {
7691         struct devlink_port *devlink_port;
7692         char *reporter_name;
7693
7694         if (!attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
7695                 return NULL;
7696
7697         reporter_name = nla_data(attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
7698         devlink_port = devlink_port_get_from_attrs(devlink, attrs);
7699         if (IS_ERR(devlink_port))
7700                 return devlink_health_reporter_find_by_name(devlink,
7701                                                             reporter_name);
7702         else
7703                 return devlink_port_health_reporter_find_by_name(devlink_port,
7704                                                                  reporter_name);
7705 }
7706
7707 static struct devlink_health_reporter *
7708 devlink_health_reporter_get_from_info(struct devlink *devlink,
7709                                       struct genl_info *info)
7710 {
7711         return devlink_health_reporter_get_from_attrs(devlink, info->attrs);
7712 }
7713
7714 static struct devlink_health_reporter *
7715 devlink_health_reporter_get_from_cb(struct netlink_callback *cb)
7716 {
7717         const struct genl_dumpit_info *info = genl_dumpit_info(cb);
7718         struct devlink_health_reporter *reporter;
7719         struct nlattr **attrs = info->attrs;
7720         struct devlink *devlink;
7721
7722         devlink = devlink_get_from_attrs_lock(sock_net(cb->skb->sk), attrs);
7723         if (IS_ERR(devlink))
7724                 return NULL;
7725         devl_unlock(devlink);
7726
7727         reporter = devlink_health_reporter_get_from_attrs(devlink, attrs);
7728         devlink_put(devlink);
7729         return reporter;
7730 }
7731
7732 void
7733 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
7734                                      enum devlink_health_reporter_state state)
7735 {
7736         if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
7737                     state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
7738                 return;
7739
7740         if (reporter->health_state == state)
7741                 return;
7742
7743         reporter->health_state = state;
7744         trace_devlink_health_reporter_state_update(reporter->devlink,
7745                                                    reporter->ops->name, state);
7746         devlink_recover_notify(reporter, DEVLINK_CMD_HEALTH_REPORTER_RECOVER);
7747 }
7748 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
7749
7750 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
7751                                                    struct genl_info *info)
7752 {
7753         struct devlink *devlink = info->user_ptr[0];
7754         struct devlink_health_reporter *reporter;
7755         struct sk_buff *msg;
7756         int err;
7757
7758         reporter = devlink_health_reporter_get_from_info(devlink, info);
7759         if (!reporter)
7760                 return -EINVAL;
7761
7762         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
7763         if (!msg)
7764                 return -ENOMEM;
7765
7766         err = devlink_nl_health_reporter_fill(msg, reporter,
7767                                               DEVLINK_CMD_HEALTH_REPORTER_GET,
7768                                               info->snd_portid, info->snd_seq,
7769                                               0);
7770         if (err) {
7771                 nlmsg_free(msg);
7772                 return err;
7773         }
7774
7775         return genlmsg_reply(msg, info);
7776 }
7777
7778 static int
7779 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
7780                                           struct netlink_callback *cb)
7781 {
7782         struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7783         struct devlink *devlink;
7784         int err;
7785
7786         devlink_dump_for_each_instance_get(msg, state, devlink) {
7787                 struct devlink_health_reporter *reporter;
7788                 struct devlink_port *port;
7789                 unsigned long port_index;
7790                 int idx = 0;
7791
7792                 devl_lock(devlink);
7793                 if (!devl_is_registered(devlink))
7794                         goto next_devlink;
7795
7796                 list_for_each_entry(reporter, &devlink->reporter_list,
7797                                     list) {
7798                         if (idx < state->idx) {
7799                                 idx++;
7800                                 continue;
7801                         }
7802                         err = devlink_nl_health_reporter_fill(
7803                                 msg, reporter, DEVLINK_CMD_HEALTH_REPORTER_GET,
7804                                 NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
7805                                 NLM_F_MULTI);
7806                         if (err) {
7807                                 devl_unlock(devlink);
7808                                 devlink_put(devlink);
7809                                 state->idx = idx;
7810                                 goto out;
7811                         }
7812                         idx++;
7813                 }
7814
7815                 xa_for_each(&devlink->ports, port_index, port) {
7816                         list_for_each_entry(reporter, &port->reporter_list, list) {
7817                                 if (idx < state->idx) {
7818                                         idx++;
7819                                         continue;
7820                                 }
7821                                 err = devlink_nl_health_reporter_fill(
7822                                         msg, reporter,
7823                                         DEVLINK_CMD_HEALTH_REPORTER_GET,
7824                                         NETLINK_CB(cb->skb).portid,
7825                                         cb->nlh->nlmsg_seq, NLM_F_MULTI);
7826                                 if (err) {
7827                                         devl_unlock(devlink);
7828                                         devlink_put(devlink);
7829                                         state->idx = idx;
7830                                         goto out;
7831                                 }
7832                                 idx++;
7833                         }
7834                 }
7835 next_devlink:
7836                 devl_unlock(devlink);
7837                 devlink_put(devlink);
7838         }
7839 out:
7840         return msg->len;
7841 }
7842
7843 static int
7844 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
7845                                         struct genl_info *info)
7846 {
7847         struct devlink *devlink = info->user_ptr[0];
7848         struct devlink_health_reporter *reporter;
7849
7850         reporter = devlink_health_reporter_get_from_info(devlink, info);
7851         if (!reporter)
7852                 return -EINVAL;
7853
7854         if (!reporter->ops->recover &&
7855             (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
7856              info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]))
7857                 return -EOPNOTSUPP;
7858
7859         if (!reporter->ops->dump &&
7860             info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
7861                 return -EOPNOTSUPP;
7862
7863         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
7864                 reporter->graceful_period =
7865                         nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
7866
7867         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
7868                 reporter->auto_recover =
7869                         nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
7870
7871         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP])
7872                 reporter->auto_dump =
7873                 nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_DUMP]);
7874
7875         return 0;
7876 }
7877
7878 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
7879                                                        struct genl_info *info)
7880 {
7881         struct devlink *devlink = info->user_ptr[0];
7882         struct devlink_health_reporter *reporter;
7883
7884         reporter = devlink_health_reporter_get_from_info(devlink, info);
7885         if (!reporter)
7886                 return -EINVAL;
7887
7888         return devlink_health_reporter_recover(reporter, NULL, info->extack);
7889 }
7890
7891 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
7892                                                         struct genl_info *info)
7893 {
7894         struct devlink *devlink = info->user_ptr[0];
7895         struct devlink_health_reporter *reporter;
7896         struct devlink_fmsg *fmsg;
7897         int err;
7898
7899         reporter = devlink_health_reporter_get_from_info(devlink, info);
7900         if (!reporter)
7901                 return -EINVAL;
7902
7903         if (!reporter->ops->diagnose)
7904                 return -EOPNOTSUPP;
7905
7906         fmsg = devlink_fmsg_alloc();
7907         if (!fmsg)
7908                 return -ENOMEM;
7909
7910         err = devlink_fmsg_obj_nest_start(fmsg);
7911         if (err)
7912                 return err;
7913
7914         err = reporter->ops->diagnose(reporter, fmsg, info->extack);
7915         if (err)
7916                 return err;
7917
7918         err = devlink_fmsg_obj_nest_end(fmsg);
7919         if (err)
7920                 return err;
7921
7922         return devlink_fmsg_snd(fmsg, info,
7923                                 DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
7924 }
7925
7926 static int
7927 devlink_nl_cmd_health_reporter_dump_get_dumpit(struct sk_buff *skb,
7928                                                struct netlink_callback *cb)
7929 {
7930         struct devlink_nl_dump_state *state = devlink_dump_state(cb);
7931         struct devlink_health_reporter *reporter;
7932         int err;
7933
7934         reporter = devlink_health_reporter_get_from_cb(cb);
7935         if (!reporter)
7936                 return -EINVAL;
7937
7938         if (!reporter->ops->dump)
7939                 return -EOPNOTSUPP;
7940
7941         mutex_lock(&reporter->dump_lock);
7942         if (!state->idx) {
7943                 err = devlink_health_do_dump(reporter, NULL, cb->extack);
7944                 if (err)
7945                         goto unlock;
7946                 state->dump_ts = reporter->dump_ts;
7947         }
7948         if (!reporter->dump_fmsg || state->dump_ts != reporter->dump_ts) {
7949                 NL_SET_ERR_MSG_MOD(cb->extack, "Dump trampled, please retry");
7950                 err = -EAGAIN;
7951                 goto unlock;
7952         }
7953
7954         err = devlink_fmsg_dumpit(reporter->dump_fmsg, skb, cb,
7955                                   DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET);
7956 unlock:
7957         mutex_unlock(&reporter->dump_lock);
7958         return err;
7959 }
7960
7961 static int
7962 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
7963                                                struct genl_info *info)
7964 {
7965         struct devlink *devlink = info->user_ptr[0];
7966         struct devlink_health_reporter *reporter;
7967
7968         reporter = devlink_health_reporter_get_from_info(devlink, info);
7969         if (!reporter)
7970                 return -EINVAL;
7971
7972         if (!reporter->ops->dump)
7973                 return -EOPNOTSUPP;
7974
7975         mutex_lock(&reporter->dump_lock);
7976         devlink_health_dump_clear(reporter);
7977         mutex_unlock(&reporter->dump_lock);
7978         return 0;
7979 }
7980
7981 static int devlink_nl_cmd_health_reporter_test_doit(struct sk_buff *skb,
7982                                                     struct genl_info *info)
7983 {
7984         struct devlink *devlink = info->user_ptr[0];
7985         struct devlink_health_reporter *reporter;
7986
7987         reporter = devlink_health_reporter_get_from_info(devlink, info);
7988         if (!reporter)
7989                 return -EINVAL;
7990
7991         if (!reporter->ops->test)
7992                 return -EOPNOTSUPP;
7993
7994         return reporter->ops->test(reporter, info->extack);
7995 }
7996
7997 struct devlink_stats {
7998         u64_stats_t rx_bytes;
7999         u64_stats_t rx_packets;
8000         struct u64_stats_sync syncp;
8001 };
8002
8003 /**
8004  * struct devlink_trap_policer_item - Packet trap policer attributes.
8005  * @policer: Immutable packet trap policer attributes.
8006  * @rate: Rate in packets / sec.
8007  * @burst: Burst size in packets.
8008  * @list: trap_policer_list member.
8009  *
8010  * Describes packet trap policer attributes. Created by devlink during trap
8011  * policer registration.
8012  */
8013 struct devlink_trap_policer_item {
8014         const struct devlink_trap_policer *policer;
8015         u64 rate;
8016         u64 burst;
8017         struct list_head list;
8018 };
8019
8020 /**
8021  * struct devlink_trap_group_item - Packet trap group attributes.
8022  * @group: Immutable packet trap group attributes.
8023  * @policer_item: Associated policer item. Can be NULL.
8024  * @list: trap_group_list member.
8025  * @stats: Trap group statistics.
8026  *
8027  * Describes packet trap group attributes. Created by devlink during trap
8028  * group registration.
8029  */
8030 struct devlink_trap_group_item {
8031         const struct devlink_trap_group *group;
8032         struct devlink_trap_policer_item *policer_item;
8033         struct list_head list;
8034         struct devlink_stats __percpu *stats;
8035 };
8036
8037 /**
8038  * struct devlink_trap_item - Packet trap attributes.
8039  * @trap: Immutable packet trap attributes.
8040  * @group_item: Associated group item.
8041  * @list: trap_list member.
8042  * @action: Trap action.
8043  * @stats: Trap statistics.
8044  * @priv: Driver private information.
8045  *
8046  * Describes both mutable and immutable packet trap attributes. Created by
8047  * devlink during trap registration and used for all trap related operations.
8048  */
8049 struct devlink_trap_item {
8050         const struct devlink_trap *trap;
8051         struct devlink_trap_group_item *group_item;
8052         struct list_head list;
8053         enum devlink_trap_action action;
8054         struct devlink_stats __percpu *stats;
8055         void *priv;
8056 };
8057
8058 static struct devlink_trap_policer_item *
8059 devlink_trap_policer_item_lookup(struct devlink *devlink, u32 id)
8060 {
8061         struct devlink_trap_policer_item *policer_item;
8062
8063         list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
8064                 if (policer_item->policer->id == id)
8065                         return policer_item;
8066         }
8067
8068         return NULL;
8069 }
8070
8071 static struct devlink_trap_item *
8072 devlink_trap_item_lookup(struct devlink *devlink, const char *name)
8073 {
8074         struct devlink_trap_item *trap_item;
8075
8076         list_for_each_entry(trap_item, &devlink->trap_list, list) {
8077                 if (!strcmp(trap_item->trap->name, name))
8078                         return trap_item;
8079         }
8080
8081         return NULL;
8082 }
8083
8084 static struct devlink_trap_item *
8085 devlink_trap_item_get_from_info(struct devlink *devlink,
8086                                 struct genl_info *info)
8087 {
8088         struct nlattr *attr;
8089
8090         if (!info->attrs[DEVLINK_ATTR_TRAP_NAME])
8091                 return NULL;
8092         attr = info->attrs[DEVLINK_ATTR_TRAP_NAME];
8093
8094         return devlink_trap_item_lookup(devlink, nla_data(attr));
8095 }
8096
8097 static int
8098 devlink_trap_action_get_from_info(struct genl_info *info,
8099                                   enum devlink_trap_action *p_trap_action)
8100 {
8101         u8 val;
8102
8103         val = nla_get_u8(info->attrs[DEVLINK_ATTR_TRAP_ACTION]);
8104         switch (val) {
8105         case DEVLINK_TRAP_ACTION_DROP:
8106         case DEVLINK_TRAP_ACTION_TRAP:
8107         case DEVLINK_TRAP_ACTION_MIRROR:
8108                 *p_trap_action = val;
8109                 break;
8110         default:
8111                 return -EINVAL;
8112         }
8113
8114         return 0;
8115 }
8116
8117 static int devlink_trap_metadata_put(struct sk_buff *msg,
8118                                      const struct devlink_trap *trap)
8119 {
8120         struct nlattr *attr;
8121
8122         attr = nla_nest_start(msg, DEVLINK_ATTR_TRAP_METADATA);
8123         if (!attr)
8124                 return -EMSGSIZE;
8125
8126         if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_IN_PORT) &&
8127             nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_IN_PORT))
8128                 goto nla_put_failure;
8129         if ((trap->metadata_cap & DEVLINK_TRAP_METADATA_TYPE_F_FA_COOKIE) &&
8130             nla_put_flag(msg, DEVLINK_ATTR_TRAP_METADATA_TYPE_FA_COOKIE))
8131                 goto nla_put_failure;
8132
8133         nla_nest_end(msg, attr);
8134
8135         return 0;
8136
8137 nla_put_failure:
8138         nla_nest_cancel(msg, attr);
8139         return -EMSGSIZE;
8140 }
8141
8142 static void devlink_trap_stats_read(struct devlink_stats __percpu *trap_stats,
8143                                     struct devlink_stats *stats)
8144 {
8145         int i;
8146
8147         memset(stats, 0, sizeof(*stats));
8148         for_each_possible_cpu(i) {
8149                 struct devlink_stats *cpu_stats;
8150                 u64 rx_packets, rx_bytes;
8151                 unsigned int start;
8152
8153                 cpu_stats = per_cpu_ptr(trap_stats, i);
8154                 do {
8155                         start = u64_stats_fetch_begin(&cpu_stats->syncp);
8156                         rx_packets = u64_stats_read(&cpu_stats->rx_packets);
8157                         rx_bytes = u64_stats_read(&cpu_stats->rx_bytes);
8158                 } while (u64_stats_fetch_retry(&cpu_stats->syncp, start));
8159
8160                 u64_stats_add(&stats->rx_packets, rx_packets);
8161                 u64_stats_add(&stats->rx_bytes, rx_bytes);
8162         }
8163 }
8164
8165 static int
8166 devlink_trap_group_stats_put(struct sk_buff *msg,
8167                              struct devlink_stats __percpu *trap_stats)
8168 {
8169         struct devlink_stats stats;
8170         struct nlattr *attr;
8171
8172         devlink_trap_stats_read(trap_stats, &stats);
8173
8174         attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8175         if (!attr)
8176                 return -EMSGSIZE;
8177
8178         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8179                               u64_stats_read(&stats.rx_packets),
8180                               DEVLINK_ATTR_PAD))
8181                 goto nla_put_failure;
8182
8183         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8184                               u64_stats_read(&stats.rx_bytes),
8185                               DEVLINK_ATTR_PAD))
8186                 goto nla_put_failure;
8187
8188         nla_nest_end(msg, attr);
8189
8190         return 0;
8191
8192 nla_put_failure:
8193         nla_nest_cancel(msg, attr);
8194         return -EMSGSIZE;
8195 }
8196
8197 static int devlink_trap_stats_put(struct sk_buff *msg, struct devlink *devlink,
8198                                   const struct devlink_trap_item *trap_item)
8199 {
8200         struct devlink_stats stats;
8201         struct nlattr *attr;
8202         u64 drops = 0;
8203         int err;
8204
8205         if (devlink->ops->trap_drop_counter_get) {
8206                 err = devlink->ops->trap_drop_counter_get(devlink,
8207                                                           trap_item->trap,
8208                                                           &drops);
8209                 if (err)
8210                         return err;
8211         }
8212
8213         devlink_trap_stats_read(trap_item->stats, &stats);
8214
8215         attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8216         if (!attr)
8217                 return -EMSGSIZE;
8218
8219         if (devlink->ops->trap_drop_counter_get &&
8220             nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8221                               DEVLINK_ATTR_PAD))
8222                 goto nla_put_failure;
8223
8224         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_PACKETS,
8225                               u64_stats_read(&stats.rx_packets),
8226                               DEVLINK_ATTR_PAD))
8227                 goto nla_put_failure;
8228
8229         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_BYTES,
8230                               u64_stats_read(&stats.rx_bytes),
8231                               DEVLINK_ATTR_PAD))
8232                 goto nla_put_failure;
8233
8234         nla_nest_end(msg, attr);
8235
8236         return 0;
8237
8238 nla_put_failure:
8239         nla_nest_cancel(msg, attr);
8240         return -EMSGSIZE;
8241 }
8242
8243 static int devlink_nl_trap_fill(struct sk_buff *msg, struct devlink *devlink,
8244                                 const struct devlink_trap_item *trap_item,
8245                                 enum devlink_command cmd, u32 portid, u32 seq,
8246                                 int flags)
8247 {
8248         struct devlink_trap_group_item *group_item = trap_item->group_item;
8249         void *hdr;
8250         int err;
8251
8252         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8253         if (!hdr)
8254                 return -EMSGSIZE;
8255
8256         if (devlink_nl_put_handle(msg, devlink))
8257                 goto nla_put_failure;
8258
8259         if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8260                            group_item->group->name))
8261                 goto nla_put_failure;
8262
8263         if (nla_put_string(msg, DEVLINK_ATTR_TRAP_NAME, trap_item->trap->name))
8264                 goto nla_put_failure;
8265
8266         if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_TYPE, trap_item->trap->type))
8267                 goto nla_put_failure;
8268
8269         if (trap_item->trap->generic &&
8270             nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8271                 goto nla_put_failure;
8272
8273         if (nla_put_u8(msg, DEVLINK_ATTR_TRAP_ACTION, trap_item->action))
8274                 goto nla_put_failure;
8275
8276         err = devlink_trap_metadata_put(msg, trap_item->trap);
8277         if (err)
8278                 goto nla_put_failure;
8279
8280         err = devlink_trap_stats_put(msg, devlink, trap_item);
8281         if (err)
8282                 goto nla_put_failure;
8283
8284         genlmsg_end(msg, hdr);
8285
8286         return 0;
8287
8288 nla_put_failure:
8289         genlmsg_cancel(msg, hdr);
8290         return -EMSGSIZE;
8291 }
8292
8293 static int devlink_nl_cmd_trap_get_doit(struct sk_buff *skb,
8294                                         struct genl_info *info)
8295 {
8296         struct netlink_ext_ack *extack = info->extack;
8297         struct devlink *devlink = info->user_ptr[0];
8298         struct devlink_trap_item *trap_item;
8299         struct sk_buff *msg;
8300         int err;
8301
8302         if (list_empty(&devlink->trap_list))
8303                 return -EOPNOTSUPP;
8304
8305         trap_item = devlink_trap_item_get_from_info(devlink, info);
8306         if (!trap_item) {
8307                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8308                 return -ENOENT;
8309         }
8310
8311         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8312         if (!msg)
8313                 return -ENOMEM;
8314
8315         err = devlink_nl_trap_fill(msg, devlink, trap_item,
8316                                    DEVLINK_CMD_TRAP_NEW, info->snd_portid,
8317                                    info->snd_seq, 0);
8318         if (err)
8319                 goto err_trap_fill;
8320
8321         return genlmsg_reply(msg, info);
8322
8323 err_trap_fill:
8324         nlmsg_free(msg);
8325         return err;
8326 }
8327
8328 static int
8329 devlink_nl_cmd_trap_get_dump_one(struct sk_buff *msg, struct devlink *devlink,
8330                                  struct netlink_callback *cb)
8331 {
8332         struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8333         struct devlink_trap_item *trap_item;
8334         int idx = 0;
8335         int err = 0;
8336
8337         list_for_each_entry(trap_item, &devlink->trap_list, list) {
8338                 if (idx < state->idx) {
8339                         idx++;
8340                         continue;
8341                 }
8342                 err = devlink_nl_trap_fill(msg, devlink, trap_item,
8343                                            DEVLINK_CMD_TRAP_NEW,
8344                                            NETLINK_CB(cb->skb).portid,
8345                                            cb->nlh->nlmsg_seq,
8346                                            NLM_F_MULTI);
8347                 if (err) {
8348                         state->idx = idx;
8349                         break;
8350                 }
8351                 idx++;
8352         }
8353
8354         return err;
8355 }
8356
8357 const struct devlink_gen_cmd devl_gen_trap = {
8358         .dump_one               = devlink_nl_cmd_trap_get_dump_one,
8359 };
8360
8361 static int __devlink_trap_action_set(struct devlink *devlink,
8362                                      struct devlink_trap_item *trap_item,
8363                                      enum devlink_trap_action trap_action,
8364                                      struct netlink_ext_ack *extack)
8365 {
8366         int err;
8367
8368         if (trap_item->action != trap_action &&
8369             trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP) {
8370                 NL_SET_ERR_MSG_MOD(extack, "Cannot change action of non-drop traps. Skipping");
8371                 return 0;
8372         }
8373
8374         err = devlink->ops->trap_action_set(devlink, trap_item->trap,
8375                                             trap_action, extack);
8376         if (err)
8377                 return err;
8378
8379         trap_item->action = trap_action;
8380
8381         return 0;
8382 }
8383
8384 static int devlink_trap_action_set(struct devlink *devlink,
8385                                    struct devlink_trap_item *trap_item,
8386                                    struct genl_info *info)
8387 {
8388         enum devlink_trap_action trap_action;
8389         int err;
8390
8391         if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8392                 return 0;
8393
8394         err = devlink_trap_action_get_from_info(info, &trap_action);
8395         if (err) {
8396                 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8397                 return -EINVAL;
8398         }
8399
8400         return __devlink_trap_action_set(devlink, trap_item, trap_action,
8401                                          info->extack);
8402 }
8403
8404 static int devlink_nl_cmd_trap_set_doit(struct sk_buff *skb,
8405                                         struct genl_info *info)
8406 {
8407         struct netlink_ext_ack *extack = info->extack;
8408         struct devlink *devlink = info->user_ptr[0];
8409         struct devlink_trap_item *trap_item;
8410
8411         if (list_empty(&devlink->trap_list))
8412                 return -EOPNOTSUPP;
8413
8414         trap_item = devlink_trap_item_get_from_info(devlink, info);
8415         if (!trap_item) {
8416                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap");
8417                 return -ENOENT;
8418         }
8419
8420         return devlink_trap_action_set(devlink, trap_item, info);
8421 }
8422
8423 static struct devlink_trap_group_item *
8424 devlink_trap_group_item_lookup(struct devlink *devlink, const char *name)
8425 {
8426         struct devlink_trap_group_item *group_item;
8427
8428         list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8429                 if (!strcmp(group_item->group->name, name))
8430                         return group_item;
8431         }
8432
8433         return NULL;
8434 }
8435
8436 static struct devlink_trap_group_item *
8437 devlink_trap_group_item_lookup_by_id(struct devlink *devlink, u16 id)
8438 {
8439         struct devlink_trap_group_item *group_item;
8440
8441         list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8442                 if (group_item->group->id == id)
8443                         return group_item;
8444         }
8445
8446         return NULL;
8447 }
8448
8449 static struct devlink_trap_group_item *
8450 devlink_trap_group_item_get_from_info(struct devlink *devlink,
8451                                       struct genl_info *info)
8452 {
8453         char *name;
8454
8455         if (!info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME])
8456                 return NULL;
8457         name = nla_data(info->attrs[DEVLINK_ATTR_TRAP_GROUP_NAME]);
8458
8459         return devlink_trap_group_item_lookup(devlink, name);
8460 }
8461
8462 static int
8463 devlink_nl_trap_group_fill(struct sk_buff *msg, struct devlink *devlink,
8464                            const struct devlink_trap_group_item *group_item,
8465                            enum devlink_command cmd, u32 portid, u32 seq,
8466                            int flags)
8467 {
8468         void *hdr;
8469         int err;
8470
8471         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8472         if (!hdr)
8473                 return -EMSGSIZE;
8474
8475         if (devlink_nl_put_handle(msg, devlink))
8476                 goto nla_put_failure;
8477
8478         if (nla_put_string(msg, DEVLINK_ATTR_TRAP_GROUP_NAME,
8479                            group_item->group->name))
8480                 goto nla_put_failure;
8481
8482         if (group_item->group->generic &&
8483             nla_put_flag(msg, DEVLINK_ATTR_TRAP_GENERIC))
8484                 goto nla_put_failure;
8485
8486         if (group_item->policer_item &&
8487             nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8488                         group_item->policer_item->policer->id))
8489                 goto nla_put_failure;
8490
8491         err = devlink_trap_group_stats_put(msg, group_item->stats);
8492         if (err)
8493                 goto nla_put_failure;
8494
8495         genlmsg_end(msg, hdr);
8496
8497         return 0;
8498
8499 nla_put_failure:
8500         genlmsg_cancel(msg, hdr);
8501         return -EMSGSIZE;
8502 }
8503
8504 static int devlink_nl_cmd_trap_group_get_doit(struct sk_buff *skb,
8505                                               struct genl_info *info)
8506 {
8507         struct netlink_ext_ack *extack = info->extack;
8508         struct devlink *devlink = info->user_ptr[0];
8509         struct devlink_trap_group_item *group_item;
8510         struct sk_buff *msg;
8511         int err;
8512
8513         if (list_empty(&devlink->trap_group_list))
8514                 return -EOPNOTSUPP;
8515
8516         group_item = devlink_trap_group_item_get_from_info(devlink, info);
8517         if (!group_item) {
8518                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8519                 return -ENOENT;
8520         }
8521
8522         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8523         if (!msg)
8524                 return -ENOMEM;
8525
8526         err = devlink_nl_trap_group_fill(msg, devlink, group_item,
8527                                          DEVLINK_CMD_TRAP_GROUP_NEW,
8528                                          info->snd_portid, info->snd_seq, 0);
8529         if (err)
8530                 goto err_trap_group_fill;
8531
8532         return genlmsg_reply(msg, info);
8533
8534 err_trap_group_fill:
8535         nlmsg_free(msg);
8536         return err;
8537 }
8538
8539 static int
8540 devlink_nl_cmd_trap_group_get_dump_one(struct sk_buff *msg,
8541                                        struct devlink *devlink,
8542                                        struct netlink_callback *cb)
8543 {
8544         struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8545         struct devlink_trap_group_item *group_item;
8546         int idx = 0;
8547         int err = 0;
8548
8549
8550         list_for_each_entry(group_item, &devlink->trap_group_list, list) {
8551                 if (idx < state->idx) {
8552                         idx++;
8553                         continue;
8554                 }
8555                 err = devlink_nl_trap_group_fill(msg, devlink, group_item,
8556                                                  DEVLINK_CMD_TRAP_GROUP_NEW,
8557                                                  NETLINK_CB(cb->skb).portid,
8558                                                  cb->nlh->nlmsg_seq,
8559                                                  NLM_F_MULTI);
8560                 if (err) {
8561                         state->idx = idx;
8562                         break;
8563                 }
8564                 idx++;
8565         }
8566
8567         return err;
8568 }
8569
8570 const struct devlink_gen_cmd devl_gen_trap_group = {
8571         .dump_one               = devlink_nl_cmd_trap_group_get_dump_one,
8572 };
8573
8574 static int
8575 __devlink_trap_group_action_set(struct devlink *devlink,
8576                                 struct devlink_trap_group_item *group_item,
8577                                 enum devlink_trap_action trap_action,
8578                                 struct netlink_ext_ack *extack)
8579 {
8580         const char *group_name = group_item->group->name;
8581         struct devlink_trap_item *trap_item;
8582         int err;
8583
8584         if (devlink->ops->trap_group_action_set) {
8585                 err = devlink->ops->trap_group_action_set(devlink, group_item->group,
8586                                                           trap_action, extack);
8587                 if (err)
8588                         return err;
8589
8590                 list_for_each_entry(trap_item, &devlink->trap_list, list) {
8591                         if (strcmp(trap_item->group_item->group->name, group_name))
8592                                 continue;
8593                         if (trap_item->action != trap_action &&
8594                             trap_item->trap->type != DEVLINK_TRAP_TYPE_DROP)
8595                                 continue;
8596                         trap_item->action = trap_action;
8597                 }
8598
8599                 return 0;
8600         }
8601
8602         list_for_each_entry(trap_item, &devlink->trap_list, list) {
8603                 if (strcmp(trap_item->group_item->group->name, group_name))
8604                         continue;
8605                 err = __devlink_trap_action_set(devlink, trap_item,
8606                                                 trap_action, extack);
8607                 if (err)
8608                         return err;
8609         }
8610
8611         return 0;
8612 }
8613
8614 static int
8615 devlink_trap_group_action_set(struct devlink *devlink,
8616                               struct devlink_trap_group_item *group_item,
8617                               struct genl_info *info, bool *p_modified)
8618 {
8619         enum devlink_trap_action trap_action;
8620         int err;
8621
8622         if (!info->attrs[DEVLINK_ATTR_TRAP_ACTION])
8623                 return 0;
8624
8625         err = devlink_trap_action_get_from_info(info, &trap_action);
8626         if (err) {
8627                 NL_SET_ERR_MSG_MOD(info->extack, "Invalid trap action");
8628                 return -EINVAL;
8629         }
8630
8631         err = __devlink_trap_group_action_set(devlink, group_item, trap_action,
8632                                               info->extack);
8633         if (err)
8634                 return err;
8635
8636         *p_modified = true;
8637
8638         return 0;
8639 }
8640
8641 static int devlink_trap_group_set(struct devlink *devlink,
8642                                   struct devlink_trap_group_item *group_item,
8643                                   struct genl_info *info)
8644 {
8645         struct devlink_trap_policer_item *policer_item;
8646         struct netlink_ext_ack *extack = info->extack;
8647         const struct devlink_trap_policer *policer;
8648         struct nlattr **attrs = info->attrs;
8649         u32 policer_id;
8650         int err;
8651
8652         if (!attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8653                 return 0;
8654
8655         if (!devlink->ops->trap_group_set)
8656                 return -EOPNOTSUPP;
8657
8658         policer_id = nla_get_u32(attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8659         policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
8660         if (policer_id && !policer_item) {
8661                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8662                 return -ENOENT;
8663         }
8664         policer = policer_item ? policer_item->policer : NULL;
8665
8666         err = devlink->ops->trap_group_set(devlink, group_item->group, policer,
8667                                            extack);
8668         if (err)
8669                 return err;
8670
8671         group_item->policer_item = policer_item;
8672
8673         return 0;
8674 }
8675
8676 static int devlink_nl_cmd_trap_group_set_doit(struct sk_buff *skb,
8677                                               struct genl_info *info)
8678 {
8679         struct netlink_ext_ack *extack = info->extack;
8680         struct devlink *devlink = info->user_ptr[0];
8681         struct devlink_trap_group_item *group_item;
8682         bool modified = false;
8683         int err;
8684
8685         if (list_empty(&devlink->trap_group_list))
8686                 return -EOPNOTSUPP;
8687
8688         group_item = devlink_trap_group_item_get_from_info(devlink, info);
8689         if (!group_item) {
8690                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap group");
8691                 return -ENOENT;
8692         }
8693
8694         err = devlink_trap_group_action_set(devlink, group_item, info,
8695                                             &modified);
8696         if (err)
8697                 return err;
8698
8699         err = devlink_trap_group_set(devlink, group_item, info);
8700         if (err)
8701                 goto err_trap_group_set;
8702
8703         return 0;
8704
8705 err_trap_group_set:
8706         if (modified)
8707                 NL_SET_ERR_MSG_MOD(extack, "Trap group set failed, but some changes were committed already");
8708         return err;
8709 }
8710
8711 static struct devlink_trap_policer_item *
8712 devlink_trap_policer_item_get_from_info(struct devlink *devlink,
8713                                         struct genl_info *info)
8714 {
8715         u32 id;
8716
8717         if (!info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID])
8718                 return NULL;
8719         id = nla_get_u32(info->attrs[DEVLINK_ATTR_TRAP_POLICER_ID]);
8720
8721         return devlink_trap_policer_item_lookup(devlink, id);
8722 }
8723
8724 static int
8725 devlink_trap_policer_stats_put(struct sk_buff *msg, struct devlink *devlink,
8726                                const struct devlink_trap_policer *policer)
8727 {
8728         struct nlattr *attr;
8729         u64 drops;
8730         int err;
8731
8732         if (!devlink->ops->trap_policer_counter_get)
8733                 return 0;
8734
8735         err = devlink->ops->trap_policer_counter_get(devlink, policer, &drops);
8736         if (err)
8737                 return err;
8738
8739         attr = nla_nest_start(msg, DEVLINK_ATTR_STATS);
8740         if (!attr)
8741                 return -EMSGSIZE;
8742
8743         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_STATS_RX_DROPPED, drops,
8744                               DEVLINK_ATTR_PAD))
8745                 goto nla_put_failure;
8746
8747         nla_nest_end(msg, attr);
8748
8749         return 0;
8750
8751 nla_put_failure:
8752         nla_nest_cancel(msg, attr);
8753         return -EMSGSIZE;
8754 }
8755
8756 static int
8757 devlink_nl_trap_policer_fill(struct sk_buff *msg, struct devlink *devlink,
8758                              const struct devlink_trap_policer_item *policer_item,
8759                              enum devlink_command cmd, u32 portid, u32 seq,
8760                              int flags)
8761 {
8762         void *hdr;
8763         int err;
8764
8765         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
8766         if (!hdr)
8767                 return -EMSGSIZE;
8768
8769         if (devlink_nl_put_handle(msg, devlink))
8770                 goto nla_put_failure;
8771
8772         if (nla_put_u32(msg, DEVLINK_ATTR_TRAP_POLICER_ID,
8773                         policer_item->policer->id))
8774                 goto nla_put_failure;
8775
8776         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_RATE,
8777                               policer_item->rate, DEVLINK_ATTR_PAD))
8778                 goto nla_put_failure;
8779
8780         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_TRAP_POLICER_BURST,
8781                               policer_item->burst, DEVLINK_ATTR_PAD))
8782                 goto nla_put_failure;
8783
8784         err = devlink_trap_policer_stats_put(msg, devlink,
8785                                              policer_item->policer);
8786         if (err)
8787                 goto nla_put_failure;
8788
8789         genlmsg_end(msg, hdr);
8790
8791         return 0;
8792
8793 nla_put_failure:
8794         genlmsg_cancel(msg, hdr);
8795         return -EMSGSIZE;
8796 }
8797
8798 static int devlink_nl_cmd_trap_policer_get_doit(struct sk_buff *skb,
8799                                                 struct genl_info *info)
8800 {
8801         struct devlink_trap_policer_item *policer_item;
8802         struct netlink_ext_ack *extack = info->extack;
8803         struct devlink *devlink = info->user_ptr[0];
8804         struct sk_buff *msg;
8805         int err;
8806
8807         if (list_empty(&devlink->trap_policer_list))
8808                 return -EOPNOTSUPP;
8809
8810         policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8811         if (!policer_item) {
8812                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8813                 return -ENOENT;
8814         }
8815
8816         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
8817         if (!msg)
8818                 return -ENOMEM;
8819
8820         err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
8821                                            DEVLINK_CMD_TRAP_POLICER_NEW,
8822                                            info->snd_portid, info->snd_seq, 0);
8823         if (err)
8824                 goto err_trap_policer_fill;
8825
8826         return genlmsg_reply(msg, info);
8827
8828 err_trap_policer_fill:
8829         nlmsg_free(msg);
8830         return err;
8831 }
8832
8833 static int
8834 devlink_nl_cmd_trap_policer_get_dump_one(struct sk_buff *msg,
8835                                          struct devlink *devlink,
8836                                          struct netlink_callback *cb)
8837 {
8838         struct devlink_nl_dump_state *state = devlink_dump_state(cb);
8839         struct devlink_trap_policer_item *policer_item;
8840         int idx = 0;
8841         int err = 0;
8842
8843         list_for_each_entry(policer_item, &devlink->trap_policer_list, list) {
8844                 if (idx < state->idx) {
8845                         idx++;
8846                         continue;
8847                 }
8848                 err = devlink_nl_trap_policer_fill(msg, devlink, policer_item,
8849                                                    DEVLINK_CMD_TRAP_POLICER_NEW,
8850                                                    NETLINK_CB(cb->skb).portid,
8851                                                    cb->nlh->nlmsg_seq,
8852                                                    NLM_F_MULTI);
8853                 if (err) {
8854                         state->idx = idx;
8855                         break;
8856                 }
8857                 idx++;
8858         }
8859
8860         return err;
8861 }
8862
8863 const struct devlink_gen_cmd devl_gen_trap_policer = {
8864         .dump_one               = devlink_nl_cmd_trap_policer_get_dump_one,
8865 };
8866
8867 static int
8868 devlink_trap_policer_set(struct devlink *devlink,
8869                          struct devlink_trap_policer_item *policer_item,
8870                          struct genl_info *info)
8871 {
8872         struct netlink_ext_ack *extack = info->extack;
8873         struct nlattr **attrs = info->attrs;
8874         u64 rate, burst;
8875         int err;
8876
8877         rate = policer_item->rate;
8878         burst = policer_item->burst;
8879
8880         if (attrs[DEVLINK_ATTR_TRAP_POLICER_RATE])
8881                 rate = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_RATE]);
8882
8883         if (attrs[DEVLINK_ATTR_TRAP_POLICER_BURST])
8884                 burst = nla_get_u64(attrs[DEVLINK_ATTR_TRAP_POLICER_BURST]);
8885
8886         if (rate < policer_item->policer->min_rate) {
8887                 NL_SET_ERR_MSG_MOD(extack, "Policer rate lower than limit");
8888                 return -EINVAL;
8889         }
8890
8891         if (rate > policer_item->policer->max_rate) {
8892                 NL_SET_ERR_MSG_MOD(extack, "Policer rate higher than limit");
8893                 return -EINVAL;
8894         }
8895
8896         if (burst < policer_item->policer->min_burst) {
8897                 NL_SET_ERR_MSG_MOD(extack, "Policer burst size lower than limit");
8898                 return -EINVAL;
8899         }
8900
8901         if (burst > policer_item->policer->max_burst) {
8902                 NL_SET_ERR_MSG_MOD(extack, "Policer burst size higher than limit");
8903                 return -EINVAL;
8904         }
8905
8906         err = devlink->ops->trap_policer_set(devlink, policer_item->policer,
8907                                              rate, burst, info->extack);
8908         if (err)
8909                 return err;
8910
8911         policer_item->rate = rate;
8912         policer_item->burst = burst;
8913
8914         return 0;
8915 }
8916
8917 static int devlink_nl_cmd_trap_policer_set_doit(struct sk_buff *skb,
8918                                                 struct genl_info *info)
8919 {
8920         struct devlink_trap_policer_item *policer_item;
8921         struct netlink_ext_ack *extack = info->extack;
8922         struct devlink *devlink = info->user_ptr[0];
8923
8924         if (list_empty(&devlink->trap_policer_list))
8925                 return -EOPNOTSUPP;
8926
8927         if (!devlink->ops->trap_policer_set)
8928                 return -EOPNOTSUPP;
8929
8930         policer_item = devlink_trap_policer_item_get_from_info(devlink, info);
8931         if (!policer_item) {
8932                 NL_SET_ERR_MSG_MOD(extack, "Device did not register this trap policer");
8933                 return -ENOENT;
8934         }
8935
8936         return devlink_trap_policer_set(devlink, policer_item, info);
8937 }
8938
8939 const struct genl_small_ops devlink_nl_ops[56] = {
8940         {
8941                 .cmd = DEVLINK_CMD_GET,
8942                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8943                 .doit = devlink_nl_cmd_get_doit,
8944                 .dumpit = devlink_nl_instance_iter_dump,
8945                 /* can be retrieved by unprivileged users */
8946         },
8947         {
8948                 .cmd = DEVLINK_CMD_PORT_GET,
8949                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8950                 .doit = devlink_nl_cmd_port_get_doit,
8951                 .dumpit = devlink_nl_instance_iter_dump,
8952                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8953                 /* can be retrieved by unprivileged users */
8954         },
8955         {
8956                 .cmd = DEVLINK_CMD_PORT_SET,
8957                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8958                 .doit = devlink_nl_cmd_port_set_doit,
8959                 .flags = GENL_ADMIN_PERM,
8960                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8961         },
8962         {
8963                 .cmd = DEVLINK_CMD_RATE_GET,
8964                 .doit = devlink_nl_cmd_rate_get_doit,
8965                 .dumpit = devlink_nl_instance_iter_dump,
8966                 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
8967                 /* can be retrieved by unprivileged users */
8968         },
8969         {
8970                 .cmd = DEVLINK_CMD_RATE_SET,
8971                 .doit = devlink_nl_cmd_rate_set_doit,
8972                 .flags = GENL_ADMIN_PERM,
8973                 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE,
8974         },
8975         {
8976                 .cmd = DEVLINK_CMD_RATE_NEW,
8977                 .doit = devlink_nl_cmd_rate_new_doit,
8978                 .flags = GENL_ADMIN_PERM,
8979         },
8980         {
8981                 .cmd = DEVLINK_CMD_RATE_DEL,
8982                 .doit = devlink_nl_cmd_rate_del_doit,
8983                 .flags = GENL_ADMIN_PERM,
8984                 .internal_flags = DEVLINK_NL_FLAG_NEED_RATE_NODE,
8985         },
8986         {
8987                 .cmd = DEVLINK_CMD_PORT_SPLIT,
8988                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8989                 .doit = devlink_nl_cmd_port_split_doit,
8990                 .flags = GENL_ADMIN_PERM,
8991                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8992         },
8993         {
8994                 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
8995                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
8996                 .doit = devlink_nl_cmd_port_unsplit_doit,
8997                 .flags = GENL_ADMIN_PERM,
8998                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
8999         },
9000         {
9001                 .cmd = DEVLINK_CMD_PORT_NEW,
9002                 .doit = devlink_nl_cmd_port_new_doit,
9003                 .flags = GENL_ADMIN_PERM,
9004         },
9005         {
9006                 .cmd = DEVLINK_CMD_PORT_DEL,
9007                 .doit = devlink_nl_cmd_port_del_doit,
9008                 .flags = GENL_ADMIN_PERM,
9009         },
9010         {
9011                 .cmd = DEVLINK_CMD_LINECARD_GET,
9012                 .doit = devlink_nl_cmd_linecard_get_doit,
9013                 .dumpit = devlink_nl_cmd_linecard_get_dumpit,
9014                 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9015                 /* can be retrieved by unprivileged users */
9016         },
9017         {
9018                 .cmd = DEVLINK_CMD_LINECARD_SET,
9019                 .doit = devlink_nl_cmd_linecard_set_doit,
9020                 .flags = GENL_ADMIN_PERM,
9021                 .internal_flags = DEVLINK_NL_FLAG_NEED_LINECARD,
9022         },
9023         {
9024                 .cmd = DEVLINK_CMD_SB_GET,
9025                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9026                 .doit = devlink_nl_cmd_sb_get_doit,
9027                 .dumpit = devlink_nl_instance_iter_dump,
9028                 /* can be retrieved by unprivileged users */
9029         },
9030         {
9031                 .cmd = DEVLINK_CMD_SB_POOL_GET,
9032                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9033                 .doit = devlink_nl_cmd_sb_pool_get_doit,
9034                 .dumpit = devlink_nl_instance_iter_dump,
9035                 /* can be retrieved by unprivileged users */
9036         },
9037         {
9038                 .cmd = DEVLINK_CMD_SB_POOL_SET,
9039                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9040                 .doit = devlink_nl_cmd_sb_pool_set_doit,
9041                 .flags = GENL_ADMIN_PERM,
9042         },
9043         {
9044                 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
9045                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9046                 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
9047                 .dumpit = devlink_nl_instance_iter_dump,
9048                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9049                 /* can be retrieved by unprivileged users */
9050         },
9051         {
9052                 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
9053                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9054                 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
9055                 .flags = GENL_ADMIN_PERM,
9056                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9057         },
9058         {
9059                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
9060                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9061                 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
9062                 .dumpit = devlink_nl_instance_iter_dump,
9063                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9064                 /* can be retrieved by unprivileged users */
9065         },
9066         {
9067                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
9068                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9069                 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
9070                 .flags = GENL_ADMIN_PERM,
9071                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9072         },
9073         {
9074                 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
9075                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9076                 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
9077                 .flags = GENL_ADMIN_PERM,
9078         },
9079         {
9080                 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
9081                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9082                 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
9083                 .flags = GENL_ADMIN_PERM,
9084         },
9085         {
9086                 .cmd = DEVLINK_CMD_ESWITCH_GET,
9087                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9088                 .doit = devlink_nl_cmd_eswitch_get_doit,
9089                 .flags = GENL_ADMIN_PERM,
9090         },
9091         {
9092                 .cmd = DEVLINK_CMD_ESWITCH_SET,
9093                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9094                 .doit = devlink_nl_cmd_eswitch_set_doit,
9095                 .flags = GENL_ADMIN_PERM,
9096         },
9097         {
9098                 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
9099                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9100                 .doit = devlink_nl_cmd_dpipe_table_get,
9101                 /* can be retrieved by unprivileged users */
9102         },
9103         {
9104                 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
9105                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9106                 .doit = devlink_nl_cmd_dpipe_entries_get,
9107                 /* can be retrieved by unprivileged users */
9108         },
9109         {
9110                 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
9111                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9112                 .doit = devlink_nl_cmd_dpipe_headers_get,
9113                 /* can be retrieved by unprivileged users */
9114         },
9115         {
9116                 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
9117                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9118                 .doit = devlink_nl_cmd_dpipe_table_counters_set,
9119                 .flags = GENL_ADMIN_PERM,
9120         },
9121         {
9122                 .cmd = DEVLINK_CMD_RESOURCE_SET,
9123                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9124                 .doit = devlink_nl_cmd_resource_set,
9125                 .flags = GENL_ADMIN_PERM,
9126         },
9127         {
9128                 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
9129                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9130                 .doit = devlink_nl_cmd_resource_dump,
9131                 /* can be retrieved by unprivileged users */
9132         },
9133         {
9134                 .cmd = DEVLINK_CMD_RELOAD,
9135                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9136                 .doit = devlink_nl_cmd_reload,
9137                 .flags = GENL_ADMIN_PERM,
9138         },
9139         {
9140                 .cmd = DEVLINK_CMD_PARAM_GET,
9141                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9142                 .doit = devlink_nl_cmd_param_get_doit,
9143                 .dumpit = devlink_nl_instance_iter_dump,
9144                 /* can be retrieved by unprivileged users */
9145         },
9146         {
9147                 .cmd = DEVLINK_CMD_PARAM_SET,
9148                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9149                 .doit = devlink_nl_cmd_param_set_doit,
9150                 .flags = GENL_ADMIN_PERM,
9151         },
9152         {
9153                 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
9154                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9155                 .doit = devlink_nl_cmd_port_param_get_doit,
9156                 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
9157                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9158                 /* can be retrieved by unprivileged users */
9159         },
9160         {
9161                 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
9162                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9163                 .doit = devlink_nl_cmd_port_param_set_doit,
9164                 .flags = GENL_ADMIN_PERM,
9165                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
9166         },
9167         {
9168                 .cmd = DEVLINK_CMD_REGION_GET,
9169                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9170                 .doit = devlink_nl_cmd_region_get_doit,
9171                 .dumpit = devlink_nl_instance_iter_dump,
9172                 .flags = GENL_ADMIN_PERM,
9173         },
9174         {
9175                 .cmd = DEVLINK_CMD_REGION_NEW,
9176                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9177                 .doit = devlink_nl_cmd_region_new,
9178                 .flags = GENL_ADMIN_PERM,
9179         },
9180         {
9181                 .cmd = DEVLINK_CMD_REGION_DEL,
9182                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9183                 .doit = devlink_nl_cmd_region_del,
9184                 .flags = GENL_ADMIN_PERM,
9185         },
9186         {
9187                 .cmd = DEVLINK_CMD_REGION_READ,
9188                 .validate = GENL_DONT_VALIDATE_STRICT |
9189                             GENL_DONT_VALIDATE_DUMP_STRICT,
9190                 .dumpit = devlink_nl_cmd_region_read_dumpit,
9191                 .flags = GENL_ADMIN_PERM,
9192         },
9193         {
9194                 .cmd = DEVLINK_CMD_INFO_GET,
9195                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9196                 .doit = devlink_nl_cmd_info_get_doit,
9197                 .dumpit = devlink_nl_instance_iter_dump,
9198                 /* can be retrieved by unprivileged users */
9199         },
9200         {
9201                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
9202                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9203                 .doit = devlink_nl_cmd_health_reporter_get_doit,
9204                 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
9205                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9206                 /* can be retrieved by unprivileged users */
9207         },
9208         {
9209                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
9210                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9211                 .doit = devlink_nl_cmd_health_reporter_set_doit,
9212                 .flags = GENL_ADMIN_PERM,
9213                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9214         },
9215         {
9216                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
9217                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9218                 .doit = devlink_nl_cmd_health_reporter_recover_doit,
9219                 .flags = GENL_ADMIN_PERM,
9220                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9221         },
9222         {
9223                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
9224                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9225                 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
9226                 .flags = GENL_ADMIN_PERM,
9227                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9228         },
9229         {
9230                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
9231                 .validate = GENL_DONT_VALIDATE_STRICT |
9232                             GENL_DONT_VALIDATE_DUMP_STRICT,
9233                 .dumpit = devlink_nl_cmd_health_reporter_dump_get_dumpit,
9234                 .flags = GENL_ADMIN_PERM,
9235         },
9236         {
9237                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
9238                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9239                 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
9240                 .flags = GENL_ADMIN_PERM,
9241                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9242         },
9243         {
9244                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_TEST,
9245                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9246                 .doit = devlink_nl_cmd_health_reporter_test_doit,
9247                 .flags = GENL_ADMIN_PERM,
9248                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK_OR_PORT,
9249         },
9250         {
9251                 .cmd = DEVLINK_CMD_FLASH_UPDATE,
9252                 .validate = GENL_DONT_VALIDATE_STRICT | GENL_DONT_VALIDATE_DUMP,
9253                 .doit = devlink_nl_cmd_flash_update,
9254                 .flags = GENL_ADMIN_PERM,
9255         },
9256         {
9257                 .cmd = DEVLINK_CMD_TRAP_GET,
9258                 .doit = devlink_nl_cmd_trap_get_doit,
9259                 .dumpit = devlink_nl_instance_iter_dump,
9260                 /* can be retrieved by unprivileged users */
9261         },
9262         {
9263                 .cmd = DEVLINK_CMD_TRAP_SET,
9264                 .doit = devlink_nl_cmd_trap_set_doit,
9265                 .flags = GENL_ADMIN_PERM,
9266         },
9267         {
9268                 .cmd = DEVLINK_CMD_TRAP_GROUP_GET,
9269                 .doit = devlink_nl_cmd_trap_group_get_doit,
9270                 .dumpit = devlink_nl_instance_iter_dump,
9271                 /* can be retrieved by unprivileged users */
9272         },
9273         {
9274                 .cmd = DEVLINK_CMD_TRAP_GROUP_SET,
9275                 .doit = devlink_nl_cmd_trap_group_set_doit,
9276                 .flags = GENL_ADMIN_PERM,
9277         },
9278         {
9279                 .cmd = DEVLINK_CMD_TRAP_POLICER_GET,
9280                 .doit = devlink_nl_cmd_trap_policer_get_doit,
9281                 .dumpit = devlink_nl_instance_iter_dump,
9282                 /* can be retrieved by unprivileged users */
9283         },
9284         {
9285                 .cmd = DEVLINK_CMD_TRAP_POLICER_SET,
9286                 .doit = devlink_nl_cmd_trap_policer_set_doit,
9287                 .flags = GENL_ADMIN_PERM,
9288         },
9289         {
9290                 .cmd = DEVLINK_CMD_SELFTESTS_GET,
9291                 .doit = devlink_nl_cmd_selftests_get_doit,
9292                 .dumpit = devlink_nl_instance_iter_dump,
9293                 /* can be retrieved by unprivileged users */
9294         },
9295         {
9296                 .cmd = DEVLINK_CMD_SELFTESTS_RUN,
9297                 .doit = devlink_nl_cmd_selftests_run,
9298                 .flags = GENL_ADMIN_PERM,
9299         },
9300         /* -- No new ops here! Use split ops going forward! -- */
9301 };
9302
9303 bool devlink_reload_actions_valid(const struct devlink_ops *ops)
9304 {
9305         const struct devlink_reload_combination *comb;
9306         int i;
9307
9308         if (!devlink_reload_supported(ops)) {
9309                 if (WARN_ON(ops->reload_actions))
9310                         return false;
9311                 return true;
9312         }
9313
9314         if (WARN_ON(!ops->reload_actions ||
9315                     ops->reload_actions & BIT(DEVLINK_RELOAD_ACTION_UNSPEC) ||
9316                     ops->reload_actions >= BIT(__DEVLINK_RELOAD_ACTION_MAX)))
9317                 return false;
9318
9319         if (WARN_ON(ops->reload_limits & BIT(DEVLINK_RELOAD_LIMIT_UNSPEC) ||
9320                     ops->reload_limits >= BIT(__DEVLINK_RELOAD_LIMIT_MAX)))
9321                 return false;
9322
9323         for (i = 0; i < ARRAY_SIZE(devlink_reload_invalid_combinations); i++)  {
9324                 comb = &devlink_reload_invalid_combinations[i];
9325                 if (ops->reload_actions == BIT(comb->action) &&
9326                     ops->reload_limits == BIT(comb->limit))
9327                         return false;
9328         }
9329         return true;
9330 }
9331
9332 static void
9333 devlink_trap_policer_notify(struct devlink *devlink,
9334                             const struct devlink_trap_policer_item *policer_item,
9335                             enum devlink_command cmd);
9336 static void
9337 devlink_trap_group_notify(struct devlink *devlink,
9338                           const struct devlink_trap_group_item *group_item,
9339                           enum devlink_command cmd);
9340 static void devlink_trap_notify(struct devlink *devlink,
9341                                 const struct devlink_trap_item *trap_item,
9342                                 enum devlink_command cmd);
9343
9344 void devlink_notify_register(struct devlink *devlink)
9345 {
9346         struct devlink_trap_policer_item *policer_item;
9347         struct devlink_trap_group_item *group_item;
9348         struct devlink_param_item *param_item;
9349         struct devlink_trap_item *trap_item;
9350         struct devlink_port *devlink_port;
9351         struct devlink_linecard *linecard;
9352         struct devlink_rate *rate_node;
9353         struct devlink_region *region;
9354         unsigned long port_index;
9355
9356         devlink_notify(devlink, DEVLINK_CMD_NEW);
9357         list_for_each_entry(linecard, &devlink->linecard_list, list)
9358                 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
9359
9360         xa_for_each(&devlink->ports, port_index, devlink_port)
9361                 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9362
9363         list_for_each_entry(policer_item, &devlink->trap_policer_list, list)
9364                 devlink_trap_policer_notify(devlink, policer_item,
9365                                             DEVLINK_CMD_TRAP_POLICER_NEW);
9366
9367         list_for_each_entry(group_item, &devlink->trap_group_list, list)
9368                 devlink_trap_group_notify(devlink, group_item,
9369                                           DEVLINK_CMD_TRAP_GROUP_NEW);
9370
9371         list_for_each_entry(trap_item, &devlink->trap_list, list)
9372                 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
9373
9374         list_for_each_entry(rate_node, &devlink->rate_list, list)
9375                 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
9376
9377         list_for_each_entry(region, &devlink->region_list, list)
9378                 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
9379
9380         list_for_each_entry(param_item, &devlink->param_list, list)
9381                 devlink_param_notify(devlink, 0, param_item,
9382                                      DEVLINK_CMD_PARAM_NEW);
9383 }
9384
9385 void devlink_notify_unregister(struct devlink *devlink)
9386 {
9387         struct devlink_trap_policer_item *policer_item;
9388         struct devlink_trap_group_item *group_item;
9389         struct devlink_param_item *param_item;
9390         struct devlink_trap_item *trap_item;
9391         struct devlink_port *devlink_port;
9392         struct devlink_rate *rate_node;
9393         struct devlink_region *region;
9394         unsigned long port_index;
9395
9396         list_for_each_entry_reverse(param_item, &devlink->param_list, list)
9397                 devlink_param_notify(devlink, 0, param_item,
9398                                      DEVLINK_CMD_PARAM_DEL);
9399
9400         list_for_each_entry_reverse(region, &devlink->region_list, list)
9401                 devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
9402
9403         list_for_each_entry_reverse(rate_node, &devlink->rate_list, list)
9404                 devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_DEL);
9405
9406         list_for_each_entry_reverse(trap_item, &devlink->trap_list, list)
9407                 devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
9408
9409         list_for_each_entry_reverse(group_item, &devlink->trap_group_list, list)
9410                 devlink_trap_group_notify(devlink, group_item,
9411                                           DEVLINK_CMD_TRAP_GROUP_DEL);
9412         list_for_each_entry_reverse(policer_item, &devlink->trap_policer_list,
9413                                     list)
9414                 devlink_trap_policer_notify(devlink, policer_item,
9415                                             DEVLINK_CMD_TRAP_POLICER_DEL);
9416
9417         xa_for_each(&devlink->ports, port_index, devlink_port)
9418                 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9419         devlink_notify(devlink, DEVLINK_CMD_DEL);
9420 }
9421
9422 static void devlink_port_type_warn(struct work_struct *work)
9423 {
9424         WARN(true, "Type was not set for devlink port.");
9425 }
9426
9427 static bool devlink_port_type_should_warn(struct devlink_port *devlink_port)
9428 {
9429         /* Ignore CPU and DSA flavours. */
9430         return devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_CPU &&
9431                devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_DSA &&
9432                devlink_port->attrs.flavour != DEVLINK_PORT_FLAVOUR_UNUSED;
9433 }
9434
9435 #define DEVLINK_PORT_TYPE_WARN_TIMEOUT (HZ * 3600)
9436
9437 static void devlink_port_type_warn_schedule(struct devlink_port *devlink_port)
9438 {
9439         if (!devlink_port_type_should_warn(devlink_port))
9440                 return;
9441         /* Schedule a work to WARN in case driver does not set port
9442          * type within timeout.
9443          */
9444         schedule_delayed_work(&devlink_port->type_warn_dw,
9445                               DEVLINK_PORT_TYPE_WARN_TIMEOUT);
9446 }
9447
9448 static void devlink_port_type_warn_cancel(struct devlink_port *devlink_port)
9449 {
9450         if (!devlink_port_type_should_warn(devlink_port))
9451                 return;
9452         cancel_delayed_work_sync(&devlink_port->type_warn_dw);
9453 }
9454
9455 /**
9456  * devlink_port_init() - Init devlink port
9457  *
9458  * @devlink: devlink
9459  * @devlink_port: devlink port
9460  *
9461  * Initialize essencial stuff that is needed for functions
9462  * that may be called before devlink port registration.
9463  * Call to this function is optional and not needed
9464  * in case the driver does not use such functions.
9465  */
9466 void devlink_port_init(struct devlink *devlink,
9467                        struct devlink_port *devlink_port)
9468 {
9469         if (devlink_port->initialized)
9470                 return;
9471         devlink_port->devlink = devlink;
9472         INIT_LIST_HEAD(&devlink_port->region_list);
9473         devlink_port->initialized = true;
9474 }
9475 EXPORT_SYMBOL_GPL(devlink_port_init);
9476
9477 /**
9478  * devlink_port_fini() - Deinitialize devlink port
9479  *
9480  * @devlink_port: devlink port
9481  *
9482  * Deinitialize essencial stuff that is in use for functions
9483  * that may be called after devlink port unregistration.
9484  * Call to this function is optional and not needed
9485  * in case the driver does not use such functions.
9486  */
9487 void devlink_port_fini(struct devlink_port *devlink_port)
9488 {
9489         WARN_ON(!list_empty(&devlink_port->region_list));
9490 }
9491 EXPORT_SYMBOL_GPL(devlink_port_fini);
9492
9493 /**
9494  * devl_port_register() - Register devlink port
9495  *
9496  * @devlink: devlink
9497  * @devlink_port: devlink port
9498  * @port_index: driver-specific numerical identifier of the port
9499  *
9500  * Register devlink port with provided port index. User can use
9501  * any indexing, even hw-related one. devlink_port structure
9502  * is convenient to be embedded inside user driver private structure.
9503  * Note that the caller should take care of zeroing the devlink_port
9504  * structure.
9505  */
9506 int devl_port_register(struct devlink *devlink,
9507                        struct devlink_port *devlink_port,
9508                        unsigned int port_index)
9509 {
9510         int err;
9511
9512         devl_assert_locked(devlink);
9513
9514         ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9515
9516         devlink_port_init(devlink, devlink_port);
9517         devlink_port->registered = true;
9518         devlink_port->index = port_index;
9519         spin_lock_init(&devlink_port->type_lock);
9520         INIT_LIST_HEAD(&devlink_port->reporter_list);
9521         err = xa_insert(&devlink->ports, port_index, devlink_port, GFP_KERNEL);
9522         if (err)
9523                 return err;
9524
9525         INIT_DELAYED_WORK(&devlink_port->type_warn_dw, &devlink_port_type_warn);
9526         devlink_port_type_warn_schedule(devlink_port);
9527         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9528         return 0;
9529 }
9530 EXPORT_SYMBOL_GPL(devl_port_register);
9531
9532 /**
9533  *      devlink_port_register - Register devlink port
9534  *
9535  *      @devlink: devlink
9536  *      @devlink_port: devlink port
9537  *      @port_index: driver-specific numerical identifier of the port
9538  *
9539  *      Register devlink port with provided port index. User can use
9540  *      any indexing, even hw-related one. devlink_port structure
9541  *      is convenient to be embedded inside user driver private structure.
9542  *      Note that the caller should take care of zeroing the devlink_port
9543  *      structure.
9544  *
9545  *      Context: Takes and release devlink->lock <mutex>.
9546  */
9547 int devlink_port_register(struct devlink *devlink,
9548                           struct devlink_port *devlink_port,
9549                           unsigned int port_index)
9550 {
9551         int err;
9552
9553         devl_lock(devlink);
9554         err = devl_port_register(devlink, devlink_port, port_index);
9555         devl_unlock(devlink);
9556         return err;
9557 }
9558 EXPORT_SYMBOL_GPL(devlink_port_register);
9559
9560 /**
9561  * devl_port_unregister() - Unregister devlink port
9562  *
9563  * @devlink_port: devlink port
9564  */
9565 void devl_port_unregister(struct devlink_port *devlink_port)
9566 {
9567         lockdep_assert_held(&devlink_port->devlink->lock);
9568         WARN_ON(devlink_port->type != DEVLINK_PORT_TYPE_NOTSET);
9569
9570         devlink_port_type_warn_cancel(devlink_port);
9571         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
9572         xa_erase(&devlink_port->devlink->ports, devlink_port->index);
9573         WARN_ON(!list_empty(&devlink_port->reporter_list));
9574         devlink_port->registered = false;
9575 }
9576 EXPORT_SYMBOL_GPL(devl_port_unregister);
9577
9578 /**
9579  *      devlink_port_unregister - Unregister devlink port
9580  *
9581  *      @devlink_port: devlink port
9582  *
9583  *      Context: Takes and release devlink->lock <mutex>.
9584  */
9585 void devlink_port_unregister(struct devlink_port *devlink_port)
9586 {
9587         struct devlink *devlink = devlink_port->devlink;
9588
9589         devl_lock(devlink);
9590         devl_port_unregister(devlink_port);
9591         devl_unlock(devlink);
9592 }
9593 EXPORT_SYMBOL_GPL(devlink_port_unregister);
9594
9595 static void devlink_port_type_netdev_checks(struct devlink_port *devlink_port,
9596                                             struct net_device *netdev)
9597 {
9598         const struct net_device_ops *ops = netdev->netdev_ops;
9599
9600         /* If driver registers devlink port, it should set devlink port
9601          * attributes accordingly so the compat functions are called
9602          * and the original ops are not used.
9603          */
9604         if (ops->ndo_get_phys_port_name) {
9605                 /* Some drivers use the same set of ndos for netdevs
9606                  * that have devlink_port registered and also for
9607                  * those who don't. Make sure that ndo_get_phys_port_name
9608                  * returns -EOPNOTSUPP here in case it is defined.
9609                  * Warn if not.
9610                  */
9611                 char name[IFNAMSIZ];
9612                 int err;
9613
9614                 err = ops->ndo_get_phys_port_name(netdev, name, sizeof(name));
9615                 WARN_ON(err != -EOPNOTSUPP);
9616         }
9617         if (ops->ndo_get_port_parent_id) {
9618                 /* Some drivers use the same set of ndos for netdevs
9619                  * that have devlink_port registered and also for
9620                  * those who don't. Make sure that ndo_get_port_parent_id
9621                  * returns -EOPNOTSUPP here in case it is defined.
9622                  * Warn if not.
9623                  */
9624                 struct netdev_phys_item_id ppid;
9625                 int err;
9626
9627                 err = ops->ndo_get_port_parent_id(netdev, &ppid);
9628                 WARN_ON(err != -EOPNOTSUPP);
9629         }
9630 }
9631
9632 static void __devlink_port_type_set(struct devlink_port *devlink_port,
9633                                     enum devlink_port_type type,
9634                                     void *type_dev)
9635 {
9636         struct net_device *netdev = type_dev;
9637
9638         ASSERT_DEVLINK_PORT_REGISTERED(devlink_port);
9639
9640         if (type == DEVLINK_PORT_TYPE_NOTSET) {
9641                 devlink_port_type_warn_schedule(devlink_port);
9642         } else {
9643                 devlink_port_type_warn_cancel(devlink_port);
9644                 if (type == DEVLINK_PORT_TYPE_ETH && netdev)
9645                         devlink_port_type_netdev_checks(devlink_port, netdev);
9646         }
9647
9648         spin_lock_bh(&devlink_port->type_lock);
9649         devlink_port->type = type;
9650         switch (type) {
9651         case DEVLINK_PORT_TYPE_ETH:
9652                 devlink_port->type_eth.netdev = netdev;
9653                 if (netdev) {
9654                         ASSERT_RTNL();
9655                         devlink_port->type_eth.ifindex = netdev->ifindex;
9656                         BUILD_BUG_ON(sizeof(devlink_port->type_eth.ifname) !=
9657                                      sizeof(netdev->name));
9658                         strcpy(devlink_port->type_eth.ifname, netdev->name);
9659                 }
9660                 break;
9661         case DEVLINK_PORT_TYPE_IB:
9662                 devlink_port->type_ib.ibdev = type_dev;
9663                 break;
9664         default:
9665                 break;
9666         }
9667         spin_unlock_bh(&devlink_port->type_lock);
9668         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
9669 }
9670
9671 /**
9672  *      devlink_port_type_eth_set - Set port type to Ethernet
9673  *
9674  *      @devlink_port: devlink port
9675  *
9676  *      If driver is calling this, most likely it is doing something wrong.
9677  */
9678 void devlink_port_type_eth_set(struct devlink_port *devlink_port)
9679 {
9680         dev_warn(devlink_port->devlink->dev,
9681                  "devlink port type for port %d set to Ethernet without a software interface reference, device type not supported by the kernel?\n",
9682                  devlink_port->index);
9683         __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH, NULL);
9684 }
9685 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
9686
9687 /**
9688  *      devlink_port_type_ib_set - Set port type to InfiniBand
9689  *
9690  *      @devlink_port: devlink port
9691  *      @ibdev: related IB device
9692  */
9693 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
9694                               struct ib_device *ibdev)
9695 {
9696         __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_IB, ibdev);
9697 }
9698 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
9699
9700 /**
9701  *      devlink_port_type_clear - Clear port type
9702  *
9703  *      @devlink_port: devlink port
9704  *
9705  *      If driver is calling this for clearing Ethernet type, most likely
9706  *      it is doing something wrong.
9707  */
9708 void devlink_port_type_clear(struct devlink_port *devlink_port)
9709 {
9710         if (devlink_port->type == DEVLINK_PORT_TYPE_ETH)
9711                 dev_warn(devlink_port->devlink->dev,
9712                          "devlink port type for port %d cleared without a software interface reference, device type not supported by the kernel?\n",
9713                          devlink_port->index);
9714         __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET, NULL);
9715 }
9716 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
9717
9718 int devlink_port_netdevice_event(struct notifier_block *nb,
9719                                  unsigned long event, void *ptr)
9720 {
9721         struct net_device *netdev = netdev_notifier_info_to_dev(ptr);
9722         struct devlink_port *devlink_port = netdev->devlink_port;
9723         struct devlink *devlink;
9724
9725         devlink = container_of(nb, struct devlink, netdevice_nb);
9726
9727         if (!devlink_port || devlink_port->devlink != devlink)
9728                 return NOTIFY_OK;
9729
9730         switch (event) {
9731         case NETDEV_POST_INIT:
9732                 /* Set the type but not netdev pointer. It is going to be set
9733                  * later on by NETDEV_REGISTER event. Happens once during
9734                  * netdevice register
9735                  */
9736                 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_ETH,
9737                                         NULL);
9738                 break;
9739         case NETDEV_REGISTER:
9740         case NETDEV_CHANGENAME:
9741                 /* Set the netdev on top of previously set type. Note this
9742                  * event happens also during net namespace change so here
9743                  * we take into account netdev pointer appearing in this
9744                  * namespace.
9745                  */
9746                 __devlink_port_type_set(devlink_port, devlink_port->type,
9747                                         netdev);
9748                 break;
9749         case NETDEV_UNREGISTER:
9750                 /* Clear netdev pointer, but not the type. This event happens
9751                  * also during net namespace change so we need to clear
9752                  * pointer to netdev that is going to another net namespace.
9753                  */
9754                 __devlink_port_type_set(devlink_port, devlink_port->type,
9755                                         NULL);
9756                 break;
9757         case NETDEV_PRE_UNINIT:
9758                 /* Clear the type and the netdev pointer. Happens one during
9759                  * netdevice unregister.
9760                  */
9761                 __devlink_port_type_set(devlink_port, DEVLINK_PORT_TYPE_NOTSET,
9762                                         NULL);
9763                 break;
9764         }
9765
9766         return NOTIFY_OK;
9767 }
9768
9769 static int __devlink_port_attrs_set(struct devlink_port *devlink_port,
9770                                     enum devlink_port_flavour flavour)
9771 {
9772         struct devlink_port_attrs *attrs = &devlink_port->attrs;
9773
9774         devlink_port->attrs_set = true;
9775         attrs->flavour = flavour;
9776         if (attrs->switch_id.id_len) {
9777                 devlink_port->switch_port = true;
9778                 if (WARN_ON(attrs->switch_id.id_len > MAX_PHYS_ITEM_ID_LEN))
9779                         attrs->switch_id.id_len = MAX_PHYS_ITEM_ID_LEN;
9780         } else {
9781                 devlink_port->switch_port = false;
9782         }
9783         return 0;
9784 }
9785
9786 /**
9787  *      devlink_port_attrs_set - Set port attributes
9788  *
9789  *      @devlink_port: devlink port
9790  *      @attrs: devlink port attrs
9791  */
9792 void devlink_port_attrs_set(struct devlink_port *devlink_port,
9793                             struct devlink_port_attrs *attrs)
9794 {
9795         int ret;
9796
9797         ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9798
9799         devlink_port->attrs = *attrs;
9800         ret = __devlink_port_attrs_set(devlink_port, attrs->flavour);
9801         if (ret)
9802                 return;
9803         WARN_ON(attrs->splittable && attrs->split);
9804 }
9805 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
9806
9807 /**
9808  *      devlink_port_attrs_pci_pf_set - Set PCI PF port attributes
9809  *
9810  *      @devlink_port: devlink port
9811  *      @controller: associated controller number for the devlink port instance
9812  *      @pf: associated PF for the devlink port instance
9813  *      @external: indicates if the port is for an external controller
9814  */
9815 void devlink_port_attrs_pci_pf_set(struct devlink_port *devlink_port, u32 controller,
9816                                    u16 pf, bool external)
9817 {
9818         struct devlink_port_attrs *attrs = &devlink_port->attrs;
9819         int ret;
9820
9821         ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9822
9823         ret = __devlink_port_attrs_set(devlink_port,
9824                                        DEVLINK_PORT_FLAVOUR_PCI_PF);
9825         if (ret)
9826                 return;
9827         attrs->pci_pf.controller = controller;
9828         attrs->pci_pf.pf = pf;
9829         attrs->pci_pf.external = external;
9830 }
9831 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_pf_set);
9832
9833 /**
9834  *      devlink_port_attrs_pci_vf_set - Set PCI VF port attributes
9835  *
9836  *      @devlink_port: devlink port
9837  *      @controller: associated controller number for the devlink port instance
9838  *      @pf: associated PF for the devlink port instance
9839  *      @vf: associated VF of a PF for the devlink port instance
9840  *      @external: indicates if the port is for an external controller
9841  */
9842 void devlink_port_attrs_pci_vf_set(struct devlink_port *devlink_port, u32 controller,
9843                                    u16 pf, u16 vf, bool external)
9844 {
9845         struct devlink_port_attrs *attrs = &devlink_port->attrs;
9846         int ret;
9847
9848         ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9849
9850         ret = __devlink_port_attrs_set(devlink_port,
9851                                        DEVLINK_PORT_FLAVOUR_PCI_VF);
9852         if (ret)
9853                 return;
9854         attrs->pci_vf.controller = controller;
9855         attrs->pci_vf.pf = pf;
9856         attrs->pci_vf.vf = vf;
9857         attrs->pci_vf.external = external;
9858 }
9859 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_vf_set);
9860
9861 /**
9862  *      devlink_port_attrs_pci_sf_set - Set PCI SF port attributes
9863  *
9864  *      @devlink_port: devlink port
9865  *      @controller: associated controller number for the devlink port instance
9866  *      @pf: associated PF for the devlink port instance
9867  *      @sf: associated SF of a PF for the devlink port instance
9868  *      @external: indicates if the port is for an external controller
9869  */
9870 void devlink_port_attrs_pci_sf_set(struct devlink_port *devlink_port, u32 controller,
9871                                    u16 pf, u32 sf, bool external)
9872 {
9873         struct devlink_port_attrs *attrs = &devlink_port->attrs;
9874         int ret;
9875
9876         ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
9877
9878         ret = __devlink_port_attrs_set(devlink_port,
9879                                        DEVLINK_PORT_FLAVOUR_PCI_SF);
9880         if (ret)
9881                 return;
9882         attrs->pci_sf.controller = controller;
9883         attrs->pci_sf.pf = pf;
9884         attrs->pci_sf.sf = sf;
9885         attrs->pci_sf.external = external;
9886 }
9887 EXPORT_SYMBOL_GPL(devlink_port_attrs_pci_sf_set);
9888
9889 /**
9890  * devl_rate_node_create - create devlink rate node
9891  * @devlink: devlink instance
9892  * @priv: driver private data
9893  * @node_name: name of the resulting node
9894  * @parent: parent devlink_rate struct
9895  *
9896  * Create devlink rate object of type node
9897  */
9898 struct devlink_rate *
9899 devl_rate_node_create(struct devlink *devlink, void *priv, char *node_name,
9900                       struct devlink_rate *parent)
9901 {
9902         struct devlink_rate *rate_node;
9903
9904         rate_node = devlink_rate_node_get_by_name(devlink, node_name);
9905         if (!IS_ERR(rate_node))
9906                 return ERR_PTR(-EEXIST);
9907
9908         rate_node = kzalloc(sizeof(*rate_node), GFP_KERNEL);
9909         if (!rate_node)
9910                 return ERR_PTR(-ENOMEM);
9911
9912         if (parent) {
9913                 rate_node->parent = parent;
9914                 refcount_inc(&rate_node->parent->refcnt);
9915         }
9916
9917         rate_node->type = DEVLINK_RATE_TYPE_NODE;
9918         rate_node->devlink = devlink;
9919         rate_node->priv = priv;
9920
9921         rate_node->name = kstrdup(node_name, GFP_KERNEL);
9922         if (!rate_node->name) {
9923                 kfree(rate_node);
9924                 return ERR_PTR(-ENOMEM);
9925         }
9926
9927         refcount_set(&rate_node->refcnt, 1);
9928         list_add(&rate_node->list, &devlink->rate_list);
9929         devlink_rate_notify(rate_node, DEVLINK_CMD_RATE_NEW);
9930         return rate_node;
9931 }
9932 EXPORT_SYMBOL_GPL(devl_rate_node_create);
9933
9934 /**
9935  * devl_rate_leaf_create - create devlink rate leaf
9936  * @devlink_port: devlink port object to create rate object on
9937  * @priv: driver private data
9938  * @parent: parent devlink_rate struct
9939  *
9940  * Create devlink rate object of type leaf on provided @devlink_port.
9941  */
9942 int devl_rate_leaf_create(struct devlink_port *devlink_port, void *priv,
9943                           struct devlink_rate *parent)
9944 {
9945         struct devlink *devlink = devlink_port->devlink;
9946         struct devlink_rate *devlink_rate;
9947
9948         devl_assert_locked(devlink_port->devlink);
9949
9950         if (WARN_ON(devlink_port->devlink_rate))
9951                 return -EBUSY;
9952
9953         devlink_rate = kzalloc(sizeof(*devlink_rate), GFP_KERNEL);
9954         if (!devlink_rate)
9955                 return -ENOMEM;
9956
9957         if (parent) {
9958                 devlink_rate->parent = parent;
9959                 refcount_inc(&devlink_rate->parent->refcnt);
9960         }
9961
9962         devlink_rate->type = DEVLINK_RATE_TYPE_LEAF;
9963         devlink_rate->devlink = devlink;
9964         devlink_rate->devlink_port = devlink_port;
9965         devlink_rate->priv = priv;
9966         list_add_tail(&devlink_rate->list, &devlink->rate_list);
9967         devlink_port->devlink_rate = devlink_rate;
9968         devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_NEW);
9969
9970         return 0;
9971 }
9972 EXPORT_SYMBOL_GPL(devl_rate_leaf_create);
9973
9974 /**
9975  * devl_rate_leaf_destroy - destroy devlink rate leaf
9976  *
9977  * @devlink_port: devlink port linked to the rate object
9978  *
9979  * Destroy the devlink rate object of type leaf on provided @devlink_port.
9980  */
9981 void devl_rate_leaf_destroy(struct devlink_port *devlink_port)
9982 {
9983         struct devlink_rate *devlink_rate = devlink_port->devlink_rate;
9984
9985         devl_assert_locked(devlink_port->devlink);
9986         if (!devlink_rate)
9987                 return;
9988
9989         devlink_rate_notify(devlink_rate, DEVLINK_CMD_RATE_DEL);
9990         if (devlink_rate->parent)
9991                 refcount_dec(&devlink_rate->parent->refcnt);
9992         list_del(&devlink_rate->list);
9993         devlink_port->devlink_rate = NULL;
9994         kfree(devlink_rate);
9995 }
9996 EXPORT_SYMBOL_GPL(devl_rate_leaf_destroy);
9997
9998 /**
9999  * devl_rate_nodes_destroy - destroy all devlink rate nodes on device
10000  * @devlink: devlink instance
10001  *
10002  * Unset parent for all rate objects and destroy all rate nodes
10003  * on specified device.
10004  */
10005 void devl_rate_nodes_destroy(struct devlink *devlink)
10006 {
10007         static struct devlink_rate *devlink_rate, *tmp;
10008         const struct devlink_ops *ops = devlink->ops;
10009
10010         devl_assert_locked(devlink);
10011
10012         list_for_each_entry(devlink_rate, &devlink->rate_list, list) {
10013                 if (!devlink_rate->parent)
10014                         continue;
10015
10016                 refcount_dec(&devlink_rate->parent->refcnt);
10017                 if (devlink_rate_is_leaf(devlink_rate))
10018                         ops->rate_leaf_parent_set(devlink_rate, NULL, devlink_rate->priv,
10019                                                   NULL, NULL);
10020                 else if (devlink_rate_is_node(devlink_rate))
10021                         ops->rate_node_parent_set(devlink_rate, NULL, devlink_rate->priv,
10022                                                   NULL, NULL);
10023         }
10024         list_for_each_entry_safe(devlink_rate, tmp, &devlink->rate_list, list) {
10025                 if (devlink_rate_is_node(devlink_rate)) {
10026                         ops->rate_node_del(devlink_rate, devlink_rate->priv, NULL);
10027                         list_del(&devlink_rate->list);
10028                         kfree(devlink_rate->name);
10029                         kfree(devlink_rate);
10030                 }
10031         }
10032 }
10033 EXPORT_SYMBOL_GPL(devl_rate_nodes_destroy);
10034
10035 /**
10036  *      devlink_port_linecard_set - Link port with a linecard
10037  *
10038  *      @devlink_port: devlink port
10039  *      @linecard: devlink linecard
10040  */
10041 void devlink_port_linecard_set(struct devlink_port *devlink_port,
10042                                struct devlink_linecard *linecard)
10043 {
10044         ASSERT_DEVLINK_PORT_NOT_REGISTERED(devlink_port);
10045
10046         devlink_port->linecard = linecard;
10047 }
10048 EXPORT_SYMBOL_GPL(devlink_port_linecard_set);
10049
10050 static int __devlink_port_phys_port_name_get(struct devlink_port *devlink_port,
10051                                              char *name, size_t len)
10052 {
10053         struct devlink_port_attrs *attrs = &devlink_port->attrs;
10054         int n = 0;
10055
10056         if (!devlink_port->attrs_set)
10057                 return -EOPNOTSUPP;
10058
10059         switch (attrs->flavour) {
10060         case DEVLINK_PORT_FLAVOUR_PHYSICAL:
10061                 if (devlink_port->linecard)
10062                         n = snprintf(name, len, "l%u",
10063                                      devlink_port->linecard->index);
10064                 if (n < len)
10065                         n += snprintf(name + n, len - n, "p%u",
10066                                       attrs->phys.port_number);
10067                 if (n < len && attrs->split)
10068                         n += snprintf(name + n, len - n, "s%u",
10069                                       attrs->phys.split_subport_number);
10070                 break;
10071         case DEVLINK_PORT_FLAVOUR_CPU:
10072         case DEVLINK_PORT_FLAVOUR_DSA:
10073         case DEVLINK_PORT_FLAVOUR_UNUSED:
10074                 /* As CPU and DSA ports do not have a netdevice associated
10075                  * case should not ever happen.
10076                  */
10077                 WARN_ON(1);
10078                 return -EINVAL;
10079         case DEVLINK_PORT_FLAVOUR_PCI_PF:
10080                 if (attrs->pci_pf.external) {
10081                         n = snprintf(name, len, "c%u", attrs->pci_pf.controller);
10082                         if (n >= len)
10083                                 return -EINVAL;
10084                         len -= n;
10085                         name += n;
10086                 }
10087                 n = snprintf(name, len, "pf%u", attrs->pci_pf.pf);
10088                 break;
10089         case DEVLINK_PORT_FLAVOUR_PCI_VF:
10090                 if (attrs->pci_vf.external) {
10091                         n = snprintf(name, len, "c%u", attrs->pci_vf.controller);
10092                         if (n >= len)
10093                                 return -EINVAL;
10094                         len -= n;
10095                         name += n;
10096                 }
10097                 n = snprintf(name, len, "pf%uvf%u",
10098                              attrs->pci_vf.pf, attrs->pci_vf.vf);
10099                 break;
10100         case DEVLINK_PORT_FLAVOUR_PCI_SF:
10101                 if (attrs->pci_sf.external) {
10102                         n = snprintf(name, len, "c%u", attrs->pci_sf.controller);
10103                         if (n >= len)
10104                                 return -EINVAL;
10105                         len -= n;
10106                         name += n;
10107                 }
10108                 n = snprintf(name, len, "pf%usf%u", attrs->pci_sf.pf,
10109                              attrs->pci_sf.sf);
10110                 break;
10111         case DEVLINK_PORT_FLAVOUR_VIRTUAL:
10112                 return -EOPNOTSUPP;
10113         }
10114
10115         if (n >= len)
10116                 return -EINVAL;
10117
10118         return 0;
10119 }
10120
10121 static int devlink_linecard_types_init(struct devlink_linecard *linecard)
10122 {
10123         struct devlink_linecard_type *linecard_type;
10124         unsigned int count;
10125         int i;
10126
10127         count = linecard->ops->types_count(linecard, linecard->priv);
10128         linecard->types = kmalloc_array(count, sizeof(*linecard_type),
10129                                         GFP_KERNEL);
10130         if (!linecard->types)
10131                 return -ENOMEM;
10132         linecard->types_count = count;
10133
10134         for (i = 0; i < count; i++) {
10135                 linecard_type = &linecard->types[i];
10136                 linecard->ops->types_get(linecard, linecard->priv, i,
10137                                          &linecard_type->type,
10138                                          &linecard_type->priv);
10139         }
10140         return 0;
10141 }
10142
10143 static void devlink_linecard_types_fini(struct devlink_linecard *linecard)
10144 {
10145         kfree(linecard->types);
10146 }
10147
10148 /**
10149  *      devl_linecard_create - Create devlink linecard
10150  *
10151  *      @devlink: devlink
10152  *      @linecard_index: driver-specific numerical identifier of the linecard
10153  *      @ops: linecards ops
10154  *      @priv: user priv pointer
10155  *
10156  *      Create devlink linecard instance with provided linecard index.
10157  *      Caller can use any indexing, even hw-related one.
10158  *
10159  *      Return: Line card structure or an ERR_PTR() encoded error code.
10160  */
10161 struct devlink_linecard *
10162 devl_linecard_create(struct devlink *devlink, unsigned int linecard_index,
10163                      const struct devlink_linecard_ops *ops, void *priv)
10164 {
10165         struct devlink_linecard *linecard;
10166         int err;
10167
10168         if (WARN_ON(!ops || !ops->provision || !ops->unprovision ||
10169                     !ops->types_count || !ops->types_get))
10170                 return ERR_PTR(-EINVAL);
10171
10172         if (devlink_linecard_index_exists(devlink, linecard_index))
10173                 return ERR_PTR(-EEXIST);
10174
10175         linecard = kzalloc(sizeof(*linecard), GFP_KERNEL);
10176         if (!linecard)
10177                 return ERR_PTR(-ENOMEM);
10178
10179         linecard->devlink = devlink;
10180         linecard->index = linecard_index;
10181         linecard->ops = ops;
10182         linecard->priv = priv;
10183         linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10184         mutex_init(&linecard->state_lock);
10185
10186         err = devlink_linecard_types_init(linecard);
10187         if (err) {
10188                 mutex_destroy(&linecard->state_lock);
10189                 kfree(linecard);
10190                 return ERR_PTR(err);
10191         }
10192
10193         list_add_tail(&linecard->list, &devlink->linecard_list);
10194         devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10195         return linecard;
10196 }
10197 EXPORT_SYMBOL_GPL(devl_linecard_create);
10198
10199 /**
10200  *      devl_linecard_destroy - Destroy devlink linecard
10201  *
10202  *      @linecard: devlink linecard
10203  */
10204 void devl_linecard_destroy(struct devlink_linecard *linecard)
10205 {
10206         devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_DEL);
10207         list_del(&linecard->list);
10208         devlink_linecard_types_fini(linecard);
10209         mutex_destroy(&linecard->state_lock);
10210         kfree(linecard);
10211 }
10212 EXPORT_SYMBOL_GPL(devl_linecard_destroy);
10213
10214 /**
10215  *      devlink_linecard_provision_set - Set provisioning on linecard
10216  *
10217  *      @linecard: devlink linecard
10218  *      @type: linecard type
10219  *
10220  *      This is either called directly from the provision() op call or
10221  *      as a result of the provision() op call asynchronously.
10222  */
10223 void devlink_linecard_provision_set(struct devlink_linecard *linecard,
10224                                     const char *type)
10225 {
10226         mutex_lock(&linecard->state_lock);
10227         WARN_ON(linecard->type && strcmp(linecard->type, type));
10228         linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10229         linecard->type = type;
10230         devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10231         mutex_unlock(&linecard->state_lock);
10232 }
10233 EXPORT_SYMBOL_GPL(devlink_linecard_provision_set);
10234
10235 /**
10236  *      devlink_linecard_provision_clear - Clear provisioning on linecard
10237  *
10238  *      @linecard: devlink linecard
10239  *
10240  *      This is either called directly from the unprovision() op call or
10241  *      as a result of the unprovision() op call asynchronously.
10242  */
10243 void devlink_linecard_provision_clear(struct devlink_linecard *linecard)
10244 {
10245         mutex_lock(&linecard->state_lock);
10246         WARN_ON(linecard->nested_devlink);
10247         linecard->state = DEVLINK_LINECARD_STATE_UNPROVISIONED;
10248         linecard->type = NULL;
10249         devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10250         mutex_unlock(&linecard->state_lock);
10251 }
10252 EXPORT_SYMBOL_GPL(devlink_linecard_provision_clear);
10253
10254 /**
10255  *      devlink_linecard_provision_fail - Fail provisioning on linecard
10256  *
10257  *      @linecard: devlink linecard
10258  *
10259  *      This is either called directly from the provision() op call or
10260  *      as a result of the provision() op call asynchronously.
10261  */
10262 void devlink_linecard_provision_fail(struct devlink_linecard *linecard)
10263 {
10264         mutex_lock(&linecard->state_lock);
10265         WARN_ON(linecard->nested_devlink);
10266         linecard->state = DEVLINK_LINECARD_STATE_PROVISIONING_FAILED;
10267         devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10268         mutex_unlock(&linecard->state_lock);
10269 }
10270 EXPORT_SYMBOL_GPL(devlink_linecard_provision_fail);
10271
10272 /**
10273  *      devlink_linecard_activate - Set linecard active
10274  *
10275  *      @linecard: devlink linecard
10276  */
10277 void devlink_linecard_activate(struct devlink_linecard *linecard)
10278 {
10279         mutex_lock(&linecard->state_lock);
10280         WARN_ON(linecard->state != DEVLINK_LINECARD_STATE_PROVISIONED);
10281         linecard->state = DEVLINK_LINECARD_STATE_ACTIVE;
10282         devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10283         mutex_unlock(&linecard->state_lock);
10284 }
10285 EXPORT_SYMBOL_GPL(devlink_linecard_activate);
10286
10287 /**
10288  *      devlink_linecard_deactivate - Set linecard inactive
10289  *
10290  *      @linecard: devlink linecard
10291  */
10292 void devlink_linecard_deactivate(struct devlink_linecard *linecard)
10293 {
10294         mutex_lock(&linecard->state_lock);
10295         switch (linecard->state) {
10296         case DEVLINK_LINECARD_STATE_ACTIVE:
10297                 linecard->state = DEVLINK_LINECARD_STATE_PROVISIONED;
10298                 devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10299                 break;
10300         case DEVLINK_LINECARD_STATE_UNPROVISIONING:
10301                 /* Line card is being deactivated as part
10302                  * of unprovisioning flow.
10303                  */
10304                 break;
10305         default:
10306                 WARN_ON(1);
10307                 break;
10308         }
10309         mutex_unlock(&linecard->state_lock);
10310 }
10311 EXPORT_SYMBOL_GPL(devlink_linecard_deactivate);
10312
10313 /**
10314  *      devlink_linecard_nested_dl_set - Attach/detach nested devlink
10315  *                                       instance to linecard.
10316  *
10317  *      @linecard: devlink linecard
10318  *      @nested_devlink: devlink instance to attach or NULL to detach
10319  */
10320 void devlink_linecard_nested_dl_set(struct devlink_linecard *linecard,
10321                                     struct devlink *nested_devlink)
10322 {
10323         mutex_lock(&linecard->state_lock);
10324         linecard->nested_devlink = nested_devlink;
10325         devlink_linecard_notify(linecard, DEVLINK_CMD_LINECARD_NEW);
10326         mutex_unlock(&linecard->state_lock);
10327 }
10328 EXPORT_SYMBOL_GPL(devlink_linecard_nested_dl_set);
10329
10330 int devl_sb_register(struct devlink *devlink, unsigned int sb_index,
10331                      u32 size, u16 ingress_pools_count,
10332                      u16 egress_pools_count, u16 ingress_tc_count,
10333                      u16 egress_tc_count)
10334 {
10335         struct devlink_sb *devlink_sb;
10336
10337         lockdep_assert_held(&devlink->lock);
10338
10339         if (devlink_sb_index_exists(devlink, sb_index))
10340                 return -EEXIST;
10341
10342         devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
10343         if (!devlink_sb)
10344                 return -ENOMEM;
10345         devlink_sb->index = sb_index;
10346         devlink_sb->size = size;
10347         devlink_sb->ingress_pools_count = ingress_pools_count;
10348         devlink_sb->egress_pools_count = egress_pools_count;
10349         devlink_sb->ingress_tc_count = ingress_tc_count;
10350         devlink_sb->egress_tc_count = egress_tc_count;
10351         list_add_tail(&devlink_sb->list, &devlink->sb_list);
10352         return 0;
10353 }
10354 EXPORT_SYMBOL_GPL(devl_sb_register);
10355
10356 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
10357                         u32 size, u16 ingress_pools_count,
10358                         u16 egress_pools_count, u16 ingress_tc_count,
10359                         u16 egress_tc_count)
10360 {
10361         int err;
10362
10363         devl_lock(devlink);
10364         err = devl_sb_register(devlink, sb_index, size, ingress_pools_count,
10365                                egress_pools_count, ingress_tc_count,
10366                                egress_tc_count);
10367         devl_unlock(devlink);
10368         return err;
10369 }
10370 EXPORT_SYMBOL_GPL(devlink_sb_register);
10371
10372 void devl_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10373 {
10374         struct devlink_sb *devlink_sb;
10375
10376         lockdep_assert_held(&devlink->lock);
10377
10378         devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
10379         WARN_ON(!devlink_sb);
10380         list_del(&devlink_sb->list);
10381         kfree(devlink_sb);
10382 }
10383 EXPORT_SYMBOL_GPL(devl_sb_unregister);
10384
10385 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
10386 {
10387         devl_lock(devlink);
10388         devl_sb_unregister(devlink, sb_index);
10389         devl_unlock(devlink);
10390 }
10391 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
10392
10393 /**
10394  * devl_dpipe_headers_register - register dpipe headers
10395  *
10396  * @devlink: devlink
10397  * @dpipe_headers: dpipe header array
10398  *
10399  * Register the headers supported by hardware.
10400  */
10401 void devl_dpipe_headers_register(struct devlink *devlink,
10402                                  struct devlink_dpipe_headers *dpipe_headers)
10403 {
10404         lockdep_assert_held(&devlink->lock);
10405
10406         devlink->dpipe_headers = dpipe_headers;
10407 }
10408 EXPORT_SYMBOL_GPL(devl_dpipe_headers_register);
10409
10410 /**
10411  * devl_dpipe_headers_unregister - unregister dpipe headers
10412  *
10413  * @devlink: devlink
10414  *
10415  * Unregister the headers supported by hardware.
10416  */
10417 void devl_dpipe_headers_unregister(struct devlink *devlink)
10418 {
10419         lockdep_assert_held(&devlink->lock);
10420
10421         devlink->dpipe_headers = NULL;
10422 }
10423 EXPORT_SYMBOL_GPL(devl_dpipe_headers_unregister);
10424
10425 /**
10426  *      devlink_dpipe_table_counter_enabled - check if counter allocation
10427  *                                            required
10428  *      @devlink: devlink
10429  *      @table_name: tables name
10430  *
10431  *      Used by driver to check if counter allocation is required.
10432  *      After counter allocation is turned on the table entries
10433  *      are updated to include counter statistics.
10434  *
10435  *      After that point on the driver must respect the counter
10436  *      state so that each entry added to the table is added
10437  *      with a counter.
10438  */
10439 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
10440                                          const char *table_name)
10441 {
10442         struct devlink_dpipe_table *table;
10443         bool enabled;
10444
10445         rcu_read_lock();
10446         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10447                                          table_name, devlink);
10448         enabled = false;
10449         if (table)
10450                 enabled = table->counters_enabled;
10451         rcu_read_unlock();
10452         return enabled;
10453 }
10454 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
10455
10456 /**
10457  * devl_dpipe_table_register - register dpipe table
10458  *
10459  * @devlink: devlink
10460  * @table_name: table name
10461  * @table_ops: table ops
10462  * @priv: priv
10463  * @counter_control_extern: external control for counters
10464  */
10465 int devl_dpipe_table_register(struct devlink *devlink,
10466                               const char *table_name,
10467                               struct devlink_dpipe_table_ops *table_ops,
10468                               void *priv, bool counter_control_extern)
10469 {
10470         struct devlink_dpipe_table *table;
10471
10472         lockdep_assert_held(&devlink->lock);
10473
10474         if (WARN_ON(!table_ops->size_get))
10475                 return -EINVAL;
10476
10477         if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name,
10478                                      devlink))
10479                 return -EEXIST;
10480
10481         table = kzalloc(sizeof(*table), GFP_KERNEL);
10482         if (!table)
10483                 return -ENOMEM;
10484
10485         table->name = table_name;
10486         table->table_ops = table_ops;
10487         table->priv = priv;
10488         table->counter_control_extern = counter_control_extern;
10489
10490         list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
10491
10492         return 0;
10493 }
10494 EXPORT_SYMBOL_GPL(devl_dpipe_table_register);
10495
10496 /**
10497  * devl_dpipe_table_unregister - unregister dpipe table
10498  *
10499  * @devlink: devlink
10500  * @table_name: table name
10501  */
10502 void devl_dpipe_table_unregister(struct devlink *devlink,
10503                                  const char *table_name)
10504 {
10505         struct devlink_dpipe_table *table;
10506
10507         lockdep_assert_held(&devlink->lock);
10508
10509         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10510                                          table_name, devlink);
10511         if (!table)
10512                 return;
10513         list_del_rcu(&table->list);
10514         kfree_rcu(table, rcu);
10515 }
10516 EXPORT_SYMBOL_GPL(devl_dpipe_table_unregister);
10517
10518 /**
10519  * devl_resource_register - devlink resource register
10520  *
10521  * @devlink: devlink
10522  * @resource_name: resource's name
10523  * @resource_size: resource's size
10524  * @resource_id: resource's id
10525  * @parent_resource_id: resource's parent id
10526  * @size_params: size parameters
10527  *
10528  * Generic resources should reuse the same names across drivers.
10529  * Please see the generic resources list at:
10530  * Documentation/networking/devlink/devlink-resource.rst
10531  */
10532 int devl_resource_register(struct devlink *devlink,
10533                            const char *resource_name,
10534                            u64 resource_size,
10535                            u64 resource_id,
10536                            u64 parent_resource_id,
10537                            const struct devlink_resource_size_params *size_params)
10538 {
10539         struct devlink_resource *resource;
10540         struct list_head *resource_list;
10541         bool top_hierarchy;
10542
10543         lockdep_assert_held(&devlink->lock);
10544
10545         top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
10546
10547         resource = devlink_resource_find(devlink, NULL, resource_id);
10548         if (resource)
10549                 return -EINVAL;
10550
10551         resource = kzalloc(sizeof(*resource), GFP_KERNEL);
10552         if (!resource)
10553                 return -ENOMEM;
10554
10555         if (top_hierarchy) {
10556                 resource_list = &devlink->resource_list;
10557         } else {
10558                 struct devlink_resource *parent_resource;
10559
10560                 parent_resource = devlink_resource_find(devlink, NULL,
10561                                                         parent_resource_id);
10562                 if (parent_resource) {
10563                         resource_list = &parent_resource->resource_list;
10564                         resource->parent = parent_resource;
10565                 } else {
10566                         kfree(resource);
10567                         return -EINVAL;
10568                 }
10569         }
10570
10571         resource->name = resource_name;
10572         resource->size = resource_size;
10573         resource->size_new = resource_size;
10574         resource->id = resource_id;
10575         resource->size_valid = true;
10576         memcpy(&resource->size_params, size_params,
10577                sizeof(resource->size_params));
10578         INIT_LIST_HEAD(&resource->resource_list);
10579         list_add_tail(&resource->list, resource_list);
10580
10581         return 0;
10582 }
10583 EXPORT_SYMBOL_GPL(devl_resource_register);
10584
10585 /**
10586  *      devlink_resource_register - devlink resource register
10587  *
10588  *      @devlink: devlink
10589  *      @resource_name: resource's name
10590  *      @resource_size: resource's size
10591  *      @resource_id: resource's id
10592  *      @parent_resource_id: resource's parent id
10593  *      @size_params: size parameters
10594  *
10595  *      Generic resources should reuse the same names across drivers.
10596  *      Please see the generic resources list at:
10597  *      Documentation/networking/devlink/devlink-resource.rst
10598  *
10599  *      Context: Takes and release devlink->lock <mutex>.
10600  */
10601 int devlink_resource_register(struct devlink *devlink,
10602                               const char *resource_name,
10603                               u64 resource_size,
10604                               u64 resource_id,
10605                               u64 parent_resource_id,
10606                               const struct devlink_resource_size_params *size_params)
10607 {
10608         int err;
10609
10610         devl_lock(devlink);
10611         err = devl_resource_register(devlink, resource_name, resource_size,
10612                                      resource_id, parent_resource_id, size_params);
10613         devl_unlock(devlink);
10614         return err;
10615 }
10616 EXPORT_SYMBOL_GPL(devlink_resource_register);
10617
10618 static void devlink_resource_unregister(struct devlink *devlink,
10619                                         struct devlink_resource *resource)
10620 {
10621         struct devlink_resource *tmp, *child_resource;
10622
10623         list_for_each_entry_safe(child_resource, tmp, &resource->resource_list,
10624                                  list) {
10625                 devlink_resource_unregister(devlink, child_resource);
10626                 list_del(&child_resource->list);
10627                 kfree(child_resource);
10628         }
10629 }
10630
10631 /**
10632  * devl_resources_unregister - free all resources
10633  *
10634  * @devlink: devlink
10635  */
10636 void devl_resources_unregister(struct devlink *devlink)
10637 {
10638         struct devlink_resource *tmp, *child_resource;
10639
10640         lockdep_assert_held(&devlink->lock);
10641
10642         list_for_each_entry_safe(child_resource, tmp, &devlink->resource_list,
10643                                  list) {
10644                 devlink_resource_unregister(devlink, child_resource);
10645                 list_del(&child_resource->list);
10646                 kfree(child_resource);
10647         }
10648 }
10649 EXPORT_SYMBOL_GPL(devl_resources_unregister);
10650
10651 /**
10652  *      devlink_resources_unregister - free all resources
10653  *
10654  *      @devlink: devlink
10655  *
10656  *      Context: Takes and release devlink->lock <mutex>.
10657  */
10658 void devlink_resources_unregister(struct devlink *devlink)
10659 {
10660         devl_lock(devlink);
10661         devl_resources_unregister(devlink);
10662         devl_unlock(devlink);
10663 }
10664 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
10665
10666 /**
10667  * devl_resource_size_get - get and update size
10668  *
10669  * @devlink: devlink
10670  * @resource_id: the requested resource id
10671  * @p_resource_size: ptr to update
10672  */
10673 int devl_resource_size_get(struct devlink *devlink,
10674                            u64 resource_id,
10675                            u64 *p_resource_size)
10676 {
10677         struct devlink_resource *resource;
10678
10679         lockdep_assert_held(&devlink->lock);
10680
10681         resource = devlink_resource_find(devlink, NULL, resource_id);
10682         if (!resource)
10683                 return -EINVAL;
10684         *p_resource_size = resource->size_new;
10685         resource->size = resource->size_new;
10686         return 0;
10687 }
10688 EXPORT_SYMBOL_GPL(devl_resource_size_get);
10689
10690 /**
10691  * devl_dpipe_table_resource_set - set the resource id
10692  *
10693  * @devlink: devlink
10694  * @table_name: table name
10695  * @resource_id: resource id
10696  * @resource_units: number of resource's units consumed per table's entry
10697  */
10698 int devl_dpipe_table_resource_set(struct devlink *devlink,
10699                                   const char *table_name, u64 resource_id,
10700                                   u64 resource_units)
10701 {
10702         struct devlink_dpipe_table *table;
10703
10704         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
10705                                          table_name, devlink);
10706         if (!table)
10707                 return -EINVAL;
10708
10709         table->resource_id = resource_id;
10710         table->resource_units = resource_units;
10711         table->resource_valid = true;
10712         return 0;
10713 }
10714 EXPORT_SYMBOL_GPL(devl_dpipe_table_resource_set);
10715
10716 /**
10717  * devl_resource_occ_get_register - register occupancy getter
10718  *
10719  * @devlink: devlink
10720  * @resource_id: resource id
10721  * @occ_get: occupancy getter callback
10722  * @occ_get_priv: occupancy getter callback priv
10723  */
10724 void devl_resource_occ_get_register(struct devlink *devlink,
10725                                     u64 resource_id,
10726                                     devlink_resource_occ_get_t *occ_get,
10727                                     void *occ_get_priv)
10728 {
10729         struct devlink_resource *resource;
10730
10731         lockdep_assert_held(&devlink->lock);
10732
10733         resource = devlink_resource_find(devlink, NULL, resource_id);
10734         if (WARN_ON(!resource))
10735                 return;
10736         WARN_ON(resource->occ_get);
10737
10738         resource->occ_get = occ_get;
10739         resource->occ_get_priv = occ_get_priv;
10740 }
10741 EXPORT_SYMBOL_GPL(devl_resource_occ_get_register);
10742
10743 /**
10744  *      devlink_resource_occ_get_register - register occupancy getter
10745  *
10746  *      @devlink: devlink
10747  *      @resource_id: resource id
10748  *      @occ_get: occupancy getter callback
10749  *      @occ_get_priv: occupancy getter callback priv
10750  *
10751  *      Context: Takes and release devlink->lock <mutex>.
10752  */
10753 void devlink_resource_occ_get_register(struct devlink *devlink,
10754                                        u64 resource_id,
10755                                        devlink_resource_occ_get_t *occ_get,
10756                                        void *occ_get_priv)
10757 {
10758         devl_lock(devlink);
10759         devl_resource_occ_get_register(devlink, resource_id,
10760                                        occ_get, occ_get_priv);
10761         devl_unlock(devlink);
10762 }
10763 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
10764
10765 /**
10766  * devl_resource_occ_get_unregister - unregister occupancy getter
10767  *
10768  * @devlink: devlink
10769  * @resource_id: resource id
10770  */
10771 void devl_resource_occ_get_unregister(struct devlink *devlink,
10772                                       u64 resource_id)
10773 {
10774         struct devlink_resource *resource;
10775
10776         lockdep_assert_held(&devlink->lock);
10777
10778         resource = devlink_resource_find(devlink, NULL, resource_id);
10779         if (WARN_ON(!resource))
10780                 return;
10781         WARN_ON(!resource->occ_get);
10782
10783         resource->occ_get = NULL;
10784         resource->occ_get_priv = NULL;
10785 }
10786 EXPORT_SYMBOL_GPL(devl_resource_occ_get_unregister);
10787
10788 /**
10789  *      devlink_resource_occ_get_unregister - unregister occupancy getter
10790  *
10791  *      @devlink: devlink
10792  *      @resource_id: resource id
10793  *
10794  *      Context: Takes and release devlink->lock <mutex>.
10795  */
10796 void devlink_resource_occ_get_unregister(struct devlink *devlink,
10797                                          u64 resource_id)
10798 {
10799         devl_lock(devlink);
10800         devl_resource_occ_get_unregister(devlink, resource_id);
10801         devl_unlock(devlink);
10802 }
10803 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
10804
10805 static int devlink_param_verify(const struct devlink_param *param)
10806 {
10807         if (!param || !param->name || !param->supported_cmodes)
10808                 return -EINVAL;
10809         if (param->generic)
10810                 return devlink_param_generic_verify(param);
10811         else
10812                 return devlink_param_driver_verify(param);
10813 }
10814
10815 /**
10816  *      devlink_params_register - register configuration parameters
10817  *
10818  *      @devlink: devlink
10819  *      @params: configuration parameters array
10820  *      @params_count: number of parameters provided
10821  *
10822  *      Register the configuration parameters supported by the driver.
10823  */
10824 int devlink_params_register(struct devlink *devlink,
10825                             const struct devlink_param *params,
10826                             size_t params_count)
10827 {
10828         const struct devlink_param *param = params;
10829         int i, err;
10830
10831         for (i = 0; i < params_count; i++, param++) {
10832                 err = devlink_param_register(devlink, param);
10833                 if (err)
10834                         goto rollback;
10835         }
10836         return 0;
10837
10838 rollback:
10839         if (!i)
10840                 return err;
10841
10842         for (param--; i > 0; i--, param--)
10843                 devlink_param_unregister(devlink, param);
10844         return err;
10845 }
10846 EXPORT_SYMBOL_GPL(devlink_params_register);
10847
10848 /**
10849  *      devlink_params_unregister - unregister configuration parameters
10850  *      @devlink: devlink
10851  *      @params: configuration parameters to unregister
10852  *      @params_count: number of parameters provided
10853  */
10854 void devlink_params_unregister(struct devlink *devlink,
10855                                const struct devlink_param *params,
10856                                size_t params_count)
10857 {
10858         const struct devlink_param *param = params;
10859         int i;
10860
10861         for (i = 0; i < params_count; i++, param++)
10862                 devlink_param_unregister(devlink, param);
10863 }
10864 EXPORT_SYMBOL_GPL(devlink_params_unregister);
10865
10866 /**
10867  * devlink_param_register - register one configuration parameter
10868  *
10869  * @devlink: devlink
10870  * @param: one configuration parameter
10871  *
10872  * Register the configuration parameter supported by the driver.
10873  * Return: returns 0 on successful registration or error code otherwise.
10874  */
10875 int devlink_param_register(struct devlink *devlink,
10876                            const struct devlink_param *param)
10877 {
10878         struct devlink_param_item *param_item;
10879
10880         WARN_ON(devlink_param_verify(param));
10881         WARN_ON(devlink_param_find_by_name(&devlink->param_list, param->name));
10882
10883         if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
10884                 WARN_ON(param->get || param->set);
10885         else
10886                 WARN_ON(!param->get || !param->set);
10887
10888         param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
10889         if (!param_item)
10890                 return -ENOMEM;
10891
10892         param_item->param = param;
10893
10894         list_add_tail(&param_item->list, &devlink->param_list);
10895         devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
10896         return 0;
10897 }
10898 EXPORT_SYMBOL_GPL(devlink_param_register);
10899
10900 /**
10901  * devlink_param_unregister - unregister one configuration parameter
10902  * @devlink: devlink
10903  * @param: configuration parameter to unregister
10904  */
10905 void devlink_param_unregister(struct devlink *devlink,
10906                               const struct devlink_param *param)
10907 {
10908         struct devlink_param_item *param_item;
10909
10910         param_item =
10911                 devlink_param_find_by_name(&devlink->param_list, param->name);
10912         WARN_ON(!param_item);
10913         devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_DEL);
10914         list_del(&param_item->list);
10915         kfree(param_item);
10916 }
10917 EXPORT_SYMBOL_GPL(devlink_param_unregister);
10918
10919 /**
10920  *      devlink_param_driverinit_value_get - get configuration parameter
10921  *                                           value for driver initializing
10922  *
10923  *      @devlink: devlink
10924  *      @param_id: parameter ID
10925  *      @init_val: value of parameter in driverinit configuration mode
10926  *
10927  *      This function should be used by the driver to get driverinit
10928  *      configuration for initialization after reload command.
10929  */
10930 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
10931                                        union devlink_param_value *init_val)
10932 {
10933         struct devlink_param_item *param_item;
10934
10935         if (!devlink_reload_supported(devlink->ops))
10936                 return -EOPNOTSUPP;
10937
10938         param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
10939         if (!param_item)
10940                 return -EINVAL;
10941
10942         if (!param_item->driverinit_value_valid ||
10943             !devlink_param_cmode_is_supported(param_item->param,
10944                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
10945                 return -EOPNOTSUPP;
10946
10947         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
10948                 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
10949         else
10950                 *init_val = param_item->driverinit_value;
10951
10952         return 0;
10953 }
10954 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
10955
10956 /**
10957  *      devlink_param_driverinit_value_set - set value of configuration
10958  *                                           parameter for driverinit
10959  *                                           configuration mode
10960  *
10961  *      @devlink: devlink
10962  *      @param_id: parameter ID
10963  *      @init_val: value of parameter to set for driverinit configuration mode
10964  *
10965  *      This function should be used by the driver to set driverinit
10966  *      configuration mode default value.
10967  */
10968 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
10969                                        union devlink_param_value init_val)
10970 {
10971         struct devlink_param_item *param_item;
10972
10973         param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
10974         if (!param_item)
10975                 return -EINVAL;
10976
10977         if (!devlink_param_cmode_is_supported(param_item->param,
10978                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
10979                 return -EOPNOTSUPP;
10980
10981         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
10982                 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
10983         else
10984                 param_item->driverinit_value = init_val;
10985         param_item->driverinit_value_valid = true;
10986
10987         devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
10988         return 0;
10989 }
10990 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
10991
10992 /**
10993  *      devlink_param_value_changed - notify devlink on a parameter's value
10994  *                                    change. Should be called by the driver
10995  *                                    right after the change.
10996  *
10997  *      @devlink: devlink
10998  *      @param_id: parameter ID
10999  *
11000  *      This function should be used by the driver to notify devlink on value
11001  *      change, excluding driverinit configuration mode.
11002  *      For driverinit configuration mode driver should use the function
11003  */
11004 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
11005 {
11006         struct devlink_param_item *param_item;
11007
11008         param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
11009         WARN_ON(!param_item);
11010
11011         devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
11012 }
11013 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
11014
11015 /**
11016  * devl_region_create - create a new address region
11017  *
11018  * @devlink: devlink
11019  * @ops: region operations and name
11020  * @region_max_snapshots: Maximum supported number of snapshots for region
11021  * @region_size: size of region
11022  */
11023 struct devlink_region *devl_region_create(struct devlink *devlink,
11024                                           const struct devlink_region_ops *ops,
11025                                           u32 region_max_snapshots,
11026                                           u64 region_size)
11027 {
11028         struct devlink_region *region;
11029
11030         devl_assert_locked(devlink);
11031
11032         if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11033                 return ERR_PTR(-EINVAL);
11034
11035         if (devlink_region_get_by_name(devlink, ops->name))
11036                 return ERR_PTR(-EEXIST);
11037
11038         region = kzalloc(sizeof(*region), GFP_KERNEL);
11039         if (!region)
11040                 return ERR_PTR(-ENOMEM);
11041
11042         region->devlink = devlink;
11043         region->max_snapshots = region_max_snapshots;
11044         region->ops = ops;
11045         region->size = region_size;
11046         INIT_LIST_HEAD(&region->snapshot_list);
11047         mutex_init(&region->snapshot_lock);
11048         list_add_tail(&region->list, &devlink->region_list);
11049         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11050
11051         return region;
11052 }
11053 EXPORT_SYMBOL_GPL(devl_region_create);
11054
11055 /**
11056  *      devlink_region_create - create a new address region
11057  *
11058  *      @devlink: devlink
11059  *      @ops: region operations and name
11060  *      @region_max_snapshots: Maximum supported number of snapshots for region
11061  *      @region_size: size of region
11062  *
11063  *      Context: Takes and release devlink->lock <mutex>.
11064  */
11065 struct devlink_region *
11066 devlink_region_create(struct devlink *devlink,
11067                       const struct devlink_region_ops *ops,
11068                       u32 region_max_snapshots, u64 region_size)
11069 {
11070         struct devlink_region *region;
11071
11072         devl_lock(devlink);
11073         region = devl_region_create(devlink, ops, region_max_snapshots,
11074                                     region_size);
11075         devl_unlock(devlink);
11076         return region;
11077 }
11078 EXPORT_SYMBOL_GPL(devlink_region_create);
11079
11080 /**
11081  *      devlink_port_region_create - create a new address region for a port
11082  *
11083  *      @port: devlink port
11084  *      @ops: region operations and name
11085  *      @region_max_snapshots: Maximum supported number of snapshots for region
11086  *      @region_size: size of region
11087  *
11088  *      Context: Takes and release devlink->lock <mutex>.
11089  */
11090 struct devlink_region *
11091 devlink_port_region_create(struct devlink_port *port,
11092                            const struct devlink_port_region_ops *ops,
11093                            u32 region_max_snapshots, u64 region_size)
11094 {
11095         struct devlink *devlink = port->devlink;
11096         struct devlink_region *region;
11097         int err = 0;
11098
11099         ASSERT_DEVLINK_PORT_INITIALIZED(port);
11100
11101         if (WARN_ON(!ops) || WARN_ON(!ops->destructor))
11102                 return ERR_PTR(-EINVAL);
11103
11104         devl_lock(devlink);
11105
11106         if (devlink_port_region_get_by_name(port, ops->name)) {
11107                 err = -EEXIST;
11108                 goto unlock;
11109         }
11110
11111         region = kzalloc(sizeof(*region), GFP_KERNEL);
11112         if (!region) {
11113                 err = -ENOMEM;
11114                 goto unlock;
11115         }
11116
11117         region->devlink = devlink;
11118         region->port = port;
11119         region->max_snapshots = region_max_snapshots;
11120         region->port_ops = ops;
11121         region->size = region_size;
11122         INIT_LIST_HEAD(&region->snapshot_list);
11123         mutex_init(&region->snapshot_lock);
11124         list_add_tail(&region->list, &port->region_list);
11125         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
11126
11127         devl_unlock(devlink);
11128         return region;
11129
11130 unlock:
11131         devl_unlock(devlink);
11132         return ERR_PTR(err);
11133 }
11134 EXPORT_SYMBOL_GPL(devlink_port_region_create);
11135
11136 /**
11137  * devl_region_destroy - destroy address region
11138  *
11139  * @region: devlink region to destroy
11140  */
11141 void devl_region_destroy(struct devlink_region *region)
11142 {
11143         struct devlink *devlink = region->devlink;
11144         struct devlink_snapshot *snapshot, *ts;
11145
11146         devl_assert_locked(devlink);
11147
11148         /* Free all snapshots of region */
11149         mutex_lock(&region->snapshot_lock);
11150         list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
11151                 devlink_region_snapshot_del(region, snapshot);
11152         mutex_unlock(&region->snapshot_lock);
11153
11154         list_del(&region->list);
11155         mutex_destroy(&region->snapshot_lock);
11156
11157         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
11158         kfree(region);
11159 }
11160 EXPORT_SYMBOL_GPL(devl_region_destroy);
11161
11162 /**
11163  *      devlink_region_destroy - destroy address region
11164  *
11165  *      @region: devlink region to destroy
11166  *
11167  *      Context: Takes and release devlink->lock <mutex>.
11168  */
11169 void devlink_region_destroy(struct devlink_region *region)
11170 {
11171         struct devlink *devlink = region->devlink;
11172
11173         devl_lock(devlink);
11174         devl_region_destroy(region);
11175         devl_unlock(devlink);
11176 }
11177 EXPORT_SYMBOL_GPL(devlink_region_destroy);
11178
11179 /**
11180  *      devlink_region_snapshot_id_get - get snapshot ID
11181  *
11182  *      This callback should be called when adding a new snapshot,
11183  *      Driver should use the same id for multiple snapshots taken
11184  *      on multiple regions at the same time/by the same trigger.
11185  *
11186  *      The caller of this function must use devlink_region_snapshot_id_put
11187  *      when finished creating regions using this id.
11188  *
11189  *      Returns zero on success, or a negative error code on failure.
11190  *
11191  *      @devlink: devlink
11192  *      @id: storage to return id
11193  */
11194 int devlink_region_snapshot_id_get(struct devlink *devlink, u32 *id)
11195 {
11196         return __devlink_region_snapshot_id_get(devlink, id);
11197 }
11198 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_get);
11199
11200 /**
11201  *      devlink_region_snapshot_id_put - put snapshot ID reference
11202  *
11203  *      This should be called by a driver after finishing creating snapshots
11204  *      with an id. Doing so ensures that the ID can later be released in the
11205  *      event that all snapshots using it have been destroyed.
11206  *
11207  *      @devlink: devlink
11208  *      @id: id to release reference on
11209  */
11210 void devlink_region_snapshot_id_put(struct devlink *devlink, u32 id)
11211 {
11212         __devlink_snapshot_id_decrement(devlink, id);
11213 }
11214 EXPORT_SYMBOL_GPL(devlink_region_snapshot_id_put);
11215
11216 /**
11217  *      devlink_region_snapshot_create - create a new snapshot
11218  *      This will add a new snapshot of a region. The snapshot
11219  *      will be stored on the region struct and can be accessed
11220  *      from devlink. This is useful for future analyses of snapshots.
11221  *      Multiple snapshots can be created on a region.
11222  *      The @snapshot_id should be obtained using the getter function.
11223  *
11224  *      @region: devlink region of the snapshot
11225  *      @data: snapshot data
11226  *      @snapshot_id: snapshot id to be created
11227  */
11228 int devlink_region_snapshot_create(struct devlink_region *region,
11229                                    u8 *data, u32 snapshot_id)
11230 {
11231         int err;
11232
11233         mutex_lock(&region->snapshot_lock);
11234         err = __devlink_region_snapshot_create(region, data, snapshot_id);
11235         mutex_unlock(&region->snapshot_lock);
11236         return err;
11237 }
11238 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
11239
11240 #define DEVLINK_TRAP(_id, _type)                                              \
11241         {                                                                     \
11242                 .type = DEVLINK_TRAP_TYPE_##_type,                            \
11243                 .id = DEVLINK_TRAP_GENERIC_ID_##_id,                          \
11244                 .name = DEVLINK_TRAP_GENERIC_NAME_##_id,                      \
11245         }
11246
11247 static const struct devlink_trap devlink_trap_generic[] = {
11248         DEVLINK_TRAP(SMAC_MC, DROP),
11249         DEVLINK_TRAP(VLAN_TAG_MISMATCH, DROP),
11250         DEVLINK_TRAP(INGRESS_VLAN_FILTER, DROP),
11251         DEVLINK_TRAP(INGRESS_STP_FILTER, DROP),
11252         DEVLINK_TRAP(EMPTY_TX_LIST, DROP),
11253         DEVLINK_TRAP(PORT_LOOPBACK_FILTER, DROP),
11254         DEVLINK_TRAP(BLACKHOLE_ROUTE, DROP),
11255         DEVLINK_TRAP(TTL_ERROR, EXCEPTION),
11256         DEVLINK_TRAP(TAIL_DROP, DROP),
11257         DEVLINK_TRAP(NON_IP_PACKET, DROP),
11258         DEVLINK_TRAP(UC_DIP_MC_DMAC, DROP),
11259         DEVLINK_TRAP(DIP_LB, DROP),
11260         DEVLINK_TRAP(SIP_MC, DROP),
11261         DEVLINK_TRAP(SIP_LB, DROP),
11262         DEVLINK_TRAP(CORRUPTED_IP_HDR, DROP),
11263         DEVLINK_TRAP(IPV4_SIP_BC, DROP),
11264         DEVLINK_TRAP(IPV6_MC_DIP_RESERVED_SCOPE, DROP),
11265         DEVLINK_TRAP(IPV6_MC_DIP_INTERFACE_LOCAL_SCOPE, DROP),
11266         DEVLINK_TRAP(MTU_ERROR, EXCEPTION),
11267         DEVLINK_TRAP(UNRESOLVED_NEIGH, EXCEPTION),
11268         DEVLINK_TRAP(RPF, EXCEPTION),
11269         DEVLINK_TRAP(REJECT_ROUTE, EXCEPTION),
11270         DEVLINK_TRAP(IPV4_LPM_UNICAST_MISS, EXCEPTION),
11271         DEVLINK_TRAP(IPV6_LPM_UNICAST_MISS, EXCEPTION),
11272         DEVLINK_TRAP(NON_ROUTABLE, DROP),
11273         DEVLINK_TRAP(DECAP_ERROR, EXCEPTION),
11274         DEVLINK_TRAP(OVERLAY_SMAC_MC, DROP),
11275         DEVLINK_TRAP(INGRESS_FLOW_ACTION_DROP, DROP),
11276         DEVLINK_TRAP(EGRESS_FLOW_ACTION_DROP, DROP),
11277         DEVLINK_TRAP(STP, CONTROL),
11278         DEVLINK_TRAP(LACP, CONTROL),
11279         DEVLINK_TRAP(LLDP, CONTROL),
11280         DEVLINK_TRAP(IGMP_QUERY, CONTROL),
11281         DEVLINK_TRAP(IGMP_V1_REPORT, CONTROL),
11282         DEVLINK_TRAP(IGMP_V2_REPORT, CONTROL),
11283         DEVLINK_TRAP(IGMP_V3_REPORT, CONTROL),
11284         DEVLINK_TRAP(IGMP_V2_LEAVE, CONTROL),
11285         DEVLINK_TRAP(MLD_QUERY, CONTROL),
11286         DEVLINK_TRAP(MLD_V1_REPORT, CONTROL),
11287         DEVLINK_TRAP(MLD_V2_REPORT, CONTROL),
11288         DEVLINK_TRAP(MLD_V1_DONE, CONTROL),
11289         DEVLINK_TRAP(IPV4_DHCP, CONTROL),
11290         DEVLINK_TRAP(IPV6_DHCP, CONTROL),
11291         DEVLINK_TRAP(ARP_REQUEST, CONTROL),
11292         DEVLINK_TRAP(ARP_RESPONSE, CONTROL),
11293         DEVLINK_TRAP(ARP_OVERLAY, CONTROL),
11294         DEVLINK_TRAP(IPV6_NEIGH_SOLICIT, CONTROL),
11295         DEVLINK_TRAP(IPV6_NEIGH_ADVERT, CONTROL),
11296         DEVLINK_TRAP(IPV4_BFD, CONTROL),
11297         DEVLINK_TRAP(IPV6_BFD, CONTROL),
11298         DEVLINK_TRAP(IPV4_OSPF, CONTROL),
11299         DEVLINK_TRAP(IPV6_OSPF, CONTROL),
11300         DEVLINK_TRAP(IPV4_BGP, CONTROL),
11301         DEVLINK_TRAP(IPV6_BGP, CONTROL),
11302         DEVLINK_TRAP(IPV4_VRRP, CONTROL),
11303         DEVLINK_TRAP(IPV6_VRRP, CONTROL),
11304         DEVLINK_TRAP(IPV4_PIM, CONTROL),
11305         DEVLINK_TRAP(IPV6_PIM, CONTROL),
11306         DEVLINK_TRAP(UC_LB, CONTROL),
11307         DEVLINK_TRAP(LOCAL_ROUTE, CONTROL),
11308         DEVLINK_TRAP(EXTERNAL_ROUTE, CONTROL),
11309         DEVLINK_TRAP(IPV6_UC_DIP_LINK_LOCAL_SCOPE, CONTROL),
11310         DEVLINK_TRAP(IPV6_DIP_ALL_NODES, CONTROL),
11311         DEVLINK_TRAP(IPV6_DIP_ALL_ROUTERS, CONTROL),
11312         DEVLINK_TRAP(IPV6_ROUTER_SOLICIT, CONTROL),
11313         DEVLINK_TRAP(IPV6_ROUTER_ADVERT, CONTROL),
11314         DEVLINK_TRAP(IPV6_REDIRECT, CONTROL),
11315         DEVLINK_TRAP(IPV4_ROUTER_ALERT, CONTROL),
11316         DEVLINK_TRAP(IPV6_ROUTER_ALERT, CONTROL),
11317         DEVLINK_TRAP(PTP_EVENT, CONTROL),
11318         DEVLINK_TRAP(PTP_GENERAL, CONTROL),
11319         DEVLINK_TRAP(FLOW_ACTION_SAMPLE, CONTROL),
11320         DEVLINK_TRAP(FLOW_ACTION_TRAP, CONTROL),
11321         DEVLINK_TRAP(EARLY_DROP, DROP),
11322         DEVLINK_TRAP(VXLAN_PARSING, DROP),
11323         DEVLINK_TRAP(LLC_SNAP_PARSING, DROP),
11324         DEVLINK_TRAP(VLAN_PARSING, DROP),
11325         DEVLINK_TRAP(PPPOE_PPP_PARSING, DROP),
11326         DEVLINK_TRAP(MPLS_PARSING, DROP),
11327         DEVLINK_TRAP(ARP_PARSING, DROP),
11328         DEVLINK_TRAP(IP_1_PARSING, DROP),
11329         DEVLINK_TRAP(IP_N_PARSING, DROP),
11330         DEVLINK_TRAP(GRE_PARSING, DROP),
11331         DEVLINK_TRAP(UDP_PARSING, DROP),
11332         DEVLINK_TRAP(TCP_PARSING, DROP),
11333         DEVLINK_TRAP(IPSEC_PARSING, DROP),
11334         DEVLINK_TRAP(SCTP_PARSING, DROP),
11335         DEVLINK_TRAP(DCCP_PARSING, DROP),
11336         DEVLINK_TRAP(GTP_PARSING, DROP),
11337         DEVLINK_TRAP(ESP_PARSING, DROP),
11338         DEVLINK_TRAP(BLACKHOLE_NEXTHOP, DROP),
11339         DEVLINK_TRAP(DMAC_FILTER, DROP),
11340         DEVLINK_TRAP(EAPOL, CONTROL),
11341         DEVLINK_TRAP(LOCKED_PORT, DROP),
11342 };
11343
11344 #define DEVLINK_TRAP_GROUP(_id)                                               \
11345         {                                                                     \
11346                 .id = DEVLINK_TRAP_GROUP_GENERIC_ID_##_id,                    \
11347                 .name = DEVLINK_TRAP_GROUP_GENERIC_NAME_##_id,                \
11348         }
11349
11350 static const struct devlink_trap_group devlink_trap_group_generic[] = {
11351         DEVLINK_TRAP_GROUP(L2_DROPS),
11352         DEVLINK_TRAP_GROUP(L3_DROPS),
11353         DEVLINK_TRAP_GROUP(L3_EXCEPTIONS),
11354         DEVLINK_TRAP_GROUP(BUFFER_DROPS),
11355         DEVLINK_TRAP_GROUP(TUNNEL_DROPS),
11356         DEVLINK_TRAP_GROUP(ACL_DROPS),
11357         DEVLINK_TRAP_GROUP(STP),
11358         DEVLINK_TRAP_GROUP(LACP),
11359         DEVLINK_TRAP_GROUP(LLDP),
11360         DEVLINK_TRAP_GROUP(MC_SNOOPING),
11361         DEVLINK_TRAP_GROUP(DHCP),
11362         DEVLINK_TRAP_GROUP(NEIGH_DISCOVERY),
11363         DEVLINK_TRAP_GROUP(BFD),
11364         DEVLINK_TRAP_GROUP(OSPF),
11365         DEVLINK_TRAP_GROUP(BGP),
11366         DEVLINK_TRAP_GROUP(VRRP),
11367         DEVLINK_TRAP_GROUP(PIM),
11368         DEVLINK_TRAP_GROUP(UC_LB),
11369         DEVLINK_TRAP_GROUP(LOCAL_DELIVERY),
11370         DEVLINK_TRAP_GROUP(EXTERNAL_DELIVERY),
11371         DEVLINK_TRAP_GROUP(IPV6),
11372         DEVLINK_TRAP_GROUP(PTP_EVENT),
11373         DEVLINK_TRAP_GROUP(PTP_GENERAL),
11374         DEVLINK_TRAP_GROUP(ACL_SAMPLE),
11375         DEVLINK_TRAP_GROUP(ACL_TRAP),
11376         DEVLINK_TRAP_GROUP(PARSER_ERROR_DROPS),
11377         DEVLINK_TRAP_GROUP(EAPOL),
11378 };
11379
11380 static int devlink_trap_generic_verify(const struct devlink_trap *trap)
11381 {
11382         if (trap->id > DEVLINK_TRAP_GENERIC_ID_MAX)
11383                 return -EINVAL;
11384
11385         if (strcmp(trap->name, devlink_trap_generic[trap->id].name))
11386                 return -EINVAL;
11387
11388         if (trap->type != devlink_trap_generic[trap->id].type)
11389                 return -EINVAL;
11390
11391         return 0;
11392 }
11393
11394 static int devlink_trap_driver_verify(const struct devlink_trap *trap)
11395 {
11396         int i;
11397
11398         if (trap->id <= DEVLINK_TRAP_GENERIC_ID_MAX)
11399                 return -EINVAL;
11400
11401         for (i = 0; i < ARRAY_SIZE(devlink_trap_generic); i++) {
11402                 if (!strcmp(trap->name, devlink_trap_generic[i].name))
11403                         return -EEXIST;
11404         }
11405
11406         return 0;
11407 }
11408
11409 static int devlink_trap_verify(const struct devlink_trap *trap)
11410 {
11411         if (!trap || !trap->name)
11412                 return -EINVAL;
11413
11414         if (trap->generic)
11415                 return devlink_trap_generic_verify(trap);
11416         else
11417                 return devlink_trap_driver_verify(trap);
11418 }
11419
11420 static int
11421 devlink_trap_group_generic_verify(const struct devlink_trap_group *group)
11422 {
11423         if (group->id > DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11424                 return -EINVAL;
11425
11426         if (strcmp(group->name, devlink_trap_group_generic[group->id].name))
11427                 return -EINVAL;
11428
11429         return 0;
11430 }
11431
11432 static int
11433 devlink_trap_group_driver_verify(const struct devlink_trap_group *group)
11434 {
11435         int i;
11436
11437         if (group->id <= DEVLINK_TRAP_GROUP_GENERIC_ID_MAX)
11438                 return -EINVAL;
11439
11440         for (i = 0; i < ARRAY_SIZE(devlink_trap_group_generic); i++) {
11441                 if (!strcmp(group->name, devlink_trap_group_generic[i].name))
11442                         return -EEXIST;
11443         }
11444
11445         return 0;
11446 }
11447
11448 static int devlink_trap_group_verify(const struct devlink_trap_group *group)
11449 {
11450         if (group->generic)
11451                 return devlink_trap_group_generic_verify(group);
11452         else
11453                 return devlink_trap_group_driver_verify(group);
11454 }
11455
11456 static void
11457 devlink_trap_group_notify(struct devlink *devlink,
11458                           const struct devlink_trap_group_item *group_item,
11459                           enum devlink_command cmd)
11460 {
11461         struct sk_buff *msg;
11462         int err;
11463
11464         WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_GROUP_NEW &&
11465                      cmd != DEVLINK_CMD_TRAP_GROUP_DEL);
11466         if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11467                 return;
11468
11469         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11470         if (!msg)
11471                 return;
11472
11473         err = devlink_nl_trap_group_fill(msg, devlink, group_item, cmd, 0, 0,
11474                                          0);
11475         if (err) {
11476                 nlmsg_free(msg);
11477                 return;
11478         }
11479
11480         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11481                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11482 }
11483
11484 static int
11485 devlink_trap_item_group_link(struct devlink *devlink,
11486                              struct devlink_trap_item *trap_item)
11487 {
11488         u16 group_id = trap_item->trap->init_group_id;
11489         struct devlink_trap_group_item *group_item;
11490
11491         group_item = devlink_trap_group_item_lookup_by_id(devlink, group_id);
11492         if (WARN_ON_ONCE(!group_item))
11493                 return -EINVAL;
11494
11495         trap_item->group_item = group_item;
11496
11497         return 0;
11498 }
11499
11500 static void devlink_trap_notify(struct devlink *devlink,
11501                                 const struct devlink_trap_item *trap_item,
11502                                 enum devlink_command cmd)
11503 {
11504         struct sk_buff *msg;
11505         int err;
11506
11507         WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_NEW &&
11508                      cmd != DEVLINK_CMD_TRAP_DEL);
11509         if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11510                 return;
11511
11512         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11513         if (!msg)
11514                 return;
11515
11516         err = devlink_nl_trap_fill(msg, devlink, trap_item, cmd, 0, 0, 0);
11517         if (err) {
11518                 nlmsg_free(msg);
11519                 return;
11520         }
11521
11522         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11523                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11524 }
11525
11526 static int
11527 devlink_trap_register(struct devlink *devlink,
11528                       const struct devlink_trap *trap, void *priv)
11529 {
11530         struct devlink_trap_item *trap_item;
11531         int err;
11532
11533         if (devlink_trap_item_lookup(devlink, trap->name))
11534                 return -EEXIST;
11535
11536         trap_item = kzalloc(sizeof(*trap_item), GFP_KERNEL);
11537         if (!trap_item)
11538                 return -ENOMEM;
11539
11540         trap_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11541         if (!trap_item->stats) {
11542                 err = -ENOMEM;
11543                 goto err_stats_alloc;
11544         }
11545
11546         trap_item->trap = trap;
11547         trap_item->action = trap->init_action;
11548         trap_item->priv = priv;
11549
11550         err = devlink_trap_item_group_link(devlink, trap_item);
11551         if (err)
11552                 goto err_group_link;
11553
11554         err = devlink->ops->trap_init(devlink, trap, trap_item);
11555         if (err)
11556                 goto err_trap_init;
11557
11558         list_add_tail(&trap_item->list, &devlink->trap_list);
11559         devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_NEW);
11560
11561         return 0;
11562
11563 err_trap_init:
11564 err_group_link:
11565         free_percpu(trap_item->stats);
11566 err_stats_alloc:
11567         kfree(trap_item);
11568         return err;
11569 }
11570
11571 static void devlink_trap_unregister(struct devlink *devlink,
11572                                     const struct devlink_trap *trap)
11573 {
11574         struct devlink_trap_item *trap_item;
11575
11576         trap_item = devlink_trap_item_lookup(devlink, trap->name);
11577         if (WARN_ON_ONCE(!trap_item))
11578                 return;
11579
11580         devlink_trap_notify(devlink, trap_item, DEVLINK_CMD_TRAP_DEL);
11581         list_del(&trap_item->list);
11582         if (devlink->ops->trap_fini)
11583                 devlink->ops->trap_fini(devlink, trap, trap_item);
11584         free_percpu(trap_item->stats);
11585         kfree(trap_item);
11586 }
11587
11588 static void devlink_trap_disable(struct devlink *devlink,
11589                                  const struct devlink_trap *trap)
11590 {
11591         struct devlink_trap_item *trap_item;
11592
11593         trap_item = devlink_trap_item_lookup(devlink, trap->name);
11594         if (WARN_ON_ONCE(!trap_item))
11595                 return;
11596
11597         devlink->ops->trap_action_set(devlink, trap, DEVLINK_TRAP_ACTION_DROP,
11598                                       NULL);
11599         trap_item->action = DEVLINK_TRAP_ACTION_DROP;
11600 }
11601
11602 /**
11603  * devl_traps_register - Register packet traps with devlink.
11604  * @devlink: devlink.
11605  * @traps: Packet traps.
11606  * @traps_count: Count of provided packet traps.
11607  * @priv: Driver private information.
11608  *
11609  * Return: Non-zero value on failure.
11610  */
11611 int devl_traps_register(struct devlink *devlink,
11612                         const struct devlink_trap *traps,
11613                         size_t traps_count, void *priv)
11614 {
11615         int i, err;
11616
11617         if (!devlink->ops->trap_init || !devlink->ops->trap_action_set)
11618                 return -EINVAL;
11619
11620         devl_assert_locked(devlink);
11621         for (i = 0; i < traps_count; i++) {
11622                 const struct devlink_trap *trap = &traps[i];
11623
11624                 err = devlink_trap_verify(trap);
11625                 if (err)
11626                         goto err_trap_verify;
11627
11628                 err = devlink_trap_register(devlink, trap, priv);
11629                 if (err)
11630                         goto err_trap_register;
11631         }
11632
11633         return 0;
11634
11635 err_trap_register:
11636 err_trap_verify:
11637         for (i--; i >= 0; i--)
11638                 devlink_trap_unregister(devlink, &traps[i]);
11639         return err;
11640 }
11641 EXPORT_SYMBOL_GPL(devl_traps_register);
11642
11643 /**
11644  * devlink_traps_register - Register packet traps with devlink.
11645  * @devlink: devlink.
11646  * @traps: Packet traps.
11647  * @traps_count: Count of provided packet traps.
11648  * @priv: Driver private information.
11649  *
11650  * Context: Takes and release devlink->lock <mutex>.
11651  *
11652  * Return: Non-zero value on failure.
11653  */
11654 int devlink_traps_register(struct devlink *devlink,
11655                            const struct devlink_trap *traps,
11656                            size_t traps_count, void *priv)
11657 {
11658         int err;
11659
11660         devl_lock(devlink);
11661         err = devl_traps_register(devlink, traps, traps_count, priv);
11662         devl_unlock(devlink);
11663         return err;
11664 }
11665 EXPORT_SYMBOL_GPL(devlink_traps_register);
11666
11667 /**
11668  * devl_traps_unregister - Unregister packet traps from devlink.
11669  * @devlink: devlink.
11670  * @traps: Packet traps.
11671  * @traps_count: Count of provided packet traps.
11672  */
11673 void devl_traps_unregister(struct devlink *devlink,
11674                            const struct devlink_trap *traps,
11675                            size_t traps_count)
11676 {
11677         int i;
11678
11679         devl_assert_locked(devlink);
11680         /* Make sure we do not have any packets in-flight while unregistering
11681          * traps by disabling all of them and waiting for a grace period.
11682          */
11683         for (i = traps_count - 1; i >= 0; i--)
11684                 devlink_trap_disable(devlink, &traps[i]);
11685         synchronize_rcu();
11686         for (i = traps_count - 1; i >= 0; i--)
11687                 devlink_trap_unregister(devlink, &traps[i]);
11688 }
11689 EXPORT_SYMBOL_GPL(devl_traps_unregister);
11690
11691 /**
11692  * devlink_traps_unregister - Unregister packet traps from devlink.
11693  * @devlink: devlink.
11694  * @traps: Packet traps.
11695  * @traps_count: Count of provided packet traps.
11696  *
11697  * Context: Takes and release devlink->lock <mutex>.
11698  */
11699 void devlink_traps_unregister(struct devlink *devlink,
11700                               const struct devlink_trap *traps,
11701                               size_t traps_count)
11702 {
11703         devl_lock(devlink);
11704         devl_traps_unregister(devlink, traps, traps_count);
11705         devl_unlock(devlink);
11706 }
11707 EXPORT_SYMBOL_GPL(devlink_traps_unregister);
11708
11709 static void
11710 devlink_trap_stats_update(struct devlink_stats __percpu *trap_stats,
11711                           size_t skb_len)
11712 {
11713         struct devlink_stats *stats;
11714
11715         stats = this_cpu_ptr(trap_stats);
11716         u64_stats_update_begin(&stats->syncp);
11717         u64_stats_add(&stats->rx_bytes, skb_len);
11718         u64_stats_inc(&stats->rx_packets);
11719         u64_stats_update_end(&stats->syncp);
11720 }
11721
11722 static void
11723 devlink_trap_report_metadata_set(struct devlink_trap_metadata *metadata,
11724                                  const struct devlink_trap_item *trap_item,
11725                                  struct devlink_port *in_devlink_port,
11726                                  const struct flow_action_cookie *fa_cookie)
11727 {
11728         metadata->trap_name = trap_item->trap->name;
11729         metadata->trap_group_name = trap_item->group_item->group->name;
11730         metadata->fa_cookie = fa_cookie;
11731         metadata->trap_type = trap_item->trap->type;
11732
11733         spin_lock(&in_devlink_port->type_lock);
11734         if (in_devlink_port->type == DEVLINK_PORT_TYPE_ETH)
11735                 metadata->input_dev = in_devlink_port->type_eth.netdev;
11736         spin_unlock(&in_devlink_port->type_lock);
11737 }
11738
11739 /**
11740  * devlink_trap_report - Report trapped packet to drop monitor.
11741  * @devlink: devlink.
11742  * @skb: Trapped packet.
11743  * @trap_ctx: Trap context.
11744  * @in_devlink_port: Input devlink port.
11745  * @fa_cookie: Flow action cookie. Could be NULL.
11746  */
11747 void devlink_trap_report(struct devlink *devlink, struct sk_buff *skb,
11748                          void *trap_ctx, struct devlink_port *in_devlink_port,
11749                          const struct flow_action_cookie *fa_cookie)
11750
11751 {
11752         struct devlink_trap_item *trap_item = trap_ctx;
11753
11754         devlink_trap_stats_update(trap_item->stats, skb->len);
11755         devlink_trap_stats_update(trap_item->group_item->stats, skb->len);
11756
11757         if (trace_devlink_trap_report_enabled()) {
11758                 struct devlink_trap_metadata metadata = {};
11759
11760                 devlink_trap_report_metadata_set(&metadata, trap_item,
11761                                                  in_devlink_port, fa_cookie);
11762                 trace_devlink_trap_report(devlink, skb, &metadata);
11763         }
11764 }
11765 EXPORT_SYMBOL_GPL(devlink_trap_report);
11766
11767 /**
11768  * devlink_trap_ctx_priv - Trap context to driver private information.
11769  * @trap_ctx: Trap context.
11770  *
11771  * Return: Driver private information passed during registration.
11772  */
11773 void *devlink_trap_ctx_priv(void *trap_ctx)
11774 {
11775         struct devlink_trap_item *trap_item = trap_ctx;
11776
11777         return trap_item->priv;
11778 }
11779 EXPORT_SYMBOL_GPL(devlink_trap_ctx_priv);
11780
11781 static int
11782 devlink_trap_group_item_policer_link(struct devlink *devlink,
11783                                      struct devlink_trap_group_item *group_item)
11784 {
11785         u32 policer_id = group_item->group->init_policer_id;
11786         struct devlink_trap_policer_item *policer_item;
11787
11788         if (policer_id == 0)
11789                 return 0;
11790
11791         policer_item = devlink_trap_policer_item_lookup(devlink, policer_id);
11792         if (WARN_ON_ONCE(!policer_item))
11793                 return -EINVAL;
11794
11795         group_item->policer_item = policer_item;
11796
11797         return 0;
11798 }
11799
11800 static int
11801 devlink_trap_group_register(struct devlink *devlink,
11802                             const struct devlink_trap_group *group)
11803 {
11804         struct devlink_trap_group_item *group_item;
11805         int err;
11806
11807         if (devlink_trap_group_item_lookup(devlink, group->name))
11808                 return -EEXIST;
11809
11810         group_item = kzalloc(sizeof(*group_item), GFP_KERNEL);
11811         if (!group_item)
11812                 return -ENOMEM;
11813
11814         group_item->stats = netdev_alloc_pcpu_stats(struct devlink_stats);
11815         if (!group_item->stats) {
11816                 err = -ENOMEM;
11817                 goto err_stats_alloc;
11818         }
11819
11820         group_item->group = group;
11821
11822         err = devlink_trap_group_item_policer_link(devlink, group_item);
11823         if (err)
11824                 goto err_policer_link;
11825
11826         if (devlink->ops->trap_group_init) {
11827                 err = devlink->ops->trap_group_init(devlink, group);
11828                 if (err)
11829                         goto err_group_init;
11830         }
11831
11832         list_add_tail(&group_item->list, &devlink->trap_group_list);
11833         devlink_trap_group_notify(devlink, group_item,
11834                                   DEVLINK_CMD_TRAP_GROUP_NEW);
11835
11836         return 0;
11837
11838 err_group_init:
11839 err_policer_link:
11840         free_percpu(group_item->stats);
11841 err_stats_alloc:
11842         kfree(group_item);
11843         return err;
11844 }
11845
11846 static void
11847 devlink_trap_group_unregister(struct devlink *devlink,
11848                               const struct devlink_trap_group *group)
11849 {
11850         struct devlink_trap_group_item *group_item;
11851
11852         group_item = devlink_trap_group_item_lookup(devlink, group->name);
11853         if (WARN_ON_ONCE(!group_item))
11854                 return;
11855
11856         devlink_trap_group_notify(devlink, group_item,
11857                                   DEVLINK_CMD_TRAP_GROUP_DEL);
11858         list_del(&group_item->list);
11859         free_percpu(group_item->stats);
11860         kfree(group_item);
11861 }
11862
11863 /**
11864  * devl_trap_groups_register - Register packet trap groups with devlink.
11865  * @devlink: devlink.
11866  * @groups: Packet trap groups.
11867  * @groups_count: Count of provided packet trap groups.
11868  *
11869  * Return: Non-zero value on failure.
11870  */
11871 int devl_trap_groups_register(struct devlink *devlink,
11872                               const struct devlink_trap_group *groups,
11873                               size_t groups_count)
11874 {
11875         int i, err;
11876
11877         devl_assert_locked(devlink);
11878         for (i = 0; i < groups_count; i++) {
11879                 const struct devlink_trap_group *group = &groups[i];
11880
11881                 err = devlink_trap_group_verify(group);
11882                 if (err)
11883                         goto err_trap_group_verify;
11884
11885                 err = devlink_trap_group_register(devlink, group);
11886                 if (err)
11887                         goto err_trap_group_register;
11888         }
11889
11890         return 0;
11891
11892 err_trap_group_register:
11893 err_trap_group_verify:
11894         for (i--; i >= 0; i--)
11895                 devlink_trap_group_unregister(devlink, &groups[i]);
11896         return err;
11897 }
11898 EXPORT_SYMBOL_GPL(devl_trap_groups_register);
11899
11900 /**
11901  * devlink_trap_groups_register - Register packet trap groups with devlink.
11902  * @devlink: devlink.
11903  * @groups: Packet trap groups.
11904  * @groups_count: Count of provided packet trap groups.
11905  *
11906  * Context: Takes and release devlink->lock <mutex>.
11907  *
11908  * Return: Non-zero value on failure.
11909  */
11910 int devlink_trap_groups_register(struct devlink *devlink,
11911                                  const struct devlink_trap_group *groups,
11912                                  size_t groups_count)
11913 {
11914         int err;
11915
11916         devl_lock(devlink);
11917         err = devl_trap_groups_register(devlink, groups, groups_count);
11918         devl_unlock(devlink);
11919         return err;
11920 }
11921 EXPORT_SYMBOL_GPL(devlink_trap_groups_register);
11922
11923 /**
11924  * devl_trap_groups_unregister - Unregister packet trap groups from devlink.
11925  * @devlink: devlink.
11926  * @groups: Packet trap groups.
11927  * @groups_count: Count of provided packet trap groups.
11928  */
11929 void devl_trap_groups_unregister(struct devlink *devlink,
11930                                  const struct devlink_trap_group *groups,
11931                                  size_t groups_count)
11932 {
11933         int i;
11934
11935         devl_assert_locked(devlink);
11936         for (i = groups_count - 1; i >= 0; i--)
11937                 devlink_trap_group_unregister(devlink, &groups[i]);
11938 }
11939 EXPORT_SYMBOL_GPL(devl_trap_groups_unregister);
11940
11941 /**
11942  * devlink_trap_groups_unregister - Unregister packet trap groups from devlink.
11943  * @devlink: devlink.
11944  * @groups: Packet trap groups.
11945  * @groups_count: Count of provided packet trap groups.
11946  *
11947  * Context: Takes and release devlink->lock <mutex>.
11948  */
11949 void devlink_trap_groups_unregister(struct devlink *devlink,
11950                                     const struct devlink_trap_group *groups,
11951                                     size_t groups_count)
11952 {
11953         devl_lock(devlink);
11954         devl_trap_groups_unregister(devlink, groups, groups_count);
11955         devl_unlock(devlink);
11956 }
11957 EXPORT_SYMBOL_GPL(devlink_trap_groups_unregister);
11958
11959 static void
11960 devlink_trap_policer_notify(struct devlink *devlink,
11961                             const struct devlink_trap_policer_item *policer_item,
11962                             enum devlink_command cmd)
11963 {
11964         struct sk_buff *msg;
11965         int err;
11966
11967         WARN_ON_ONCE(cmd != DEVLINK_CMD_TRAP_POLICER_NEW &&
11968                      cmd != DEVLINK_CMD_TRAP_POLICER_DEL);
11969         if (!xa_get_mark(&devlinks, devlink->index, DEVLINK_REGISTERED))
11970                 return;
11971
11972         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
11973         if (!msg)
11974                 return;
11975
11976         err = devlink_nl_trap_policer_fill(msg, devlink, policer_item, cmd, 0,
11977                                            0, 0);
11978         if (err) {
11979                 nlmsg_free(msg);
11980                 return;
11981         }
11982
11983         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
11984                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
11985 }
11986
11987 static int
11988 devlink_trap_policer_register(struct devlink *devlink,
11989                               const struct devlink_trap_policer *policer)
11990 {
11991         struct devlink_trap_policer_item *policer_item;
11992         int err;
11993
11994         if (devlink_trap_policer_item_lookup(devlink, policer->id))
11995                 return -EEXIST;
11996
11997         policer_item = kzalloc(sizeof(*policer_item), GFP_KERNEL);
11998         if (!policer_item)
11999                 return -ENOMEM;
12000
12001         policer_item->policer = policer;
12002         policer_item->rate = policer->init_rate;
12003         policer_item->burst = policer->init_burst;
12004
12005         if (devlink->ops->trap_policer_init) {
12006                 err = devlink->ops->trap_policer_init(devlink, policer);
12007                 if (err)
12008                         goto err_policer_init;
12009         }
12010
12011         list_add_tail(&policer_item->list, &devlink->trap_policer_list);
12012         devlink_trap_policer_notify(devlink, policer_item,
12013                                     DEVLINK_CMD_TRAP_POLICER_NEW);
12014
12015         return 0;
12016
12017 err_policer_init:
12018         kfree(policer_item);
12019         return err;
12020 }
12021
12022 static void
12023 devlink_trap_policer_unregister(struct devlink *devlink,
12024                                 const struct devlink_trap_policer *policer)
12025 {
12026         struct devlink_trap_policer_item *policer_item;
12027
12028         policer_item = devlink_trap_policer_item_lookup(devlink, policer->id);
12029         if (WARN_ON_ONCE(!policer_item))
12030                 return;
12031
12032         devlink_trap_policer_notify(devlink, policer_item,
12033                                     DEVLINK_CMD_TRAP_POLICER_DEL);
12034         list_del(&policer_item->list);
12035         if (devlink->ops->trap_policer_fini)
12036                 devlink->ops->trap_policer_fini(devlink, policer);
12037         kfree(policer_item);
12038 }
12039
12040 /**
12041  * devl_trap_policers_register - Register packet trap policers with devlink.
12042  * @devlink: devlink.
12043  * @policers: Packet trap policers.
12044  * @policers_count: Count of provided packet trap policers.
12045  *
12046  * Return: Non-zero value on failure.
12047  */
12048 int
12049 devl_trap_policers_register(struct devlink *devlink,
12050                             const struct devlink_trap_policer *policers,
12051                             size_t policers_count)
12052 {
12053         int i, err;
12054
12055         devl_assert_locked(devlink);
12056         for (i = 0; i < policers_count; i++) {
12057                 const struct devlink_trap_policer *policer = &policers[i];
12058
12059                 if (WARN_ON(policer->id == 0 ||
12060                             policer->max_rate < policer->min_rate ||
12061                             policer->max_burst < policer->min_burst)) {
12062                         err = -EINVAL;
12063                         goto err_trap_policer_verify;
12064                 }
12065
12066                 err = devlink_trap_policer_register(devlink, policer);
12067                 if (err)
12068                         goto err_trap_policer_register;
12069         }
12070         return 0;
12071
12072 err_trap_policer_register:
12073 err_trap_policer_verify:
12074         for (i--; i >= 0; i--)
12075                 devlink_trap_policer_unregister(devlink, &policers[i]);
12076         return err;
12077 }
12078 EXPORT_SYMBOL_GPL(devl_trap_policers_register);
12079
12080 /**
12081  * devl_trap_policers_unregister - Unregister packet trap policers from devlink.
12082  * @devlink: devlink.
12083  * @policers: Packet trap policers.
12084  * @policers_count: Count of provided packet trap policers.
12085  */
12086 void
12087 devl_trap_policers_unregister(struct devlink *devlink,
12088                               const struct devlink_trap_policer *policers,
12089                               size_t policers_count)
12090 {
12091         int i;
12092
12093         devl_assert_locked(devlink);
12094         for (i = policers_count - 1; i >= 0; i--)
12095                 devlink_trap_policer_unregister(devlink, &policers[i]);
12096 }
12097 EXPORT_SYMBOL_GPL(devl_trap_policers_unregister);
12098
12099 static void __devlink_compat_running_version(struct devlink *devlink,
12100                                              char *buf, size_t len)
12101 {
12102         struct devlink_info_req req = {};
12103         const struct nlattr *nlattr;
12104         struct sk_buff *msg;
12105         int rem, err;
12106
12107         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
12108         if (!msg)
12109                 return;
12110
12111         req.msg = msg;
12112         err = devlink->ops->info_get(devlink, &req, NULL);
12113         if (err)
12114                 goto free_msg;
12115
12116         nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
12117                 const struct nlattr *kv;
12118                 int rem_kv;
12119
12120                 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
12121                         continue;
12122
12123                 nla_for_each_nested(kv, nlattr, rem_kv) {
12124                         if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
12125                                 continue;
12126
12127                         strlcat(buf, nla_data(kv), len);
12128                         strlcat(buf, " ", len);
12129                 }
12130         }
12131 free_msg:
12132         nlmsg_free(msg);
12133 }
12134
12135 void devlink_compat_running_version(struct devlink *devlink,
12136                                     char *buf, size_t len)
12137 {
12138         if (!devlink->ops->info_get)
12139                 return;
12140
12141         devl_lock(devlink);
12142         if (devl_is_registered(devlink))
12143                 __devlink_compat_running_version(devlink, buf, len);
12144         devl_unlock(devlink);
12145 }
12146
12147 int devlink_compat_flash_update(struct devlink *devlink, const char *file_name)
12148 {
12149         struct devlink_flash_update_params params = {};
12150         int ret;
12151
12152         devl_lock(devlink);
12153         if (!devl_is_registered(devlink)) {
12154                 ret = -ENODEV;
12155                 goto out_unlock;
12156         }
12157
12158         if (!devlink->ops->flash_update) {
12159                 ret = -EOPNOTSUPP;
12160                 goto out_unlock;
12161         }
12162
12163         ret = request_firmware(&params.fw, file_name, devlink->dev);
12164         if (ret)
12165                 goto out_unlock;
12166
12167         devlink_flash_update_begin_notify(devlink);
12168         ret = devlink->ops->flash_update(devlink, &params, NULL);
12169         devlink_flash_update_end_notify(devlink);
12170
12171         release_firmware(params.fw);
12172 out_unlock:
12173         devl_unlock(devlink);
12174
12175         return ret;
12176 }
12177
12178 int devlink_compat_phys_port_name_get(struct net_device *dev,
12179                                       char *name, size_t len)
12180 {
12181         struct devlink_port *devlink_port;
12182
12183         /* RTNL mutex is held here which ensures that devlink_port
12184          * instance cannot disappear in the middle. No need to take
12185          * any devlink lock as only permanent values are accessed.
12186          */
12187         ASSERT_RTNL();
12188
12189         devlink_port = dev->devlink_port;
12190         if (!devlink_port)
12191                 return -EOPNOTSUPP;
12192
12193         return __devlink_port_phys_port_name_get(devlink_port, name, len);
12194 }
12195
12196 int devlink_compat_switch_id_get(struct net_device *dev,
12197                                  struct netdev_phys_item_id *ppid)
12198 {
12199         struct devlink_port *devlink_port;
12200
12201         /* Caller must hold RTNL mutex or reference to dev, which ensures that
12202          * devlink_port instance cannot disappear in the middle. No need to take
12203          * any devlink lock as only permanent values are accessed.
12204          */
12205         devlink_port = dev->devlink_port;
12206         if (!devlink_port || !devlink_port->switch_port)
12207                 return -EOPNOTSUPP;
12208
12209         memcpy(ppid, &devlink_port->attrs.switch_id, sizeof(*ppid));
12210
12211         return 0;
12212 }