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