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