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