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