ACPI / scan: Add labels for PNP button devices
[sfrench/cifs-2.6.git] / net / core / devlink.c
1 /*
2  * net/core/devlink.c - Network physical/parent device Netlink interface
3  *
4  * Heavily inspired by net/wireless/
5  * Copyright (c) 2016 Mellanox Technologies. All rights reserved.
6  * Copyright (c) 2016 Jiri Pirko <jiri@mellanox.com>
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  */
13
14 #include <linux/kernel.h>
15 #include <linux/module.h>
16 #include <linux/types.h>
17 #include <linux/slab.h>
18 #include <linux/gfp.h>
19 #include <linux/device.h>
20 #include <linux/list.h>
21 #include <linux/netdevice.h>
22 #include <rdma/ib_verbs.h>
23 #include <net/netlink.h>
24 #include <net/genetlink.h>
25 #include <net/rtnetlink.h>
26 #include <net/net_namespace.h>
27 #include <net/sock.h>
28 #include <net/devlink.h>
29 #define CREATE_TRACE_POINTS
30 #include <trace/events/devlink.h>
31
32 static struct devlink_dpipe_field devlink_dpipe_fields_ethernet[] = {
33         {
34                 .name = "destination mac",
35                 .id = DEVLINK_DPIPE_FIELD_ETHERNET_DST_MAC,
36                 .bitwidth = 48,
37         },
38 };
39
40 struct devlink_dpipe_header devlink_dpipe_header_ethernet = {
41         .name = "ethernet",
42         .id = DEVLINK_DPIPE_HEADER_ETHERNET,
43         .fields = devlink_dpipe_fields_ethernet,
44         .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ethernet),
45         .global = true,
46 };
47 EXPORT_SYMBOL(devlink_dpipe_header_ethernet);
48
49 static struct devlink_dpipe_field devlink_dpipe_fields_ipv4[] = {
50         {
51                 .name = "destination ip",
52                 .id = DEVLINK_DPIPE_FIELD_IPV4_DST_IP,
53                 .bitwidth = 32,
54         },
55 };
56
57 struct devlink_dpipe_header devlink_dpipe_header_ipv4 = {
58         .name = "ipv4",
59         .id = DEVLINK_DPIPE_HEADER_IPV4,
60         .fields = devlink_dpipe_fields_ipv4,
61         .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv4),
62         .global = true,
63 };
64 EXPORT_SYMBOL(devlink_dpipe_header_ipv4);
65
66 static struct devlink_dpipe_field devlink_dpipe_fields_ipv6[] = {
67         {
68                 .name = "destination ip",
69                 .id = DEVLINK_DPIPE_FIELD_IPV6_DST_IP,
70                 .bitwidth = 128,
71         },
72 };
73
74 struct devlink_dpipe_header devlink_dpipe_header_ipv6 = {
75         .name = "ipv6",
76         .id = DEVLINK_DPIPE_HEADER_IPV6,
77         .fields = devlink_dpipe_fields_ipv6,
78         .fields_count = ARRAY_SIZE(devlink_dpipe_fields_ipv6),
79         .global = true,
80 };
81 EXPORT_SYMBOL(devlink_dpipe_header_ipv6);
82
83 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwmsg);
84 EXPORT_TRACEPOINT_SYMBOL_GPL(devlink_hwerr);
85
86 static LIST_HEAD(devlink_list);
87
88 /* devlink_mutex
89  *
90  * An overall lock guarding every operation coming from userspace.
91  * It also guards devlink devices list and it is taken when
92  * driver registers/unregisters it.
93  */
94 static DEFINE_MUTEX(devlink_mutex);
95
96 static struct net *devlink_net(const struct devlink *devlink)
97 {
98         return read_pnet(&devlink->_net);
99 }
100
101 static void devlink_net_set(struct devlink *devlink, struct net *net)
102 {
103         write_pnet(&devlink->_net, net);
104 }
105
106 static struct devlink *devlink_get_from_attrs(struct net *net,
107                                               struct nlattr **attrs)
108 {
109         struct devlink *devlink;
110         char *busname;
111         char *devname;
112
113         if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
114                 return ERR_PTR(-EINVAL);
115
116         busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
117         devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
118
119         lockdep_assert_held(&devlink_mutex);
120
121         list_for_each_entry(devlink, &devlink_list, list) {
122                 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
123                     strcmp(dev_name(devlink->dev), devname) == 0 &&
124                     net_eq(devlink_net(devlink), net))
125                         return devlink;
126         }
127
128         return ERR_PTR(-ENODEV);
129 }
130
131 static struct devlink *devlink_get_from_info(struct genl_info *info)
132 {
133         return devlink_get_from_attrs(genl_info_net(info), info->attrs);
134 }
135
136 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
137                                                       int port_index)
138 {
139         struct devlink_port *devlink_port;
140
141         list_for_each_entry(devlink_port, &devlink->port_list, list) {
142                 if (devlink_port->index == port_index)
143                         return devlink_port;
144         }
145         return NULL;
146 }
147
148 static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
149 {
150         return devlink_port_get_by_index(devlink, port_index);
151 }
152
153 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
154                                                         struct nlattr **attrs)
155 {
156         if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
157                 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
158                 struct devlink_port *devlink_port;
159
160                 devlink_port = devlink_port_get_by_index(devlink, port_index);
161                 if (!devlink_port)
162                         return ERR_PTR(-ENODEV);
163                 return devlink_port;
164         }
165         return ERR_PTR(-EINVAL);
166 }
167
168 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
169                                                        struct genl_info *info)
170 {
171         return devlink_port_get_from_attrs(devlink, info->attrs);
172 }
173
174 struct devlink_sb {
175         struct list_head list;
176         unsigned int index;
177         u32 size;
178         u16 ingress_pools_count;
179         u16 egress_pools_count;
180         u16 ingress_tc_count;
181         u16 egress_tc_count;
182 };
183
184 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
185 {
186         return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
187 }
188
189 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
190                                                   unsigned int sb_index)
191 {
192         struct devlink_sb *devlink_sb;
193
194         list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
195                 if (devlink_sb->index == sb_index)
196                         return devlink_sb;
197         }
198         return NULL;
199 }
200
201 static bool devlink_sb_index_exists(struct devlink *devlink,
202                                     unsigned int sb_index)
203 {
204         return devlink_sb_get_by_index(devlink, sb_index);
205 }
206
207 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
208                                                     struct nlattr **attrs)
209 {
210         if (attrs[DEVLINK_ATTR_SB_INDEX]) {
211                 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
212                 struct devlink_sb *devlink_sb;
213
214                 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
215                 if (!devlink_sb)
216                         return ERR_PTR(-ENODEV);
217                 return devlink_sb;
218         }
219         return ERR_PTR(-EINVAL);
220 }
221
222 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
223                                                    struct genl_info *info)
224 {
225         return devlink_sb_get_from_attrs(devlink, info->attrs);
226 }
227
228 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
229                                                 struct nlattr **attrs,
230                                                 u16 *p_pool_index)
231 {
232         u16 val;
233
234         if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
235                 return -EINVAL;
236
237         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
238         if (val >= devlink_sb_pool_count(devlink_sb))
239                 return -EINVAL;
240         *p_pool_index = val;
241         return 0;
242 }
243
244 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
245                                                struct genl_info *info,
246                                                u16 *p_pool_index)
247 {
248         return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
249                                                     p_pool_index);
250 }
251
252 static int
253 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
254                                     enum devlink_sb_pool_type *p_pool_type)
255 {
256         u8 val;
257
258         if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
259                 return -EINVAL;
260
261         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
262         if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
263             val != DEVLINK_SB_POOL_TYPE_EGRESS)
264                 return -EINVAL;
265         *p_pool_type = val;
266         return 0;
267 }
268
269 static int
270 devlink_sb_pool_type_get_from_info(struct genl_info *info,
271                                    enum devlink_sb_pool_type *p_pool_type)
272 {
273         return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
274 }
275
276 static int
277 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
278                                   enum devlink_sb_threshold_type *p_th_type)
279 {
280         u8 val;
281
282         if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
283                 return -EINVAL;
284
285         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
286         if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
287             val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
288                 return -EINVAL;
289         *p_th_type = val;
290         return 0;
291 }
292
293 static int
294 devlink_sb_th_type_get_from_info(struct genl_info *info,
295                                  enum devlink_sb_threshold_type *p_th_type)
296 {
297         return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
298 }
299
300 static int
301 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
302                                    struct nlattr **attrs,
303                                    enum devlink_sb_pool_type pool_type,
304                                    u16 *p_tc_index)
305 {
306         u16 val;
307
308         if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
309                 return -EINVAL;
310
311         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
312         if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
313             val >= devlink_sb->ingress_tc_count)
314                 return -EINVAL;
315         if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
316             val >= devlink_sb->egress_tc_count)
317                 return -EINVAL;
318         *p_tc_index = val;
319         return 0;
320 }
321
322 static int
323 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
324                                   struct genl_info *info,
325                                   enum devlink_sb_pool_type pool_type,
326                                   u16 *p_tc_index)
327 {
328         return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
329                                                   pool_type, p_tc_index);
330 }
331
332 struct devlink_region {
333         struct devlink *devlink;
334         struct list_head list;
335         const char *name;
336         struct list_head snapshot_list;
337         u32 max_snapshots;
338         u32 cur_snapshots;
339         u64 size;
340 };
341
342 struct devlink_snapshot {
343         struct list_head list;
344         struct devlink_region *region;
345         devlink_snapshot_data_dest_t *data_destructor;
346         u64 data_len;
347         u8 *data;
348         u32 id;
349 };
350
351 static struct devlink_region *
352 devlink_region_get_by_name(struct devlink *devlink, const char *region_name)
353 {
354         struct devlink_region *region;
355
356         list_for_each_entry(region, &devlink->region_list, list)
357                 if (!strcmp(region->name, region_name))
358                         return region;
359
360         return NULL;
361 }
362
363 static struct devlink_snapshot *
364 devlink_region_snapshot_get_by_id(struct devlink_region *region, u32 id)
365 {
366         struct devlink_snapshot *snapshot;
367
368         list_for_each_entry(snapshot, &region->snapshot_list, list)
369                 if (snapshot->id == id)
370                         return snapshot;
371
372         return NULL;
373 }
374
375 static void devlink_region_snapshot_del(struct devlink_snapshot *snapshot)
376 {
377         snapshot->region->cur_snapshots--;
378         list_del(&snapshot->list);
379         (*snapshot->data_destructor)(snapshot->data);
380         kfree(snapshot);
381 }
382
383 #define DEVLINK_NL_FLAG_NEED_DEVLINK    BIT(0)
384 #define DEVLINK_NL_FLAG_NEED_PORT       BIT(1)
385 #define DEVLINK_NL_FLAG_NEED_SB         BIT(2)
386
387 /* The per devlink instance lock is taken by default in the pre-doit
388  * operation, yet several commands do not require this. The global
389  * devlink lock is taken and protects from disruption by user-calls.
390  */
391 #define DEVLINK_NL_FLAG_NO_LOCK         BIT(3)
392
393 static int devlink_nl_pre_doit(const struct genl_ops *ops,
394                                struct sk_buff *skb, struct genl_info *info)
395 {
396         struct devlink *devlink;
397         int err;
398
399         mutex_lock(&devlink_mutex);
400         devlink = devlink_get_from_info(info);
401         if (IS_ERR(devlink)) {
402                 mutex_unlock(&devlink_mutex);
403                 return PTR_ERR(devlink);
404         }
405         if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
406                 mutex_lock(&devlink->lock);
407         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
408                 info->user_ptr[0] = devlink;
409         } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
410                 struct devlink_port *devlink_port;
411
412                 devlink_port = devlink_port_get_from_info(devlink, info);
413                 if (IS_ERR(devlink_port)) {
414                         err = PTR_ERR(devlink_port);
415                         goto unlock;
416                 }
417                 info->user_ptr[0] = devlink_port;
418         }
419         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
420                 struct devlink_sb *devlink_sb;
421
422                 devlink_sb = devlink_sb_get_from_info(devlink, info);
423                 if (IS_ERR(devlink_sb)) {
424                         err = PTR_ERR(devlink_sb);
425                         goto unlock;
426                 }
427                 info->user_ptr[1] = devlink_sb;
428         }
429         return 0;
430
431 unlock:
432         if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
433                 mutex_unlock(&devlink->lock);
434         mutex_unlock(&devlink_mutex);
435         return err;
436 }
437
438 static void devlink_nl_post_doit(const struct genl_ops *ops,
439                                  struct sk_buff *skb, struct genl_info *info)
440 {
441         struct devlink *devlink;
442
443         devlink = devlink_get_from_info(info);
444         if (~ops->internal_flags & DEVLINK_NL_FLAG_NO_LOCK)
445                 mutex_unlock(&devlink->lock);
446         mutex_unlock(&devlink_mutex);
447 }
448
449 static struct genl_family devlink_nl_family;
450
451 enum devlink_multicast_groups {
452         DEVLINK_MCGRP_CONFIG,
453 };
454
455 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
456         [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
457 };
458
459 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
460 {
461         if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
462                 return -EMSGSIZE;
463         if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
464                 return -EMSGSIZE;
465         return 0;
466 }
467
468 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
469                            enum devlink_command cmd, u32 portid,
470                            u32 seq, int flags)
471 {
472         void *hdr;
473
474         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
475         if (!hdr)
476                 return -EMSGSIZE;
477
478         if (devlink_nl_put_handle(msg, devlink))
479                 goto nla_put_failure;
480
481         genlmsg_end(msg, hdr);
482         return 0;
483
484 nla_put_failure:
485         genlmsg_cancel(msg, hdr);
486         return -EMSGSIZE;
487 }
488
489 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
490 {
491         struct sk_buff *msg;
492         int err;
493
494         WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
495
496         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
497         if (!msg)
498                 return;
499
500         err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
501         if (err) {
502                 nlmsg_free(msg);
503                 return;
504         }
505
506         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
507                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
508 }
509
510 static int devlink_nl_port_attrs_put(struct sk_buff *msg,
511                                      struct devlink_port *devlink_port)
512 {
513         struct devlink_port_attrs *attrs = &devlink_port->attrs;
514
515         if (!attrs->set)
516                 return 0;
517         if (nla_put_u16(msg, DEVLINK_ATTR_PORT_FLAVOUR, attrs->flavour))
518                 return -EMSGSIZE;
519         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_NUMBER, attrs->port_number))
520                 return -EMSGSIZE;
521         if (!attrs->split)
522                 return 0;
523         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP, attrs->port_number))
524                 return -EMSGSIZE;
525         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_SUBPORT_NUMBER,
526                         attrs->split_subport_number))
527                 return -EMSGSIZE;
528         return 0;
529 }
530
531 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
532                                 struct devlink_port *devlink_port,
533                                 enum devlink_command cmd, u32 portid,
534                                 u32 seq, int flags)
535 {
536         void *hdr;
537
538         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
539         if (!hdr)
540                 return -EMSGSIZE;
541
542         if (devlink_nl_put_handle(msg, devlink))
543                 goto nla_put_failure;
544         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
545                 goto nla_put_failure;
546         if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
547                 goto nla_put_failure;
548         if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
549             nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
550                         devlink_port->desired_type))
551                 goto nla_put_failure;
552         if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
553                 struct net_device *netdev = devlink_port->type_dev;
554
555                 if (netdev &&
556                     (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
557                                  netdev->ifindex) ||
558                      nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
559                                     netdev->name)))
560                         goto nla_put_failure;
561         }
562         if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
563                 struct ib_device *ibdev = devlink_port->type_dev;
564
565                 if (ibdev &&
566                     nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
567                                    ibdev->name))
568                         goto nla_put_failure;
569         }
570         if (devlink_nl_port_attrs_put(msg, devlink_port))
571                 goto nla_put_failure;
572
573         genlmsg_end(msg, hdr);
574         return 0;
575
576 nla_put_failure:
577         genlmsg_cancel(msg, hdr);
578         return -EMSGSIZE;
579 }
580
581 static void devlink_port_notify(struct devlink_port *devlink_port,
582                                 enum devlink_command cmd)
583 {
584         struct devlink *devlink = devlink_port->devlink;
585         struct sk_buff *msg;
586         int err;
587
588         if (!devlink_port->registered)
589                 return;
590
591         WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
592
593         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
594         if (!msg)
595                 return;
596
597         err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
598         if (err) {
599                 nlmsg_free(msg);
600                 return;
601         }
602
603         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
604                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
605 }
606
607 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
608 {
609         struct devlink *devlink = info->user_ptr[0];
610         struct sk_buff *msg;
611         int err;
612
613         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
614         if (!msg)
615                 return -ENOMEM;
616
617         err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
618                               info->snd_portid, info->snd_seq, 0);
619         if (err) {
620                 nlmsg_free(msg);
621                 return err;
622         }
623
624         return genlmsg_reply(msg, info);
625 }
626
627 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
628                                      struct netlink_callback *cb)
629 {
630         struct devlink *devlink;
631         int start = cb->args[0];
632         int idx = 0;
633         int err;
634
635         mutex_lock(&devlink_mutex);
636         list_for_each_entry(devlink, &devlink_list, list) {
637                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
638                         continue;
639                 if (idx < start) {
640                         idx++;
641                         continue;
642                 }
643                 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
644                                       NETLINK_CB(cb->skb).portid,
645                                       cb->nlh->nlmsg_seq, NLM_F_MULTI);
646                 if (err)
647                         goto out;
648                 idx++;
649         }
650 out:
651         mutex_unlock(&devlink_mutex);
652
653         cb->args[0] = idx;
654         return msg->len;
655 }
656
657 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
658                                         struct genl_info *info)
659 {
660         struct devlink_port *devlink_port = info->user_ptr[0];
661         struct devlink *devlink = devlink_port->devlink;
662         struct sk_buff *msg;
663         int err;
664
665         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
666         if (!msg)
667                 return -ENOMEM;
668
669         err = devlink_nl_port_fill(msg, devlink, devlink_port,
670                                    DEVLINK_CMD_PORT_NEW,
671                                    info->snd_portid, info->snd_seq, 0);
672         if (err) {
673                 nlmsg_free(msg);
674                 return err;
675         }
676
677         return genlmsg_reply(msg, info);
678 }
679
680 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
681                                           struct netlink_callback *cb)
682 {
683         struct devlink *devlink;
684         struct devlink_port *devlink_port;
685         int start = cb->args[0];
686         int idx = 0;
687         int err;
688
689         mutex_lock(&devlink_mutex);
690         list_for_each_entry(devlink, &devlink_list, list) {
691                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
692                         continue;
693                 mutex_lock(&devlink->lock);
694                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
695                         if (idx < start) {
696                                 idx++;
697                                 continue;
698                         }
699                         err = devlink_nl_port_fill(msg, devlink, devlink_port,
700                                                    DEVLINK_CMD_NEW,
701                                                    NETLINK_CB(cb->skb).portid,
702                                                    cb->nlh->nlmsg_seq,
703                                                    NLM_F_MULTI);
704                         if (err) {
705                                 mutex_unlock(&devlink->lock);
706                                 goto out;
707                         }
708                         idx++;
709                 }
710                 mutex_unlock(&devlink->lock);
711         }
712 out:
713         mutex_unlock(&devlink_mutex);
714
715         cb->args[0] = idx;
716         return msg->len;
717 }
718
719 static int devlink_port_type_set(struct devlink *devlink,
720                                  struct devlink_port *devlink_port,
721                                  enum devlink_port_type port_type)
722
723 {
724         int err;
725
726         if (devlink->ops->port_type_set) {
727                 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
728                         return -EINVAL;
729                 if (port_type == devlink_port->type)
730                         return 0;
731                 err = devlink->ops->port_type_set(devlink_port, port_type);
732                 if (err)
733                         return err;
734                 devlink_port->desired_type = port_type;
735                 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
736                 return 0;
737         }
738         return -EOPNOTSUPP;
739 }
740
741 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
742                                         struct genl_info *info)
743 {
744         struct devlink_port *devlink_port = info->user_ptr[0];
745         struct devlink *devlink = devlink_port->devlink;
746         int err;
747
748         if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
749                 enum devlink_port_type port_type;
750
751                 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
752                 err = devlink_port_type_set(devlink, devlink_port, port_type);
753                 if (err)
754                         return err;
755         }
756         return 0;
757 }
758
759 static int devlink_port_split(struct devlink *devlink, u32 port_index,
760                               u32 count, struct netlink_ext_ack *extack)
761
762 {
763         if (devlink->ops->port_split)
764                 return devlink->ops->port_split(devlink, port_index, count,
765                                                 extack);
766         return -EOPNOTSUPP;
767 }
768
769 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
770                                           struct genl_info *info)
771 {
772         struct devlink *devlink = info->user_ptr[0];
773         u32 port_index;
774         u32 count;
775
776         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
777             !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
778                 return -EINVAL;
779
780         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
781         count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
782         return devlink_port_split(devlink, port_index, count, info->extack);
783 }
784
785 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index,
786                                 struct netlink_ext_ack *extack)
787
788 {
789         if (devlink->ops->port_unsplit)
790                 return devlink->ops->port_unsplit(devlink, port_index, extack);
791         return -EOPNOTSUPP;
792 }
793
794 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
795                                             struct genl_info *info)
796 {
797         struct devlink *devlink = info->user_ptr[0];
798         u32 port_index;
799
800         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
801                 return -EINVAL;
802
803         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
804         return devlink_port_unsplit(devlink, port_index, info->extack);
805 }
806
807 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
808                               struct devlink_sb *devlink_sb,
809                               enum devlink_command cmd, u32 portid,
810                               u32 seq, int flags)
811 {
812         void *hdr;
813
814         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
815         if (!hdr)
816                 return -EMSGSIZE;
817
818         if (devlink_nl_put_handle(msg, devlink))
819                 goto nla_put_failure;
820         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
821                 goto nla_put_failure;
822         if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
823                 goto nla_put_failure;
824         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
825                         devlink_sb->ingress_pools_count))
826                 goto nla_put_failure;
827         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
828                         devlink_sb->egress_pools_count))
829                 goto nla_put_failure;
830         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
831                         devlink_sb->ingress_tc_count))
832                 goto nla_put_failure;
833         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
834                         devlink_sb->egress_tc_count))
835                 goto nla_put_failure;
836
837         genlmsg_end(msg, hdr);
838         return 0;
839
840 nla_put_failure:
841         genlmsg_cancel(msg, hdr);
842         return -EMSGSIZE;
843 }
844
845 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
846                                       struct genl_info *info)
847 {
848         struct devlink *devlink = info->user_ptr[0];
849         struct devlink_sb *devlink_sb = info->user_ptr[1];
850         struct sk_buff *msg;
851         int err;
852
853         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
854         if (!msg)
855                 return -ENOMEM;
856
857         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
858                                  DEVLINK_CMD_SB_NEW,
859                                  info->snd_portid, info->snd_seq, 0);
860         if (err) {
861                 nlmsg_free(msg);
862                 return err;
863         }
864
865         return genlmsg_reply(msg, info);
866 }
867
868 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
869                                         struct netlink_callback *cb)
870 {
871         struct devlink *devlink;
872         struct devlink_sb *devlink_sb;
873         int start = cb->args[0];
874         int idx = 0;
875         int err;
876
877         mutex_lock(&devlink_mutex);
878         list_for_each_entry(devlink, &devlink_list, list) {
879                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
880                         continue;
881                 mutex_lock(&devlink->lock);
882                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
883                         if (idx < start) {
884                                 idx++;
885                                 continue;
886                         }
887                         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
888                                                  DEVLINK_CMD_SB_NEW,
889                                                  NETLINK_CB(cb->skb).portid,
890                                                  cb->nlh->nlmsg_seq,
891                                                  NLM_F_MULTI);
892                         if (err) {
893                                 mutex_unlock(&devlink->lock);
894                                 goto out;
895                         }
896                         idx++;
897                 }
898                 mutex_unlock(&devlink->lock);
899         }
900 out:
901         mutex_unlock(&devlink_mutex);
902
903         cb->args[0] = idx;
904         return msg->len;
905 }
906
907 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
908                                    struct devlink_sb *devlink_sb,
909                                    u16 pool_index, enum devlink_command cmd,
910                                    u32 portid, u32 seq, int flags)
911 {
912         struct devlink_sb_pool_info pool_info;
913         void *hdr;
914         int err;
915
916         err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
917                                         pool_index, &pool_info);
918         if (err)
919                 return err;
920
921         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
922         if (!hdr)
923                 return -EMSGSIZE;
924
925         if (devlink_nl_put_handle(msg, devlink))
926                 goto nla_put_failure;
927         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
928                 goto nla_put_failure;
929         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
930                 goto nla_put_failure;
931         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
932                 goto nla_put_failure;
933         if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
934                 goto nla_put_failure;
935         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
936                        pool_info.threshold_type))
937                 goto nla_put_failure;
938         if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_CELL_SIZE,
939                         pool_info.cell_size))
940                 goto nla_put_failure;
941
942         genlmsg_end(msg, hdr);
943         return 0;
944
945 nla_put_failure:
946         genlmsg_cancel(msg, hdr);
947         return -EMSGSIZE;
948 }
949
950 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
951                                            struct genl_info *info)
952 {
953         struct devlink *devlink = info->user_ptr[0];
954         struct devlink_sb *devlink_sb = info->user_ptr[1];
955         struct sk_buff *msg;
956         u16 pool_index;
957         int err;
958
959         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
960                                                   &pool_index);
961         if (err)
962                 return err;
963
964         if (!devlink->ops->sb_pool_get)
965                 return -EOPNOTSUPP;
966
967         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
968         if (!msg)
969                 return -ENOMEM;
970
971         err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
972                                       DEVLINK_CMD_SB_POOL_NEW,
973                                       info->snd_portid, info->snd_seq, 0);
974         if (err) {
975                 nlmsg_free(msg);
976                 return err;
977         }
978
979         return genlmsg_reply(msg, info);
980 }
981
982 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
983                                 struct devlink *devlink,
984                                 struct devlink_sb *devlink_sb,
985                                 u32 portid, u32 seq)
986 {
987         u16 pool_count = devlink_sb_pool_count(devlink_sb);
988         u16 pool_index;
989         int err;
990
991         for (pool_index = 0; pool_index < pool_count; pool_index++) {
992                 if (*p_idx < start) {
993                         (*p_idx)++;
994                         continue;
995                 }
996                 err = devlink_nl_sb_pool_fill(msg, devlink,
997                                               devlink_sb,
998                                               pool_index,
999                                               DEVLINK_CMD_SB_POOL_NEW,
1000                                               portid, seq, NLM_F_MULTI);
1001                 if (err)
1002                         return err;
1003                 (*p_idx)++;
1004         }
1005         return 0;
1006 }
1007
1008 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
1009                                              struct netlink_callback *cb)
1010 {
1011         struct devlink *devlink;
1012         struct devlink_sb *devlink_sb;
1013         int start = cb->args[0];
1014         int idx = 0;
1015         int err;
1016
1017         mutex_lock(&devlink_mutex);
1018         list_for_each_entry(devlink, &devlink_list, list) {
1019                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1020                     !devlink->ops->sb_pool_get)
1021                         continue;
1022                 mutex_lock(&devlink->lock);
1023                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1024                         err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
1025                                                    devlink_sb,
1026                                                    NETLINK_CB(cb->skb).portid,
1027                                                    cb->nlh->nlmsg_seq);
1028                         if (err && err != -EOPNOTSUPP) {
1029                                 mutex_unlock(&devlink->lock);
1030                                 goto out;
1031                         }
1032                 }
1033                 mutex_unlock(&devlink->lock);
1034         }
1035 out:
1036         mutex_unlock(&devlink_mutex);
1037
1038         cb->args[0] = idx;
1039         return msg->len;
1040 }
1041
1042 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
1043                                u16 pool_index, u32 size,
1044                                enum devlink_sb_threshold_type threshold_type)
1045
1046 {
1047         const struct devlink_ops *ops = devlink->ops;
1048
1049         if (ops->sb_pool_set)
1050                 return ops->sb_pool_set(devlink, sb_index, pool_index,
1051                                         size, threshold_type);
1052         return -EOPNOTSUPP;
1053 }
1054
1055 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
1056                                            struct genl_info *info)
1057 {
1058         struct devlink *devlink = info->user_ptr[0];
1059         struct devlink_sb *devlink_sb = info->user_ptr[1];
1060         enum devlink_sb_threshold_type threshold_type;
1061         u16 pool_index;
1062         u32 size;
1063         int err;
1064
1065         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1066                                                   &pool_index);
1067         if (err)
1068                 return err;
1069
1070         err = devlink_sb_th_type_get_from_info(info, &threshold_type);
1071         if (err)
1072                 return err;
1073
1074         if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
1075                 return -EINVAL;
1076
1077         size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
1078         return devlink_sb_pool_set(devlink, devlink_sb->index,
1079                                    pool_index, size, threshold_type);
1080 }
1081
1082 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
1083                                         struct devlink *devlink,
1084                                         struct devlink_port *devlink_port,
1085                                         struct devlink_sb *devlink_sb,
1086                                         u16 pool_index,
1087                                         enum devlink_command cmd,
1088                                         u32 portid, u32 seq, int flags)
1089 {
1090         const struct devlink_ops *ops = devlink->ops;
1091         u32 threshold;
1092         void *hdr;
1093         int err;
1094
1095         err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
1096                                     pool_index, &threshold);
1097         if (err)
1098                 return err;
1099
1100         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1101         if (!hdr)
1102                 return -EMSGSIZE;
1103
1104         if (devlink_nl_put_handle(msg, devlink))
1105                 goto nla_put_failure;
1106         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1107                 goto nla_put_failure;
1108         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1109                 goto nla_put_failure;
1110         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1111                 goto nla_put_failure;
1112         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1113                 goto nla_put_failure;
1114
1115         if (ops->sb_occ_port_pool_get) {
1116                 u32 cur;
1117                 u32 max;
1118
1119                 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
1120                                                 pool_index, &cur, &max);
1121                 if (err && err != -EOPNOTSUPP)
1122                         return err;
1123                 if (!err) {
1124                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1125                                 goto nla_put_failure;
1126                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1127                                 goto nla_put_failure;
1128                 }
1129         }
1130
1131         genlmsg_end(msg, hdr);
1132         return 0;
1133
1134 nla_put_failure:
1135         genlmsg_cancel(msg, hdr);
1136         return -EMSGSIZE;
1137 }
1138
1139 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1140                                                 struct genl_info *info)
1141 {
1142         struct devlink_port *devlink_port = info->user_ptr[0];
1143         struct devlink *devlink = devlink_port->devlink;
1144         struct devlink_sb *devlink_sb = info->user_ptr[1];
1145         struct sk_buff *msg;
1146         u16 pool_index;
1147         int err;
1148
1149         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1150                                                   &pool_index);
1151         if (err)
1152                 return err;
1153
1154         if (!devlink->ops->sb_port_pool_get)
1155                 return -EOPNOTSUPP;
1156
1157         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1158         if (!msg)
1159                 return -ENOMEM;
1160
1161         err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1162                                            devlink_sb, pool_index,
1163                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1164                                            info->snd_portid, info->snd_seq, 0);
1165         if (err) {
1166                 nlmsg_free(msg);
1167                 return err;
1168         }
1169
1170         return genlmsg_reply(msg, info);
1171 }
1172
1173 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1174                                      struct devlink *devlink,
1175                                      struct devlink_sb *devlink_sb,
1176                                      u32 portid, u32 seq)
1177 {
1178         struct devlink_port *devlink_port;
1179         u16 pool_count = devlink_sb_pool_count(devlink_sb);
1180         u16 pool_index;
1181         int err;
1182
1183         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1184                 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1185                         if (*p_idx < start) {
1186                                 (*p_idx)++;
1187                                 continue;
1188                         }
1189                         err = devlink_nl_sb_port_pool_fill(msg, devlink,
1190                                                            devlink_port,
1191                                                            devlink_sb,
1192                                                            pool_index,
1193                                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1194                                                            portid, seq,
1195                                                            NLM_F_MULTI);
1196                         if (err)
1197                                 return err;
1198                         (*p_idx)++;
1199                 }
1200         }
1201         return 0;
1202 }
1203
1204 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1205                                                   struct netlink_callback *cb)
1206 {
1207         struct devlink *devlink;
1208         struct devlink_sb *devlink_sb;
1209         int start = cb->args[0];
1210         int idx = 0;
1211         int err;
1212
1213         mutex_lock(&devlink_mutex);
1214         list_for_each_entry(devlink, &devlink_list, list) {
1215                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1216                     !devlink->ops->sb_port_pool_get)
1217                         continue;
1218                 mutex_lock(&devlink->lock);
1219                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1220                         err = __sb_port_pool_get_dumpit(msg, start, &idx,
1221                                                         devlink, devlink_sb,
1222                                                         NETLINK_CB(cb->skb).portid,
1223                                                         cb->nlh->nlmsg_seq);
1224                         if (err && err != -EOPNOTSUPP) {
1225                                 mutex_unlock(&devlink->lock);
1226                                 goto out;
1227                         }
1228                 }
1229                 mutex_unlock(&devlink->lock);
1230         }
1231 out:
1232         mutex_unlock(&devlink_mutex);
1233
1234         cb->args[0] = idx;
1235         return msg->len;
1236 }
1237
1238 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1239                                     unsigned int sb_index, u16 pool_index,
1240                                     u32 threshold)
1241
1242 {
1243         const struct devlink_ops *ops = devlink_port->devlink->ops;
1244
1245         if (ops->sb_port_pool_set)
1246                 return ops->sb_port_pool_set(devlink_port, sb_index,
1247                                              pool_index, threshold);
1248         return -EOPNOTSUPP;
1249 }
1250
1251 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1252                                                 struct genl_info *info)
1253 {
1254         struct devlink_port *devlink_port = info->user_ptr[0];
1255         struct devlink_sb *devlink_sb = info->user_ptr[1];
1256         u16 pool_index;
1257         u32 threshold;
1258         int err;
1259
1260         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1261                                                   &pool_index);
1262         if (err)
1263                 return err;
1264
1265         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1266                 return -EINVAL;
1267
1268         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1269         return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1270                                         pool_index, threshold);
1271 }
1272
1273 static int
1274 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1275                                 struct devlink_port *devlink_port,
1276                                 struct devlink_sb *devlink_sb, u16 tc_index,
1277                                 enum devlink_sb_pool_type pool_type,
1278                                 enum devlink_command cmd,
1279                                 u32 portid, u32 seq, int flags)
1280 {
1281         const struct devlink_ops *ops = devlink->ops;
1282         u16 pool_index;
1283         u32 threshold;
1284         void *hdr;
1285         int err;
1286
1287         err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1288                                        tc_index, pool_type,
1289                                        &pool_index, &threshold);
1290         if (err)
1291                 return err;
1292
1293         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1294         if (!hdr)
1295                 return -EMSGSIZE;
1296
1297         if (devlink_nl_put_handle(msg, devlink))
1298                 goto nla_put_failure;
1299         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1300                 goto nla_put_failure;
1301         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1302                 goto nla_put_failure;
1303         if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1304                 goto nla_put_failure;
1305         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1306                 goto nla_put_failure;
1307         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1308                 goto nla_put_failure;
1309         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1310                 goto nla_put_failure;
1311
1312         if (ops->sb_occ_tc_port_bind_get) {
1313                 u32 cur;
1314                 u32 max;
1315
1316                 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1317                                                    devlink_sb->index,
1318                                                    tc_index, pool_type,
1319                                                    &cur, &max);
1320                 if (err && err != -EOPNOTSUPP)
1321                         return err;
1322                 if (!err) {
1323                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1324                                 goto nla_put_failure;
1325                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1326                                 goto nla_put_failure;
1327                 }
1328         }
1329
1330         genlmsg_end(msg, hdr);
1331         return 0;
1332
1333 nla_put_failure:
1334         genlmsg_cancel(msg, hdr);
1335         return -EMSGSIZE;
1336 }
1337
1338 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1339                                                    struct genl_info *info)
1340 {
1341         struct devlink_port *devlink_port = info->user_ptr[0];
1342         struct devlink *devlink = devlink_port->devlink;
1343         struct devlink_sb *devlink_sb = info->user_ptr[1];
1344         struct sk_buff *msg;
1345         enum devlink_sb_pool_type pool_type;
1346         u16 tc_index;
1347         int err;
1348
1349         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1350         if (err)
1351                 return err;
1352
1353         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1354                                                 pool_type, &tc_index);
1355         if (err)
1356                 return err;
1357
1358         if (!devlink->ops->sb_tc_pool_bind_get)
1359                 return -EOPNOTSUPP;
1360
1361         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1362         if (!msg)
1363                 return -ENOMEM;
1364
1365         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1366                                               devlink_sb, tc_index, pool_type,
1367                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1368                                               info->snd_portid,
1369                                               info->snd_seq, 0);
1370         if (err) {
1371                 nlmsg_free(msg);
1372                 return err;
1373         }
1374
1375         return genlmsg_reply(msg, info);
1376 }
1377
1378 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1379                                         int start, int *p_idx,
1380                                         struct devlink *devlink,
1381                                         struct devlink_sb *devlink_sb,
1382                                         u32 portid, u32 seq)
1383 {
1384         struct devlink_port *devlink_port;
1385         u16 tc_index;
1386         int err;
1387
1388         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1389                 for (tc_index = 0;
1390                      tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1391                         if (*p_idx < start) {
1392                                 (*p_idx)++;
1393                                 continue;
1394                         }
1395                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1396                                                               devlink_port,
1397                                                               devlink_sb,
1398                                                               tc_index,
1399                                                               DEVLINK_SB_POOL_TYPE_INGRESS,
1400                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1401                                                               portid, seq,
1402                                                               NLM_F_MULTI);
1403                         if (err)
1404                                 return err;
1405                         (*p_idx)++;
1406                 }
1407                 for (tc_index = 0;
1408                      tc_index < devlink_sb->egress_tc_count; tc_index++) {
1409                         if (*p_idx < start) {
1410                                 (*p_idx)++;
1411                                 continue;
1412                         }
1413                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1414                                                               devlink_port,
1415                                                               devlink_sb,
1416                                                               tc_index,
1417                                                               DEVLINK_SB_POOL_TYPE_EGRESS,
1418                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1419                                                               portid, seq,
1420                                                               NLM_F_MULTI);
1421                         if (err)
1422                                 return err;
1423                         (*p_idx)++;
1424                 }
1425         }
1426         return 0;
1427 }
1428
1429 static int
1430 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1431                                           struct netlink_callback *cb)
1432 {
1433         struct devlink *devlink;
1434         struct devlink_sb *devlink_sb;
1435         int start = cb->args[0];
1436         int idx = 0;
1437         int err;
1438
1439         mutex_lock(&devlink_mutex);
1440         list_for_each_entry(devlink, &devlink_list, list) {
1441                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1442                     !devlink->ops->sb_tc_pool_bind_get)
1443                         continue;
1444
1445                 mutex_lock(&devlink->lock);
1446                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1447                         err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1448                                                            devlink,
1449                                                            devlink_sb,
1450                                                            NETLINK_CB(cb->skb).portid,
1451                                                            cb->nlh->nlmsg_seq);
1452                         if (err && err != -EOPNOTSUPP) {
1453                                 mutex_unlock(&devlink->lock);
1454                                 goto out;
1455                         }
1456                 }
1457                 mutex_unlock(&devlink->lock);
1458         }
1459 out:
1460         mutex_unlock(&devlink_mutex);
1461
1462         cb->args[0] = idx;
1463         return msg->len;
1464 }
1465
1466 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1467                                        unsigned int sb_index, u16 tc_index,
1468                                        enum devlink_sb_pool_type pool_type,
1469                                        u16 pool_index, u32 threshold)
1470
1471 {
1472         const struct devlink_ops *ops = devlink_port->devlink->ops;
1473
1474         if (ops->sb_tc_pool_bind_set)
1475                 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1476                                                 tc_index, pool_type,
1477                                                 pool_index, threshold);
1478         return -EOPNOTSUPP;
1479 }
1480
1481 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1482                                                    struct genl_info *info)
1483 {
1484         struct devlink_port *devlink_port = info->user_ptr[0];
1485         struct devlink_sb *devlink_sb = info->user_ptr[1];
1486         enum devlink_sb_pool_type pool_type;
1487         u16 tc_index;
1488         u16 pool_index;
1489         u32 threshold;
1490         int err;
1491
1492         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1493         if (err)
1494                 return err;
1495
1496         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1497                                                 pool_type, &tc_index);
1498         if (err)
1499                 return err;
1500
1501         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1502                                                   &pool_index);
1503         if (err)
1504                 return err;
1505
1506         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1507                 return -EINVAL;
1508
1509         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1510         return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1511                                            tc_index, pool_type,
1512                                            pool_index, threshold);
1513 }
1514
1515 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1516                                                struct genl_info *info)
1517 {
1518         struct devlink *devlink = info->user_ptr[0];
1519         struct devlink_sb *devlink_sb = info->user_ptr[1];
1520         const struct devlink_ops *ops = devlink->ops;
1521
1522         if (ops->sb_occ_snapshot)
1523                 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1524         return -EOPNOTSUPP;
1525 }
1526
1527 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1528                                                 struct genl_info *info)
1529 {
1530         struct devlink *devlink = info->user_ptr[0];
1531         struct devlink_sb *devlink_sb = info->user_ptr[1];
1532         const struct devlink_ops *ops = devlink->ops;
1533
1534         if (ops->sb_occ_max_clear)
1535                 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1536         return -EOPNOTSUPP;
1537 }
1538
1539 static int devlink_nl_eswitch_fill(struct sk_buff *msg, struct devlink *devlink,
1540                                    enum devlink_command cmd, u32 portid,
1541                                    u32 seq, int flags)
1542 {
1543         const struct devlink_ops *ops = devlink->ops;
1544         u8 inline_mode, encap_mode;
1545         void *hdr;
1546         int err = 0;
1547         u16 mode;
1548
1549         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1550         if (!hdr)
1551                 return -EMSGSIZE;
1552
1553         err = devlink_nl_put_handle(msg, devlink);
1554         if (err)
1555                 goto nla_put_failure;
1556
1557         if (ops->eswitch_mode_get) {
1558                 err = ops->eswitch_mode_get(devlink, &mode);
1559                 if (err)
1560                         goto nla_put_failure;
1561                 err = nla_put_u16(msg, DEVLINK_ATTR_ESWITCH_MODE, mode);
1562                 if (err)
1563                         goto nla_put_failure;
1564         }
1565
1566         if (ops->eswitch_inline_mode_get) {
1567                 err = ops->eswitch_inline_mode_get(devlink, &inline_mode);
1568                 if (err)
1569                         goto nla_put_failure;
1570                 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_INLINE_MODE,
1571                                  inline_mode);
1572                 if (err)
1573                         goto nla_put_failure;
1574         }
1575
1576         if (ops->eswitch_encap_mode_get) {
1577                 err = ops->eswitch_encap_mode_get(devlink, &encap_mode);
1578                 if (err)
1579                         goto nla_put_failure;
1580                 err = nla_put_u8(msg, DEVLINK_ATTR_ESWITCH_ENCAP_MODE, encap_mode);
1581                 if (err)
1582                         goto nla_put_failure;
1583         }
1584
1585         genlmsg_end(msg, hdr);
1586         return 0;
1587
1588 nla_put_failure:
1589         genlmsg_cancel(msg, hdr);
1590         return err;
1591 }
1592
1593 static int devlink_nl_cmd_eswitch_get_doit(struct sk_buff *skb,
1594                                            struct genl_info *info)
1595 {
1596         struct devlink *devlink = info->user_ptr[0];
1597         struct sk_buff *msg;
1598         int err;
1599
1600         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1601         if (!msg)
1602                 return -ENOMEM;
1603
1604         err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1605                                       info->snd_portid, info->snd_seq, 0);
1606
1607         if (err) {
1608                 nlmsg_free(msg);
1609                 return err;
1610         }
1611
1612         return genlmsg_reply(msg, info);
1613 }
1614
1615 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1616                                            struct genl_info *info)
1617 {
1618         struct devlink *devlink = info->user_ptr[0];
1619         const struct devlink_ops *ops = devlink->ops;
1620         u8 inline_mode, encap_mode;
1621         int err = 0;
1622         u16 mode;
1623
1624         if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1625                 if (!ops->eswitch_mode_set)
1626                         return -EOPNOTSUPP;
1627                 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1628                 err = ops->eswitch_mode_set(devlink, mode, info->extack);
1629                 if (err)
1630                         return err;
1631         }
1632
1633         if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1634                 if (!ops->eswitch_inline_mode_set)
1635                         return -EOPNOTSUPP;
1636                 inline_mode = nla_get_u8(
1637                                 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1638                 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
1639                                                    info->extack);
1640                 if (err)
1641                         return err;
1642         }
1643
1644         if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1645                 if (!ops->eswitch_encap_mode_set)
1646                         return -EOPNOTSUPP;
1647                 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1648                 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
1649                                                   info->extack);
1650                 if (err)
1651                         return err;
1652         }
1653
1654         return 0;
1655 }
1656
1657 int devlink_dpipe_match_put(struct sk_buff *skb,
1658                             struct devlink_dpipe_match *match)
1659 {
1660         struct devlink_dpipe_header *header = match->header;
1661         struct devlink_dpipe_field *field = &header->fields[match->field_id];
1662         struct nlattr *match_attr;
1663
1664         match_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_MATCH);
1665         if (!match_attr)
1666                 return -EMSGSIZE;
1667
1668         if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1669             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1670             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1671             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1672             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1673                 goto nla_put_failure;
1674
1675         nla_nest_end(skb, match_attr);
1676         return 0;
1677
1678 nla_put_failure:
1679         nla_nest_cancel(skb, match_attr);
1680         return -EMSGSIZE;
1681 }
1682 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1683
1684 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1685                                      struct sk_buff *skb)
1686 {
1687         struct nlattr *matches_attr;
1688
1689         matches_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1690         if (!matches_attr)
1691                 return -EMSGSIZE;
1692
1693         if (table->table_ops->matches_dump(table->priv, skb))
1694                 goto nla_put_failure;
1695
1696         nla_nest_end(skb, matches_attr);
1697         return 0;
1698
1699 nla_put_failure:
1700         nla_nest_cancel(skb, matches_attr);
1701         return -EMSGSIZE;
1702 }
1703
1704 int devlink_dpipe_action_put(struct sk_buff *skb,
1705                              struct devlink_dpipe_action *action)
1706 {
1707         struct devlink_dpipe_header *header = action->header;
1708         struct devlink_dpipe_field *field = &header->fields[action->field_id];
1709         struct nlattr *action_attr;
1710
1711         action_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ACTION);
1712         if (!action_attr)
1713                 return -EMSGSIZE;
1714
1715         if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1716             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1717             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1718             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1719             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1720                 goto nla_put_failure;
1721
1722         nla_nest_end(skb, action_attr);
1723         return 0;
1724
1725 nla_put_failure:
1726         nla_nest_cancel(skb, action_attr);
1727         return -EMSGSIZE;
1728 }
1729 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1730
1731 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1732                                      struct sk_buff *skb)
1733 {
1734         struct nlattr *actions_attr;
1735
1736         actions_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1737         if (!actions_attr)
1738                 return -EMSGSIZE;
1739
1740         if (table->table_ops->actions_dump(table->priv, skb))
1741                 goto nla_put_failure;
1742
1743         nla_nest_end(skb, actions_attr);
1744         return 0;
1745
1746 nla_put_failure:
1747         nla_nest_cancel(skb, actions_attr);
1748         return -EMSGSIZE;
1749 }
1750
1751 static int devlink_dpipe_table_put(struct sk_buff *skb,
1752                                    struct devlink_dpipe_table *table)
1753 {
1754         struct nlattr *table_attr;
1755         u64 table_size;
1756
1757         table_size = table->table_ops->size_get(table->priv);
1758         table_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE);
1759         if (!table_attr)
1760                 return -EMSGSIZE;
1761
1762         if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1763             nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1764                               DEVLINK_ATTR_PAD))
1765                 goto nla_put_failure;
1766         if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1767                        table->counters_enabled))
1768                 goto nla_put_failure;
1769
1770         if (table->resource_valid) {
1771                 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
1772                                       table->resource_id, DEVLINK_ATTR_PAD) ||
1773                     nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
1774                                       table->resource_units, DEVLINK_ATTR_PAD))
1775                         goto nla_put_failure;
1776         }
1777         if (devlink_dpipe_matches_put(table, skb))
1778                 goto nla_put_failure;
1779
1780         if (devlink_dpipe_actions_put(table, skb))
1781                 goto nla_put_failure;
1782
1783         nla_nest_end(skb, table_attr);
1784         return 0;
1785
1786 nla_put_failure:
1787         nla_nest_cancel(skb, table_attr);
1788         return -EMSGSIZE;
1789 }
1790
1791 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1792                                             struct genl_info *info)
1793 {
1794         int err;
1795
1796         if (*pskb) {
1797                 err = genlmsg_reply(*pskb, info);
1798                 if (err)
1799                         return err;
1800         }
1801         *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1802         if (!*pskb)
1803                 return -ENOMEM;
1804         return 0;
1805 }
1806
1807 static int devlink_dpipe_tables_fill(struct genl_info *info,
1808                                      enum devlink_command cmd, int flags,
1809                                      struct list_head *dpipe_tables,
1810                                      const char *table_name)
1811 {
1812         struct devlink *devlink = info->user_ptr[0];
1813         struct devlink_dpipe_table *table;
1814         struct nlattr *tables_attr;
1815         struct sk_buff *skb = NULL;
1816         struct nlmsghdr *nlh;
1817         bool incomplete;
1818         void *hdr;
1819         int i;
1820         int err;
1821
1822         table = list_first_entry(dpipe_tables,
1823                                  struct devlink_dpipe_table, list);
1824 start_again:
1825         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1826         if (err)
1827                 return err;
1828
1829         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
1830                           &devlink_nl_family, NLM_F_MULTI, cmd);
1831         if (!hdr) {
1832                 nlmsg_free(skb);
1833                 return -EMSGSIZE;
1834         }
1835
1836         if (devlink_nl_put_handle(skb, devlink))
1837                 goto nla_put_failure;
1838         tables_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLES);
1839         if (!tables_attr)
1840                 goto nla_put_failure;
1841
1842         i = 0;
1843         incomplete = false;
1844         list_for_each_entry_from(table, dpipe_tables, list) {
1845                 if (!table_name) {
1846                         err = devlink_dpipe_table_put(skb, table);
1847                         if (err) {
1848                                 if (!i)
1849                                         goto err_table_put;
1850                                 incomplete = true;
1851                                 break;
1852                         }
1853                 } else {
1854                         if (!strcmp(table->name, table_name)) {
1855                                 err = devlink_dpipe_table_put(skb, table);
1856                                 if (err)
1857                                         break;
1858                         }
1859                 }
1860                 i++;
1861         }
1862
1863         nla_nest_end(skb, tables_attr);
1864         genlmsg_end(skb, hdr);
1865         if (incomplete)
1866                 goto start_again;
1867
1868 send_done:
1869         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
1870                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
1871         if (!nlh) {
1872                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1873                 if (err)
1874                         return err;
1875                 goto send_done;
1876         }
1877
1878         return genlmsg_reply(skb, info);
1879
1880 nla_put_failure:
1881         err = -EMSGSIZE;
1882 err_table_put:
1883         nlmsg_free(skb);
1884         return err;
1885 }
1886
1887 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
1888                                           struct genl_info *info)
1889 {
1890         struct devlink *devlink = info->user_ptr[0];
1891         const char *table_name =  NULL;
1892
1893         if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
1894                 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
1895
1896         return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
1897                                          &devlink->dpipe_table_list,
1898                                          table_name);
1899 }
1900
1901 static int devlink_dpipe_value_put(struct sk_buff *skb,
1902                                    struct devlink_dpipe_value *value)
1903 {
1904         if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
1905                     value->value_size, value->value))
1906                 return -EMSGSIZE;
1907         if (value->mask)
1908                 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
1909                             value->value_size, value->mask))
1910                         return -EMSGSIZE;
1911         if (value->mapping_valid)
1912                 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
1913                                 value->mapping_value))
1914                         return -EMSGSIZE;
1915         return 0;
1916 }
1917
1918 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
1919                                           struct devlink_dpipe_value *value)
1920 {
1921         if (!value->action)
1922                 return -EINVAL;
1923         if (devlink_dpipe_action_put(skb, value->action))
1924                 return -EMSGSIZE;
1925         if (devlink_dpipe_value_put(skb, value))
1926                 return -EMSGSIZE;
1927         return 0;
1928 }
1929
1930 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
1931                                            struct devlink_dpipe_value *values,
1932                                            unsigned int values_count)
1933 {
1934         struct nlattr *action_attr;
1935         int i;
1936         int err;
1937
1938         for (i = 0; i < values_count; i++) {
1939                 action_attr = nla_nest_start(skb,
1940                                              DEVLINK_ATTR_DPIPE_ACTION_VALUE);
1941                 if (!action_attr)
1942                         return -EMSGSIZE;
1943                 err = devlink_dpipe_action_value_put(skb, &values[i]);
1944                 if (err)
1945                         goto err_action_value_put;
1946                 nla_nest_end(skb, action_attr);
1947         }
1948         return 0;
1949
1950 err_action_value_put:
1951         nla_nest_cancel(skb, action_attr);
1952         return err;
1953 }
1954
1955 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
1956                                          struct devlink_dpipe_value *value)
1957 {
1958         if (!value->match)
1959                 return -EINVAL;
1960         if (devlink_dpipe_match_put(skb, value->match))
1961                 return -EMSGSIZE;
1962         if (devlink_dpipe_value_put(skb, value))
1963                 return -EMSGSIZE;
1964         return 0;
1965 }
1966
1967 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
1968                                           struct devlink_dpipe_value *values,
1969                                           unsigned int values_count)
1970 {
1971         struct nlattr *match_attr;
1972         int i;
1973         int err;
1974
1975         for (i = 0; i < values_count; i++) {
1976                 match_attr = nla_nest_start(skb,
1977                                             DEVLINK_ATTR_DPIPE_MATCH_VALUE);
1978                 if (!match_attr)
1979                         return -EMSGSIZE;
1980                 err = devlink_dpipe_match_value_put(skb, &values[i]);
1981                 if (err)
1982                         goto err_match_value_put;
1983                 nla_nest_end(skb, match_attr);
1984         }
1985         return 0;
1986
1987 err_match_value_put:
1988         nla_nest_cancel(skb, match_attr);
1989         return err;
1990 }
1991
1992 static int devlink_dpipe_entry_put(struct sk_buff *skb,
1993                                    struct devlink_dpipe_entry *entry)
1994 {
1995         struct nlattr *entry_attr, *matches_attr, *actions_attr;
1996         int err;
1997
1998         entry_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ENTRY);
1999         if (!entry_attr)
2000                 return  -EMSGSIZE;
2001
2002         if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
2003                               DEVLINK_ATTR_PAD))
2004                 goto nla_put_failure;
2005         if (entry->counter_valid)
2006                 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
2007                                       entry->counter, DEVLINK_ATTR_PAD))
2008                         goto nla_put_failure;
2009
2010         matches_attr = nla_nest_start(skb,
2011                                       DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
2012         if (!matches_attr)
2013                 goto nla_put_failure;
2014
2015         err = devlink_dpipe_match_values_put(skb, entry->match_values,
2016                                              entry->match_values_count);
2017         if (err) {
2018                 nla_nest_cancel(skb, matches_attr);
2019                 goto err_match_values_put;
2020         }
2021         nla_nest_end(skb, matches_attr);
2022
2023         actions_attr = nla_nest_start(skb,
2024                                       DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
2025         if (!actions_attr)
2026                 goto nla_put_failure;
2027
2028         err = devlink_dpipe_action_values_put(skb, entry->action_values,
2029                                               entry->action_values_count);
2030         if (err) {
2031                 nla_nest_cancel(skb, actions_attr);
2032                 goto err_action_values_put;
2033         }
2034         nla_nest_end(skb, actions_attr);
2035
2036         nla_nest_end(skb, entry_attr);
2037         return 0;
2038
2039 nla_put_failure:
2040         err = -EMSGSIZE;
2041 err_match_values_put:
2042 err_action_values_put:
2043         nla_nest_cancel(skb, entry_attr);
2044         return err;
2045 }
2046
2047 static struct devlink_dpipe_table *
2048 devlink_dpipe_table_find(struct list_head *dpipe_tables,
2049                          const char *table_name)
2050 {
2051         struct devlink_dpipe_table *table;
2052
2053         list_for_each_entry_rcu(table, dpipe_tables, list) {
2054                 if (!strcmp(table->name, table_name))
2055                         return table;
2056         }
2057         return NULL;
2058 }
2059
2060 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
2061 {
2062         struct devlink *devlink;
2063         int err;
2064
2065         err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
2066                                                dump_ctx->info);
2067         if (err)
2068                 return err;
2069
2070         dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
2071                                     dump_ctx->info->snd_portid,
2072                                     dump_ctx->info->snd_seq,
2073                                     &devlink_nl_family, NLM_F_MULTI,
2074                                     dump_ctx->cmd);
2075         if (!dump_ctx->hdr)
2076                 goto nla_put_failure;
2077
2078         devlink = dump_ctx->info->user_ptr[0];
2079         if (devlink_nl_put_handle(dump_ctx->skb, devlink))
2080                 goto nla_put_failure;
2081         dump_ctx->nest = nla_nest_start(dump_ctx->skb,
2082                                         DEVLINK_ATTR_DPIPE_ENTRIES);
2083         if (!dump_ctx->nest)
2084                 goto nla_put_failure;
2085         return 0;
2086
2087 nla_put_failure:
2088         nlmsg_free(dump_ctx->skb);
2089         return -EMSGSIZE;
2090 }
2091 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2092
2093 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2094                                    struct devlink_dpipe_entry *entry)
2095 {
2096         return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2097 }
2098 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2099
2100 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2101 {
2102         nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2103         genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2104         return 0;
2105 }
2106 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2107
2108 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2109
2110 {
2111         unsigned int value_count, value_index;
2112         struct devlink_dpipe_value *value;
2113
2114         value = entry->action_values;
2115         value_count = entry->action_values_count;
2116         for (value_index = 0; value_index < value_count; value_index++) {
2117                 kfree(value[value_index].value);
2118                 kfree(value[value_index].mask);
2119         }
2120
2121         value = entry->match_values;
2122         value_count = entry->match_values_count;
2123         for (value_index = 0; value_index < value_count; value_index++) {
2124                 kfree(value[value_index].value);
2125                 kfree(value[value_index].mask);
2126         }
2127 }
2128 EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2129
2130 static int devlink_dpipe_entries_fill(struct genl_info *info,
2131                                       enum devlink_command cmd, int flags,
2132                                       struct devlink_dpipe_table *table)
2133 {
2134         struct devlink_dpipe_dump_ctx dump_ctx;
2135         struct nlmsghdr *nlh;
2136         int err;
2137
2138         dump_ctx.skb = NULL;
2139         dump_ctx.cmd = cmd;
2140         dump_ctx.info = info;
2141
2142         err = table->table_ops->entries_dump(table->priv,
2143                                              table->counters_enabled,
2144                                              &dump_ctx);
2145         if (err)
2146                 return err;
2147
2148 send_done:
2149         nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2150                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2151         if (!nlh) {
2152                 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2153                 if (err)
2154                         return err;
2155                 goto send_done;
2156         }
2157         return genlmsg_reply(dump_ctx.skb, info);
2158 }
2159
2160 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2161                                             struct genl_info *info)
2162 {
2163         struct devlink *devlink = info->user_ptr[0];
2164         struct devlink_dpipe_table *table;
2165         const char *table_name;
2166
2167         if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2168                 return -EINVAL;
2169
2170         table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2171         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2172                                          table_name);
2173         if (!table)
2174                 return -EINVAL;
2175
2176         if (!table->table_ops->entries_dump)
2177                 return -EINVAL;
2178
2179         return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2180                                           0, table);
2181 }
2182
2183 static int devlink_dpipe_fields_put(struct sk_buff *skb,
2184                                     const struct devlink_dpipe_header *header)
2185 {
2186         struct devlink_dpipe_field *field;
2187         struct nlattr *field_attr;
2188         int i;
2189
2190         for (i = 0; i < header->fields_count; i++) {
2191                 field = &header->fields[i];
2192                 field_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_FIELD);
2193                 if (!field_attr)
2194                         return -EMSGSIZE;
2195                 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2196                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2197                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2198                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2199                         goto nla_put_failure;
2200                 nla_nest_end(skb, field_attr);
2201         }
2202         return 0;
2203
2204 nla_put_failure:
2205         nla_nest_cancel(skb, field_attr);
2206         return -EMSGSIZE;
2207 }
2208
2209 static int devlink_dpipe_header_put(struct sk_buff *skb,
2210                                     struct devlink_dpipe_header *header)
2211 {
2212         struct nlattr *fields_attr, *header_attr;
2213         int err;
2214
2215         header_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER);
2216         if (!header_attr)
2217                 return -EMSGSIZE;
2218
2219         if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2220             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2221             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2222                 goto nla_put_failure;
2223
2224         fields_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2225         if (!fields_attr)
2226                 goto nla_put_failure;
2227
2228         err = devlink_dpipe_fields_put(skb, header);
2229         if (err) {
2230                 nla_nest_cancel(skb, fields_attr);
2231                 goto nla_put_failure;
2232         }
2233         nla_nest_end(skb, fields_attr);
2234         nla_nest_end(skb, header_attr);
2235         return 0;
2236
2237 nla_put_failure:
2238         err = -EMSGSIZE;
2239         nla_nest_cancel(skb, header_attr);
2240         return err;
2241 }
2242
2243 static int devlink_dpipe_headers_fill(struct genl_info *info,
2244                                       enum devlink_command cmd, int flags,
2245                                       struct devlink_dpipe_headers *
2246                                       dpipe_headers)
2247 {
2248         struct devlink *devlink = info->user_ptr[0];
2249         struct nlattr *headers_attr;
2250         struct sk_buff *skb = NULL;
2251         struct nlmsghdr *nlh;
2252         void *hdr;
2253         int i, j;
2254         int err;
2255
2256         i = 0;
2257 start_again:
2258         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2259         if (err)
2260                 return err;
2261
2262         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2263                           &devlink_nl_family, NLM_F_MULTI, cmd);
2264         if (!hdr) {
2265                 nlmsg_free(skb);
2266                 return -EMSGSIZE;
2267         }
2268
2269         if (devlink_nl_put_handle(skb, devlink))
2270                 goto nla_put_failure;
2271         headers_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2272         if (!headers_attr)
2273                 goto nla_put_failure;
2274
2275         j = 0;
2276         for (; i < dpipe_headers->headers_count; i++) {
2277                 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2278                 if (err) {
2279                         if (!j)
2280                                 goto err_table_put;
2281                         break;
2282                 }
2283                 j++;
2284         }
2285         nla_nest_end(skb, headers_attr);
2286         genlmsg_end(skb, hdr);
2287         if (i != dpipe_headers->headers_count)
2288                 goto start_again;
2289
2290 send_done:
2291         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2292                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2293         if (!nlh) {
2294                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2295                 if (err)
2296                         return err;
2297                 goto send_done;
2298         }
2299         return genlmsg_reply(skb, info);
2300
2301 nla_put_failure:
2302         err = -EMSGSIZE;
2303 err_table_put:
2304         nlmsg_free(skb);
2305         return err;
2306 }
2307
2308 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2309                                             struct genl_info *info)
2310 {
2311         struct devlink *devlink = info->user_ptr[0];
2312
2313         if (!devlink->dpipe_headers)
2314                 return -EOPNOTSUPP;
2315         return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2316                                           0, devlink->dpipe_headers);
2317 }
2318
2319 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2320                                             const char *table_name,
2321                                             bool enable)
2322 {
2323         struct devlink_dpipe_table *table;
2324
2325         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2326                                          table_name);
2327         if (!table)
2328                 return -EINVAL;
2329
2330         if (table->counter_control_extern)
2331                 return -EOPNOTSUPP;
2332
2333         if (!(table->counters_enabled ^ enable))
2334                 return 0;
2335
2336         table->counters_enabled = enable;
2337         if (table->table_ops->counters_set_update)
2338                 table->table_ops->counters_set_update(table->priv, enable);
2339         return 0;
2340 }
2341
2342 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2343                                                    struct genl_info *info)
2344 {
2345         struct devlink *devlink = info->user_ptr[0];
2346         const char *table_name;
2347         bool counters_enable;
2348
2349         if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2350             !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2351                 return -EINVAL;
2352
2353         table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2354         counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2355
2356         return devlink_dpipe_table_counters_set(devlink, table_name,
2357                                                 counters_enable);
2358 }
2359
2360 static struct devlink_resource *
2361 devlink_resource_find(struct devlink *devlink,
2362                       struct devlink_resource *resource, u64 resource_id)
2363 {
2364         struct list_head *resource_list;
2365
2366         if (resource)
2367                 resource_list = &resource->resource_list;
2368         else
2369                 resource_list = &devlink->resource_list;
2370
2371         list_for_each_entry(resource, resource_list, list) {
2372                 struct devlink_resource *child_resource;
2373
2374                 if (resource->id == resource_id)
2375                         return resource;
2376
2377                 child_resource = devlink_resource_find(devlink, resource,
2378                                                        resource_id);
2379                 if (child_resource)
2380                         return child_resource;
2381         }
2382         return NULL;
2383 }
2384
2385 static void
2386 devlink_resource_validate_children(struct devlink_resource *resource)
2387 {
2388         struct devlink_resource *child_resource;
2389         bool size_valid = true;
2390         u64 parts_size = 0;
2391
2392         if (list_empty(&resource->resource_list))
2393                 goto out;
2394
2395         list_for_each_entry(child_resource, &resource->resource_list, list)
2396                 parts_size += child_resource->size_new;
2397
2398         if (parts_size > resource->size_new)
2399                 size_valid = false;
2400 out:
2401         resource->size_valid = size_valid;
2402 }
2403
2404 static int
2405 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2406                                struct netlink_ext_ack *extack)
2407 {
2408         u64 reminder;
2409         int err = 0;
2410
2411         if (size > resource->size_params.size_max) {
2412                 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2413                 err = -EINVAL;
2414         }
2415
2416         if (size < resource->size_params.size_min) {
2417                 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2418                 err = -EINVAL;
2419         }
2420
2421         div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2422         if (reminder) {
2423                 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2424                 err = -EINVAL;
2425         }
2426
2427         return err;
2428 }
2429
2430 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2431                                        struct genl_info *info)
2432 {
2433         struct devlink *devlink = info->user_ptr[0];
2434         struct devlink_resource *resource;
2435         u64 resource_id;
2436         u64 size;
2437         int err;
2438
2439         if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
2440             !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
2441                 return -EINVAL;
2442         resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
2443
2444         resource = devlink_resource_find(devlink, NULL, resource_id);
2445         if (!resource)
2446                 return -EINVAL;
2447
2448         size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2449         err = devlink_resource_validate_size(resource, size, info->extack);
2450         if (err)
2451                 return err;
2452
2453         resource->size_new = size;
2454         devlink_resource_validate_children(resource);
2455         if (resource->parent)
2456                 devlink_resource_validate_children(resource->parent);
2457         return 0;
2458 }
2459
2460 static int
2461 devlink_resource_size_params_put(struct devlink_resource *resource,
2462                                  struct sk_buff *skb)
2463 {
2464         struct devlink_resource_size_params *size_params;
2465
2466         size_params = &resource->size_params;
2467         if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
2468                               size_params->size_granularity, DEVLINK_ATTR_PAD) ||
2469             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
2470                               size_params->size_max, DEVLINK_ATTR_PAD) ||
2471             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
2472                               size_params->size_min, DEVLINK_ATTR_PAD) ||
2473             nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
2474                 return -EMSGSIZE;
2475         return 0;
2476 }
2477
2478 static int devlink_resource_occ_put(struct devlink_resource *resource,
2479                                     struct sk_buff *skb)
2480 {
2481         if (!resource->occ_get)
2482                 return 0;
2483         return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
2484                                  resource->occ_get(resource->occ_get_priv),
2485                                  DEVLINK_ATTR_PAD);
2486 }
2487
2488 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
2489                                 struct devlink_resource *resource)
2490 {
2491         struct devlink_resource *child_resource;
2492         struct nlattr *child_resource_attr;
2493         struct nlattr *resource_attr;
2494
2495         resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE);
2496         if (!resource_attr)
2497                 return -EMSGSIZE;
2498
2499         if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
2500             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
2501                               DEVLINK_ATTR_PAD) ||
2502             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
2503                               DEVLINK_ATTR_PAD))
2504                 goto nla_put_failure;
2505         if (resource->size != resource->size_new)
2506                 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
2507                                   resource->size_new, DEVLINK_ATTR_PAD);
2508         if (devlink_resource_occ_put(resource, skb))
2509                 goto nla_put_failure;
2510         if (devlink_resource_size_params_put(resource, skb))
2511                 goto nla_put_failure;
2512         if (list_empty(&resource->resource_list))
2513                 goto out;
2514
2515         if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
2516                        resource->size_valid))
2517                 goto nla_put_failure;
2518
2519         child_resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST);
2520         if (!child_resource_attr)
2521                 goto nla_put_failure;
2522
2523         list_for_each_entry(child_resource, &resource->resource_list, list) {
2524                 if (devlink_resource_put(devlink, skb, child_resource))
2525                         goto resource_put_failure;
2526         }
2527
2528         nla_nest_end(skb, child_resource_attr);
2529 out:
2530         nla_nest_end(skb, resource_attr);
2531         return 0;
2532
2533 resource_put_failure:
2534         nla_nest_cancel(skb, child_resource_attr);
2535 nla_put_failure:
2536         nla_nest_cancel(skb, resource_attr);
2537         return -EMSGSIZE;
2538 }
2539
2540 static int devlink_resource_fill(struct genl_info *info,
2541                                  enum devlink_command cmd, int flags)
2542 {
2543         struct devlink *devlink = info->user_ptr[0];
2544         struct devlink_resource *resource;
2545         struct nlattr *resources_attr;
2546         struct sk_buff *skb = NULL;
2547         struct nlmsghdr *nlh;
2548         bool incomplete;
2549         void *hdr;
2550         int i;
2551         int err;
2552
2553         resource = list_first_entry(&devlink->resource_list,
2554                                     struct devlink_resource, list);
2555 start_again:
2556         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2557         if (err)
2558                 return err;
2559
2560         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2561                           &devlink_nl_family, NLM_F_MULTI, cmd);
2562         if (!hdr) {
2563                 nlmsg_free(skb);
2564                 return -EMSGSIZE;
2565         }
2566
2567         if (devlink_nl_put_handle(skb, devlink))
2568                 goto nla_put_failure;
2569
2570         resources_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST);
2571         if (!resources_attr)
2572                 goto nla_put_failure;
2573
2574         incomplete = false;
2575         i = 0;
2576         list_for_each_entry_from(resource, &devlink->resource_list, list) {
2577                 err = devlink_resource_put(devlink, skb, resource);
2578                 if (err) {
2579                         if (!i)
2580                                 goto err_resource_put;
2581                         incomplete = true;
2582                         break;
2583                 }
2584                 i++;
2585         }
2586         nla_nest_end(skb, resources_attr);
2587         genlmsg_end(skb, hdr);
2588         if (incomplete)
2589                 goto start_again;
2590 send_done:
2591         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2592                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2593         if (!nlh) {
2594                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2595                 if (err)
2596                         return err;
2597                 goto send_done;
2598         }
2599         return genlmsg_reply(skb, info);
2600
2601 nla_put_failure:
2602         err = -EMSGSIZE;
2603 err_resource_put:
2604         nlmsg_free(skb);
2605         return err;
2606 }
2607
2608 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
2609                                         struct genl_info *info)
2610 {
2611         struct devlink *devlink = info->user_ptr[0];
2612
2613         if (list_empty(&devlink->resource_list))
2614                 return -EOPNOTSUPP;
2615
2616         return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
2617 }
2618
2619 static int
2620 devlink_resources_validate(struct devlink *devlink,
2621                            struct devlink_resource *resource,
2622                            struct genl_info *info)
2623 {
2624         struct list_head *resource_list;
2625         int err = 0;
2626
2627         if (resource)
2628                 resource_list = &resource->resource_list;
2629         else
2630                 resource_list = &devlink->resource_list;
2631
2632         list_for_each_entry(resource, resource_list, list) {
2633                 if (!resource->size_valid)
2634                         return -EINVAL;
2635                 err = devlink_resources_validate(devlink, resource, info);
2636                 if (err)
2637                         return err;
2638         }
2639         return err;
2640 }
2641
2642 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2643 {
2644         struct devlink *devlink = info->user_ptr[0];
2645         int err;
2646
2647         if (!devlink->ops->reload)
2648                 return -EOPNOTSUPP;
2649
2650         err = devlink_resources_validate(devlink, NULL, info);
2651         if (err) {
2652                 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
2653                 return err;
2654         }
2655         return devlink->ops->reload(devlink, info->extack);
2656 }
2657
2658 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
2659                                        struct genl_info *info)
2660 {
2661         struct devlink *devlink = info->user_ptr[0];
2662         const char *file_name, *component;
2663         struct nlattr *nla_component;
2664
2665         if (!devlink->ops->flash_update)
2666                 return -EOPNOTSUPP;
2667
2668         if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
2669                 return -EINVAL;
2670         file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
2671
2672         nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
2673         component = nla_component ? nla_data(nla_component) : NULL;
2674
2675         return devlink->ops->flash_update(devlink, file_name, component,
2676                                           info->extack);
2677 }
2678
2679 static const struct devlink_param devlink_param_generic[] = {
2680         {
2681                 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
2682                 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
2683                 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
2684         },
2685         {
2686                 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
2687                 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
2688                 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
2689         },
2690         {
2691                 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
2692                 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
2693                 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
2694         },
2695         {
2696                 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
2697                 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
2698                 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
2699         },
2700         {
2701                 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
2702                 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
2703                 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
2704         },
2705         {
2706                 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
2707                 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
2708                 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
2709         },
2710         {
2711                 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
2712                 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
2713                 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
2714         },
2715         {
2716                 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
2717                 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
2718                 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
2719         },
2720 };
2721
2722 static int devlink_param_generic_verify(const struct devlink_param *param)
2723 {
2724         /* verify it match generic parameter by id and name */
2725         if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
2726                 return -EINVAL;
2727         if (strcmp(param->name, devlink_param_generic[param->id].name))
2728                 return -ENOENT;
2729
2730         WARN_ON(param->type != devlink_param_generic[param->id].type);
2731
2732         return 0;
2733 }
2734
2735 static int devlink_param_driver_verify(const struct devlink_param *param)
2736 {
2737         int i;
2738
2739         if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
2740                 return -EINVAL;
2741         /* verify no such name in generic params */
2742         for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
2743                 if (!strcmp(param->name, devlink_param_generic[i].name))
2744                         return -EEXIST;
2745
2746         return 0;
2747 }
2748
2749 static struct devlink_param_item *
2750 devlink_param_find_by_name(struct list_head *param_list,
2751                            const char *param_name)
2752 {
2753         struct devlink_param_item *param_item;
2754
2755         list_for_each_entry(param_item, param_list, list)
2756                 if (!strcmp(param_item->param->name, param_name))
2757                         return param_item;
2758         return NULL;
2759 }
2760
2761 static struct devlink_param_item *
2762 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
2763 {
2764         struct devlink_param_item *param_item;
2765
2766         list_for_each_entry(param_item, param_list, list)
2767                 if (param_item->param->id == param_id)
2768                         return param_item;
2769         return NULL;
2770 }
2771
2772 static bool
2773 devlink_param_cmode_is_supported(const struct devlink_param *param,
2774                                  enum devlink_param_cmode cmode)
2775 {
2776         return test_bit(cmode, &param->supported_cmodes);
2777 }
2778
2779 static int devlink_param_get(struct devlink *devlink,
2780                              const struct devlink_param *param,
2781                              struct devlink_param_gset_ctx *ctx)
2782 {
2783         if (!param->get)
2784                 return -EOPNOTSUPP;
2785         return param->get(devlink, param->id, ctx);
2786 }
2787
2788 static int devlink_param_set(struct devlink *devlink,
2789                              const struct devlink_param *param,
2790                              struct devlink_param_gset_ctx *ctx)
2791 {
2792         if (!param->set)
2793                 return -EOPNOTSUPP;
2794         return param->set(devlink, param->id, ctx);
2795 }
2796
2797 static int
2798 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
2799 {
2800         switch (param_type) {
2801         case DEVLINK_PARAM_TYPE_U8:
2802                 return NLA_U8;
2803         case DEVLINK_PARAM_TYPE_U16:
2804                 return NLA_U16;
2805         case DEVLINK_PARAM_TYPE_U32:
2806                 return NLA_U32;
2807         case DEVLINK_PARAM_TYPE_STRING:
2808                 return NLA_STRING;
2809         case DEVLINK_PARAM_TYPE_BOOL:
2810                 return NLA_FLAG;
2811         default:
2812                 return -EINVAL;
2813         }
2814 }
2815
2816 static int
2817 devlink_nl_param_value_fill_one(struct sk_buff *msg,
2818                                 enum devlink_param_type type,
2819                                 enum devlink_param_cmode cmode,
2820                                 union devlink_param_value val)
2821 {
2822         struct nlattr *param_value_attr;
2823
2824         param_value_attr = nla_nest_start(msg, DEVLINK_ATTR_PARAM_VALUE);
2825         if (!param_value_attr)
2826                 goto nla_put_failure;
2827
2828         if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
2829                 goto value_nest_cancel;
2830
2831         switch (type) {
2832         case DEVLINK_PARAM_TYPE_U8:
2833                 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
2834                         goto value_nest_cancel;
2835                 break;
2836         case DEVLINK_PARAM_TYPE_U16:
2837                 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
2838                         goto value_nest_cancel;
2839                 break;
2840         case DEVLINK_PARAM_TYPE_U32:
2841                 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
2842                         goto value_nest_cancel;
2843                 break;
2844         case DEVLINK_PARAM_TYPE_STRING:
2845                 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
2846                                    val.vstr))
2847                         goto value_nest_cancel;
2848                 break;
2849         case DEVLINK_PARAM_TYPE_BOOL:
2850                 if (val.vbool &&
2851                     nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
2852                         goto value_nest_cancel;
2853                 break;
2854         }
2855
2856         nla_nest_end(msg, param_value_attr);
2857         return 0;
2858
2859 value_nest_cancel:
2860         nla_nest_cancel(msg, param_value_attr);
2861 nla_put_failure:
2862         return -EMSGSIZE;
2863 }
2864
2865 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
2866                                  unsigned int port_index,
2867                                  struct devlink_param_item *param_item,
2868                                  enum devlink_command cmd,
2869                                  u32 portid, u32 seq, int flags)
2870 {
2871         union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
2872         bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
2873         const struct devlink_param *param = param_item->param;
2874         struct devlink_param_gset_ctx ctx;
2875         struct nlattr *param_values_list;
2876         struct nlattr *param_attr;
2877         int nla_type;
2878         void *hdr;
2879         int err;
2880         int i;
2881
2882         /* Get value from driver part to driverinit configuration mode */
2883         for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
2884                 if (!devlink_param_cmode_is_supported(param, i))
2885                         continue;
2886                 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
2887                         if (!param_item->driverinit_value_valid)
2888                                 return -EOPNOTSUPP;
2889                         param_value[i] = param_item->driverinit_value;
2890                 } else {
2891                         if (!param_item->published)
2892                                 continue;
2893                         ctx.cmode = i;
2894                         err = devlink_param_get(devlink, param, &ctx);
2895                         if (err)
2896                                 return err;
2897                         param_value[i] = ctx.val;
2898                 }
2899                 param_value_set[i] = true;
2900         }
2901
2902         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2903         if (!hdr)
2904                 return -EMSGSIZE;
2905
2906         if (devlink_nl_put_handle(msg, devlink))
2907                 goto genlmsg_cancel;
2908
2909         if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
2910             cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
2911             cmd == DEVLINK_CMD_PORT_PARAM_DEL)
2912                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
2913                         goto genlmsg_cancel;
2914
2915         param_attr = nla_nest_start(msg, DEVLINK_ATTR_PARAM);
2916         if (!param_attr)
2917                 goto genlmsg_cancel;
2918         if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
2919                 goto param_nest_cancel;
2920         if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
2921                 goto param_nest_cancel;
2922
2923         nla_type = devlink_param_type_to_nla_type(param->type);
2924         if (nla_type < 0)
2925                 goto param_nest_cancel;
2926         if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
2927                 goto param_nest_cancel;
2928
2929         param_values_list = nla_nest_start(msg, DEVLINK_ATTR_PARAM_VALUES_LIST);
2930         if (!param_values_list)
2931                 goto param_nest_cancel;
2932
2933         for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
2934                 if (!param_value_set[i])
2935                         continue;
2936                 err = devlink_nl_param_value_fill_one(msg, param->type,
2937                                                       i, param_value[i]);
2938                 if (err)
2939                         goto values_list_nest_cancel;
2940         }
2941
2942         nla_nest_end(msg, param_values_list);
2943         nla_nest_end(msg, param_attr);
2944         genlmsg_end(msg, hdr);
2945         return 0;
2946
2947 values_list_nest_cancel:
2948         nla_nest_end(msg, param_values_list);
2949 param_nest_cancel:
2950         nla_nest_cancel(msg, param_attr);
2951 genlmsg_cancel:
2952         genlmsg_cancel(msg, hdr);
2953         return -EMSGSIZE;
2954 }
2955
2956 static void devlink_param_notify(struct devlink *devlink,
2957                                  unsigned int port_index,
2958                                  struct devlink_param_item *param_item,
2959                                  enum devlink_command cmd)
2960 {
2961         struct sk_buff *msg;
2962         int err;
2963
2964         WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
2965                 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
2966                 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
2967
2968         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2969         if (!msg)
2970                 return;
2971         err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
2972                                     0, 0, 0);
2973         if (err) {
2974                 nlmsg_free(msg);
2975                 return;
2976         }
2977
2978         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2979                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
2980 }
2981
2982 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
2983                                            struct netlink_callback *cb)
2984 {
2985         struct devlink_param_item *param_item;
2986         struct devlink *devlink;
2987         int start = cb->args[0];
2988         int idx = 0;
2989         int err;
2990
2991         mutex_lock(&devlink_mutex);
2992         list_for_each_entry(devlink, &devlink_list, list) {
2993                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
2994                         continue;
2995                 mutex_lock(&devlink->lock);
2996                 list_for_each_entry(param_item, &devlink->param_list, list) {
2997                         if (idx < start) {
2998                                 idx++;
2999                                 continue;
3000                         }
3001                         err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3002                                                     DEVLINK_CMD_PARAM_GET,
3003                                                     NETLINK_CB(cb->skb).portid,
3004                                                     cb->nlh->nlmsg_seq,
3005                                                     NLM_F_MULTI);
3006                         if (err) {
3007                                 mutex_unlock(&devlink->lock);
3008                                 goto out;
3009                         }
3010                         idx++;
3011                 }
3012                 mutex_unlock(&devlink->lock);
3013         }
3014 out:
3015         mutex_unlock(&devlink_mutex);
3016
3017         cb->args[0] = idx;
3018         return msg->len;
3019 }
3020
3021 static int
3022 devlink_param_type_get_from_info(struct genl_info *info,
3023                                  enum devlink_param_type *param_type)
3024 {
3025         if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE])
3026                 return -EINVAL;
3027
3028         switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
3029         case NLA_U8:
3030                 *param_type = DEVLINK_PARAM_TYPE_U8;
3031                 break;
3032         case NLA_U16:
3033                 *param_type = DEVLINK_PARAM_TYPE_U16;
3034                 break;
3035         case NLA_U32:
3036                 *param_type = DEVLINK_PARAM_TYPE_U32;
3037                 break;
3038         case NLA_STRING:
3039                 *param_type = DEVLINK_PARAM_TYPE_STRING;
3040                 break;
3041         case NLA_FLAG:
3042                 *param_type = DEVLINK_PARAM_TYPE_BOOL;
3043                 break;
3044         default:
3045                 return -EINVAL;
3046         }
3047
3048         return 0;
3049 }
3050
3051 static int
3052 devlink_param_value_get_from_info(const struct devlink_param *param,
3053                                   struct genl_info *info,
3054                                   union devlink_param_value *value)
3055 {
3056         int len;
3057
3058         if (param->type != DEVLINK_PARAM_TYPE_BOOL &&
3059             !info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])
3060                 return -EINVAL;
3061
3062         switch (param->type) {
3063         case DEVLINK_PARAM_TYPE_U8:
3064                 value->vu8 = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3065                 break;
3066         case DEVLINK_PARAM_TYPE_U16:
3067                 value->vu16 = nla_get_u16(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3068                 break;
3069         case DEVLINK_PARAM_TYPE_U32:
3070                 value->vu32 = nla_get_u32(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3071                 break;
3072         case DEVLINK_PARAM_TYPE_STRING:
3073                 len = strnlen(nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]),
3074                               nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
3075                 if (len == nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) ||
3076                     len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
3077                         return -EINVAL;
3078                 strcpy(value->vstr,
3079                        nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
3080                 break;
3081         case DEVLINK_PARAM_TYPE_BOOL:
3082                 value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ?
3083                                true : false;
3084                 break;
3085         }
3086         return 0;
3087 }
3088
3089 static struct devlink_param_item *
3090 devlink_param_get_from_info(struct list_head *param_list,
3091                             struct genl_info *info)
3092 {
3093         char *param_name;
3094
3095         if (!info->attrs[DEVLINK_ATTR_PARAM_NAME])
3096                 return NULL;
3097
3098         param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
3099         return devlink_param_find_by_name(param_list, param_name);
3100 }
3101
3102 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
3103                                          struct genl_info *info)
3104 {
3105         struct devlink *devlink = info->user_ptr[0];
3106         struct devlink_param_item *param_item;
3107         struct sk_buff *msg;
3108         int err;
3109
3110         param_item = devlink_param_get_from_info(&devlink->param_list, info);
3111         if (!param_item)
3112                 return -EINVAL;
3113
3114         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3115         if (!msg)
3116                 return -ENOMEM;
3117
3118         err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3119                                     DEVLINK_CMD_PARAM_GET,
3120                                     info->snd_portid, info->snd_seq, 0);
3121         if (err) {
3122                 nlmsg_free(msg);
3123                 return err;
3124         }
3125
3126         return genlmsg_reply(msg, info);
3127 }
3128
3129 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
3130                                            unsigned int port_index,
3131                                            struct list_head *param_list,
3132                                            struct genl_info *info,
3133                                            enum devlink_command cmd)
3134 {
3135         enum devlink_param_type param_type;
3136         struct devlink_param_gset_ctx ctx;
3137         enum devlink_param_cmode cmode;
3138         struct devlink_param_item *param_item;
3139         const struct devlink_param *param;
3140         union devlink_param_value value;
3141         int err = 0;
3142
3143         param_item = devlink_param_get_from_info(param_list, info);
3144         if (!param_item)
3145                 return -EINVAL;
3146         param = param_item->param;
3147         err = devlink_param_type_get_from_info(info, &param_type);
3148         if (err)
3149                 return err;
3150         if (param_type != param->type)
3151                 return -EINVAL;
3152         err = devlink_param_value_get_from_info(param, info, &value);
3153         if (err)
3154                 return err;
3155         if (param->validate) {
3156                 err = param->validate(devlink, param->id, value, info->extack);
3157                 if (err)
3158                         return err;
3159         }
3160
3161         if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE])
3162                 return -EINVAL;
3163         cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
3164         if (!devlink_param_cmode_is_supported(param, cmode))
3165                 return -EOPNOTSUPP;
3166
3167         if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3168                 if (param->type == DEVLINK_PARAM_TYPE_STRING)
3169                         strcpy(param_item->driverinit_value.vstr, value.vstr);
3170                 else
3171                         param_item->driverinit_value = value;
3172                 param_item->driverinit_value_valid = true;
3173         } else {
3174                 if (!param->set)
3175                         return -EOPNOTSUPP;
3176                 ctx.val = value;
3177                 ctx.cmode = cmode;
3178                 err = devlink_param_set(devlink, param, &ctx);
3179                 if (err)
3180                         return err;
3181         }
3182
3183         devlink_param_notify(devlink, port_index, param_item, cmd);
3184         return 0;
3185 }
3186
3187 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
3188                                          struct genl_info *info)
3189 {
3190         struct devlink *devlink = info->user_ptr[0];
3191
3192         return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
3193                                                info, DEVLINK_CMD_PARAM_NEW);
3194 }
3195
3196 static int devlink_param_register_one(struct devlink *devlink,
3197                                       unsigned int port_index,
3198                                       struct list_head *param_list,
3199                                       const struct devlink_param *param,
3200                                       enum devlink_command cmd)
3201 {
3202         struct devlink_param_item *param_item;
3203
3204         if (devlink_param_find_by_name(param_list, param->name))
3205                 return -EEXIST;
3206
3207         if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
3208                 WARN_ON(param->get || param->set);
3209         else
3210                 WARN_ON(!param->get || !param->set);
3211
3212         param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
3213         if (!param_item)
3214                 return -ENOMEM;
3215         param_item->param = param;
3216
3217         list_add_tail(&param_item->list, param_list);
3218         devlink_param_notify(devlink, port_index, param_item, cmd);
3219         return 0;
3220 }
3221
3222 static void devlink_param_unregister_one(struct devlink *devlink,
3223                                          unsigned int port_index,
3224                                          struct list_head *param_list,
3225                                          const struct devlink_param *param,
3226                                          enum devlink_command cmd)
3227 {
3228         struct devlink_param_item *param_item;
3229
3230         param_item = devlink_param_find_by_name(param_list, param->name);
3231         WARN_ON(!param_item);
3232         devlink_param_notify(devlink, port_index, param_item, cmd);
3233         list_del(&param_item->list);
3234         kfree(param_item);
3235 }
3236
3237 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
3238                                                 struct netlink_callback *cb)
3239 {
3240         struct devlink_param_item *param_item;
3241         struct devlink_port *devlink_port;
3242         struct devlink *devlink;
3243         int start = cb->args[0];
3244         int idx = 0;
3245         int err;
3246
3247         mutex_lock(&devlink_mutex);
3248         list_for_each_entry(devlink, &devlink_list, list) {
3249                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3250                         continue;
3251                 mutex_lock(&devlink->lock);
3252                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
3253                         list_for_each_entry(param_item,
3254                                             &devlink_port->param_list, list) {
3255                                 if (idx < start) {
3256                                         idx++;
3257                                         continue;
3258                                 }
3259                                 err = devlink_nl_param_fill(msg,
3260                                                 devlink_port->devlink,
3261                                                 devlink_port->index, param_item,
3262                                                 DEVLINK_CMD_PORT_PARAM_GET,
3263                                                 NETLINK_CB(cb->skb).portid,
3264                                                 cb->nlh->nlmsg_seq,
3265                                                 NLM_F_MULTI);
3266                                 if (err) {
3267                                         mutex_unlock(&devlink->lock);
3268                                         goto out;
3269                                 }
3270                                 idx++;
3271                         }
3272                 }
3273                 mutex_unlock(&devlink->lock);
3274         }
3275 out:
3276         mutex_unlock(&devlink_mutex);
3277
3278         cb->args[0] = idx;
3279         return msg->len;
3280 }
3281
3282 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
3283                                               struct genl_info *info)
3284 {
3285         struct devlink_port *devlink_port = info->user_ptr[0];
3286         struct devlink_param_item *param_item;
3287         struct sk_buff *msg;
3288         int err;
3289
3290         param_item = devlink_param_get_from_info(&devlink_port->param_list,
3291                                                  info);
3292         if (!param_item)
3293                 return -EINVAL;
3294
3295         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3296         if (!msg)
3297                 return -ENOMEM;
3298
3299         err = devlink_nl_param_fill(msg, devlink_port->devlink,
3300                                     devlink_port->index, param_item,
3301                                     DEVLINK_CMD_PORT_PARAM_GET,
3302                                     info->snd_portid, info->snd_seq, 0);
3303         if (err) {
3304                 nlmsg_free(msg);
3305                 return err;
3306         }
3307
3308         return genlmsg_reply(msg, info);
3309 }
3310
3311 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
3312                                               struct genl_info *info)
3313 {
3314         struct devlink_port *devlink_port = info->user_ptr[0];
3315
3316         return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
3317                                                devlink_port->index,
3318                                                &devlink_port->param_list, info,
3319                                                DEVLINK_CMD_PORT_PARAM_NEW);
3320 }
3321
3322 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
3323                                              struct devlink *devlink,
3324                                              struct devlink_snapshot *snapshot)
3325 {
3326         struct nlattr *snap_attr;
3327         int err;
3328
3329         snap_attr = nla_nest_start(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
3330         if (!snap_attr)
3331                 return -EINVAL;
3332
3333         err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
3334         if (err)
3335                 goto nla_put_failure;
3336
3337         nla_nest_end(msg, snap_attr);
3338         return 0;
3339
3340 nla_put_failure:
3341         nla_nest_cancel(msg, snap_attr);
3342         return err;
3343 }
3344
3345 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
3346                                               struct devlink *devlink,
3347                                               struct devlink_region *region)
3348 {
3349         struct devlink_snapshot *snapshot;
3350         struct nlattr *snapshots_attr;
3351         int err;
3352
3353         snapshots_attr = nla_nest_start(msg, DEVLINK_ATTR_REGION_SNAPSHOTS);
3354         if (!snapshots_attr)
3355                 return -EINVAL;
3356
3357         list_for_each_entry(snapshot, &region->snapshot_list, list) {
3358                 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
3359                 if (err)
3360                         goto nla_put_failure;
3361         }
3362
3363         nla_nest_end(msg, snapshots_attr);
3364         return 0;
3365
3366 nla_put_failure:
3367         nla_nest_cancel(msg, snapshots_attr);
3368         return err;
3369 }
3370
3371 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3372                                   enum devlink_command cmd, u32 portid,
3373                                   u32 seq, int flags,
3374                                   struct devlink_region *region)
3375 {
3376         void *hdr;
3377         int err;
3378
3379         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3380         if (!hdr)
3381                 return -EMSGSIZE;
3382
3383         err = devlink_nl_put_handle(msg, devlink);
3384         if (err)
3385                 goto nla_put_failure;
3386
3387         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->name);
3388         if (err)
3389                 goto nla_put_failure;
3390
3391         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3392                                 region->size,
3393                                 DEVLINK_ATTR_PAD);
3394         if (err)
3395                 goto nla_put_failure;
3396
3397         err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
3398         if (err)
3399                 goto nla_put_failure;
3400
3401         genlmsg_end(msg, hdr);
3402         return 0;
3403
3404 nla_put_failure:
3405         genlmsg_cancel(msg, hdr);
3406         return err;
3407 }
3408
3409 static void devlink_nl_region_notify(struct devlink_region *region,
3410                                      struct devlink_snapshot *snapshot,
3411                                      enum devlink_command cmd)
3412 {
3413         struct devlink *devlink = region->devlink;
3414         struct sk_buff *msg;
3415         void *hdr;
3416         int err;
3417
3418         WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
3419
3420         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3421         if (!msg)
3422                 return;
3423
3424         hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
3425         if (!hdr)
3426                 goto out_free_msg;
3427
3428         err = devlink_nl_put_handle(msg, devlink);
3429         if (err)
3430                 goto out_cancel_msg;
3431
3432         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
3433                              region->name);
3434         if (err)
3435                 goto out_cancel_msg;
3436
3437         if (snapshot) {
3438                 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
3439                                   snapshot->id);
3440                 if (err)
3441                         goto out_cancel_msg;
3442         } else {
3443                 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3444                                         region->size, DEVLINK_ATTR_PAD);
3445                 if (err)
3446                         goto out_cancel_msg;
3447         }
3448         genlmsg_end(msg, hdr);
3449
3450         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3451                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3452
3453         return;
3454
3455 out_cancel_msg:
3456         genlmsg_cancel(msg, hdr);
3457 out_free_msg:
3458         nlmsg_free(msg);
3459 }
3460
3461 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
3462                                           struct genl_info *info)
3463 {
3464         struct devlink *devlink = info->user_ptr[0];
3465         struct devlink_region *region;
3466         const char *region_name;
3467         struct sk_buff *msg;
3468         int err;
3469
3470         if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
3471                 return -EINVAL;
3472
3473         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3474         region = devlink_region_get_by_name(devlink, region_name);
3475         if (!region)
3476                 return -EINVAL;
3477
3478         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3479         if (!msg)
3480                 return -ENOMEM;
3481
3482         err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
3483                                      info->snd_portid, info->snd_seq, 0,
3484                                      region);
3485         if (err) {
3486                 nlmsg_free(msg);
3487                 return err;
3488         }
3489
3490         return genlmsg_reply(msg, info);
3491 }
3492
3493 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
3494                                             struct netlink_callback *cb)
3495 {
3496         struct devlink_region *region;
3497         struct devlink *devlink;
3498         int start = cb->args[0];
3499         int idx = 0;
3500         int err;
3501
3502         mutex_lock(&devlink_mutex);
3503         list_for_each_entry(devlink, &devlink_list, list) {
3504                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3505                         continue;
3506
3507                 mutex_lock(&devlink->lock);
3508                 list_for_each_entry(region, &devlink->region_list, list) {
3509                         if (idx < start) {
3510                                 idx++;
3511                                 continue;
3512                         }
3513                         err = devlink_nl_region_fill(msg, devlink,
3514                                                      DEVLINK_CMD_REGION_GET,
3515                                                      NETLINK_CB(cb->skb).portid,
3516                                                      cb->nlh->nlmsg_seq,
3517                                                      NLM_F_MULTI, region);
3518                         if (err) {
3519                                 mutex_unlock(&devlink->lock);
3520                                 goto out;
3521                         }
3522                         idx++;
3523                 }
3524                 mutex_unlock(&devlink->lock);
3525         }
3526 out:
3527         mutex_unlock(&devlink_mutex);
3528         cb->args[0] = idx;
3529         return msg->len;
3530 }
3531
3532 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
3533                                      struct genl_info *info)
3534 {
3535         struct devlink *devlink = info->user_ptr[0];
3536         struct devlink_snapshot *snapshot;
3537         struct devlink_region *region;
3538         const char *region_name;
3539         u32 snapshot_id;
3540
3541         if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
3542             !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
3543                 return -EINVAL;
3544
3545         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3546         snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3547
3548         region = devlink_region_get_by_name(devlink, region_name);
3549         if (!region)
3550                 return -EINVAL;
3551
3552         snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3553         if (!snapshot)
3554                 return -EINVAL;
3555
3556         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
3557         devlink_region_snapshot_del(snapshot);
3558         return 0;
3559 }
3560
3561 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
3562                                                  struct devlink *devlink,
3563                                                  u8 *chunk, u32 chunk_size,
3564                                                  u64 addr)
3565 {
3566         struct nlattr *chunk_attr;
3567         int err;
3568
3569         chunk_attr = nla_nest_start(msg, DEVLINK_ATTR_REGION_CHUNK);
3570         if (!chunk_attr)
3571                 return -EINVAL;
3572
3573         err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
3574         if (err)
3575                 goto nla_put_failure;
3576
3577         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
3578                                 DEVLINK_ATTR_PAD);
3579         if (err)
3580                 goto nla_put_failure;
3581
3582         nla_nest_end(msg, chunk_attr);
3583         return 0;
3584
3585 nla_put_failure:
3586         nla_nest_cancel(msg, chunk_attr);
3587         return err;
3588 }
3589
3590 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
3591
3592 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
3593                                                 struct devlink *devlink,
3594                                                 struct devlink_region *region,
3595                                                 struct nlattr **attrs,
3596                                                 u64 start_offset,
3597                                                 u64 end_offset,
3598                                                 bool dump,
3599                                                 u64 *new_offset)
3600 {
3601         struct devlink_snapshot *snapshot;
3602         u64 curr_offset = start_offset;
3603         u32 snapshot_id;
3604         int err = 0;
3605
3606         *new_offset = start_offset;
3607
3608         snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3609         snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3610         if (!snapshot)
3611                 return -EINVAL;
3612
3613         if (end_offset > snapshot->data_len || dump)
3614                 end_offset = snapshot->data_len;
3615
3616         while (curr_offset < end_offset) {
3617                 u32 data_size;
3618                 u8 *data;
3619
3620                 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
3621                         data_size = end_offset - curr_offset;
3622                 else
3623                         data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
3624
3625                 data = &snapshot->data[curr_offset];
3626                 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
3627                                                             data, data_size,
3628                                                             curr_offset);
3629                 if (err)
3630                         break;
3631
3632                 curr_offset += data_size;
3633         }
3634         *new_offset = curr_offset;
3635
3636         return err;
3637 }
3638
3639 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
3640                                              struct netlink_callback *cb)
3641 {
3642         u64 ret_offset, start_offset, end_offset = 0;
3643         const struct genl_ops *ops = cb->data;
3644         struct devlink_region *region;
3645         struct nlattr *chunks_attr;
3646         const char *region_name;
3647         struct devlink *devlink;
3648         struct nlattr **attrs;
3649         bool dump = true;
3650         void *hdr;
3651         int err;
3652
3653         start_offset = *((u64 *)&cb->args[0]);
3654
3655         attrs = kmalloc_array(DEVLINK_ATTR_MAX + 1, sizeof(*attrs), GFP_KERNEL);
3656         if (!attrs)
3657                 return -ENOMEM;
3658
3659         err = nlmsg_parse(cb->nlh, GENL_HDRLEN + devlink_nl_family.hdrsize,
3660                           attrs, DEVLINK_ATTR_MAX, ops->policy, cb->extack);
3661         if (err)
3662                 goto out_free;
3663
3664         mutex_lock(&devlink_mutex);
3665         devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
3666         if (IS_ERR(devlink)) {
3667                 err = PTR_ERR(devlink);
3668                 goto out_dev;
3669         }
3670
3671         mutex_lock(&devlink->lock);
3672
3673         if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
3674             !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
3675                 err = -EINVAL;
3676                 goto out_unlock;
3677         }
3678
3679         region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
3680         region = devlink_region_get_by_name(devlink, region_name);
3681         if (!region) {
3682                 err = -EINVAL;
3683                 goto out_unlock;
3684         }
3685
3686         hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
3687                           &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
3688                           DEVLINK_CMD_REGION_READ);
3689         if (!hdr) {
3690                 err = -EMSGSIZE;
3691                 goto out_unlock;
3692         }
3693
3694         err = devlink_nl_put_handle(skb, devlink);
3695         if (err)
3696                 goto nla_put_failure;
3697
3698         err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
3699         if (err)
3700                 goto nla_put_failure;
3701
3702         chunks_attr = nla_nest_start(skb, DEVLINK_ATTR_REGION_CHUNKS);
3703         if (!chunks_attr) {
3704                 err = -EMSGSIZE;
3705                 goto nla_put_failure;
3706         }
3707
3708         if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
3709             attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
3710                 if (!start_offset)
3711                         start_offset =
3712                                 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3713
3714                 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3715                 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
3716                 dump = false;
3717         }
3718
3719         err = devlink_nl_region_read_snapshot_fill(skb, devlink,
3720                                                    region, attrs,
3721                                                    start_offset,
3722                                                    end_offset, dump,
3723                                                    &ret_offset);
3724
3725         if (err && err != -EMSGSIZE)
3726                 goto nla_put_failure;
3727
3728         /* Check if there was any progress done to prevent infinite loop */
3729         if (ret_offset == start_offset) {
3730                 err = -EINVAL;
3731                 goto nla_put_failure;
3732         }
3733
3734         *((u64 *)&cb->args[0]) = ret_offset;
3735
3736         nla_nest_end(skb, chunks_attr);
3737         genlmsg_end(skb, hdr);
3738         mutex_unlock(&devlink->lock);
3739         mutex_unlock(&devlink_mutex);
3740         kfree(attrs);
3741
3742         return skb->len;
3743
3744 nla_put_failure:
3745         genlmsg_cancel(skb, hdr);
3746 out_unlock:
3747         mutex_unlock(&devlink->lock);
3748 out_dev:
3749         mutex_unlock(&devlink_mutex);
3750 out_free:
3751         kfree(attrs);
3752         return err;
3753 }
3754
3755 struct devlink_info_req {
3756         struct sk_buff *msg;
3757 };
3758
3759 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
3760 {
3761         return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
3762 }
3763 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
3764
3765 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
3766 {
3767         return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
3768 }
3769 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
3770
3771 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
3772                                     const char *version_name,
3773                                     const char *version_value)
3774 {
3775         struct nlattr *nest;
3776         int err;
3777
3778         nest = nla_nest_start(req->msg, attr);
3779         if (!nest)
3780                 return -EMSGSIZE;
3781
3782         err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
3783                              version_name);
3784         if (err)
3785                 goto nla_put_failure;
3786
3787         err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
3788                              version_value);
3789         if (err)
3790                 goto nla_put_failure;
3791
3792         nla_nest_end(req->msg, nest);
3793
3794         return 0;
3795
3796 nla_put_failure:
3797         nla_nest_cancel(req->msg, nest);
3798         return err;
3799 }
3800
3801 int devlink_info_version_fixed_put(struct devlink_info_req *req,
3802                                    const char *version_name,
3803                                    const char *version_value)
3804 {
3805         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
3806                                         version_name, version_value);
3807 }
3808 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
3809
3810 int devlink_info_version_stored_put(struct devlink_info_req *req,
3811                                     const char *version_name,
3812                                     const char *version_value)
3813 {
3814         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
3815                                         version_name, version_value);
3816 }
3817 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
3818
3819 int devlink_info_version_running_put(struct devlink_info_req *req,
3820                                      const char *version_name,
3821                                      const char *version_value)
3822 {
3823         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
3824                                         version_name, version_value);
3825 }
3826 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
3827
3828 static int
3829 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
3830                      enum devlink_command cmd, u32 portid,
3831                      u32 seq, int flags, struct netlink_ext_ack *extack)
3832 {
3833         struct devlink_info_req req;
3834         void *hdr;
3835         int err;
3836
3837         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3838         if (!hdr)
3839                 return -EMSGSIZE;
3840
3841         err = -EMSGSIZE;
3842         if (devlink_nl_put_handle(msg, devlink))
3843                 goto err_cancel_msg;
3844
3845         req.msg = msg;
3846         err = devlink->ops->info_get(devlink, &req, extack);
3847         if (err)
3848                 goto err_cancel_msg;
3849
3850         genlmsg_end(msg, hdr);
3851         return 0;
3852
3853 err_cancel_msg:
3854         genlmsg_cancel(msg, hdr);
3855         return err;
3856 }
3857
3858 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
3859                                         struct genl_info *info)
3860 {
3861         struct devlink *devlink = info->user_ptr[0];
3862         struct sk_buff *msg;
3863         int err;
3864
3865         if (!devlink->ops->info_get)
3866                 return -EOPNOTSUPP;
3867
3868         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3869         if (!msg)
3870                 return -ENOMEM;
3871
3872         err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
3873                                    info->snd_portid, info->snd_seq, 0,
3874                                    info->extack);
3875         if (err) {
3876                 nlmsg_free(msg);
3877                 return err;
3878         }
3879
3880         return genlmsg_reply(msg, info);
3881 }
3882
3883 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
3884                                           struct netlink_callback *cb)
3885 {
3886         struct devlink *devlink;
3887         int start = cb->args[0];
3888         int idx = 0;
3889         int err;
3890
3891         mutex_lock(&devlink_mutex);
3892         list_for_each_entry(devlink, &devlink_list, list) {
3893                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3894                         continue;
3895                 if (idx < start) {
3896                         idx++;
3897                         continue;
3898                 }
3899
3900                 mutex_lock(&devlink->lock);
3901                 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
3902                                            NETLINK_CB(cb->skb).portid,
3903                                            cb->nlh->nlmsg_seq, NLM_F_MULTI,
3904                                            cb->extack);
3905                 mutex_unlock(&devlink->lock);
3906                 if (err)
3907                         break;
3908                 idx++;
3909         }
3910         mutex_unlock(&devlink_mutex);
3911
3912         cb->args[0] = idx;
3913         return msg->len;
3914 }
3915
3916 struct devlink_fmsg_item {
3917         struct list_head list;
3918         int attrtype;
3919         u8 nla_type;
3920         u16 len;
3921         int value[0];
3922 };
3923
3924 struct devlink_fmsg {
3925         struct list_head item_list;
3926 };
3927
3928 static struct devlink_fmsg *devlink_fmsg_alloc(void)
3929 {
3930         struct devlink_fmsg *fmsg;
3931
3932         fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
3933         if (!fmsg)
3934                 return NULL;
3935
3936         INIT_LIST_HEAD(&fmsg->item_list);
3937
3938         return fmsg;
3939 }
3940
3941 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
3942 {
3943         struct devlink_fmsg_item *item, *tmp;
3944
3945         list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
3946                 list_del(&item->list);
3947                 kfree(item);
3948         }
3949         kfree(fmsg);
3950 }
3951
3952 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
3953                                     int attrtype)
3954 {
3955         struct devlink_fmsg_item *item;
3956
3957         item = kzalloc(sizeof(*item), GFP_KERNEL);
3958         if (!item)
3959                 return -ENOMEM;
3960
3961         item->attrtype = attrtype;
3962         list_add_tail(&item->list, &fmsg->item_list);
3963
3964         return 0;
3965 }
3966
3967 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
3968 {
3969         return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
3970 }
3971 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
3972
3973 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
3974 {
3975         return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
3976 }
3977
3978 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
3979 {
3980         return devlink_fmsg_nest_end(fmsg);
3981 }
3982 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
3983
3984 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
3985
3986 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
3987 {
3988         struct devlink_fmsg_item *item;
3989
3990         if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
3991                 return -EMSGSIZE;
3992
3993         item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
3994         if (!item)
3995                 return -ENOMEM;
3996
3997         item->nla_type = NLA_NUL_STRING;
3998         item->len = strlen(name) + 1;
3999         item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
4000         memcpy(&item->value, name, item->len);
4001         list_add_tail(&item->list, &fmsg->item_list);
4002
4003         return 0;
4004 }
4005
4006 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
4007 {
4008         int err;
4009
4010         err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
4011         if (err)
4012                 return err;
4013
4014         err = devlink_fmsg_put_name(fmsg, name);
4015         if (err)
4016                 return err;
4017
4018         return 0;
4019 }
4020 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
4021
4022 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
4023 {
4024         return devlink_fmsg_nest_end(fmsg);
4025 }
4026 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
4027
4028 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
4029                                      const char *name)
4030 {
4031         int err;
4032
4033         err = devlink_fmsg_pair_nest_start(fmsg, name);
4034         if (err)
4035                 return err;
4036
4037         err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
4038         if (err)
4039                 return err;
4040
4041         return 0;
4042 }
4043 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
4044
4045 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
4046 {
4047         int err;
4048
4049         err = devlink_fmsg_nest_end(fmsg);
4050         if (err)
4051                 return err;
4052
4053         err = devlink_fmsg_nest_end(fmsg);
4054         if (err)
4055                 return err;
4056
4057         return 0;
4058 }
4059 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
4060
4061 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
4062                                   const void *value, u16 value_len,
4063                                   u8 value_nla_type)
4064 {
4065         struct devlink_fmsg_item *item;
4066
4067         if (value_len > DEVLINK_FMSG_MAX_SIZE)
4068                 return -EMSGSIZE;
4069
4070         item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
4071         if (!item)
4072                 return -ENOMEM;
4073
4074         item->nla_type = value_nla_type;
4075         item->len = value_len;
4076         item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4077         memcpy(&item->value, value, item->len);
4078         list_add_tail(&item->list, &fmsg->item_list);
4079
4080         return 0;
4081 }
4082
4083 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
4084 {
4085         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
4086 }
4087 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
4088
4089 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
4090 {
4091         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
4092 }
4093 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
4094
4095 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
4096 {
4097         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
4098 }
4099 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
4100
4101 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
4102 {
4103         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
4104 }
4105 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
4106
4107 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
4108 {
4109         return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
4110                                       NLA_NUL_STRING);
4111 }
4112 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
4113
4114 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
4115                             u16 value_len)
4116 {
4117         return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
4118 }
4119 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
4120
4121 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
4122                                bool value)
4123 {
4124         int err;
4125
4126         err = devlink_fmsg_pair_nest_start(fmsg, name);
4127         if (err)
4128                 return err;
4129
4130         err = devlink_fmsg_bool_put(fmsg, value);
4131         if (err)
4132                 return err;
4133
4134         err = devlink_fmsg_pair_nest_end(fmsg);
4135         if (err)
4136                 return err;
4137
4138         return 0;
4139 }
4140 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
4141
4142 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
4143                              u8 value)
4144 {
4145         int err;
4146
4147         err = devlink_fmsg_pair_nest_start(fmsg, name);
4148         if (err)
4149                 return err;
4150
4151         err = devlink_fmsg_u8_put(fmsg, value);
4152         if (err)
4153                 return err;
4154
4155         err = devlink_fmsg_pair_nest_end(fmsg);
4156         if (err)
4157                 return err;
4158
4159         return 0;
4160 }
4161 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
4162
4163 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
4164                               u32 value)
4165 {
4166         int err;
4167
4168         err = devlink_fmsg_pair_nest_start(fmsg, name);
4169         if (err)
4170                 return err;
4171
4172         err = devlink_fmsg_u32_put(fmsg, value);
4173         if (err)
4174                 return err;
4175
4176         err = devlink_fmsg_pair_nest_end(fmsg);
4177         if (err)
4178                 return err;
4179
4180         return 0;
4181 }
4182 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
4183
4184 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
4185                               u64 value)
4186 {
4187         int err;
4188
4189         err = devlink_fmsg_pair_nest_start(fmsg, name);
4190         if (err)
4191                 return err;
4192
4193         err = devlink_fmsg_u64_put(fmsg, value);
4194         if (err)
4195                 return err;
4196
4197         err = devlink_fmsg_pair_nest_end(fmsg);
4198         if (err)
4199                 return err;
4200
4201         return 0;
4202 }
4203 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
4204
4205 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
4206                                  const char *value)
4207 {
4208         int err;
4209
4210         err = devlink_fmsg_pair_nest_start(fmsg, name);
4211         if (err)
4212                 return err;
4213
4214         err = devlink_fmsg_string_put(fmsg, value);
4215         if (err)
4216                 return err;
4217
4218         err = devlink_fmsg_pair_nest_end(fmsg);
4219         if (err)
4220                 return err;
4221
4222         return 0;
4223 }
4224 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
4225
4226 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
4227                                  const void *value, u16 value_len)
4228 {
4229         int err;
4230
4231         err = devlink_fmsg_pair_nest_start(fmsg, name);
4232         if (err)
4233                 return err;
4234
4235         err = devlink_fmsg_binary_put(fmsg, value, value_len);
4236         if (err)
4237                 return err;
4238
4239         err = devlink_fmsg_pair_nest_end(fmsg);
4240         if (err)
4241                 return err;
4242
4243         return 0;
4244 }
4245 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
4246
4247 static int
4248 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4249 {
4250         switch (msg->nla_type) {
4251         case NLA_FLAG:
4252         case NLA_U8:
4253         case NLA_U32:
4254         case NLA_U64:
4255         case NLA_NUL_STRING:
4256         case NLA_BINARY:
4257                 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
4258                                   msg->nla_type);
4259         default:
4260                 return -EINVAL;
4261         }
4262 }
4263
4264 static int
4265 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4266 {
4267         int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4268         u8 tmp;
4269
4270         switch (msg->nla_type) {
4271         case NLA_FLAG:
4272                 /* Always provide flag data, regardless of its value */
4273                 tmp = *(bool *) msg->value;
4274
4275                 return nla_put_u8(skb, attrtype, tmp);
4276         case NLA_U8:
4277                 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
4278         case NLA_U32:
4279                 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
4280         case NLA_U64:
4281                 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
4282                                          DEVLINK_ATTR_PAD);
4283         case NLA_NUL_STRING:
4284                 return nla_put_string(skb, attrtype, (char *) &msg->value);
4285         case NLA_BINARY:
4286                 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
4287         default:
4288                 return -EINVAL;
4289         }
4290 }
4291
4292 static int
4293 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
4294                          int *start)
4295 {
4296         struct devlink_fmsg_item *item;
4297         struct nlattr *fmsg_nlattr;
4298         int i = 0;
4299         int err;
4300
4301         fmsg_nlattr = nla_nest_start(skb, DEVLINK_ATTR_FMSG);
4302         if (!fmsg_nlattr)
4303                 return -EMSGSIZE;
4304
4305         list_for_each_entry(item, &fmsg->item_list, list) {
4306                 if (i < *start) {
4307                         i++;
4308                         continue;
4309                 }
4310
4311                 switch (item->attrtype) {
4312                 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
4313                 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
4314                 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
4315                 case DEVLINK_ATTR_FMSG_NEST_END:
4316                         err = nla_put_flag(skb, item->attrtype);
4317                         break;
4318                 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
4319                         err = devlink_fmsg_item_fill_type(item, skb);
4320                         if (err)
4321                                 break;
4322                         err = devlink_fmsg_item_fill_data(item, skb);
4323                         break;
4324                 case DEVLINK_ATTR_FMSG_OBJ_NAME:
4325                         err = nla_put_string(skb, item->attrtype,
4326                                              (char *) &item->value);
4327                         break;
4328                 default:
4329                         err = -EINVAL;
4330                         break;
4331                 }
4332                 if (!err)
4333                         *start = ++i;
4334                 else
4335                         break;
4336         }
4337
4338         nla_nest_end(skb, fmsg_nlattr);
4339         return err;
4340 }
4341
4342 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
4343                             struct genl_info *info,
4344                             enum devlink_command cmd, int flags)
4345 {
4346         struct nlmsghdr *nlh;
4347         struct sk_buff *skb;
4348         bool last = false;
4349         int index = 0;
4350         void *hdr;
4351         int err;
4352
4353         while (!last) {
4354                 int tmp_index = index;
4355
4356                 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4357                 if (!skb)
4358                         return -ENOMEM;
4359
4360                 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4361                                   &devlink_nl_family, flags | NLM_F_MULTI, cmd);
4362                 if (!hdr) {
4363                         err = -EMSGSIZE;
4364                         goto nla_put_failure;
4365                 }
4366
4367                 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
4368                 if (!err)
4369                         last = true;
4370                 else if (err != -EMSGSIZE || tmp_index == index)
4371                         goto nla_put_failure;
4372
4373                 genlmsg_end(skb, hdr);
4374                 err = genlmsg_reply(skb, info);
4375                 if (err)
4376                         return err;
4377         }
4378
4379         skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4380         if (!skb)
4381                 return -ENOMEM;
4382         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4383                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
4384         if (!nlh) {
4385                 err = -EMSGSIZE;
4386                 goto nla_put_failure;
4387         }
4388
4389         return genlmsg_reply(skb, info);
4390
4391 nla_put_failure:
4392         nlmsg_free(skb);
4393         return err;
4394 }
4395
4396 struct devlink_health_reporter {
4397         struct list_head list;
4398         void *priv;
4399         const struct devlink_health_reporter_ops *ops;
4400         struct devlink *devlink;
4401         struct devlink_fmsg *dump_fmsg;
4402         struct mutex dump_lock; /* lock parallel read/write from dump buffers */
4403         u64 graceful_period;
4404         bool auto_recover;
4405         u8 health_state;
4406         u64 dump_ts;
4407         u64 error_count;
4408         u64 recovery_count;
4409         u64 last_recovery_ts;
4410 };
4411
4412 void *
4413 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
4414 {
4415         return reporter->priv;
4416 }
4417 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
4418
4419 static struct devlink_health_reporter *
4420 devlink_health_reporter_find_by_name(struct devlink *devlink,
4421                                      const char *reporter_name)
4422 {
4423         struct devlink_health_reporter *reporter;
4424
4425         list_for_each_entry(reporter, &devlink->reporter_list, list)
4426                 if (!strcmp(reporter->ops->name, reporter_name))
4427                         return reporter;
4428         return NULL;
4429 }
4430
4431 /**
4432  *      devlink_health_reporter_create - create devlink health reporter
4433  *
4434  *      @devlink: devlink
4435  *      @ops: ops
4436  *      @graceful_period: to avoid recovery loops, in msecs
4437  *      @auto_recover: auto recover when error occurs
4438  *      @priv: priv
4439  */
4440 struct devlink_health_reporter *
4441 devlink_health_reporter_create(struct devlink *devlink,
4442                                const struct devlink_health_reporter_ops *ops,
4443                                u64 graceful_period, bool auto_recover,
4444                                void *priv)
4445 {
4446         struct devlink_health_reporter *reporter;
4447
4448         mutex_lock(&devlink->lock);
4449         if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
4450                 reporter = ERR_PTR(-EEXIST);
4451                 goto unlock;
4452         }
4453
4454         if (WARN_ON(auto_recover && !ops->recover) ||
4455             WARN_ON(graceful_period && !ops->recover)) {
4456                 reporter = ERR_PTR(-EINVAL);
4457                 goto unlock;
4458         }
4459
4460         reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
4461         if (!reporter) {
4462                 reporter = ERR_PTR(-ENOMEM);
4463                 goto unlock;
4464         }
4465
4466         reporter->priv = priv;
4467         reporter->ops = ops;
4468         reporter->devlink = devlink;
4469         reporter->graceful_period = graceful_period;
4470         reporter->auto_recover = auto_recover;
4471         mutex_init(&reporter->dump_lock);
4472         list_add_tail(&reporter->list, &devlink->reporter_list);
4473 unlock:
4474         mutex_unlock(&devlink->lock);
4475         return reporter;
4476 }
4477 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
4478
4479 /**
4480  *      devlink_health_reporter_destroy - destroy devlink health reporter
4481  *
4482  *      @reporter: devlink health reporter to destroy
4483  */
4484 void
4485 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
4486 {
4487         mutex_lock(&reporter->devlink->lock);
4488         list_del(&reporter->list);
4489         mutex_unlock(&reporter->devlink->lock);
4490         if (reporter->dump_fmsg)
4491                 devlink_fmsg_free(reporter->dump_fmsg);
4492         kfree(reporter);
4493 }
4494 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
4495
4496 void
4497 devlink_health_reporter_state_update(struct devlink_health_reporter *reporter,
4498                                      enum devlink_health_reporter_state state)
4499 {
4500         if (WARN_ON(state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY &&
4501                     state != DEVLINK_HEALTH_REPORTER_STATE_ERROR))
4502                 return;
4503
4504         if (reporter->health_state == state)
4505                 return;
4506
4507         reporter->health_state = state;
4508         trace_devlink_health_reporter_state_update(reporter->devlink,
4509                                                    reporter->ops->name, state);
4510 }
4511 EXPORT_SYMBOL_GPL(devlink_health_reporter_state_update);
4512
4513 static int
4514 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
4515                                 void *priv_ctx)
4516 {
4517         int err;
4518
4519         if (!reporter->ops->recover)
4520                 return -EOPNOTSUPP;
4521
4522         err = reporter->ops->recover(reporter, priv_ctx);
4523         if (err)
4524                 return err;
4525
4526         reporter->recovery_count++;
4527         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
4528         reporter->last_recovery_ts = jiffies;
4529
4530         return 0;
4531 }
4532
4533 static void
4534 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
4535 {
4536         if (!reporter->dump_fmsg)
4537                 return;
4538         devlink_fmsg_free(reporter->dump_fmsg);
4539         reporter->dump_fmsg = NULL;
4540 }
4541
4542 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
4543                                   void *priv_ctx)
4544 {
4545         int err;
4546
4547         if (!reporter->ops->dump)
4548                 return 0;
4549
4550         if (reporter->dump_fmsg)
4551                 return 0;
4552
4553         reporter->dump_fmsg = devlink_fmsg_alloc();
4554         if (!reporter->dump_fmsg) {
4555                 err = -ENOMEM;
4556                 return err;
4557         }
4558
4559         err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
4560         if (err)
4561                 goto dump_err;
4562
4563         err = reporter->ops->dump(reporter, reporter->dump_fmsg,
4564                                   priv_ctx);
4565         if (err)
4566                 goto dump_err;
4567
4568         err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
4569         if (err)
4570                 goto dump_err;
4571
4572         reporter->dump_ts = jiffies;
4573
4574         return 0;
4575
4576 dump_err:
4577         devlink_health_dump_clear(reporter);
4578         return err;
4579 }
4580
4581 int devlink_health_report(struct devlink_health_reporter *reporter,
4582                           const char *msg, void *priv_ctx)
4583 {
4584         enum devlink_health_reporter_state prev_health_state;
4585         struct devlink *devlink = reporter->devlink;
4586
4587         /* write a log message of the current error */
4588         WARN_ON(!msg);
4589         trace_devlink_health_report(devlink, reporter->ops->name, msg);
4590         reporter->error_count++;
4591         prev_health_state = reporter->health_state;
4592         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
4593
4594         /* abort if the previous error wasn't recovered */
4595         if (reporter->auto_recover &&
4596             (prev_health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
4597              jiffies - reporter->last_recovery_ts <
4598              msecs_to_jiffies(reporter->graceful_period))) {
4599                 trace_devlink_health_recover_aborted(devlink,
4600                                                      reporter->ops->name,
4601                                                      reporter->health_state,
4602                                                      jiffies -
4603                                                      reporter->last_recovery_ts);
4604                 return -ECANCELED;
4605         }
4606
4607         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
4608
4609         mutex_lock(&reporter->dump_lock);
4610         /* store current dump of current error, for later analysis */
4611         devlink_health_do_dump(reporter, priv_ctx);
4612         mutex_unlock(&reporter->dump_lock);
4613
4614         if (reporter->auto_recover)
4615                 return devlink_health_reporter_recover(reporter, priv_ctx);
4616
4617         return 0;
4618 }
4619 EXPORT_SYMBOL_GPL(devlink_health_report);
4620
4621 static struct devlink_health_reporter *
4622 devlink_health_reporter_get_from_info(struct devlink *devlink,
4623                                       struct genl_info *info)
4624 {
4625         char *reporter_name;
4626
4627         if (!info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
4628                 return NULL;
4629
4630         reporter_name =
4631                 nla_data(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
4632         return devlink_health_reporter_find_by_name(devlink, reporter_name);
4633 }
4634
4635 static int
4636 devlink_nl_health_reporter_fill(struct sk_buff *msg,
4637                                 struct devlink *devlink,
4638                                 struct devlink_health_reporter *reporter,
4639                                 enum devlink_command cmd, u32 portid,
4640                                 u32 seq, int flags)
4641 {
4642         struct nlattr *reporter_attr;
4643         void *hdr;
4644
4645         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4646         if (!hdr)
4647                 return -EMSGSIZE;
4648
4649         if (devlink_nl_put_handle(msg, devlink))
4650                 goto genlmsg_cancel;
4651
4652         reporter_attr = nla_nest_start(msg, DEVLINK_ATTR_HEALTH_REPORTER);
4653         if (!reporter_attr)
4654                 goto genlmsg_cancel;
4655         if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
4656                            reporter->ops->name))
4657                 goto reporter_nest_cancel;
4658         if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
4659                        reporter->health_state))
4660                 goto reporter_nest_cancel;
4661         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
4662                               reporter->error_count, DEVLINK_ATTR_PAD))
4663                 goto reporter_nest_cancel;
4664         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
4665                               reporter->recovery_count, DEVLINK_ATTR_PAD))
4666                 goto reporter_nest_cancel;
4667         if (reporter->ops->recover &&
4668             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
4669                               reporter->graceful_period,
4670                               DEVLINK_ATTR_PAD))
4671                 goto reporter_nest_cancel;
4672         if (reporter->ops->recover &&
4673             nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
4674                        reporter->auto_recover))
4675                 goto reporter_nest_cancel;
4676         if (reporter->dump_fmsg &&
4677             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
4678                               jiffies_to_msecs(reporter->dump_ts),
4679                               DEVLINK_ATTR_PAD))
4680                 goto reporter_nest_cancel;
4681
4682         nla_nest_end(msg, reporter_attr);
4683         genlmsg_end(msg, hdr);
4684         return 0;
4685
4686 reporter_nest_cancel:
4687         nla_nest_end(msg, reporter_attr);
4688 genlmsg_cancel:
4689         genlmsg_cancel(msg, hdr);
4690         return -EMSGSIZE;
4691 }
4692
4693 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
4694                                                    struct genl_info *info)
4695 {
4696         struct devlink *devlink = info->user_ptr[0];
4697         struct devlink_health_reporter *reporter;
4698         struct sk_buff *msg;
4699         int err;
4700
4701         reporter = devlink_health_reporter_get_from_info(devlink, info);
4702         if (!reporter)
4703                 return -EINVAL;
4704
4705         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4706         if (!msg)
4707                 return -ENOMEM;
4708
4709         err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
4710                                               DEVLINK_CMD_HEALTH_REPORTER_GET,
4711                                               info->snd_portid, info->snd_seq,
4712                                               0);
4713         if (err) {
4714                 nlmsg_free(msg);
4715                 return err;
4716         }
4717
4718         return genlmsg_reply(msg, info);
4719 }
4720
4721 static int
4722 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
4723                                           struct netlink_callback *cb)
4724 {
4725         struct devlink_health_reporter *reporter;
4726         struct devlink *devlink;
4727         int start = cb->args[0];
4728         int idx = 0;
4729         int err;
4730
4731         mutex_lock(&devlink_mutex);
4732         list_for_each_entry(devlink, &devlink_list, list) {
4733                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4734                         continue;
4735                 mutex_lock(&devlink->lock);
4736                 list_for_each_entry(reporter, &devlink->reporter_list,
4737                                     list) {
4738                         if (idx < start) {
4739                                 idx++;
4740                                 continue;
4741                         }
4742                         err = devlink_nl_health_reporter_fill(msg, devlink,
4743                                                               reporter,
4744                                                               DEVLINK_CMD_HEALTH_REPORTER_GET,
4745                                                               NETLINK_CB(cb->skb).portid,
4746                                                               cb->nlh->nlmsg_seq,
4747                                                               NLM_F_MULTI);
4748                         if (err) {
4749                                 mutex_unlock(&devlink->lock);
4750                                 goto out;
4751                         }
4752                         idx++;
4753                 }
4754                 mutex_unlock(&devlink->lock);
4755         }
4756 out:
4757         mutex_unlock(&devlink_mutex);
4758
4759         cb->args[0] = idx;
4760         return msg->len;
4761 }
4762
4763 static int
4764 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
4765                                         struct genl_info *info)
4766 {
4767         struct devlink *devlink = info->user_ptr[0];
4768         struct devlink_health_reporter *reporter;
4769
4770         reporter = devlink_health_reporter_get_from_info(devlink, info);
4771         if (!reporter)
4772                 return -EINVAL;
4773
4774         if (!reporter->ops->recover &&
4775             (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
4776              info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]))
4777                 return -EOPNOTSUPP;
4778
4779         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
4780                 reporter->graceful_period =
4781                         nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
4782
4783         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
4784                 reporter->auto_recover =
4785                         nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
4786
4787         return 0;
4788 }
4789
4790 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
4791                                                        struct genl_info *info)
4792 {
4793         struct devlink *devlink = info->user_ptr[0];
4794         struct devlink_health_reporter *reporter;
4795
4796         reporter = devlink_health_reporter_get_from_info(devlink, info);
4797         if (!reporter)
4798                 return -EINVAL;
4799
4800         return devlink_health_reporter_recover(reporter, NULL);
4801 }
4802
4803 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
4804                                                         struct genl_info *info)
4805 {
4806         struct devlink *devlink = info->user_ptr[0];
4807         struct devlink_health_reporter *reporter;
4808         struct devlink_fmsg *fmsg;
4809         int err;
4810
4811         reporter = devlink_health_reporter_get_from_info(devlink, info);
4812         if (!reporter)
4813                 return -EINVAL;
4814
4815         if (!reporter->ops->diagnose)
4816                 return -EOPNOTSUPP;
4817
4818         fmsg = devlink_fmsg_alloc();
4819         if (!fmsg)
4820                 return -ENOMEM;
4821
4822         err = devlink_fmsg_obj_nest_start(fmsg);
4823         if (err)
4824                 goto out;
4825
4826         err = reporter->ops->diagnose(reporter, fmsg);
4827         if (err)
4828                 goto out;
4829
4830         err = devlink_fmsg_obj_nest_end(fmsg);
4831         if (err)
4832                 goto out;
4833
4834         err = devlink_fmsg_snd(fmsg, info,
4835                                DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
4836
4837 out:
4838         devlink_fmsg_free(fmsg);
4839         return err;
4840 }
4841
4842 static int devlink_nl_cmd_health_reporter_dump_get_doit(struct sk_buff *skb,
4843                                                         struct genl_info *info)
4844 {
4845         struct devlink *devlink = info->user_ptr[0];
4846         struct devlink_health_reporter *reporter;
4847         int err;
4848
4849         reporter = devlink_health_reporter_get_from_info(devlink, info);
4850         if (!reporter)
4851                 return -EINVAL;
4852
4853         if (!reporter->ops->dump)
4854                 return -EOPNOTSUPP;
4855
4856         mutex_lock(&reporter->dump_lock);
4857         err = devlink_health_do_dump(reporter, NULL);
4858         if (err)
4859                 goto out;
4860
4861         err = devlink_fmsg_snd(reporter->dump_fmsg, info,
4862                                DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, 0);
4863
4864 out:
4865         mutex_unlock(&reporter->dump_lock);
4866         return err;
4867 }
4868
4869 static int
4870 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
4871                                                struct genl_info *info)
4872 {
4873         struct devlink *devlink = info->user_ptr[0];
4874         struct devlink_health_reporter *reporter;
4875
4876         reporter = devlink_health_reporter_get_from_info(devlink, info);
4877         if (!reporter)
4878                 return -EINVAL;
4879
4880         if (!reporter->ops->dump)
4881                 return -EOPNOTSUPP;
4882
4883         mutex_lock(&reporter->dump_lock);
4884         devlink_health_dump_clear(reporter);
4885         mutex_unlock(&reporter->dump_lock);
4886         return 0;
4887 }
4888
4889 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
4890         [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
4891         [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
4892         [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
4893         [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
4894         [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
4895         [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
4896         [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
4897         [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
4898         [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
4899         [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
4900         [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
4901         [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
4902         [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
4903         [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
4904         [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
4905         [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
4906         [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
4907         [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
4908         [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
4909         [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
4910         [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
4911         [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
4912         [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
4913         [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
4914         [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
4915         [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
4916         [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
4917         [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
4918         [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
4919 };
4920
4921 static const struct genl_ops devlink_nl_ops[] = {
4922         {
4923                 .cmd = DEVLINK_CMD_GET,
4924                 .doit = devlink_nl_cmd_get_doit,
4925                 .dumpit = devlink_nl_cmd_get_dumpit,
4926                 .policy = devlink_nl_policy,
4927                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
4928                 /* can be retrieved by unprivileged users */
4929         },
4930         {
4931                 .cmd = DEVLINK_CMD_PORT_GET,
4932                 .doit = devlink_nl_cmd_port_get_doit,
4933                 .dumpit = devlink_nl_cmd_port_get_dumpit,
4934                 .policy = devlink_nl_policy,
4935                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
4936                 /* can be retrieved by unprivileged users */
4937         },
4938         {
4939                 .cmd = DEVLINK_CMD_PORT_SET,
4940                 .doit = devlink_nl_cmd_port_set_doit,
4941                 .policy = devlink_nl_policy,
4942                 .flags = GENL_ADMIN_PERM,
4943                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
4944         },
4945         {
4946                 .cmd = DEVLINK_CMD_PORT_SPLIT,
4947                 .doit = devlink_nl_cmd_port_split_doit,
4948                 .policy = devlink_nl_policy,
4949                 .flags = GENL_ADMIN_PERM,
4950                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
4951                                   DEVLINK_NL_FLAG_NO_LOCK,
4952         },
4953         {
4954                 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
4955                 .doit = devlink_nl_cmd_port_unsplit_doit,
4956                 .policy = devlink_nl_policy,
4957                 .flags = GENL_ADMIN_PERM,
4958                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
4959                                   DEVLINK_NL_FLAG_NO_LOCK,
4960         },
4961         {
4962                 .cmd = DEVLINK_CMD_SB_GET,
4963                 .doit = devlink_nl_cmd_sb_get_doit,
4964                 .dumpit = devlink_nl_cmd_sb_get_dumpit,
4965                 .policy = devlink_nl_policy,
4966                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
4967                                   DEVLINK_NL_FLAG_NEED_SB,
4968                 /* can be retrieved by unprivileged users */
4969         },
4970         {
4971                 .cmd = DEVLINK_CMD_SB_POOL_GET,
4972                 .doit = devlink_nl_cmd_sb_pool_get_doit,
4973                 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
4974                 .policy = devlink_nl_policy,
4975                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
4976                                   DEVLINK_NL_FLAG_NEED_SB,
4977                 /* can be retrieved by unprivileged users */
4978         },
4979         {
4980                 .cmd = DEVLINK_CMD_SB_POOL_SET,
4981                 .doit = devlink_nl_cmd_sb_pool_set_doit,
4982                 .policy = devlink_nl_policy,
4983                 .flags = GENL_ADMIN_PERM,
4984                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
4985                                   DEVLINK_NL_FLAG_NEED_SB,
4986         },
4987         {
4988                 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
4989                 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
4990                 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
4991                 .policy = devlink_nl_policy,
4992                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
4993                                   DEVLINK_NL_FLAG_NEED_SB,
4994                 /* can be retrieved by unprivileged users */
4995         },
4996         {
4997                 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
4998                 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
4999                 .policy = devlink_nl_policy,
5000                 .flags = GENL_ADMIN_PERM,
5001                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5002                                   DEVLINK_NL_FLAG_NEED_SB,
5003         },
5004         {
5005                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
5006                 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
5007                 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
5008                 .policy = devlink_nl_policy,
5009                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5010                                   DEVLINK_NL_FLAG_NEED_SB,
5011                 /* can be retrieved by unprivileged users */
5012         },
5013         {
5014                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
5015                 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
5016                 .policy = devlink_nl_policy,
5017                 .flags = GENL_ADMIN_PERM,
5018                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5019                                   DEVLINK_NL_FLAG_NEED_SB,
5020         },
5021         {
5022                 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
5023                 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
5024                 .policy = devlink_nl_policy,
5025                 .flags = GENL_ADMIN_PERM,
5026                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5027                                   DEVLINK_NL_FLAG_NEED_SB,
5028         },
5029         {
5030                 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
5031                 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
5032                 .policy = devlink_nl_policy,
5033                 .flags = GENL_ADMIN_PERM,
5034                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5035                                   DEVLINK_NL_FLAG_NEED_SB,
5036         },
5037         {
5038                 .cmd = DEVLINK_CMD_ESWITCH_GET,
5039                 .doit = devlink_nl_cmd_eswitch_get_doit,
5040                 .policy = devlink_nl_policy,
5041                 .flags = GENL_ADMIN_PERM,
5042                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5043         },
5044         {
5045                 .cmd = DEVLINK_CMD_ESWITCH_SET,
5046                 .doit = devlink_nl_cmd_eswitch_set_doit,
5047                 .policy = devlink_nl_policy,
5048                 .flags = GENL_ADMIN_PERM,
5049                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5050                                   DEVLINK_NL_FLAG_NO_LOCK,
5051         },
5052         {
5053                 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
5054                 .doit = devlink_nl_cmd_dpipe_table_get,
5055                 .policy = devlink_nl_policy,
5056                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5057                 /* can be retrieved by unprivileged users */
5058         },
5059         {
5060                 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
5061                 .doit = devlink_nl_cmd_dpipe_entries_get,
5062                 .policy = devlink_nl_policy,
5063                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5064                 /* can be retrieved by unprivileged users */
5065         },
5066         {
5067                 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
5068                 .doit = devlink_nl_cmd_dpipe_headers_get,
5069                 .policy = devlink_nl_policy,
5070                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5071                 /* can be retrieved by unprivileged users */
5072         },
5073         {
5074                 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
5075                 .doit = devlink_nl_cmd_dpipe_table_counters_set,
5076                 .policy = devlink_nl_policy,
5077                 .flags = GENL_ADMIN_PERM,
5078                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5079         },
5080         {
5081                 .cmd = DEVLINK_CMD_RESOURCE_SET,
5082                 .doit = devlink_nl_cmd_resource_set,
5083                 .policy = devlink_nl_policy,
5084                 .flags = GENL_ADMIN_PERM,
5085                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5086         },
5087         {
5088                 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
5089                 .doit = devlink_nl_cmd_resource_dump,
5090                 .policy = devlink_nl_policy,
5091                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5092                 /* can be retrieved by unprivileged users */
5093         },
5094         {
5095                 .cmd = DEVLINK_CMD_RELOAD,
5096                 .doit = devlink_nl_cmd_reload,
5097                 .policy = devlink_nl_policy,
5098                 .flags = GENL_ADMIN_PERM,
5099                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5100                                   DEVLINK_NL_FLAG_NO_LOCK,
5101         },
5102         {
5103                 .cmd = DEVLINK_CMD_PARAM_GET,
5104                 .doit = devlink_nl_cmd_param_get_doit,
5105                 .dumpit = devlink_nl_cmd_param_get_dumpit,
5106                 .policy = devlink_nl_policy,
5107                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5108                 /* can be retrieved by unprivileged users */
5109         },
5110         {
5111                 .cmd = DEVLINK_CMD_PARAM_SET,
5112                 .doit = devlink_nl_cmd_param_set_doit,
5113                 .policy = devlink_nl_policy,
5114                 .flags = GENL_ADMIN_PERM,
5115                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5116         },
5117         {
5118                 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
5119                 .doit = devlink_nl_cmd_port_param_get_doit,
5120                 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
5121                 .policy = devlink_nl_policy,
5122                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5123                 /* can be retrieved by unprivileged users */
5124         },
5125         {
5126                 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
5127                 .doit = devlink_nl_cmd_port_param_set_doit,
5128                 .policy = devlink_nl_policy,
5129                 .flags = GENL_ADMIN_PERM,
5130                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5131         },
5132         {
5133                 .cmd = DEVLINK_CMD_REGION_GET,
5134                 .doit = devlink_nl_cmd_region_get_doit,
5135                 .dumpit = devlink_nl_cmd_region_get_dumpit,
5136                 .policy = devlink_nl_policy,
5137                 .flags = GENL_ADMIN_PERM,
5138                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5139         },
5140         {
5141                 .cmd = DEVLINK_CMD_REGION_DEL,
5142                 .doit = devlink_nl_cmd_region_del,
5143                 .policy = devlink_nl_policy,
5144                 .flags = GENL_ADMIN_PERM,
5145                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5146         },
5147         {
5148                 .cmd = DEVLINK_CMD_REGION_READ,
5149                 .dumpit = devlink_nl_cmd_region_read_dumpit,
5150                 .policy = devlink_nl_policy,
5151                 .flags = GENL_ADMIN_PERM,
5152                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5153         },
5154         {
5155                 .cmd = DEVLINK_CMD_INFO_GET,
5156                 .doit = devlink_nl_cmd_info_get_doit,
5157                 .dumpit = devlink_nl_cmd_info_get_dumpit,
5158                 .policy = devlink_nl_policy,
5159                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5160                 /* can be retrieved by unprivileged users */
5161         },
5162         {
5163                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
5164                 .doit = devlink_nl_cmd_health_reporter_get_doit,
5165                 .dumpit = devlink_nl_cmd_health_reporter_get_dumpit,
5166                 .policy = devlink_nl_policy,
5167                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5168                 /* can be retrieved by unprivileged users */
5169         },
5170         {
5171                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_SET,
5172                 .doit = devlink_nl_cmd_health_reporter_set_doit,
5173                 .policy = devlink_nl_policy,
5174                 .flags = GENL_ADMIN_PERM,
5175                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5176         },
5177         {
5178                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
5179                 .doit = devlink_nl_cmd_health_reporter_recover_doit,
5180                 .policy = devlink_nl_policy,
5181                 .flags = GENL_ADMIN_PERM,
5182                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5183         },
5184         {
5185                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
5186                 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
5187                 .policy = devlink_nl_policy,
5188                 .flags = GENL_ADMIN_PERM,
5189                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5190         },
5191         {
5192                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
5193                 .doit = devlink_nl_cmd_health_reporter_dump_get_doit,
5194                 .policy = devlink_nl_policy,
5195                 .flags = GENL_ADMIN_PERM,
5196                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5197                                   DEVLINK_NL_FLAG_NO_LOCK,
5198         },
5199         {
5200                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
5201                 .doit = devlink_nl_cmd_health_reporter_dump_clear_doit,
5202                 .policy = devlink_nl_policy,
5203                 .flags = GENL_ADMIN_PERM,
5204                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5205                                   DEVLINK_NL_FLAG_NO_LOCK,
5206         },
5207         {
5208                 .cmd = DEVLINK_CMD_FLASH_UPDATE,
5209                 .doit = devlink_nl_cmd_flash_update,
5210                 .policy = devlink_nl_policy,
5211                 .flags = GENL_ADMIN_PERM,
5212                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5213         },
5214 };
5215
5216 static struct genl_family devlink_nl_family __ro_after_init = {
5217         .name           = DEVLINK_GENL_NAME,
5218         .version        = DEVLINK_GENL_VERSION,
5219         .maxattr        = DEVLINK_ATTR_MAX,
5220         .netnsok        = true,
5221         .pre_doit       = devlink_nl_pre_doit,
5222         .post_doit      = devlink_nl_post_doit,
5223         .module         = THIS_MODULE,
5224         .ops            = devlink_nl_ops,
5225         .n_ops          = ARRAY_SIZE(devlink_nl_ops),
5226         .mcgrps         = devlink_nl_mcgrps,
5227         .n_mcgrps       = ARRAY_SIZE(devlink_nl_mcgrps),
5228 };
5229
5230 /**
5231  *      devlink_alloc - Allocate new devlink instance resources
5232  *
5233  *      @ops: ops
5234  *      @priv_size: size of user private data
5235  *
5236  *      Allocate new devlink instance resources, including devlink index
5237  *      and name.
5238  */
5239 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
5240 {
5241         struct devlink *devlink;
5242
5243         if (WARN_ON(!ops))
5244                 return NULL;
5245
5246         devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
5247         if (!devlink)
5248                 return NULL;
5249         devlink->ops = ops;
5250         devlink_net_set(devlink, &init_net);
5251         INIT_LIST_HEAD(&devlink->port_list);
5252         INIT_LIST_HEAD(&devlink->sb_list);
5253         INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
5254         INIT_LIST_HEAD(&devlink->resource_list);
5255         INIT_LIST_HEAD(&devlink->param_list);
5256         INIT_LIST_HEAD(&devlink->region_list);
5257         INIT_LIST_HEAD(&devlink->reporter_list);
5258         mutex_init(&devlink->lock);
5259         return devlink;
5260 }
5261 EXPORT_SYMBOL_GPL(devlink_alloc);
5262
5263 /**
5264  *      devlink_register - Register devlink instance
5265  *
5266  *      @devlink: devlink
5267  *      @dev: parent device
5268  */
5269 int devlink_register(struct devlink *devlink, struct device *dev)
5270 {
5271         mutex_lock(&devlink_mutex);
5272         devlink->dev = dev;
5273         list_add_tail(&devlink->list, &devlink_list);
5274         devlink_notify(devlink, DEVLINK_CMD_NEW);
5275         mutex_unlock(&devlink_mutex);
5276         return 0;
5277 }
5278 EXPORT_SYMBOL_GPL(devlink_register);
5279
5280 /**
5281  *      devlink_unregister - Unregister devlink instance
5282  *
5283  *      @devlink: devlink
5284  */
5285 void devlink_unregister(struct devlink *devlink)
5286 {
5287         mutex_lock(&devlink_mutex);
5288         devlink_notify(devlink, DEVLINK_CMD_DEL);
5289         list_del(&devlink->list);
5290         mutex_unlock(&devlink_mutex);
5291 }
5292 EXPORT_SYMBOL_GPL(devlink_unregister);
5293
5294 /**
5295  *      devlink_free - Free devlink instance resources
5296  *
5297  *      @devlink: devlink
5298  */
5299 void devlink_free(struct devlink *devlink)
5300 {
5301         WARN_ON(!list_empty(&devlink->reporter_list));
5302         WARN_ON(!list_empty(&devlink->region_list));
5303         WARN_ON(!list_empty(&devlink->param_list));
5304         WARN_ON(!list_empty(&devlink->resource_list));
5305         WARN_ON(!list_empty(&devlink->dpipe_table_list));
5306         WARN_ON(!list_empty(&devlink->sb_list));
5307         WARN_ON(!list_empty(&devlink->port_list));
5308
5309         kfree(devlink);
5310 }
5311 EXPORT_SYMBOL_GPL(devlink_free);
5312
5313 /**
5314  *      devlink_port_register - Register devlink port
5315  *
5316  *      @devlink: devlink
5317  *      @devlink_port: devlink port
5318  *      @port_index: driver-specific numerical identifier of the port
5319  *
5320  *      Register devlink port with provided port index. User can use
5321  *      any indexing, even hw-related one. devlink_port structure
5322  *      is convenient to be embedded inside user driver private structure.
5323  *      Note that the caller should take care of zeroing the devlink_port
5324  *      structure.
5325  */
5326 int devlink_port_register(struct devlink *devlink,
5327                           struct devlink_port *devlink_port,
5328                           unsigned int port_index)
5329 {
5330         mutex_lock(&devlink->lock);
5331         if (devlink_port_index_exists(devlink, port_index)) {
5332                 mutex_unlock(&devlink->lock);
5333                 return -EEXIST;
5334         }
5335         devlink_port->devlink = devlink;
5336         devlink_port->index = port_index;
5337         devlink_port->registered = true;
5338         list_add_tail(&devlink_port->list, &devlink->port_list);
5339         INIT_LIST_HEAD(&devlink_port->param_list);
5340         mutex_unlock(&devlink->lock);
5341         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
5342         return 0;
5343 }
5344 EXPORT_SYMBOL_GPL(devlink_port_register);
5345
5346 /**
5347  *      devlink_port_unregister - Unregister devlink port
5348  *
5349  *      @devlink_port: devlink port
5350  */
5351 void devlink_port_unregister(struct devlink_port *devlink_port)
5352 {
5353         struct devlink *devlink = devlink_port->devlink;
5354
5355         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
5356         mutex_lock(&devlink->lock);
5357         list_del(&devlink_port->list);
5358         mutex_unlock(&devlink->lock);
5359 }
5360 EXPORT_SYMBOL_GPL(devlink_port_unregister);
5361
5362 static void __devlink_port_type_set(struct devlink_port *devlink_port,
5363                                     enum devlink_port_type type,
5364                                     void *type_dev)
5365 {
5366         devlink_port->type = type;
5367         devlink_port->type_dev = type_dev;
5368         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
5369 }
5370
5371 /**
5372  *      devlink_port_type_eth_set - Set port type to Ethernet
5373  *
5374  *      @devlink_port: devlink port
5375  *      @netdev: related netdevice
5376  */
5377 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
5378                                struct net_device *netdev)
5379 {
5380         return __devlink_port_type_set(devlink_port,
5381                                        DEVLINK_PORT_TYPE_ETH, netdev);
5382 }
5383 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
5384
5385 /**
5386  *      devlink_port_type_ib_set - Set port type to InfiniBand
5387  *
5388  *      @devlink_port: devlink port
5389  *      @ibdev: related IB device
5390  */
5391 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
5392                               struct ib_device *ibdev)
5393 {
5394         return __devlink_port_type_set(devlink_port,
5395                                        DEVLINK_PORT_TYPE_IB, ibdev);
5396 }
5397 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
5398
5399 /**
5400  *      devlink_port_type_clear - Clear port type
5401  *
5402  *      @devlink_port: devlink port
5403  */
5404 void devlink_port_type_clear(struct devlink_port *devlink_port)
5405 {
5406         return __devlink_port_type_set(devlink_port,
5407                                        DEVLINK_PORT_TYPE_NOTSET, NULL);
5408 }
5409 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
5410
5411 /**
5412  *      devlink_port_attrs_set - Set port attributes
5413  *
5414  *      @devlink_port: devlink port
5415  *      @flavour: flavour of the port
5416  *      @port_number: number of the port that is facing user, for example
5417  *                    the front panel port number
5418  *      @split: indicates if this is split port
5419  *      @split_subport_number: if the port is split, this is the number
5420  *                             of subport.
5421  */
5422 void devlink_port_attrs_set(struct devlink_port *devlink_port,
5423                             enum devlink_port_flavour flavour,
5424                             u32 port_number, bool split,
5425                             u32 split_subport_number)
5426 {
5427         struct devlink_port_attrs *attrs = &devlink_port->attrs;
5428
5429         attrs->set = true;
5430         attrs->flavour = flavour;
5431         attrs->port_number = port_number;
5432         attrs->split = split;
5433         attrs->split_subport_number = split_subport_number;
5434         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
5435 }
5436 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
5437
5438 int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
5439                                     char *name, size_t len)
5440 {
5441         struct devlink_port_attrs *attrs = &devlink_port->attrs;
5442         int n = 0;
5443
5444         if (!attrs->set)
5445                 return -EOPNOTSUPP;
5446
5447         switch (attrs->flavour) {
5448         case DEVLINK_PORT_FLAVOUR_PHYSICAL:
5449                 if (!attrs->split)
5450                         n = snprintf(name, len, "p%u", attrs->port_number);
5451                 else
5452                         n = snprintf(name, len, "p%us%u", attrs->port_number,
5453                                      attrs->split_subport_number);
5454                 break;
5455         case DEVLINK_PORT_FLAVOUR_CPU:
5456         case DEVLINK_PORT_FLAVOUR_DSA:
5457                 /* As CPU and DSA ports do not have a netdevice associated
5458                  * case should not ever happen.
5459                  */
5460                 WARN_ON(1);
5461                 return -EINVAL;
5462         }
5463
5464         if (n >= len)
5465                 return -EINVAL;
5466
5467         return 0;
5468 }
5469 EXPORT_SYMBOL_GPL(devlink_port_get_phys_port_name);
5470
5471 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
5472                         u32 size, u16 ingress_pools_count,
5473                         u16 egress_pools_count, u16 ingress_tc_count,
5474                         u16 egress_tc_count)
5475 {
5476         struct devlink_sb *devlink_sb;
5477         int err = 0;
5478
5479         mutex_lock(&devlink->lock);
5480         if (devlink_sb_index_exists(devlink, sb_index)) {
5481                 err = -EEXIST;
5482                 goto unlock;
5483         }
5484
5485         devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
5486         if (!devlink_sb) {
5487                 err = -ENOMEM;
5488                 goto unlock;
5489         }
5490         devlink_sb->index = sb_index;
5491         devlink_sb->size = size;
5492         devlink_sb->ingress_pools_count = ingress_pools_count;
5493         devlink_sb->egress_pools_count = egress_pools_count;
5494         devlink_sb->ingress_tc_count = ingress_tc_count;
5495         devlink_sb->egress_tc_count = egress_tc_count;
5496         list_add_tail(&devlink_sb->list, &devlink->sb_list);
5497 unlock:
5498         mutex_unlock(&devlink->lock);
5499         return err;
5500 }
5501 EXPORT_SYMBOL_GPL(devlink_sb_register);
5502
5503 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
5504 {
5505         struct devlink_sb *devlink_sb;
5506
5507         mutex_lock(&devlink->lock);
5508         devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
5509         WARN_ON(!devlink_sb);
5510         list_del(&devlink_sb->list);
5511         mutex_unlock(&devlink->lock);
5512         kfree(devlink_sb);
5513 }
5514 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
5515
5516 /**
5517  *      devlink_dpipe_headers_register - register dpipe headers
5518  *
5519  *      @devlink: devlink
5520  *      @dpipe_headers: dpipe header array
5521  *
5522  *      Register the headers supported by hardware.
5523  */
5524 int devlink_dpipe_headers_register(struct devlink *devlink,
5525                                    struct devlink_dpipe_headers *dpipe_headers)
5526 {
5527         mutex_lock(&devlink->lock);
5528         devlink->dpipe_headers = dpipe_headers;
5529         mutex_unlock(&devlink->lock);
5530         return 0;
5531 }
5532 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
5533
5534 /**
5535  *      devlink_dpipe_headers_unregister - unregister dpipe headers
5536  *
5537  *      @devlink: devlink
5538  *
5539  *      Unregister the headers supported by hardware.
5540  */
5541 void devlink_dpipe_headers_unregister(struct devlink *devlink)
5542 {
5543         mutex_lock(&devlink->lock);
5544         devlink->dpipe_headers = NULL;
5545         mutex_unlock(&devlink->lock);
5546 }
5547 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
5548
5549 /**
5550  *      devlink_dpipe_table_counter_enabled - check if counter allocation
5551  *                                            required
5552  *      @devlink: devlink
5553  *      @table_name: tables name
5554  *
5555  *      Used by driver to check if counter allocation is required.
5556  *      After counter allocation is turned on the table entries
5557  *      are updated to include counter statistics.
5558  *
5559  *      After that point on the driver must respect the counter
5560  *      state so that each entry added to the table is added
5561  *      with a counter.
5562  */
5563 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
5564                                          const char *table_name)
5565 {
5566         struct devlink_dpipe_table *table;
5567         bool enabled;
5568
5569         rcu_read_lock();
5570         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
5571                                          table_name);
5572         enabled = false;
5573         if (table)
5574                 enabled = table->counters_enabled;
5575         rcu_read_unlock();
5576         return enabled;
5577 }
5578 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
5579
5580 /**
5581  *      devlink_dpipe_table_register - register dpipe table
5582  *
5583  *      @devlink: devlink
5584  *      @table_name: table name
5585  *      @table_ops: table ops
5586  *      @priv: priv
5587  *      @counter_control_extern: external control for counters
5588  */
5589 int devlink_dpipe_table_register(struct devlink *devlink,
5590                                  const char *table_name,
5591                                  struct devlink_dpipe_table_ops *table_ops,
5592                                  void *priv, bool counter_control_extern)
5593 {
5594         struct devlink_dpipe_table *table;
5595
5596         if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
5597                 return -EEXIST;
5598
5599         if (WARN_ON(!table_ops->size_get))
5600                 return -EINVAL;
5601
5602         table = kzalloc(sizeof(*table), GFP_KERNEL);
5603         if (!table)
5604                 return -ENOMEM;
5605
5606         table->name = table_name;
5607         table->table_ops = table_ops;
5608         table->priv = priv;
5609         table->counter_control_extern = counter_control_extern;
5610
5611         mutex_lock(&devlink->lock);
5612         list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
5613         mutex_unlock(&devlink->lock);
5614         return 0;
5615 }
5616 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
5617
5618 /**
5619  *      devlink_dpipe_table_unregister - unregister dpipe table
5620  *
5621  *      @devlink: devlink
5622  *      @table_name: table name
5623  */
5624 void devlink_dpipe_table_unregister(struct devlink *devlink,
5625                                     const char *table_name)
5626 {
5627         struct devlink_dpipe_table *table;
5628
5629         mutex_lock(&devlink->lock);
5630         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
5631                                          table_name);
5632         if (!table)
5633                 goto unlock;
5634         list_del_rcu(&table->list);
5635         mutex_unlock(&devlink->lock);
5636         kfree_rcu(table, rcu);
5637         return;
5638 unlock:
5639         mutex_unlock(&devlink->lock);
5640 }
5641 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
5642
5643 /**
5644  *      devlink_resource_register - devlink resource register
5645  *
5646  *      @devlink: devlink
5647  *      @resource_name: resource's name
5648  *      @resource_size: resource's size
5649  *      @resource_id: resource's id
5650  *      @parent_resource_id: resource's parent id
5651  *      @size_params: size parameters
5652  */
5653 int devlink_resource_register(struct devlink *devlink,
5654                               const char *resource_name,
5655                               u64 resource_size,
5656                               u64 resource_id,
5657                               u64 parent_resource_id,
5658                               const struct devlink_resource_size_params *size_params)
5659 {
5660         struct devlink_resource *resource;
5661         struct list_head *resource_list;
5662         bool top_hierarchy;
5663         int err = 0;
5664
5665         top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
5666
5667         mutex_lock(&devlink->lock);
5668         resource = devlink_resource_find(devlink, NULL, resource_id);
5669         if (resource) {
5670                 err = -EINVAL;
5671                 goto out;
5672         }
5673
5674         resource = kzalloc(sizeof(*resource), GFP_KERNEL);
5675         if (!resource) {
5676                 err = -ENOMEM;
5677                 goto out;
5678         }
5679
5680         if (top_hierarchy) {
5681                 resource_list = &devlink->resource_list;
5682         } else {
5683                 struct devlink_resource *parent_resource;
5684
5685                 parent_resource = devlink_resource_find(devlink, NULL,
5686                                                         parent_resource_id);
5687                 if (parent_resource) {
5688                         resource_list = &parent_resource->resource_list;
5689                         resource->parent = parent_resource;
5690                 } else {
5691                         kfree(resource);
5692                         err = -EINVAL;
5693                         goto out;
5694                 }
5695         }
5696
5697         resource->name = resource_name;
5698         resource->size = resource_size;
5699         resource->size_new = resource_size;
5700         resource->id = resource_id;
5701         resource->size_valid = true;
5702         memcpy(&resource->size_params, size_params,
5703                sizeof(resource->size_params));
5704         INIT_LIST_HEAD(&resource->resource_list);
5705         list_add_tail(&resource->list, resource_list);
5706 out:
5707         mutex_unlock(&devlink->lock);
5708         return err;
5709 }
5710 EXPORT_SYMBOL_GPL(devlink_resource_register);
5711
5712 /**
5713  *      devlink_resources_unregister - free all resources
5714  *
5715  *      @devlink: devlink
5716  *      @resource: resource
5717  */
5718 void devlink_resources_unregister(struct devlink *devlink,
5719                                   struct devlink_resource *resource)
5720 {
5721         struct devlink_resource *tmp, *child_resource;
5722         struct list_head *resource_list;
5723
5724         if (resource)
5725                 resource_list = &resource->resource_list;
5726         else
5727                 resource_list = &devlink->resource_list;
5728
5729         if (!resource)
5730                 mutex_lock(&devlink->lock);
5731
5732         list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
5733                 devlink_resources_unregister(devlink, child_resource);
5734                 list_del(&child_resource->list);
5735                 kfree(child_resource);
5736         }
5737
5738         if (!resource)
5739                 mutex_unlock(&devlink->lock);
5740 }
5741 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
5742
5743 /**
5744  *      devlink_resource_size_get - get and update size
5745  *
5746  *      @devlink: devlink
5747  *      @resource_id: the requested resource id
5748  *      @p_resource_size: ptr to update
5749  */
5750 int devlink_resource_size_get(struct devlink *devlink,
5751                               u64 resource_id,
5752                               u64 *p_resource_size)
5753 {
5754         struct devlink_resource *resource;
5755         int err = 0;
5756
5757         mutex_lock(&devlink->lock);
5758         resource = devlink_resource_find(devlink, NULL, resource_id);
5759         if (!resource) {
5760                 err = -EINVAL;
5761                 goto out;
5762         }
5763         *p_resource_size = resource->size_new;
5764         resource->size = resource->size_new;
5765 out:
5766         mutex_unlock(&devlink->lock);
5767         return err;
5768 }
5769 EXPORT_SYMBOL_GPL(devlink_resource_size_get);
5770
5771 /**
5772  *      devlink_dpipe_table_resource_set - set the resource id
5773  *
5774  *      @devlink: devlink
5775  *      @table_name: table name
5776  *      @resource_id: resource id
5777  *      @resource_units: number of resource's units consumed per table's entry
5778  */
5779 int devlink_dpipe_table_resource_set(struct devlink *devlink,
5780                                      const char *table_name, u64 resource_id,
5781                                      u64 resource_units)
5782 {
5783         struct devlink_dpipe_table *table;
5784         int err = 0;
5785
5786         mutex_lock(&devlink->lock);
5787         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
5788                                          table_name);
5789         if (!table) {
5790                 err = -EINVAL;
5791                 goto out;
5792         }
5793         table->resource_id = resource_id;
5794         table->resource_units = resource_units;
5795         table->resource_valid = true;
5796 out:
5797         mutex_unlock(&devlink->lock);
5798         return err;
5799 }
5800 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
5801
5802 /**
5803  *      devlink_resource_occ_get_register - register occupancy getter
5804  *
5805  *      @devlink: devlink
5806  *      @resource_id: resource id
5807  *      @occ_get: occupancy getter callback
5808  *      @occ_get_priv: occupancy getter callback priv
5809  */
5810 void devlink_resource_occ_get_register(struct devlink *devlink,
5811                                        u64 resource_id,
5812                                        devlink_resource_occ_get_t *occ_get,
5813                                        void *occ_get_priv)
5814 {
5815         struct devlink_resource *resource;
5816
5817         mutex_lock(&devlink->lock);
5818         resource = devlink_resource_find(devlink, NULL, resource_id);
5819         if (WARN_ON(!resource))
5820                 goto out;
5821         WARN_ON(resource->occ_get);
5822
5823         resource->occ_get = occ_get;
5824         resource->occ_get_priv = occ_get_priv;
5825 out:
5826         mutex_unlock(&devlink->lock);
5827 }
5828 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
5829
5830 /**
5831  *      devlink_resource_occ_get_unregister - unregister occupancy getter
5832  *
5833  *      @devlink: devlink
5834  *      @resource_id: resource id
5835  */
5836 void devlink_resource_occ_get_unregister(struct devlink *devlink,
5837                                          u64 resource_id)
5838 {
5839         struct devlink_resource *resource;
5840
5841         mutex_lock(&devlink->lock);
5842         resource = devlink_resource_find(devlink, NULL, resource_id);
5843         if (WARN_ON(!resource))
5844                 goto out;
5845         WARN_ON(!resource->occ_get);
5846
5847         resource->occ_get = NULL;
5848         resource->occ_get_priv = NULL;
5849 out:
5850         mutex_unlock(&devlink->lock);
5851 }
5852 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
5853
5854 static int devlink_param_verify(const struct devlink_param *param)
5855 {
5856         if (!param || !param->name || !param->supported_cmodes)
5857                 return -EINVAL;
5858         if (param->generic)
5859                 return devlink_param_generic_verify(param);
5860         else
5861                 return devlink_param_driver_verify(param);
5862 }
5863
5864 static int __devlink_params_register(struct devlink *devlink,
5865                                      unsigned int port_index,
5866                                      struct list_head *param_list,
5867                                      const struct devlink_param *params,
5868                                      size_t params_count,
5869                                      enum devlink_command reg_cmd,
5870                                      enum devlink_command unreg_cmd)
5871 {
5872         const struct devlink_param *param = params;
5873         int i;
5874         int err;
5875
5876         mutex_lock(&devlink->lock);
5877         for (i = 0; i < params_count; i++, param++) {
5878                 err = devlink_param_verify(param);
5879                 if (err)
5880                         goto rollback;
5881
5882                 err = devlink_param_register_one(devlink, port_index,
5883                                                  param_list, param, reg_cmd);
5884                 if (err)
5885                         goto rollback;
5886         }
5887
5888         mutex_unlock(&devlink->lock);
5889         return 0;
5890
5891 rollback:
5892         if (!i)
5893                 goto unlock;
5894         for (param--; i > 0; i--, param--)
5895                 devlink_param_unregister_one(devlink, port_index, param_list,
5896                                              param, unreg_cmd);
5897 unlock:
5898         mutex_unlock(&devlink->lock);
5899         return err;
5900 }
5901
5902 static void __devlink_params_unregister(struct devlink *devlink,
5903                                         unsigned int port_index,
5904                                         struct list_head *param_list,
5905                                         const struct devlink_param *params,
5906                                         size_t params_count,
5907                                         enum devlink_command cmd)
5908 {
5909         const struct devlink_param *param = params;
5910         int i;
5911
5912         mutex_lock(&devlink->lock);
5913         for (i = 0; i < params_count; i++, param++)
5914                 devlink_param_unregister_one(devlink, 0, param_list, param,
5915                                              cmd);
5916         mutex_unlock(&devlink->lock);
5917 }
5918
5919 /**
5920  *      devlink_params_register - register configuration parameters
5921  *
5922  *      @devlink: devlink
5923  *      @params: configuration parameters array
5924  *      @params_count: number of parameters provided
5925  *
5926  *      Register the configuration parameters supported by the driver.
5927  */
5928 int devlink_params_register(struct devlink *devlink,
5929                             const struct devlink_param *params,
5930                             size_t params_count)
5931 {
5932         return __devlink_params_register(devlink, 0, &devlink->param_list,
5933                                          params, params_count,
5934                                          DEVLINK_CMD_PARAM_NEW,
5935                                          DEVLINK_CMD_PARAM_DEL);
5936 }
5937 EXPORT_SYMBOL_GPL(devlink_params_register);
5938
5939 /**
5940  *      devlink_params_unregister - unregister configuration parameters
5941  *      @devlink: devlink
5942  *      @params: configuration parameters to unregister
5943  *      @params_count: number of parameters provided
5944  */
5945 void devlink_params_unregister(struct devlink *devlink,
5946                                const struct devlink_param *params,
5947                                size_t params_count)
5948 {
5949         return __devlink_params_unregister(devlink, 0, &devlink->param_list,
5950                                            params, params_count,
5951                                            DEVLINK_CMD_PARAM_DEL);
5952 }
5953 EXPORT_SYMBOL_GPL(devlink_params_unregister);
5954
5955 /**
5956  *      devlink_params_publish - publish configuration parameters
5957  *
5958  *      @devlink: devlink
5959  *
5960  *      Publish previously registered configuration parameters.
5961  */
5962 void devlink_params_publish(struct devlink *devlink)
5963 {
5964         struct devlink_param_item *param_item;
5965
5966         list_for_each_entry(param_item, &devlink->param_list, list) {
5967                 if (param_item->published)
5968                         continue;
5969                 param_item->published = true;
5970                 devlink_param_notify(devlink, 0, param_item,
5971                                      DEVLINK_CMD_PARAM_NEW);
5972         }
5973 }
5974 EXPORT_SYMBOL_GPL(devlink_params_publish);
5975
5976 /**
5977  *      devlink_params_unpublish - unpublish configuration parameters
5978  *
5979  *      @devlink: devlink
5980  *
5981  *      Unpublish previously registered configuration parameters.
5982  */
5983 void devlink_params_unpublish(struct devlink *devlink)
5984 {
5985         struct devlink_param_item *param_item;
5986
5987         list_for_each_entry(param_item, &devlink->param_list, list) {
5988                 if (!param_item->published)
5989                         continue;
5990                 param_item->published = false;
5991                 devlink_param_notify(devlink, 0, param_item,
5992                                      DEVLINK_CMD_PARAM_DEL);
5993         }
5994 }
5995 EXPORT_SYMBOL_GPL(devlink_params_unpublish);
5996
5997 /**
5998  *      devlink_port_params_register - register port configuration parameters
5999  *
6000  *      @devlink_port: devlink port
6001  *      @params: configuration parameters array
6002  *      @params_count: number of parameters provided
6003  *
6004  *      Register the configuration parameters supported by the port.
6005  */
6006 int devlink_port_params_register(struct devlink_port *devlink_port,
6007                                  const struct devlink_param *params,
6008                                  size_t params_count)
6009 {
6010         return __devlink_params_register(devlink_port->devlink,
6011                                          devlink_port->index,
6012                                          &devlink_port->param_list, params,
6013                                          params_count,
6014                                          DEVLINK_CMD_PORT_PARAM_NEW,
6015                                          DEVLINK_CMD_PORT_PARAM_DEL);
6016 }
6017 EXPORT_SYMBOL_GPL(devlink_port_params_register);
6018
6019 /**
6020  *      devlink_port_params_unregister - unregister port configuration
6021  *      parameters
6022  *
6023  *      @devlink_port: devlink port
6024  *      @params: configuration parameters array
6025  *      @params_count: number of parameters provided
6026  */
6027 void devlink_port_params_unregister(struct devlink_port *devlink_port,
6028                                     const struct devlink_param *params,
6029                                     size_t params_count)
6030 {
6031         return __devlink_params_unregister(devlink_port->devlink,
6032                                            devlink_port->index,
6033                                            &devlink_port->param_list,
6034                                            params, params_count,
6035                                            DEVLINK_CMD_PORT_PARAM_DEL);
6036 }
6037 EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
6038
6039 static int
6040 __devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
6041                                      union devlink_param_value *init_val)
6042 {
6043         struct devlink_param_item *param_item;
6044
6045         param_item = devlink_param_find_by_id(param_list, param_id);
6046         if (!param_item)
6047                 return -EINVAL;
6048
6049         if (!param_item->driverinit_value_valid ||
6050             !devlink_param_cmode_is_supported(param_item->param,
6051                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
6052                 return -EOPNOTSUPP;
6053
6054         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
6055                 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
6056         else
6057                 *init_val = param_item->driverinit_value;
6058
6059         return 0;
6060 }
6061
6062 static int
6063 __devlink_param_driverinit_value_set(struct devlink *devlink,
6064                                      unsigned int port_index,
6065                                      struct list_head *param_list, u32 param_id,
6066                                      union devlink_param_value init_val,
6067                                      enum devlink_command cmd)
6068 {
6069         struct devlink_param_item *param_item;
6070
6071         param_item = devlink_param_find_by_id(param_list, param_id);
6072         if (!param_item)
6073                 return -EINVAL;
6074
6075         if (!devlink_param_cmode_is_supported(param_item->param,
6076                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
6077                 return -EOPNOTSUPP;
6078
6079         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
6080                 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
6081         else
6082                 param_item->driverinit_value = init_val;
6083         param_item->driverinit_value_valid = true;
6084
6085         devlink_param_notify(devlink, port_index, param_item, cmd);
6086         return 0;
6087 }
6088
6089 /**
6090  *      devlink_param_driverinit_value_get - get configuration parameter
6091  *                                           value for driver initializing
6092  *
6093  *      @devlink: devlink
6094  *      @param_id: parameter ID
6095  *      @init_val: value of parameter in driverinit configuration mode
6096  *
6097  *      This function should be used by the driver to get driverinit
6098  *      configuration for initialization after reload command.
6099  */
6100 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
6101                                        union devlink_param_value *init_val)
6102 {
6103         if (!devlink->ops->reload)
6104                 return -EOPNOTSUPP;
6105
6106         return __devlink_param_driverinit_value_get(&devlink->param_list,
6107                                                     param_id, init_val);
6108 }
6109 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
6110
6111 /**
6112  *      devlink_param_driverinit_value_set - set value of configuration
6113  *                                           parameter for driverinit
6114  *                                           configuration mode
6115  *
6116  *      @devlink: devlink
6117  *      @param_id: parameter ID
6118  *      @init_val: value of parameter to set for driverinit configuration mode
6119  *
6120  *      This function should be used by the driver to set driverinit
6121  *      configuration mode default value.
6122  */
6123 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
6124                                        union devlink_param_value init_val)
6125 {
6126         return __devlink_param_driverinit_value_set(devlink, 0,
6127                                                     &devlink->param_list,
6128                                                     param_id, init_val,
6129                                                     DEVLINK_CMD_PARAM_NEW);
6130 }
6131 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
6132
6133 /**
6134  *      devlink_port_param_driverinit_value_get - get configuration parameter
6135  *                                              value for driver initializing
6136  *
6137  *      @devlink_port: devlink_port
6138  *      @param_id: parameter ID
6139  *      @init_val: value of parameter in driverinit configuration mode
6140  *
6141  *      This function should be used by the driver to get driverinit
6142  *      configuration for initialization after reload command.
6143  */
6144 int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
6145                                             u32 param_id,
6146                                             union devlink_param_value *init_val)
6147 {
6148         struct devlink *devlink = devlink_port->devlink;
6149
6150         if (!devlink->ops->reload)
6151                 return -EOPNOTSUPP;
6152
6153         return __devlink_param_driverinit_value_get(&devlink_port->param_list,
6154                                                     param_id, init_val);
6155 }
6156 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get);
6157
6158 /**
6159  *     devlink_port_param_driverinit_value_set - set value of configuration
6160  *                                               parameter for driverinit
6161  *                                               configuration mode
6162  *
6163  *     @devlink_port: devlink_port
6164  *     @param_id: parameter ID
6165  *     @init_val: value of parameter to set for driverinit configuration mode
6166  *
6167  *     This function should be used by the driver to set driverinit
6168  *     configuration mode default value.
6169  */
6170 int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port,
6171                                             u32 param_id,
6172                                             union devlink_param_value init_val)
6173 {
6174         return __devlink_param_driverinit_value_set(devlink_port->devlink,
6175                                                     devlink_port->index,
6176                                                     &devlink_port->param_list,
6177                                                     param_id, init_val,
6178                                                     DEVLINK_CMD_PORT_PARAM_NEW);
6179 }
6180 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set);
6181
6182 /**
6183  *      devlink_param_value_changed - notify devlink on a parameter's value
6184  *                                    change. Should be called by the driver
6185  *                                    right after the change.
6186  *
6187  *      @devlink: devlink
6188  *      @param_id: parameter ID
6189  *
6190  *      This function should be used by the driver to notify devlink on value
6191  *      change, excluding driverinit configuration mode.
6192  *      For driverinit configuration mode driver should use the function
6193  */
6194 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
6195 {
6196         struct devlink_param_item *param_item;
6197
6198         param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
6199         WARN_ON(!param_item);
6200
6201         devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
6202 }
6203 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
6204
6205 /**
6206  *     devlink_port_param_value_changed - notify devlink on a parameter's value
6207  *                                      change. Should be called by the driver
6208  *                                      right after the change.
6209  *
6210  *     @devlink_port: devlink_port
6211  *     @param_id: parameter ID
6212  *
6213  *     This function should be used by the driver to notify devlink on value
6214  *     change, excluding driverinit configuration mode.
6215  *     For driverinit configuration mode driver should use the function
6216  *     devlink_port_param_driverinit_value_set() instead.
6217  */
6218 void devlink_port_param_value_changed(struct devlink_port *devlink_port,
6219                                       u32 param_id)
6220 {
6221         struct devlink_param_item *param_item;
6222
6223         param_item = devlink_param_find_by_id(&devlink_port->param_list,
6224                                               param_id);
6225         WARN_ON(!param_item);
6226
6227         devlink_param_notify(devlink_port->devlink, devlink_port->index,
6228                              param_item, DEVLINK_CMD_PORT_PARAM_NEW);
6229 }
6230 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed);
6231
6232 /**
6233  *      devlink_param_value_str_fill - Safely fill-up the string preventing
6234  *                                     from overflow of the preallocated buffer
6235  *
6236  *      @dst_val: destination devlink_param_value
6237  *      @src: source buffer
6238  */
6239 void devlink_param_value_str_fill(union devlink_param_value *dst_val,
6240                                   const char *src)
6241 {
6242         size_t len;
6243
6244         len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
6245         WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
6246 }
6247 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
6248
6249 /**
6250  *      devlink_region_create - create a new address region
6251  *
6252  *      @devlink: devlink
6253  *      @region_name: region name
6254  *      @region_max_snapshots: Maximum supported number of snapshots for region
6255  *      @region_size: size of region
6256  */
6257 struct devlink_region *devlink_region_create(struct devlink *devlink,
6258                                              const char *region_name,
6259                                              u32 region_max_snapshots,
6260                                              u64 region_size)
6261 {
6262         struct devlink_region *region;
6263         int err = 0;
6264
6265         mutex_lock(&devlink->lock);
6266
6267         if (devlink_region_get_by_name(devlink, region_name)) {
6268                 err = -EEXIST;
6269                 goto unlock;
6270         }
6271
6272         region = kzalloc(sizeof(*region), GFP_KERNEL);
6273         if (!region) {
6274                 err = -ENOMEM;
6275                 goto unlock;
6276         }
6277
6278         region->devlink = devlink;
6279         region->max_snapshots = region_max_snapshots;
6280         region->name = region_name;
6281         region->size = region_size;
6282         INIT_LIST_HEAD(&region->snapshot_list);
6283         list_add_tail(&region->list, &devlink->region_list);
6284         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
6285
6286         mutex_unlock(&devlink->lock);
6287         return region;
6288
6289 unlock:
6290         mutex_unlock(&devlink->lock);
6291         return ERR_PTR(err);
6292 }
6293 EXPORT_SYMBOL_GPL(devlink_region_create);
6294
6295 /**
6296  *      devlink_region_destroy - destroy address region
6297  *
6298  *      @region: devlink region to destroy
6299  */
6300 void devlink_region_destroy(struct devlink_region *region)
6301 {
6302         struct devlink *devlink = region->devlink;
6303         struct devlink_snapshot *snapshot, *ts;
6304
6305         mutex_lock(&devlink->lock);
6306
6307         /* Free all snapshots of region */
6308         list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
6309                 devlink_region_snapshot_del(snapshot);
6310
6311         list_del(&region->list);
6312
6313         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
6314         mutex_unlock(&devlink->lock);
6315         kfree(region);
6316 }
6317 EXPORT_SYMBOL_GPL(devlink_region_destroy);
6318
6319 /**
6320  *      devlink_region_shapshot_id_get - get snapshot ID
6321  *
6322  *      This callback should be called when adding a new snapshot,
6323  *      Driver should use the same id for multiple snapshots taken
6324  *      on multiple regions at the same time/by the same trigger.
6325  *
6326  *      @devlink: devlink
6327  */
6328 u32 devlink_region_shapshot_id_get(struct devlink *devlink)
6329 {
6330         u32 id;
6331
6332         mutex_lock(&devlink->lock);
6333         id = ++devlink->snapshot_id;
6334         mutex_unlock(&devlink->lock);
6335
6336         return id;
6337 }
6338 EXPORT_SYMBOL_GPL(devlink_region_shapshot_id_get);
6339
6340 /**
6341  *      devlink_region_snapshot_create - create a new snapshot
6342  *      This will add a new snapshot of a region. The snapshot
6343  *      will be stored on the region struct and can be accessed
6344  *      from devlink. This is useful for future analyses of snapshots.
6345  *      Multiple snapshots can be created on a region.
6346  *      The @snapshot_id should be obtained using the getter function.
6347  *
6348  *      @region: devlink region of the snapshot
6349  *      @data_len: size of snapshot data
6350  *      @data: snapshot data
6351  *      @snapshot_id: snapshot id to be created
6352  *      @data_destructor: pointer to destructor function to free data
6353  */
6354 int devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
6355                                    u8 *data, u32 snapshot_id,
6356                                    devlink_snapshot_data_dest_t *data_destructor)
6357 {
6358         struct devlink *devlink = region->devlink;
6359         struct devlink_snapshot *snapshot;
6360         int err;
6361
6362         mutex_lock(&devlink->lock);
6363
6364         /* check if region can hold one more snapshot */
6365         if (region->cur_snapshots == region->max_snapshots) {
6366                 err = -ENOMEM;
6367                 goto unlock;
6368         }
6369
6370         if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
6371                 err = -EEXIST;
6372                 goto unlock;
6373         }
6374
6375         snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
6376         if (!snapshot) {
6377                 err = -ENOMEM;
6378                 goto unlock;
6379         }
6380
6381         snapshot->id = snapshot_id;
6382         snapshot->region = region;
6383         snapshot->data = data;
6384         snapshot->data_len = data_len;
6385         snapshot->data_destructor = data_destructor;
6386
6387         list_add_tail(&snapshot->list, &region->snapshot_list);
6388
6389         region->cur_snapshots++;
6390
6391         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
6392         mutex_unlock(&devlink->lock);
6393         return 0;
6394
6395 unlock:
6396         mutex_unlock(&devlink->lock);
6397         return err;
6398 }
6399 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
6400
6401 static void __devlink_compat_running_version(struct devlink *devlink,
6402                                              char *buf, size_t len)
6403 {
6404         const struct nlattr *nlattr;
6405         struct devlink_info_req req;
6406         struct sk_buff *msg;
6407         int rem, err;
6408
6409         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6410         if (!msg)
6411                 return;
6412
6413         req.msg = msg;
6414         err = devlink->ops->info_get(devlink, &req, NULL);
6415         if (err)
6416                 goto free_msg;
6417
6418         nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
6419                 const struct nlattr *kv;
6420                 int rem_kv;
6421
6422                 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
6423                         continue;
6424
6425                 nla_for_each_nested(kv, nlattr, rem_kv) {
6426                         if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
6427                                 continue;
6428
6429                         strlcat(buf, nla_data(kv), len);
6430                         strlcat(buf, " ", len);
6431                 }
6432         }
6433 free_msg:
6434         nlmsg_free(msg);
6435 }
6436
6437 void devlink_compat_running_version(struct net_device *dev,
6438                                     char *buf, size_t len)
6439 {
6440         struct devlink *devlink;
6441
6442         dev_hold(dev);
6443         rtnl_unlock();
6444
6445         mutex_lock(&devlink_mutex);
6446         devlink = netdev_to_devlink(dev);
6447         if (!devlink || !devlink->ops->info_get)
6448                 goto unlock_list;
6449
6450         mutex_lock(&devlink->lock);
6451         __devlink_compat_running_version(devlink, buf, len);
6452         mutex_unlock(&devlink->lock);
6453 unlock_list:
6454         mutex_unlock(&devlink_mutex);
6455
6456         rtnl_lock();
6457         dev_put(dev);
6458 }
6459
6460 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
6461 {
6462         struct devlink *devlink;
6463         int ret = -EOPNOTSUPP;
6464
6465         dev_hold(dev);
6466         rtnl_unlock();
6467
6468         mutex_lock(&devlink_mutex);
6469         devlink = netdev_to_devlink(dev);
6470         if (!devlink || !devlink->ops->flash_update)
6471                 goto unlock_list;
6472
6473         mutex_lock(&devlink->lock);
6474         ret = devlink->ops->flash_update(devlink, file_name, NULL, NULL);
6475         mutex_unlock(&devlink->lock);
6476 unlock_list:
6477         mutex_unlock(&devlink_mutex);
6478
6479         rtnl_lock();
6480         dev_put(dev);
6481
6482         return ret;
6483 }
6484
6485 static int __init devlink_init(void)
6486 {
6487         return genl_register_family(&devlink_nl_family);
6488 }
6489
6490 subsys_initcall(devlink_init);