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