Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
[linux-2.6-microblaze.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 && 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 && 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 && 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 || !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 || !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 && 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 || !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 || !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 && 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 || !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 || !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 && 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 && 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 && 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         const struct devlink_ops *ops = devlink->ops;
1598         struct sk_buff *msg;
1599         int err;
1600
1601         if (!ops)
1602                 return -EOPNOTSUPP;
1603
1604         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1605         if (!msg)
1606                 return -ENOMEM;
1607
1608         err = devlink_nl_eswitch_fill(msg, devlink, DEVLINK_CMD_ESWITCH_GET,
1609                                       info->snd_portid, info->snd_seq, 0);
1610
1611         if (err) {
1612                 nlmsg_free(msg);
1613                 return err;
1614         }
1615
1616         return genlmsg_reply(msg, info);
1617 }
1618
1619 static int devlink_nl_cmd_eswitch_set_doit(struct sk_buff *skb,
1620                                            struct genl_info *info)
1621 {
1622         struct devlink *devlink = info->user_ptr[0];
1623         const struct devlink_ops *ops = devlink->ops;
1624         u8 inline_mode, encap_mode;
1625         int err = 0;
1626         u16 mode;
1627
1628         if (!ops)
1629                 return -EOPNOTSUPP;
1630
1631         if (info->attrs[DEVLINK_ATTR_ESWITCH_MODE]) {
1632                 if (!ops->eswitch_mode_set)
1633                         return -EOPNOTSUPP;
1634                 mode = nla_get_u16(info->attrs[DEVLINK_ATTR_ESWITCH_MODE]);
1635                 err = ops->eswitch_mode_set(devlink, mode, info->extack);
1636                 if (err)
1637                         return err;
1638         }
1639
1640         if (info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]) {
1641                 if (!ops->eswitch_inline_mode_set)
1642                         return -EOPNOTSUPP;
1643                 inline_mode = nla_get_u8(
1644                                 info->attrs[DEVLINK_ATTR_ESWITCH_INLINE_MODE]);
1645                 err = ops->eswitch_inline_mode_set(devlink, inline_mode,
1646                                                    info->extack);
1647                 if (err)
1648                         return err;
1649         }
1650
1651         if (info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]) {
1652                 if (!ops->eswitch_encap_mode_set)
1653                         return -EOPNOTSUPP;
1654                 encap_mode = nla_get_u8(info->attrs[DEVLINK_ATTR_ESWITCH_ENCAP_MODE]);
1655                 err = ops->eswitch_encap_mode_set(devlink, encap_mode,
1656                                                   info->extack);
1657                 if (err)
1658                         return err;
1659         }
1660
1661         return 0;
1662 }
1663
1664 int devlink_dpipe_match_put(struct sk_buff *skb,
1665                             struct devlink_dpipe_match *match)
1666 {
1667         struct devlink_dpipe_header *header = match->header;
1668         struct devlink_dpipe_field *field = &header->fields[match->field_id];
1669         struct nlattr *match_attr;
1670
1671         match_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_MATCH);
1672         if (!match_attr)
1673                 return -EMSGSIZE;
1674
1675         if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_MATCH_TYPE, match->type) ||
1676             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, match->header_index) ||
1677             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1678             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1679             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1680                 goto nla_put_failure;
1681
1682         nla_nest_end(skb, match_attr);
1683         return 0;
1684
1685 nla_put_failure:
1686         nla_nest_cancel(skb, match_attr);
1687         return -EMSGSIZE;
1688 }
1689 EXPORT_SYMBOL_GPL(devlink_dpipe_match_put);
1690
1691 static int devlink_dpipe_matches_put(struct devlink_dpipe_table *table,
1692                                      struct sk_buff *skb)
1693 {
1694         struct nlattr *matches_attr;
1695
1696         matches_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_MATCHES);
1697         if (!matches_attr)
1698                 return -EMSGSIZE;
1699
1700         if (table->table_ops->matches_dump(table->priv, skb))
1701                 goto nla_put_failure;
1702
1703         nla_nest_end(skb, matches_attr);
1704         return 0;
1705
1706 nla_put_failure:
1707         nla_nest_cancel(skb, matches_attr);
1708         return -EMSGSIZE;
1709 }
1710
1711 int devlink_dpipe_action_put(struct sk_buff *skb,
1712                              struct devlink_dpipe_action *action)
1713 {
1714         struct devlink_dpipe_header *header = action->header;
1715         struct devlink_dpipe_field *field = &header->fields[action->field_id];
1716         struct nlattr *action_attr;
1717
1718         action_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ACTION);
1719         if (!action_attr)
1720                 return -EMSGSIZE;
1721
1722         if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_ACTION_TYPE, action->type) ||
1723             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_INDEX, action->header_index) ||
1724             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
1725             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
1726             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
1727                 goto nla_put_failure;
1728
1729         nla_nest_end(skb, action_attr);
1730         return 0;
1731
1732 nla_put_failure:
1733         nla_nest_cancel(skb, action_attr);
1734         return -EMSGSIZE;
1735 }
1736 EXPORT_SYMBOL_GPL(devlink_dpipe_action_put);
1737
1738 static int devlink_dpipe_actions_put(struct devlink_dpipe_table *table,
1739                                      struct sk_buff *skb)
1740 {
1741         struct nlattr *actions_attr;
1742
1743         actions_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE_ACTIONS);
1744         if (!actions_attr)
1745                 return -EMSGSIZE;
1746
1747         if (table->table_ops->actions_dump(table->priv, skb))
1748                 goto nla_put_failure;
1749
1750         nla_nest_end(skb, actions_attr);
1751         return 0;
1752
1753 nla_put_failure:
1754         nla_nest_cancel(skb, actions_attr);
1755         return -EMSGSIZE;
1756 }
1757
1758 static int devlink_dpipe_table_put(struct sk_buff *skb,
1759                                    struct devlink_dpipe_table *table)
1760 {
1761         struct nlattr *table_attr;
1762         u64 table_size;
1763
1764         table_size = table->table_ops->size_get(table->priv);
1765         table_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLE);
1766         if (!table_attr)
1767                 return -EMSGSIZE;
1768
1769         if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_TABLE_NAME, table->name) ||
1770             nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_SIZE, table_size,
1771                               DEVLINK_ATTR_PAD))
1772                 goto nla_put_failure;
1773         if (nla_put_u8(skb, DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED,
1774                        table->counters_enabled))
1775                 goto nla_put_failure;
1776
1777         if (table->resource_valid) {
1778                 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_ID,
1779                                       table->resource_id, DEVLINK_ATTR_PAD) ||
1780                     nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_TABLE_RESOURCE_UNITS,
1781                                       table->resource_units, DEVLINK_ATTR_PAD))
1782                         goto nla_put_failure;
1783         }
1784         if (devlink_dpipe_matches_put(table, skb))
1785                 goto nla_put_failure;
1786
1787         if (devlink_dpipe_actions_put(table, skb))
1788                 goto nla_put_failure;
1789
1790         nla_nest_end(skb, table_attr);
1791         return 0;
1792
1793 nla_put_failure:
1794         nla_nest_cancel(skb, table_attr);
1795         return -EMSGSIZE;
1796 }
1797
1798 static int devlink_dpipe_send_and_alloc_skb(struct sk_buff **pskb,
1799                                             struct genl_info *info)
1800 {
1801         int err;
1802
1803         if (*pskb) {
1804                 err = genlmsg_reply(*pskb, info);
1805                 if (err)
1806                         return err;
1807         }
1808         *pskb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
1809         if (!*pskb)
1810                 return -ENOMEM;
1811         return 0;
1812 }
1813
1814 static int devlink_dpipe_tables_fill(struct genl_info *info,
1815                                      enum devlink_command cmd, int flags,
1816                                      struct list_head *dpipe_tables,
1817                                      const char *table_name)
1818 {
1819         struct devlink *devlink = info->user_ptr[0];
1820         struct devlink_dpipe_table *table;
1821         struct nlattr *tables_attr;
1822         struct sk_buff *skb = NULL;
1823         struct nlmsghdr *nlh;
1824         bool incomplete;
1825         void *hdr;
1826         int i;
1827         int err;
1828
1829         table = list_first_entry(dpipe_tables,
1830                                  struct devlink_dpipe_table, list);
1831 start_again:
1832         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1833         if (err)
1834                 return err;
1835
1836         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
1837                           &devlink_nl_family, NLM_F_MULTI, cmd);
1838         if (!hdr) {
1839                 nlmsg_free(skb);
1840                 return -EMSGSIZE;
1841         }
1842
1843         if (devlink_nl_put_handle(skb, devlink))
1844                 goto nla_put_failure;
1845         tables_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_TABLES);
1846         if (!tables_attr)
1847                 goto nla_put_failure;
1848
1849         i = 0;
1850         incomplete = false;
1851         list_for_each_entry_from(table, dpipe_tables, list) {
1852                 if (!table_name) {
1853                         err = devlink_dpipe_table_put(skb, table);
1854                         if (err) {
1855                                 if (!i)
1856                                         goto err_table_put;
1857                                 incomplete = true;
1858                                 break;
1859                         }
1860                 } else {
1861                         if (!strcmp(table->name, table_name)) {
1862                                 err = devlink_dpipe_table_put(skb, table);
1863                                 if (err)
1864                                         break;
1865                         }
1866                 }
1867                 i++;
1868         }
1869
1870         nla_nest_end(skb, tables_attr);
1871         genlmsg_end(skb, hdr);
1872         if (incomplete)
1873                 goto start_again;
1874
1875 send_done:
1876         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
1877                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
1878         if (!nlh) {
1879                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
1880                 if (err)
1881                         return err;
1882                 goto send_done;
1883         }
1884
1885         return genlmsg_reply(skb, info);
1886
1887 nla_put_failure:
1888         err = -EMSGSIZE;
1889 err_table_put:
1890         nlmsg_free(skb);
1891         return err;
1892 }
1893
1894 static int devlink_nl_cmd_dpipe_table_get(struct sk_buff *skb,
1895                                           struct genl_info *info)
1896 {
1897         struct devlink *devlink = info->user_ptr[0];
1898         const char *table_name =  NULL;
1899
1900         if (info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
1901                 table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
1902
1903         return devlink_dpipe_tables_fill(info, DEVLINK_CMD_DPIPE_TABLE_GET, 0,
1904                                          &devlink->dpipe_table_list,
1905                                          table_name);
1906 }
1907
1908 static int devlink_dpipe_value_put(struct sk_buff *skb,
1909                                    struct devlink_dpipe_value *value)
1910 {
1911         if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE,
1912                     value->value_size, value->value))
1913                 return -EMSGSIZE;
1914         if (value->mask)
1915                 if (nla_put(skb, DEVLINK_ATTR_DPIPE_VALUE_MASK,
1916                             value->value_size, value->mask))
1917                         return -EMSGSIZE;
1918         if (value->mapping_valid)
1919                 if (nla_put_u32(skb, DEVLINK_ATTR_DPIPE_VALUE_MAPPING,
1920                                 value->mapping_value))
1921                         return -EMSGSIZE;
1922         return 0;
1923 }
1924
1925 static int devlink_dpipe_action_value_put(struct sk_buff *skb,
1926                                           struct devlink_dpipe_value *value)
1927 {
1928         if (!value->action)
1929                 return -EINVAL;
1930         if (devlink_dpipe_action_put(skb, value->action))
1931                 return -EMSGSIZE;
1932         if (devlink_dpipe_value_put(skb, value))
1933                 return -EMSGSIZE;
1934         return 0;
1935 }
1936
1937 static int devlink_dpipe_action_values_put(struct sk_buff *skb,
1938                                            struct devlink_dpipe_value *values,
1939                                            unsigned int values_count)
1940 {
1941         struct nlattr *action_attr;
1942         int i;
1943         int err;
1944
1945         for (i = 0; i < values_count; i++) {
1946                 action_attr = nla_nest_start(skb,
1947                                              DEVLINK_ATTR_DPIPE_ACTION_VALUE);
1948                 if (!action_attr)
1949                         return -EMSGSIZE;
1950                 err = devlink_dpipe_action_value_put(skb, &values[i]);
1951                 if (err)
1952                         goto err_action_value_put;
1953                 nla_nest_end(skb, action_attr);
1954         }
1955         return 0;
1956
1957 err_action_value_put:
1958         nla_nest_cancel(skb, action_attr);
1959         return err;
1960 }
1961
1962 static int devlink_dpipe_match_value_put(struct sk_buff *skb,
1963                                          struct devlink_dpipe_value *value)
1964 {
1965         if (!value->match)
1966                 return -EINVAL;
1967         if (devlink_dpipe_match_put(skb, value->match))
1968                 return -EMSGSIZE;
1969         if (devlink_dpipe_value_put(skb, value))
1970                 return -EMSGSIZE;
1971         return 0;
1972 }
1973
1974 static int devlink_dpipe_match_values_put(struct sk_buff *skb,
1975                                           struct devlink_dpipe_value *values,
1976                                           unsigned int values_count)
1977 {
1978         struct nlattr *match_attr;
1979         int i;
1980         int err;
1981
1982         for (i = 0; i < values_count; i++) {
1983                 match_attr = nla_nest_start(skb,
1984                                             DEVLINK_ATTR_DPIPE_MATCH_VALUE);
1985                 if (!match_attr)
1986                         return -EMSGSIZE;
1987                 err = devlink_dpipe_match_value_put(skb, &values[i]);
1988                 if (err)
1989                         goto err_match_value_put;
1990                 nla_nest_end(skb, match_attr);
1991         }
1992         return 0;
1993
1994 err_match_value_put:
1995         nla_nest_cancel(skb, match_attr);
1996         return err;
1997 }
1998
1999 static int devlink_dpipe_entry_put(struct sk_buff *skb,
2000                                    struct devlink_dpipe_entry *entry)
2001 {
2002         struct nlattr *entry_attr, *matches_attr, *actions_attr;
2003         int err;
2004
2005         entry_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_ENTRY);
2006         if (!entry_attr)
2007                 return  -EMSGSIZE;
2008
2009         if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_INDEX, entry->index,
2010                               DEVLINK_ATTR_PAD))
2011                 goto nla_put_failure;
2012         if (entry->counter_valid)
2013                 if (nla_put_u64_64bit(skb, DEVLINK_ATTR_DPIPE_ENTRY_COUNTER,
2014                                       entry->counter, DEVLINK_ATTR_PAD))
2015                         goto nla_put_failure;
2016
2017         matches_attr = nla_nest_start(skb,
2018                                       DEVLINK_ATTR_DPIPE_ENTRY_MATCH_VALUES);
2019         if (!matches_attr)
2020                 goto nla_put_failure;
2021
2022         err = devlink_dpipe_match_values_put(skb, entry->match_values,
2023                                              entry->match_values_count);
2024         if (err) {
2025                 nla_nest_cancel(skb, matches_attr);
2026                 goto err_match_values_put;
2027         }
2028         nla_nest_end(skb, matches_attr);
2029
2030         actions_attr = nla_nest_start(skb,
2031                                       DEVLINK_ATTR_DPIPE_ENTRY_ACTION_VALUES);
2032         if (!actions_attr)
2033                 goto nla_put_failure;
2034
2035         err = devlink_dpipe_action_values_put(skb, entry->action_values,
2036                                               entry->action_values_count);
2037         if (err) {
2038                 nla_nest_cancel(skb, actions_attr);
2039                 goto err_action_values_put;
2040         }
2041         nla_nest_end(skb, actions_attr);
2042
2043         nla_nest_end(skb, entry_attr);
2044         return 0;
2045
2046 nla_put_failure:
2047         err = -EMSGSIZE;
2048 err_match_values_put:
2049 err_action_values_put:
2050         nla_nest_cancel(skb, entry_attr);
2051         return err;
2052 }
2053
2054 static struct devlink_dpipe_table *
2055 devlink_dpipe_table_find(struct list_head *dpipe_tables,
2056                          const char *table_name)
2057 {
2058         struct devlink_dpipe_table *table;
2059
2060         list_for_each_entry_rcu(table, dpipe_tables, list) {
2061                 if (!strcmp(table->name, table_name))
2062                         return table;
2063         }
2064         return NULL;
2065 }
2066
2067 int devlink_dpipe_entry_ctx_prepare(struct devlink_dpipe_dump_ctx *dump_ctx)
2068 {
2069         struct devlink *devlink;
2070         int err;
2071
2072         err = devlink_dpipe_send_and_alloc_skb(&dump_ctx->skb,
2073                                                dump_ctx->info);
2074         if (err)
2075                 return err;
2076
2077         dump_ctx->hdr = genlmsg_put(dump_ctx->skb,
2078                                     dump_ctx->info->snd_portid,
2079                                     dump_ctx->info->snd_seq,
2080                                     &devlink_nl_family, NLM_F_MULTI,
2081                                     dump_ctx->cmd);
2082         if (!dump_ctx->hdr)
2083                 goto nla_put_failure;
2084
2085         devlink = dump_ctx->info->user_ptr[0];
2086         if (devlink_nl_put_handle(dump_ctx->skb, devlink))
2087                 goto nla_put_failure;
2088         dump_ctx->nest = nla_nest_start(dump_ctx->skb,
2089                                         DEVLINK_ATTR_DPIPE_ENTRIES);
2090         if (!dump_ctx->nest)
2091                 goto nla_put_failure;
2092         return 0;
2093
2094 nla_put_failure:
2095         nlmsg_free(dump_ctx->skb);
2096         return -EMSGSIZE;
2097 }
2098 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_prepare);
2099
2100 int devlink_dpipe_entry_ctx_append(struct devlink_dpipe_dump_ctx *dump_ctx,
2101                                    struct devlink_dpipe_entry *entry)
2102 {
2103         return devlink_dpipe_entry_put(dump_ctx->skb, entry);
2104 }
2105 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_append);
2106
2107 int devlink_dpipe_entry_ctx_close(struct devlink_dpipe_dump_ctx *dump_ctx)
2108 {
2109         nla_nest_end(dump_ctx->skb, dump_ctx->nest);
2110         genlmsg_end(dump_ctx->skb, dump_ctx->hdr);
2111         return 0;
2112 }
2113 EXPORT_SYMBOL_GPL(devlink_dpipe_entry_ctx_close);
2114
2115 void devlink_dpipe_entry_clear(struct devlink_dpipe_entry *entry)
2116
2117 {
2118         unsigned int value_count, value_index;
2119         struct devlink_dpipe_value *value;
2120
2121         value = entry->action_values;
2122         value_count = entry->action_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         value = entry->match_values;
2129         value_count = entry->match_values_count;
2130         for (value_index = 0; value_index < value_count; value_index++) {
2131                 kfree(value[value_index].value);
2132                 kfree(value[value_index].mask);
2133         }
2134 }
2135 EXPORT_SYMBOL(devlink_dpipe_entry_clear);
2136
2137 static int devlink_dpipe_entries_fill(struct genl_info *info,
2138                                       enum devlink_command cmd, int flags,
2139                                       struct devlink_dpipe_table *table)
2140 {
2141         struct devlink_dpipe_dump_ctx dump_ctx;
2142         struct nlmsghdr *nlh;
2143         int err;
2144
2145         dump_ctx.skb = NULL;
2146         dump_ctx.cmd = cmd;
2147         dump_ctx.info = info;
2148
2149         err = table->table_ops->entries_dump(table->priv,
2150                                              table->counters_enabled,
2151                                              &dump_ctx);
2152         if (err)
2153                 return err;
2154
2155 send_done:
2156         nlh = nlmsg_put(dump_ctx.skb, info->snd_portid, info->snd_seq,
2157                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2158         if (!nlh) {
2159                 err = devlink_dpipe_send_and_alloc_skb(&dump_ctx.skb, info);
2160                 if (err)
2161                         return err;
2162                 goto send_done;
2163         }
2164         return genlmsg_reply(dump_ctx.skb, info);
2165 }
2166
2167 static int devlink_nl_cmd_dpipe_entries_get(struct sk_buff *skb,
2168                                             struct genl_info *info)
2169 {
2170         struct devlink *devlink = info->user_ptr[0];
2171         struct devlink_dpipe_table *table;
2172         const char *table_name;
2173
2174         if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME])
2175                 return -EINVAL;
2176
2177         table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2178         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2179                                          table_name);
2180         if (!table)
2181                 return -EINVAL;
2182
2183         if (!table->table_ops->entries_dump)
2184                 return -EINVAL;
2185
2186         return devlink_dpipe_entries_fill(info, DEVLINK_CMD_DPIPE_ENTRIES_GET,
2187                                           0, table);
2188 }
2189
2190 static int devlink_dpipe_fields_put(struct sk_buff *skb,
2191                                     const struct devlink_dpipe_header *header)
2192 {
2193         struct devlink_dpipe_field *field;
2194         struct nlattr *field_attr;
2195         int i;
2196
2197         for (i = 0; i < header->fields_count; i++) {
2198                 field = &header->fields[i];
2199                 field_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_FIELD);
2200                 if (!field_attr)
2201                         return -EMSGSIZE;
2202                 if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_FIELD_NAME, field->name) ||
2203                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_ID, field->id) ||
2204                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_BITWIDTH, field->bitwidth) ||
2205                     nla_put_u32(skb, DEVLINK_ATTR_DPIPE_FIELD_MAPPING_TYPE, field->mapping_type))
2206                         goto nla_put_failure;
2207                 nla_nest_end(skb, field_attr);
2208         }
2209         return 0;
2210
2211 nla_put_failure:
2212         nla_nest_cancel(skb, field_attr);
2213         return -EMSGSIZE;
2214 }
2215
2216 static int devlink_dpipe_header_put(struct sk_buff *skb,
2217                                     struct devlink_dpipe_header *header)
2218 {
2219         struct nlattr *fields_attr, *header_attr;
2220         int err;
2221
2222         header_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER);
2223         if (!header_attr)
2224                 return -EMSGSIZE;
2225
2226         if (nla_put_string(skb, DEVLINK_ATTR_DPIPE_HEADER_NAME, header->name) ||
2227             nla_put_u32(skb, DEVLINK_ATTR_DPIPE_HEADER_ID, header->id) ||
2228             nla_put_u8(skb, DEVLINK_ATTR_DPIPE_HEADER_GLOBAL, header->global))
2229                 goto nla_put_failure;
2230
2231         fields_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADER_FIELDS);
2232         if (!fields_attr)
2233                 goto nla_put_failure;
2234
2235         err = devlink_dpipe_fields_put(skb, header);
2236         if (err) {
2237                 nla_nest_cancel(skb, fields_attr);
2238                 goto nla_put_failure;
2239         }
2240         nla_nest_end(skb, fields_attr);
2241         nla_nest_end(skb, header_attr);
2242         return 0;
2243
2244 nla_put_failure:
2245         err = -EMSGSIZE;
2246         nla_nest_cancel(skb, header_attr);
2247         return err;
2248 }
2249
2250 static int devlink_dpipe_headers_fill(struct genl_info *info,
2251                                       enum devlink_command cmd, int flags,
2252                                       struct devlink_dpipe_headers *
2253                                       dpipe_headers)
2254 {
2255         struct devlink *devlink = info->user_ptr[0];
2256         struct nlattr *headers_attr;
2257         struct sk_buff *skb = NULL;
2258         struct nlmsghdr *nlh;
2259         void *hdr;
2260         int i, j;
2261         int err;
2262
2263         i = 0;
2264 start_again:
2265         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2266         if (err)
2267                 return err;
2268
2269         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2270                           &devlink_nl_family, NLM_F_MULTI, cmd);
2271         if (!hdr) {
2272                 nlmsg_free(skb);
2273                 return -EMSGSIZE;
2274         }
2275
2276         if (devlink_nl_put_handle(skb, devlink))
2277                 goto nla_put_failure;
2278         headers_attr = nla_nest_start(skb, DEVLINK_ATTR_DPIPE_HEADERS);
2279         if (!headers_attr)
2280                 goto nla_put_failure;
2281
2282         j = 0;
2283         for (; i < dpipe_headers->headers_count; i++) {
2284                 err = devlink_dpipe_header_put(skb, dpipe_headers->headers[i]);
2285                 if (err) {
2286                         if (!j)
2287                                 goto err_table_put;
2288                         break;
2289                 }
2290                 j++;
2291         }
2292         nla_nest_end(skb, headers_attr);
2293         genlmsg_end(skb, hdr);
2294         if (i != dpipe_headers->headers_count)
2295                 goto start_again;
2296
2297 send_done:
2298         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2299                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2300         if (!nlh) {
2301                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2302                 if (err)
2303                         return err;
2304                 goto send_done;
2305         }
2306         return genlmsg_reply(skb, info);
2307
2308 nla_put_failure:
2309         err = -EMSGSIZE;
2310 err_table_put:
2311         nlmsg_free(skb);
2312         return err;
2313 }
2314
2315 static int devlink_nl_cmd_dpipe_headers_get(struct sk_buff *skb,
2316                                             struct genl_info *info)
2317 {
2318         struct devlink *devlink = info->user_ptr[0];
2319
2320         if (!devlink->dpipe_headers)
2321                 return -EOPNOTSUPP;
2322         return devlink_dpipe_headers_fill(info, DEVLINK_CMD_DPIPE_HEADERS_GET,
2323                                           0, devlink->dpipe_headers);
2324 }
2325
2326 static int devlink_dpipe_table_counters_set(struct devlink *devlink,
2327                                             const char *table_name,
2328                                             bool enable)
2329 {
2330         struct devlink_dpipe_table *table;
2331
2332         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
2333                                          table_name);
2334         if (!table)
2335                 return -EINVAL;
2336
2337         if (table->counter_control_extern)
2338                 return -EOPNOTSUPP;
2339
2340         if (!(table->counters_enabled ^ enable))
2341                 return 0;
2342
2343         table->counters_enabled = enable;
2344         if (table->table_ops->counters_set_update)
2345                 table->table_ops->counters_set_update(table->priv, enable);
2346         return 0;
2347 }
2348
2349 static int devlink_nl_cmd_dpipe_table_counters_set(struct sk_buff *skb,
2350                                                    struct genl_info *info)
2351 {
2352         struct devlink *devlink = info->user_ptr[0];
2353         const char *table_name;
2354         bool counters_enable;
2355
2356         if (!info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME] ||
2357             !info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED])
2358                 return -EINVAL;
2359
2360         table_name = nla_data(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_NAME]);
2361         counters_enable = !!nla_get_u8(info->attrs[DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED]);
2362
2363         return devlink_dpipe_table_counters_set(devlink, table_name,
2364                                                 counters_enable);
2365 }
2366
2367 static struct devlink_resource *
2368 devlink_resource_find(struct devlink *devlink,
2369                       struct devlink_resource *resource, u64 resource_id)
2370 {
2371         struct list_head *resource_list;
2372
2373         if (resource)
2374                 resource_list = &resource->resource_list;
2375         else
2376                 resource_list = &devlink->resource_list;
2377
2378         list_for_each_entry(resource, resource_list, list) {
2379                 struct devlink_resource *child_resource;
2380
2381                 if (resource->id == resource_id)
2382                         return resource;
2383
2384                 child_resource = devlink_resource_find(devlink, resource,
2385                                                        resource_id);
2386                 if (child_resource)
2387                         return child_resource;
2388         }
2389         return NULL;
2390 }
2391
2392 static void
2393 devlink_resource_validate_children(struct devlink_resource *resource)
2394 {
2395         struct devlink_resource *child_resource;
2396         bool size_valid = true;
2397         u64 parts_size = 0;
2398
2399         if (list_empty(&resource->resource_list))
2400                 goto out;
2401
2402         list_for_each_entry(child_resource, &resource->resource_list, list)
2403                 parts_size += child_resource->size_new;
2404
2405         if (parts_size > resource->size_new)
2406                 size_valid = false;
2407 out:
2408         resource->size_valid = size_valid;
2409 }
2410
2411 static int
2412 devlink_resource_validate_size(struct devlink_resource *resource, u64 size,
2413                                struct netlink_ext_ack *extack)
2414 {
2415         u64 reminder;
2416         int err = 0;
2417
2418         if (size > resource->size_params.size_max) {
2419                 NL_SET_ERR_MSG_MOD(extack, "Size larger than maximum");
2420                 err = -EINVAL;
2421         }
2422
2423         if (size < resource->size_params.size_min) {
2424                 NL_SET_ERR_MSG_MOD(extack, "Size smaller than minimum");
2425                 err = -EINVAL;
2426         }
2427
2428         div64_u64_rem(size, resource->size_params.size_granularity, &reminder);
2429         if (reminder) {
2430                 NL_SET_ERR_MSG_MOD(extack, "Wrong granularity");
2431                 err = -EINVAL;
2432         }
2433
2434         return err;
2435 }
2436
2437 static int devlink_nl_cmd_resource_set(struct sk_buff *skb,
2438                                        struct genl_info *info)
2439 {
2440         struct devlink *devlink = info->user_ptr[0];
2441         struct devlink_resource *resource;
2442         u64 resource_id;
2443         u64 size;
2444         int err;
2445
2446         if (!info->attrs[DEVLINK_ATTR_RESOURCE_ID] ||
2447             !info->attrs[DEVLINK_ATTR_RESOURCE_SIZE])
2448                 return -EINVAL;
2449         resource_id = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_ID]);
2450
2451         resource = devlink_resource_find(devlink, NULL, resource_id);
2452         if (!resource)
2453                 return -EINVAL;
2454
2455         size = nla_get_u64(info->attrs[DEVLINK_ATTR_RESOURCE_SIZE]);
2456         err = devlink_resource_validate_size(resource, size, info->extack);
2457         if (err)
2458                 return err;
2459
2460         resource->size_new = size;
2461         devlink_resource_validate_children(resource);
2462         if (resource->parent)
2463                 devlink_resource_validate_children(resource->parent);
2464         return 0;
2465 }
2466
2467 static int
2468 devlink_resource_size_params_put(struct devlink_resource *resource,
2469                                  struct sk_buff *skb)
2470 {
2471         struct devlink_resource_size_params *size_params;
2472
2473         size_params = &resource->size_params;
2474         if (nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_GRAN,
2475                               size_params->size_granularity, DEVLINK_ATTR_PAD) ||
2476             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MAX,
2477                               size_params->size_max, DEVLINK_ATTR_PAD) ||
2478             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_MIN,
2479                               size_params->size_min, DEVLINK_ATTR_PAD) ||
2480             nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_UNIT, size_params->unit))
2481                 return -EMSGSIZE;
2482         return 0;
2483 }
2484
2485 static int devlink_resource_occ_put(struct devlink_resource *resource,
2486                                     struct sk_buff *skb)
2487 {
2488         if (!resource->occ_get)
2489                 return 0;
2490         return nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_OCC,
2491                                  resource->occ_get(resource->occ_get_priv),
2492                                  DEVLINK_ATTR_PAD);
2493 }
2494
2495 static int devlink_resource_put(struct devlink *devlink, struct sk_buff *skb,
2496                                 struct devlink_resource *resource)
2497 {
2498         struct devlink_resource *child_resource;
2499         struct nlattr *child_resource_attr;
2500         struct nlattr *resource_attr;
2501
2502         resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE);
2503         if (!resource_attr)
2504                 return -EMSGSIZE;
2505
2506         if (nla_put_string(skb, DEVLINK_ATTR_RESOURCE_NAME, resource->name) ||
2507             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE, resource->size,
2508                               DEVLINK_ATTR_PAD) ||
2509             nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_ID, resource->id,
2510                               DEVLINK_ATTR_PAD))
2511                 goto nla_put_failure;
2512         if (resource->size != resource->size_new)
2513                 nla_put_u64_64bit(skb, DEVLINK_ATTR_RESOURCE_SIZE_NEW,
2514                                   resource->size_new, DEVLINK_ATTR_PAD);
2515         if (devlink_resource_occ_put(resource, skb))
2516                 goto nla_put_failure;
2517         if (devlink_resource_size_params_put(resource, skb))
2518                 goto nla_put_failure;
2519         if (list_empty(&resource->resource_list))
2520                 goto out;
2521
2522         if (nla_put_u8(skb, DEVLINK_ATTR_RESOURCE_SIZE_VALID,
2523                        resource->size_valid))
2524                 goto nla_put_failure;
2525
2526         child_resource_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST);
2527         if (!child_resource_attr)
2528                 goto nla_put_failure;
2529
2530         list_for_each_entry(child_resource, &resource->resource_list, list) {
2531                 if (devlink_resource_put(devlink, skb, child_resource))
2532                         goto resource_put_failure;
2533         }
2534
2535         nla_nest_end(skb, child_resource_attr);
2536 out:
2537         nla_nest_end(skb, resource_attr);
2538         return 0;
2539
2540 resource_put_failure:
2541         nla_nest_cancel(skb, child_resource_attr);
2542 nla_put_failure:
2543         nla_nest_cancel(skb, resource_attr);
2544         return -EMSGSIZE;
2545 }
2546
2547 static int devlink_resource_fill(struct genl_info *info,
2548                                  enum devlink_command cmd, int flags)
2549 {
2550         struct devlink *devlink = info->user_ptr[0];
2551         struct devlink_resource *resource;
2552         struct nlattr *resources_attr;
2553         struct sk_buff *skb = NULL;
2554         struct nlmsghdr *nlh;
2555         bool incomplete;
2556         void *hdr;
2557         int i;
2558         int err;
2559
2560         resource = list_first_entry(&devlink->resource_list,
2561                                     struct devlink_resource, list);
2562 start_again:
2563         err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2564         if (err)
2565                 return err;
2566
2567         hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
2568                           &devlink_nl_family, NLM_F_MULTI, cmd);
2569         if (!hdr) {
2570                 nlmsg_free(skb);
2571                 return -EMSGSIZE;
2572         }
2573
2574         if (devlink_nl_put_handle(skb, devlink))
2575                 goto nla_put_failure;
2576
2577         resources_attr = nla_nest_start(skb, DEVLINK_ATTR_RESOURCE_LIST);
2578         if (!resources_attr)
2579                 goto nla_put_failure;
2580
2581         incomplete = false;
2582         i = 0;
2583         list_for_each_entry_from(resource, &devlink->resource_list, list) {
2584                 err = devlink_resource_put(devlink, skb, resource);
2585                 if (err) {
2586                         if (!i)
2587                                 goto err_resource_put;
2588                         incomplete = true;
2589                         break;
2590                 }
2591                 i++;
2592         }
2593         nla_nest_end(skb, resources_attr);
2594         genlmsg_end(skb, hdr);
2595         if (incomplete)
2596                 goto start_again;
2597 send_done:
2598         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
2599                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
2600         if (!nlh) {
2601                 err = devlink_dpipe_send_and_alloc_skb(&skb, info);
2602                 if (err)
2603                         return err;
2604                 goto send_done;
2605         }
2606         return genlmsg_reply(skb, info);
2607
2608 nla_put_failure:
2609         err = -EMSGSIZE;
2610 err_resource_put:
2611         nlmsg_free(skb);
2612         return err;
2613 }
2614
2615 static int devlink_nl_cmd_resource_dump(struct sk_buff *skb,
2616                                         struct genl_info *info)
2617 {
2618         struct devlink *devlink = info->user_ptr[0];
2619
2620         if (list_empty(&devlink->resource_list))
2621                 return -EOPNOTSUPP;
2622
2623         return devlink_resource_fill(info, DEVLINK_CMD_RESOURCE_DUMP, 0);
2624 }
2625
2626 static int
2627 devlink_resources_validate(struct devlink *devlink,
2628                            struct devlink_resource *resource,
2629                            struct genl_info *info)
2630 {
2631         struct list_head *resource_list;
2632         int err = 0;
2633
2634         if (resource)
2635                 resource_list = &resource->resource_list;
2636         else
2637                 resource_list = &devlink->resource_list;
2638
2639         list_for_each_entry(resource, resource_list, list) {
2640                 if (!resource->size_valid)
2641                         return -EINVAL;
2642                 err = devlink_resources_validate(devlink, resource, info);
2643                 if (err)
2644                         return err;
2645         }
2646         return err;
2647 }
2648
2649 static int devlink_nl_cmd_reload(struct sk_buff *skb, struct genl_info *info)
2650 {
2651         struct devlink *devlink = info->user_ptr[0];
2652         int err;
2653
2654         if (!devlink->ops->reload)
2655                 return -EOPNOTSUPP;
2656
2657         err = devlink_resources_validate(devlink, NULL, info);
2658         if (err) {
2659                 NL_SET_ERR_MSG_MOD(info->extack, "resources size validation failed");
2660                 return err;
2661         }
2662         return devlink->ops->reload(devlink, info->extack);
2663 }
2664
2665 static int devlink_nl_cmd_flash_update(struct sk_buff *skb,
2666                                        struct genl_info *info)
2667 {
2668         struct devlink *devlink = info->user_ptr[0];
2669         const char *file_name, *component;
2670         struct nlattr *nla_component;
2671
2672         if (!devlink->ops->flash_update)
2673                 return -EOPNOTSUPP;
2674
2675         if (!info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME])
2676                 return -EINVAL;
2677         file_name = nla_data(info->attrs[DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME]);
2678
2679         nla_component = info->attrs[DEVLINK_ATTR_FLASH_UPDATE_COMPONENT];
2680         component = nla_component ? nla_data(nla_component) : NULL;
2681
2682         return devlink->ops->flash_update(devlink, file_name, component,
2683                                           info->extack);
2684 }
2685
2686 static const struct devlink_param devlink_param_generic[] = {
2687         {
2688                 .id = DEVLINK_PARAM_GENERIC_ID_INT_ERR_RESET,
2689                 .name = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_NAME,
2690                 .type = DEVLINK_PARAM_GENERIC_INT_ERR_RESET_TYPE,
2691         },
2692         {
2693                 .id = DEVLINK_PARAM_GENERIC_ID_MAX_MACS,
2694                 .name = DEVLINK_PARAM_GENERIC_MAX_MACS_NAME,
2695                 .type = DEVLINK_PARAM_GENERIC_MAX_MACS_TYPE,
2696         },
2697         {
2698                 .id = DEVLINK_PARAM_GENERIC_ID_ENABLE_SRIOV,
2699                 .name = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_NAME,
2700                 .type = DEVLINK_PARAM_GENERIC_ENABLE_SRIOV_TYPE,
2701         },
2702         {
2703                 .id = DEVLINK_PARAM_GENERIC_ID_REGION_SNAPSHOT,
2704                 .name = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_NAME,
2705                 .type = DEVLINK_PARAM_GENERIC_REGION_SNAPSHOT_TYPE,
2706         },
2707         {
2708                 .id = DEVLINK_PARAM_GENERIC_ID_IGNORE_ARI,
2709                 .name = DEVLINK_PARAM_GENERIC_IGNORE_ARI_NAME,
2710                 .type = DEVLINK_PARAM_GENERIC_IGNORE_ARI_TYPE,
2711         },
2712         {
2713                 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MAX,
2714                 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_NAME,
2715                 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MAX_TYPE,
2716         },
2717         {
2718                 .id = DEVLINK_PARAM_GENERIC_ID_MSIX_VEC_PER_PF_MIN,
2719                 .name = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_NAME,
2720                 .type = DEVLINK_PARAM_GENERIC_MSIX_VEC_PER_PF_MIN_TYPE,
2721         },
2722         {
2723                 .id = DEVLINK_PARAM_GENERIC_ID_FW_LOAD_POLICY,
2724                 .name = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_NAME,
2725                 .type = DEVLINK_PARAM_GENERIC_FW_LOAD_POLICY_TYPE,
2726         },
2727 };
2728
2729 static int devlink_param_generic_verify(const struct devlink_param *param)
2730 {
2731         /* verify it match generic parameter by id and name */
2732         if (param->id > DEVLINK_PARAM_GENERIC_ID_MAX)
2733                 return -EINVAL;
2734         if (strcmp(param->name, devlink_param_generic[param->id].name))
2735                 return -ENOENT;
2736
2737         WARN_ON(param->type != devlink_param_generic[param->id].type);
2738
2739         return 0;
2740 }
2741
2742 static int devlink_param_driver_verify(const struct devlink_param *param)
2743 {
2744         int i;
2745
2746         if (param->id <= DEVLINK_PARAM_GENERIC_ID_MAX)
2747                 return -EINVAL;
2748         /* verify no such name in generic params */
2749         for (i = 0; i <= DEVLINK_PARAM_GENERIC_ID_MAX; i++)
2750                 if (!strcmp(param->name, devlink_param_generic[i].name))
2751                         return -EEXIST;
2752
2753         return 0;
2754 }
2755
2756 static struct devlink_param_item *
2757 devlink_param_find_by_name(struct list_head *param_list,
2758                            const char *param_name)
2759 {
2760         struct devlink_param_item *param_item;
2761
2762         list_for_each_entry(param_item, param_list, list)
2763                 if (!strcmp(param_item->param->name, param_name))
2764                         return param_item;
2765         return NULL;
2766 }
2767
2768 static struct devlink_param_item *
2769 devlink_param_find_by_id(struct list_head *param_list, u32 param_id)
2770 {
2771         struct devlink_param_item *param_item;
2772
2773         list_for_each_entry(param_item, param_list, list)
2774                 if (param_item->param->id == param_id)
2775                         return param_item;
2776         return NULL;
2777 }
2778
2779 static bool
2780 devlink_param_cmode_is_supported(const struct devlink_param *param,
2781                                  enum devlink_param_cmode cmode)
2782 {
2783         return test_bit(cmode, &param->supported_cmodes);
2784 }
2785
2786 static int devlink_param_get(struct devlink *devlink,
2787                              const struct devlink_param *param,
2788                              struct devlink_param_gset_ctx *ctx)
2789 {
2790         if (!param->get)
2791                 return -EOPNOTSUPP;
2792         return param->get(devlink, param->id, ctx);
2793 }
2794
2795 static int devlink_param_set(struct devlink *devlink,
2796                              const struct devlink_param *param,
2797                              struct devlink_param_gset_ctx *ctx)
2798 {
2799         if (!param->set)
2800                 return -EOPNOTSUPP;
2801         return param->set(devlink, param->id, ctx);
2802 }
2803
2804 static int
2805 devlink_param_type_to_nla_type(enum devlink_param_type param_type)
2806 {
2807         switch (param_type) {
2808         case DEVLINK_PARAM_TYPE_U8:
2809                 return NLA_U8;
2810         case DEVLINK_PARAM_TYPE_U16:
2811                 return NLA_U16;
2812         case DEVLINK_PARAM_TYPE_U32:
2813                 return NLA_U32;
2814         case DEVLINK_PARAM_TYPE_STRING:
2815                 return NLA_STRING;
2816         case DEVLINK_PARAM_TYPE_BOOL:
2817                 return NLA_FLAG;
2818         default:
2819                 return -EINVAL;
2820         }
2821 }
2822
2823 static int
2824 devlink_nl_param_value_fill_one(struct sk_buff *msg,
2825                                 enum devlink_param_type type,
2826                                 enum devlink_param_cmode cmode,
2827                                 union devlink_param_value val)
2828 {
2829         struct nlattr *param_value_attr;
2830
2831         param_value_attr = nla_nest_start(msg, DEVLINK_ATTR_PARAM_VALUE);
2832         if (!param_value_attr)
2833                 goto nla_put_failure;
2834
2835         if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_CMODE, cmode))
2836                 goto value_nest_cancel;
2837
2838         switch (type) {
2839         case DEVLINK_PARAM_TYPE_U8:
2840                 if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu8))
2841                         goto value_nest_cancel;
2842                 break;
2843         case DEVLINK_PARAM_TYPE_U16:
2844                 if (nla_put_u16(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu16))
2845                         goto value_nest_cancel;
2846                 break;
2847         case DEVLINK_PARAM_TYPE_U32:
2848                 if (nla_put_u32(msg, DEVLINK_ATTR_PARAM_VALUE_DATA, val.vu32))
2849                         goto value_nest_cancel;
2850                 break;
2851         case DEVLINK_PARAM_TYPE_STRING:
2852                 if (nla_put_string(msg, DEVLINK_ATTR_PARAM_VALUE_DATA,
2853                                    val.vstr))
2854                         goto value_nest_cancel;
2855                 break;
2856         case DEVLINK_PARAM_TYPE_BOOL:
2857                 if (val.vbool &&
2858                     nla_put_flag(msg, DEVLINK_ATTR_PARAM_VALUE_DATA))
2859                         goto value_nest_cancel;
2860                 break;
2861         }
2862
2863         nla_nest_end(msg, param_value_attr);
2864         return 0;
2865
2866 value_nest_cancel:
2867         nla_nest_cancel(msg, param_value_attr);
2868 nla_put_failure:
2869         return -EMSGSIZE;
2870 }
2871
2872 static int devlink_nl_param_fill(struct sk_buff *msg, struct devlink *devlink,
2873                                  unsigned int port_index,
2874                                  struct devlink_param_item *param_item,
2875                                  enum devlink_command cmd,
2876                                  u32 portid, u32 seq, int flags)
2877 {
2878         union devlink_param_value param_value[DEVLINK_PARAM_CMODE_MAX + 1];
2879         bool param_value_set[DEVLINK_PARAM_CMODE_MAX + 1] = {};
2880         const struct devlink_param *param = param_item->param;
2881         struct devlink_param_gset_ctx ctx;
2882         struct nlattr *param_values_list;
2883         struct nlattr *param_attr;
2884         int nla_type;
2885         void *hdr;
2886         int err;
2887         int i;
2888
2889         /* Get value from driver part to driverinit configuration mode */
2890         for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
2891                 if (!devlink_param_cmode_is_supported(param, i))
2892                         continue;
2893                 if (i == DEVLINK_PARAM_CMODE_DRIVERINIT) {
2894                         if (!param_item->driverinit_value_valid)
2895                                 return -EOPNOTSUPP;
2896                         param_value[i] = param_item->driverinit_value;
2897                 } else {
2898                         if (!param_item->published)
2899                                 continue;
2900                         ctx.cmode = i;
2901                         err = devlink_param_get(devlink, param, &ctx);
2902                         if (err)
2903                                 return err;
2904                         param_value[i] = ctx.val;
2905                 }
2906                 param_value_set[i] = true;
2907         }
2908
2909         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
2910         if (!hdr)
2911                 return -EMSGSIZE;
2912
2913         if (devlink_nl_put_handle(msg, devlink))
2914                 goto genlmsg_cancel;
2915
2916         if (cmd == DEVLINK_CMD_PORT_PARAM_GET ||
2917             cmd == DEVLINK_CMD_PORT_PARAM_NEW ||
2918             cmd == DEVLINK_CMD_PORT_PARAM_DEL)
2919                 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, port_index))
2920                         goto genlmsg_cancel;
2921
2922         param_attr = nla_nest_start(msg, DEVLINK_ATTR_PARAM);
2923         if (!param_attr)
2924                 goto genlmsg_cancel;
2925         if (nla_put_string(msg, DEVLINK_ATTR_PARAM_NAME, param->name))
2926                 goto param_nest_cancel;
2927         if (param->generic && nla_put_flag(msg, DEVLINK_ATTR_PARAM_GENERIC))
2928                 goto param_nest_cancel;
2929
2930         nla_type = devlink_param_type_to_nla_type(param->type);
2931         if (nla_type < 0)
2932                 goto param_nest_cancel;
2933         if (nla_put_u8(msg, DEVLINK_ATTR_PARAM_TYPE, nla_type))
2934                 goto param_nest_cancel;
2935
2936         param_values_list = nla_nest_start(msg, DEVLINK_ATTR_PARAM_VALUES_LIST);
2937         if (!param_values_list)
2938                 goto param_nest_cancel;
2939
2940         for (i = 0; i <= DEVLINK_PARAM_CMODE_MAX; i++) {
2941                 if (!param_value_set[i])
2942                         continue;
2943                 err = devlink_nl_param_value_fill_one(msg, param->type,
2944                                                       i, param_value[i]);
2945                 if (err)
2946                         goto values_list_nest_cancel;
2947         }
2948
2949         nla_nest_end(msg, param_values_list);
2950         nla_nest_end(msg, param_attr);
2951         genlmsg_end(msg, hdr);
2952         return 0;
2953
2954 values_list_nest_cancel:
2955         nla_nest_end(msg, param_values_list);
2956 param_nest_cancel:
2957         nla_nest_cancel(msg, param_attr);
2958 genlmsg_cancel:
2959         genlmsg_cancel(msg, hdr);
2960         return -EMSGSIZE;
2961 }
2962
2963 static void devlink_param_notify(struct devlink *devlink,
2964                                  unsigned int port_index,
2965                                  struct devlink_param_item *param_item,
2966                                  enum devlink_command cmd)
2967 {
2968         struct sk_buff *msg;
2969         int err;
2970
2971         WARN_ON(cmd != DEVLINK_CMD_PARAM_NEW && cmd != DEVLINK_CMD_PARAM_DEL &&
2972                 cmd != DEVLINK_CMD_PORT_PARAM_NEW &&
2973                 cmd != DEVLINK_CMD_PORT_PARAM_DEL);
2974
2975         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
2976         if (!msg)
2977                 return;
2978         err = devlink_nl_param_fill(msg, devlink, port_index, param_item, cmd,
2979                                     0, 0, 0);
2980         if (err) {
2981                 nlmsg_free(msg);
2982                 return;
2983         }
2984
2985         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
2986                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
2987 }
2988
2989 static int devlink_nl_cmd_param_get_dumpit(struct sk_buff *msg,
2990                                            struct netlink_callback *cb)
2991 {
2992         struct devlink_param_item *param_item;
2993         struct devlink *devlink;
2994         int start = cb->args[0];
2995         int idx = 0;
2996         int err;
2997
2998         mutex_lock(&devlink_mutex);
2999         list_for_each_entry(devlink, &devlink_list, list) {
3000                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3001                         continue;
3002                 mutex_lock(&devlink->lock);
3003                 list_for_each_entry(param_item, &devlink->param_list, list) {
3004                         if (idx < start) {
3005                                 idx++;
3006                                 continue;
3007                         }
3008                         err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3009                                                     DEVLINK_CMD_PARAM_GET,
3010                                                     NETLINK_CB(cb->skb).portid,
3011                                                     cb->nlh->nlmsg_seq,
3012                                                     NLM_F_MULTI);
3013                         if (err) {
3014                                 mutex_unlock(&devlink->lock);
3015                                 goto out;
3016                         }
3017                         idx++;
3018                 }
3019                 mutex_unlock(&devlink->lock);
3020         }
3021 out:
3022         mutex_unlock(&devlink_mutex);
3023
3024         cb->args[0] = idx;
3025         return msg->len;
3026 }
3027
3028 static int
3029 devlink_param_type_get_from_info(struct genl_info *info,
3030                                  enum devlink_param_type *param_type)
3031 {
3032         if (!info->attrs[DEVLINK_ATTR_PARAM_TYPE])
3033                 return -EINVAL;
3034
3035         switch (nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_TYPE])) {
3036         case NLA_U8:
3037                 *param_type = DEVLINK_PARAM_TYPE_U8;
3038                 break;
3039         case NLA_U16:
3040                 *param_type = DEVLINK_PARAM_TYPE_U16;
3041                 break;
3042         case NLA_U32:
3043                 *param_type = DEVLINK_PARAM_TYPE_U32;
3044                 break;
3045         case NLA_STRING:
3046                 *param_type = DEVLINK_PARAM_TYPE_STRING;
3047                 break;
3048         case NLA_FLAG:
3049                 *param_type = DEVLINK_PARAM_TYPE_BOOL;
3050                 break;
3051         default:
3052                 return -EINVAL;
3053         }
3054
3055         return 0;
3056 }
3057
3058 static int
3059 devlink_param_value_get_from_info(const struct devlink_param *param,
3060                                   struct genl_info *info,
3061                                   union devlink_param_value *value)
3062 {
3063         int len;
3064
3065         if (param->type != DEVLINK_PARAM_TYPE_BOOL &&
3066             !info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA])
3067                 return -EINVAL;
3068
3069         switch (param->type) {
3070         case DEVLINK_PARAM_TYPE_U8:
3071                 value->vu8 = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3072                 break;
3073         case DEVLINK_PARAM_TYPE_U16:
3074                 value->vu16 = nla_get_u16(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3075                 break;
3076         case DEVLINK_PARAM_TYPE_U32:
3077                 value->vu32 = nla_get_u32(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]);
3078                 break;
3079         case DEVLINK_PARAM_TYPE_STRING:
3080                 len = strnlen(nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]),
3081                               nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
3082                 if (len == nla_len(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]) ||
3083                     len >= __DEVLINK_PARAM_MAX_STRING_VALUE)
3084                         return -EINVAL;
3085                 strcpy(value->vstr,
3086                        nla_data(info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA]));
3087                 break;
3088         case DEVLINK_PARAM_TYPE_BOOL:
3089                 value->vbool = info->attrs[DEVLINK_ATTR_PARAM_VALUE_DATA] ?
3090                                true : false;
3091                 break;
3092         }
3093         return 0;
3094 }
3095
3096 static struct devlink_param_item *
3097 devlink_param_get_from_info(struct list_head *param_list,
3098                             struct genl_info *info)
3099 {
3100         char *param_name;
3101
3102         if (!info->attrs[DEVLINK_ATTR_PARAM_NAME])
3103                 return NULL;
3104
3105         param_name = nla_data(info->attrs[DEVLINK_ATTR_PARAM_NAME]);
3106         return devlink_param_find_by_name(param_list, param_name);
3107 }
3108
3109 static int devlink_nl_cmd_param_get_doit(struct sk_buff *skb,
3110                                          struct genl_info *info)
3111 {
3112         struct devlink *devlink = info->user_ptr[0];
3113         struct devlink_param_item *param_item;
3114         struct sk_buff *msg;
3115         int err;
3116
3117         param_item = devlink_param_get_from_info(&devlink->param_list, info);
3118         if (!param_item)
3119                 return -EINVAL;
3120
3121         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3122         if (!msg)
3123                 return -ENOMEM;
3124
3125         err = devlink_nl_param_fill(msg, devlink, 0, param_item,
3126                                     DEVLINK_CMD_PARAM_GET,
3127                                     info->snd_portid, info->snd_seq, 0);
3128         if (err) {
3129                 nlmsg_free(msg);
3130                 return err;
3131         }
3132
3133         return genlmsg_reply(msg, info);
3134 }
3135
3136 static int __devlink_nl_cmd_param_set_doit(struct devlink *devlink,
3137                                            unsigned int port_index,
3138                                            struct list_head *param_list,
3139                                            struct genl_info *info,
3140                                            enum devlink_command cmd)
3141 {
3142         enum devlink_param_type param_type;
3143         struct devlink_param_gset_ctx ctx;
3144         enum devlink_param_cmode cmode;
3145         struct devlink_param_item *param_item;
3146         const struct devlink_param *param;
3147         union devlink_param_value value;
3148         int err = 0;
3149
3150         param_item = devlink_param_get_from_info(param_list, info);
3151         if (!param_item)
3152                 return -EINVAL;
3153         param = param_item->param;
3154         err = devlink_param_type_get_from_info(info, &param_type);
3155         if (err)
3156                 return err;
3157         if (param_type != param->type)
3158                 return -EINVAL;
3159         err = devlink_param_value_get_from_info(param, info, &value);
3160         if (err)
3161                 return err;
3162         if (param->validate) {
3163                 err = param->validate(devlink, param->id, value, info->extack);
3164                 if (err)
3165                         return err;
3166         }
3167
3168         if (!info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE])
3169                 return -EINVAL;
3170         cmode = nla_get_u8(info->attrs[DEVLINK_ATTR_PARAM_VALUE_CMODE]);
3171         if (!devlink_param_cmode_is_supported(param, cmode))
3172                 return -EOPNOTSUPP;
3173
3174         if (cmode == DEVLINK_PARAM_CMODE_DRIVERINIT) {
3175                 if (param->type == DEVLINK_PARAM_TYPE_STRING)
3176                         strcpy(param_item->driverinit_value.vstr, value.vstr);
3177                 else
3178                         param_item->driverinit_value = value;
3179                 param_item->driverinit_value_valid = true;
3180         } else {
3181                 if (!param->set)
3182                         return -EOPNOTSUPP;
3183                 ctx.val = value;
3184                 ctx.cmode = cmode;
3185                 err = devlink_param_set(devlink, param, &ctx);
3186                 if (err)
3187                         return err;
3188         }
3189
3190         devlink_param_notify(devlink, port_index, param_item, cmd);
3191         return 0;
3192 }
3193
3194 static int devlink_nl_cmd_param_set_doit(struct sk_buff *skb,
3195                                          struct genl_info *info)
3196 {
3197         struct devlink *devlink = info->user_ptr[0];
3198
3199         return __devlink_nl_cmd_param_set_doit(devlink, 0, &devlink->param_list,
3200                                                info, DEVLINK_CMD_PARAM_NEW);
3201 }
3202
3203 static int devlink_param_register_one(struct devlink *devlink,
3204                                       unsigned int port_index,
3205                                       struct list_head *param_list,
3206                                       const struct devlink_param *param,
3207                                       enum devlink_command cmd)
3208 {
3209         struct devlink_param_item *param_item;
3210
3211         if (devlink_param_find_by_name(param_list, param->name))
3212                 return -EEXIST;
3213
3214         if (param->supported_cmodes == BIT(DEVLINK_PARAM_CMODE_DRIVERINIT))
3215                 WARN_ON(param->get || param->set);
3216         else
3217                 WARN_ON(!param->get || !param->set);
3218
3219         param_item = kzalloc(sizeof(*param_item), GFP_KERNEL);
3220         if (!param_item)
3221                 return -ENOMEM;
3222         param_item->param = param;
3223
3224         list_add_tail(&param_item->list, param_list);
3225         devlink_param_notify(devlink, port_index, param_item, cmd);
3226         return 0;
3227 }
3228
3229 static void devlink_param_unregister_one(struct devlink *devlink,
3230                                          unsigned int port_index,
3231                                          struct list_head *param_list,
3232                                          const struct devlink_param *param,
3233                                          enum devlink_command cmd)
3234 {
3235         struct devlink_param_item *param_item;
3236
3237         param_item = devlink_param_find_by_name(param_list, param->name);
3238         WARN_ON(!param_item);
3239         devlink_param_notify(devlink, port_index, param_item, cmd);
3240         list_del(&param_item->list);
3241         kfree(param_item);
3242 }
3243
3244 static int devlink_nl_cmd_port_param_get_dumpit(struct sk_buff *msg,
3245                                                 struct netlink_callback *cb)
3246 {
3247         struct devlink_param_item *param_item;
3248         struct devlink_port *devlink_port;
3249         struct devlink *devlink;
3250         int start = cb->args[0];
3251         int idx = 0;
3252         int err;
3253
3254         mutex_lock(&devlink_mutex);
3255         list_for_each_entry(devlink, &devlink_list, list) {
3256                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3257                         continue;
3258                 mutex_lock(&devlink->lock);
3259                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
3260                         list_for_each_entry(param_item,
3261                                             &devlink_port->param_list, list) {
3262                                 if (idx < start) {
3263                                         idx++;
3264                                         continue;
3265                                 }
3266                                 err = devlink_nl_param_fill(msg,
3267                                                 devlink_port->devlink,
3268                                                 devlink_port->index, param_item,
3269                                                 DEVLINK_CMD_PORT_PARAM_GET,
3270                                                 NETLINK_CB(cb->skb).portid,
3271                                                 cb->nlh->nlmsg_seq,
3272                                                 NLM_F_MULTI);
3273                                 if (err) {
3274                                         mutex_unlock(&devlink->lock);
3275                                         goto out;
3276                                 }
3277                                 idx++;
3278                         }
3279                 }
3280                 mutex_unlock(&devlink->lock);
3281         }
3282 out:
3283         mutex_unlock(&devlink_mutex);
3284
3285         cb->args[0] = idx;
3286         return msg->len;
3287 }
3288
3289 static int devlink_nl_cmd_port_param_get_doit(struct sk_buff *skb,
3290                                               struct genl_info *info)
3291 {
3292         struct devlink_port *devlink_port = info->user_ptr[0];
3293         struct devlink_param_item *param_item;
3294         struct sk_buff *msg;
3295         int err;
3296
3297         param_item = devlink_param_get_from_info(&devlink_port->param_list,
3298                                                  info);
3299         if (!param_item)
3300                 return -EINVAL;
3301
3302         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3303         if (!msg)
3304                 return -ENOMEM;
3305
3306         err = devlink_nl_param_fill(msg, devlink_port->devlink,
3307                                     devlink_port->index, param_item,
3308                                     DEVLINK_CMD_PORT_PARAM_GET,
3309                                     info->snd_portid, info->snd_seq, 0);
3310         if (err) {
3311                 nlmsg_free(msg);
3312                 return err;
3313         }
3314
3315         return genlmsg_reply(msg, info);
3316 }
3317
3318 static int devlink_nl_cmd_port_param_set_doit(struct sk_buff *skb,
3319                                               struct genl_info *info)
3320 {
3321         struct devlink_port *devlink_port = info->user_ptr[0];
3322
3323         return __devlink_nl_cmd_param_set_doit(devlink_port->devlink,
3324                                                devlink_port->index,
3325                                                &devlink_port->param_list, info,
3326                                                DEVLINK_CMD_PORT_PARAM_NEW);
3327 }
3328
3329 static int devlink_nl_region_snapshot_id_put(struct sk_buff *msg,
3330                                              struct devlink *devlink,
3331                                              struct devlink_snapshot *snapshot)
3332 {
3333         struct nlattr *snap_attr;
3334         int err;
3335
3336         snap_attr = nla_nest_start(msg, DEVLINK_ATTR_REGION_SNAPSHOT);
3337         if (!snap_attr)
3338                 return -EINVAL;
3339
3340         err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID, snapshot->id);
3341         if (err)
3342                 goto nla_put_failure;
3343
3344         nla_nest_end(msg, snap_attr);
3345         return 0;
3346
3347 nla_put_failure:
3348         nla_nest_cancel(msg, snap_attr);
3349         return err;
3350 }
3351
3352 static int devlink_nl_region_snapshots_id_put(struct sk_buff *msg,
3353                                               struct devlink *devlink,
3354                                               struct devlink_region *region)
3355 {
3356         struct devlink_snapshot *snapshot;
3357         struct nlattr *snapshots_attr;
3358         int err;
3359
3360         snapshots_attr = nla_nest_start(msg, DEVLINK_ATTR_REGION_SNAPSHOTS);
3361         if (!snapshots_attr)
3362                 return -EINVAL;
3363
3364         list_for_each_entry(snapshot, &region->snapshot_list, list) {
3365                 err = devlink_nl_region_snapshot_id_put(msg, devlink, snapshot);
3366                 if (err)
3367                         goto nla_put_failure;
3368         }
3369
3370         nla_nest_end(msg, snapshots_attr);
3371         return 0;
3372
3373 nla_put_failure:
3374         nla_nest_cancel(msg, snapshots_attr);
3375         return err;
3376 }
3377
3378 static int devlink_nl_region_fill(struct sk_buff *msg, struct devlink *devlink,
3379                                   enum devlink_command cmd, u32 portid,
3380                                   u32 seq, int flags,
3381                                   struct devlink_region *region)
3382 {
3383         void *hdr;
3384         int err;
3385
3386         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3387         if (!hdr)
3388                 return -EMSGSIZE;
3389
3390         err = devlink_nl_put_handle(msg, devlink);
3391         if (err)
3392                 goto nla_put_failure;
3393
3394         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME, region->name);
3395         if (err)
3396                 goto nla_put_failure;
3397
3398         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3399                                 region->size,
3400                                 DEVLINK_ATTR_PAD);
3401         if (err)
3402                 goto nla_put_failure;
3403
3404         err = devlink_nl_region_snapshots_id_put(msg, devlink, region);
3405         if (err)
3406                 goto nla_put_failure;
3407
3408         genlmsg_end(msg, hdr);
3409         return 0;
3410
3411 nla_put_failure:
3412         genlmsg_cancel(msg, hdr);
3413         return err;
3414 }
3415
3416 static void devlink_nl_region_notify(struct devlink_region *region,
3417                                      struct devlink_snapshot *snapshot,
3418                                      enum devlink_command cmd)
3419 {
3420         struct devlink *devlink = region->devlink;
3421         struct sk_buff *msg;
3422         void *hdr;
3423         int err;
3424
3425         WARN_ON(cmd != DEVLINK_CMD_REGION_NEW && cmd != DEVLINK_CMD_REGION_DEL);
3426
3427         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3428         if (!msg)
3429                 return;
3430
3431         hdr = genlmsg_put(msg, 0, 0, &devlink_nl_family, 0, cmd);
3432         if (!hdr)
3433                 goto out_free_msg;
3434
3435         err = devlink_nl_put_handle(msg, devlink);
3436         if (err)
3437                 goto out_cancel_msg;
3438
3439         err = nla_put_string(msg, DEVLINK_ATTR_REGION_NAME,
3440                              region->name);
3441         if (err)
3442                 goto out_cancel_msg;
3443
3444         if (snapshot) {
3445                 err = nla_put_u32(msg, DEVLINK_ATTR_REGION_SNAPSHOT_ID,
3446                                   snapshot->id);
3447                 if (err)
3448                         goto out_cancel_msg;
3449         } else {
3450                 err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_SIZE,
3451                                         region->size, DEVLINK_ATTR_PAD);
3452                 if (err)
3453                         goto out_cancel_msg;
3454         }
3455         genlmsg_end(msg, hdr);
3456
3457         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
3458                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
3459
3460         return;
3461
3462 out_cancel_msg:
3463         genlmsg_cancel(msg, hdr);
3464 out_free_msg:
3465         nlmsg_free(msg);
3466 }
3467
3468 static int devlink_nl_cmd_region_get_doit(struct sk_buff *skb,
3469                                           struct genl_info *info)
3470 {
3471         struct devlink *devlink = info->user_ptr[0];
3472         struct devlink_region *region;
3473         const char *region_name;
3474         struct sk_buff *msg;
3475         int err;
3476
3477         if (!info->attrs[DEVLINK_ATTR_REGION_NAME])
3478                 return -EINVAL;
3479
3480         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3481         region = devlink_region_get_by_name(devlink, region_name);
3482         if (!region)
3483                 return -EINVAL;
3484
3485         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3486         if (!msg)
3487                 return -ENOMEM;
3488
3489         err = devlink_nl_region_fill(msg, devlink, DEVLINK_CMD_REGION_GET,
3490                                      info->snd_portid, info->snd_seq, 0,
3491                                      region);
3492         if (err) {
3493                 nlmsg_free(msg);
3494                 return err;
3495         }
3496
3497         return genlmsg_reply(msg, info);
3498 }
3499
3500 static int devlink_nl_cmd_region_get_dumpit(struct sk_buff *msg,
3501                                             struct netlink_callback *cb)
3502 {
3503         struct devlink_region *region;
3504         struct devlink *devlink;
3505         int start = cb->args[0];
3506         int idx = 0;
3507         int err;
3508
3509         mutex_lock(&devlink_mutex);
3510         list_for_each_entry(devlink, &devlink_list, list) {
3511                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3512                         continue;
3513
3514                 mutex_lock(&devlink->lock);
3515                 list_for_each_entry(region, &devlink->region_list, list) {
3516                         if (idx < start) {
3517                                 idx++;
3518                                 continue;
3519                         }
3520                         err = devlink_nl_region_fill(msg, devlink,
3521                                                      DEVLINK_CMD_REGION_GET,
3522                                                      NETLINK_CB(cb->skb).portid,
3523                                                      cb->nlh->nlmsg_seq,
3524                                                      NLM_F_MULTI, region);
3525                         if (err) {
3526                                 mutex_unlock(&devlink->lock);
3527                                 goto out;
3528                         }
3529                         idx++;
3530                 }
3531                 mutex_unlock(&devlink->lock);
3532         }
3533 out:
3534         mutex_unlock(&devlink_mutex);
3535         cb->args[0] = idx;
3536         return msg->len;
3537 }
3538
3539 static int devlink_nl_cmd_region_del(struct sk_buff *skb,
3540                                      struct genl_info *info)
3541 {
3542         struct devlink *devlink = info->user_ptr[0];
3543         struct devlink_snapshot *snapshot;
3544         struct devlink_region *region;
3545         const char *region_name;
3546         u32 snapshot_id;
3547
3548         if (!info->attrs[DEVLINK_ATTR_REGION_NAME] ||
3549             !info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID])
3550                 return -EINVAL;
3551
3552         region_name = nla_data(info->attrs[DEVLINK_ATTR_REGION_NAME]);
3553         snapshot_id = nla_get_u32(info->attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3554
3555         region = devlink_region_get_by_name(devlink, region_name);
3556         if (!region)
3557                 return -EINVAL;
3558
3559         snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3560         if (!snapshot)
3561                 return -EINVAL;
3562
3563         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_DEL);
3564         devlink_region_snapshot_del(snapshot);
3565         return 0;
3566 }
3567
3568 static int devlink_nl_cmd_region_read_chunk_fill(struct sk_buff *msg,
3569                                                  struct devlink *devlink,
3570                                                  u8 *chunk, u32 chunk_size,
3571                                                  u64 addr)
3572 {
3573         struct nlattr *chunk_attr;
3574         int err;
3575
3576         chunk_attr = nla_nest_start(msg, DEVLINK_ATTR_REGION_CHUNK);
3577         if (!chunk_attr)
3578                 return -EINVAL;
3579
3580         err = nla_put(msg, DEVLINK_ATTR_REGION_CHUNK_DATA, chunk_size, chunk);
3581         if (err)
3582                 goto nla_put_failure;
3583
3584         err = nla_put_u64_64bit(msg, DEVLINK_ATTR_REGION_CHUNK_ADDR, addr,
3585                                 DEVLINK_ATTR_PAD);
3586         if (err)
3587                 goto nla_put_failure;
3588
3589         nla_nest_end(msg, chunk_attr);
3590         return 0;
3591
3592 nla_put_failure:
3593         nla_nest_cancel(msg, chunk_attr);
3594         return err;
3595 }
3596
3597 #define DEVLINK_REGION_READ_CHUNK_SIZE 256
3598
3599 static int devlink_nl_region_read_snapshot_fill(struct sk_buff *skb,
3600                                                 struct devlink *devlink,
3601                                                 struct devlink_region *region,
3602                                                 struct nlattr **attrs,
3603                                                 u64 start_offset,
3604                                                 u64 end_offset,
3605                                                 bool dump,
3606                                                 u64 *new_offset)
3607 {
3608         struct devlink_snapshot *snapshot;
3609         u64 curr_offset = start_offset;
3610         u32 snapshot_id;
3611         int err = 0;
3612
3613         *new_offset = start_offset;
3614
3615         snapshot_id = nla_get_u32(attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]);
3616         snapshot = devlink_region_snapshot_get_by_id(region, snapshot_id);
3617         if (!snapshot)
3618                 return -EINVAL;
3619
3620         if (end_offset > snapshot->data_len || dump)
3621                 end_offset = snapshot->data_len;
3622
3623         while (curr_offset < end_offset) {
3624                 u32 data_size;
3625                 u8 *data;
3626
3627                 if (end_offset - curr_offset < DEVLINK_REGION_READ_CHUNK_SIZE)
3628                         data_size = end_offset - curr_offset;
3629                 else
3630                         data_size = DEVLINK_REGION_READ_CHUNK_SIZE;
3631
3632                 data = &snapshot->data[curr_offset];
3633                 err = devlink_nl_cmd_region_read_chunk_fill(skb, devlink,
3634                                                             data, data_size,
3635                                                             curr_offset);
3636                 if (err)
3637                         break;
3638
3639                 curr_offset += data_size;
3640         }
3641         *new_offset = curr_offset;
3642
3643         return err;
3644 }
3645
3646 static int devlink_nl_cmd_region_read_dumpit(struct sk_buff *skb,
3647                                              struct netlink_callback *cb)
3648 {
3649         u64 ret_offset, start_offset, end_offset = 0;
3650         const struct genl_ops *ops = cb->data;
3651         struct devlink_region *region;
3652         struct nlattr *chunks_attr;
3653         const char *region_name;
3654         struct devlink *devlink;
3655         struct nlattr **attrs;
3656         bool dump = true;
3657         void *hdr;
3658         int err;
3659
3660         start_offset = *((u64 *)&cb->args[0]);
3661
3662         attrs = kmalloc_array(DEVLINK_ATTR_MAX + 1, sizeof(*attrs), GFP_KERNEL);
3663         if (!attrs)
3664                 return -ENOMEM;
3665
3666         err = nlmsg_parse(cb->nlh, GENL_HDRLEN + devlink_nl_family.hdrsize,
3667                           attrs, DEVLINK_ATTR_MAX, ops->policy, cb->extack);
3668         if (err)
3669                 goto out_free;
3670
3671         mutex_lock(&devlink_mutex);
3672         devlink = devlink_get_from_attrs(sock_net(cb->skb->sk), attrs);
3673         if (IS_ERR(devlink)) {
3674                 err = PTR_ERR(devlink);
3675                 goto out_dev;
3676         }
3677
3678         mutex_lock(&devlink->lock);
3679
3680         if (!attrs[DEVLINK_ATTR_REGION_NAME] ||
3681             !attrs[DEVLINK_ATTR_REGION_SNAPSHOT_ID]) {
3682                 err = -EINVAL;
3683                 goto out_unlock;
3684         }
3685
3686         region_name = nla_data(attrs[DEVLINK_ATTR_REGION_NAME]);
3687         region = devlink_region_get_by_name(devlink, region_name);
3688         if (!region) {
3689                 err = -EINVAL;
3690                 goto out_unlock;
3691         }
3692
3693         hdr = genlmsg_put(skb, NETLINK_CB(cb->skb).portid, cb->nlh->nlmsg_seq,
3694                           &devlink_nl_family, NLM_F_ACK | NLM_F_MULTI,
3695                           DEVLINK_CMD_REGION_READ);
3696         if (!hdr) {
3697                 err = -EMSGSIZE;
3698                 goto out_unlock;
3699         }
3700
3701         err = devlink_nl_put_handle(skb, devlink);
3702         if (err)
3703                 goto nla_put_failure;
3704
3705         err = nla_put_string(skb, DEVLINK_ATTR_REGION_NAME, region_name);
3706         if (err)
3707                 goto nla_put_failure;
3708
3709         chunks_attr = nla_nest_start(skb, DEVLINK_ATTR_REGION_CHUNKS);
3710         if (!chunks_attr) {
3711                 err = -EMSGSIZE;
3712                 goto nla_put_failure;
3713         }
3714
3715         if (attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR] &&
3716             attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]) {
3717                 if (!start_offset)
3718                         start_offset =
3719                                 nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3720
3721                 end_offset = nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_ADDR]);
3722                 end_offset += nla_get_u64(attrs[DEVLINK_ATTR_REGION_CHUNK_LEN]);
3723                 dump = false;
3724         }
3725
3726         err = devlink_nl_region_read_snapshot_fill(skb, devlink,
3727                                                    region, attrs,
3728                                                    start_offset,
3729                                                    end_offset, dump,
3730                                                    &ret_offset);
3731
3732         if (err && err != -EMSGSIZE)
3733                 goto nla_put_failure;
3734
3735         /* Check if there was any progress done to prevent infinite loop */
3736         if (ret_offset == start_offset) {
3737                 err = -EINVAL;
3738                 goto nla_put_failure;
3739         }
3740
3741         *((u64 *)&cb->args[0]) = ret_offset;
3742
3743         nla_nest_end(skb, chunks_attr);
3744         genlmsg_end(skb, hdr);
3745         mutex_unlock(&devlink->lock);
3746         mutex_unlock(&devlink_mutex);
3747         kfree(attrs);
3748
3749         return skb->len;
3750
3751 nla_put_failure:
3752         genlmsg_cancel(skb, hdr);
3753 out_unlock:
3754         mutex_unlock(&devlink->lock);
3755 out_dev:
3756         mutex_unlock(&devlink_mutex);
3757 out_free:
3758         kfree(attrs);
3759         return err;
3760 }
3761
3762 struct devlink_info_req {
3763         struct sk_buff *msg;
3764 };
3765
3766 int devlink_info_driver_name_put(struct devlink_info_req *req, const char *name)
3767 {
3768         return nla_put_string(req->msg, DEVLINK_ATTR_INFO_DRIVER_NAME, name);
3769 }
3770 EXPORT_SYMBOL_GPL(devlink_info_driver_name_put);
3771
3772 int devlink_info_serial_number_put(struct devlink_info_req *req, const char *sn)
3773 {
3774         return nla_put_string(req->msg, DEVLINK_ATTR_INFO_SERIAL_NUMBER, sn);
3775 }
3776 EXPORT_SYMBOL_GPL(devlink_info_serial_number_put);
3777
3778 static int devlink_info_version_put(struct devlink_info_req *req, int attr,
3779                                     const char *version_name,
3780                                     const char *version_value)
3781 {
3782         struct nlattr *nest;
3783         int err;
3784
3785         nest = nla_nest_start(req->msg, attr);
3786         if (!nest)
3787                 return -EMSGSIZE;
3788
3789         err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_NAME,
3790                              version_name);
3791         if (err)
3792                 goto nla_put_failure;
3793
3794         err = nla_put_string(req->msg, DEVLINK_ATTR_INFO_VERSION_VALUE,
3795                              version_value);
3796         if (err)
3797                 goto nla_put_failure;
3798
3799         nla_nest_end(req->msg, nest);
3800
3801         return 0;
3802
3803 nla_put_failure:
3804         nla_nest_cancel(req->msg, nest);
3805         return err;
3806 }
3807
3808 int devlink_info_version_fixed_put(struct devlink_info_req *req,
3809                                    const char *version_name,
3810                                    const char *version_value)
3811 {
3812         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_FIXED,
3813                                         version_name, version_value);
3814 }
3815 EXPORT_SYMBOL_GPL(devlink_info_version_fixed_put);
3816
3817 int devlink_info_version_stored_put(struct devlink_info_req *req,
3818                                     const char *version_name,
3819                                     const char *version_value)
3820 {
3821         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_STORED,
3822                                         version_name, version_value);
3823 }
3824 EXPORT_SYMBOL_GPL(devlink_info_version_stored_put);
3825
3826 int devlink_info_version_running_put(struct devlink_info_req *req,
3827                                      const char *version_name,
3828                                      const char *version_value)
3829 {
3830         return devlink_info_version_put(req, DEVLINK_ATTR_INFO_VERSION_RUNNING,
3831                                         version_name, version_value);
3832 }
3833 EXPORT_SYMBOL_GPL(devlink_info_version_running_put);
3834
3835 static int
3836 devlink_nl_info_fill(struct sk_buff *msg, struct devlink *devlink,
3837                      enum devlink_command cmd, u32 portid,
3838                      u32 seq, int flags, struct netlink_ext_ack *extack)
3839 {
3840         struct devlink_info_req req;
3841         void *hdr;
3842         int err;
3843
3844         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
3845         if (!hdr)
3846                 return -EMSGSIZE;
3847
3848         err = -EMSGSIZE;
3849         if (devlink_nl_put_handle(msg, devlink))
3850                 goto err_cancel_msg;
3851
3852         req.msg = msg;
3853         err = devlink->ops->info_get(devlink, &req, extack);
3854         if (err)
3855                 goto err_cancel_msg;
3856
3857         genlmsg_end(msg, hdr);
3858         return 0;
3859
3860 err_cancel_msg:
3861         genlmsg_cancel(msg, hdr);
3862         return err;
3863 }
3864
3865 static int devlink_nl_cmd_info_get_doit(struct sk_buff *skb,
3866                                         struct genl_info *info)
3867 {
3868         struct devlink *devlink = info->user_ptr[0];
3869         struct sk_buff *msg;
3870         int err;
3871
3872         if (!devlink->ops || !devlink->ops->info_get)
3873                 return -EOPNOTSUPP;
3874
3875         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
3876         if (!msg)
3877                 return -ENOMEM;
3878
3879         err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
3880                                    info->snd_portid, info->snd_seq, 0,
3881                                    info->extack);
3882         if (err) {
3883                 nlmsg_free(msg);
3884                 return err;
3885         }
3886
3887         return genlmsg_reply(msg, info);
3888 }
3889
3890 static int devlink_nl_cmd_info_get_dumpit(struct sk_buff *msg,
3891                                           struct netlink_callback *cb)
3892 {
3893         struct devlink *devlink;
3894         int start = cb->args[0];
3895         int idx = 0;
3896         int err;
3897
3898         mutex_lock(&devlink_mutex);
3899         list_for_each_entry(devlink, &devlink_list, list) {
3900                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
3901                         continue;
3902                 if (idx < start) {
3903                         idx++;
3904                         continue;
3905                 }
3906
3907                 mutex_lock(&devlink->lock);
3908                 err = devlink_nl_info_fill(msg, devlink, DEVLINK_CMD_INFO_GET,
3909                                            NETLINK_CB(cb->skb).portid,
3910                                            cb->nlh->nlmsg_seq, NLM_F_MULTI,
3911                                            cb->extack);
3912                 mutex_unlock(&devlink->lock);
3913                 if (err)
3914                         break;
3915                 idx++;
3916         }
3917         mutex_unlock(&devlink_mutex);
3918
3919         cb->args[0] = idx;
3920         return msg->len;
3921 }
3922
3923 struct devlink_fmsg_item {
3924         struct list_head list;
3925         int attrtype;
3926         u8 nla_type;
3927         u16 len;
3928         int value[0];
3929 };
3930
3931 struct devlink_fmsg {
3932         struct list_head item_list;
3933 };
3934
3935 static struct devlink_fmsg *devlink_fmsg_alloc(void)
3936 {
3937         struct devlink_fmsg *fmsg;
3938
3939         fmsg = kzalloc(sizeof(*fmsg), GFP_KERNEL);
3940         if (!fmsg)
3941                 return NULL;
3942
3943         INIT_LIST_HEAD(&fmsg->item_list);
3944
3945         return fmsg;
3946 }
3947
3948 static void devlink_fmsg_free(struct devlink_fmsg *fmsg)
3949 {
3950         struct devlink_fmsg_item *item, *tmp;
3951
3952         list_for_each_entry_safe(item, tmp, &fmsg->item_list, list) {
3953                 list_del(&item->list);
3954                 kfree(item);
3955         }
3956         kfree(fmsg);
3957 }
3958
3959 static int devlink_fmsg_nest_common(struct devlink_fmsg *fmsg,
3960                                     int attrtype)
3961 {
3962         struct devlink_fmsg_item *item;
3963
3964         item = kzalloc(sizeof(*item), GFP_KERNEL);
3965         if (!item)
3966                 return -ENOMEM;
3967
3968         item->attrtype = attrtype;
3969         list_add_tail(&item->list, &fmsg->item_list);
3970
3971         return 0;
3972 }
3973
3974 int devlink_fmsg_obj_nest_start(struct devlink_fmsg *fmsg)
3975 {
3976         return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_OBJ_NEST_START);
3977 }
3978 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_start);
3979
3980 static int devlink_fmsg_nest_end(struct devlink_fmsg *fmsg)
3981 {
3982         return devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_NEST_END);
3983 }
3984
3985 int devlink_fmsg_obj_nest_end(struct devlink_fmsg *fmsg)
3986 {
3987         return devlink_fmsg_nest_end(fmsg);
3988 }
3989 EXPORT_SYMBOL_GPL(devlink_fmsg_obj_nest_end);
3990
3991 #define DEVLINK_FMSG_MAX_SIZE (GENLMSG_DEFAULT_SIZE - GENL_HDRLEN - NLA_HDRLEN)
3992
3993 static int devlink_fmsg_put_name(struct devlink_fmsg *fmsg, const char *name)
3994 {
3995         struct devlink_fmsg_item *item;
3996
3997         if (strlen(name) + 1 > DEVLINK_FMSG_MAX_SIZE)
3998                 return -EMSGSIZE;
3999
4000         item = kzalloc(sizeof(*item) + strlen(name) + 1, GFP_KERNEL);
4001         if (!item)
4002                 return -ENOMEM;
4003
4004         item->nla_type = NLA_NUL_STRING;
4005         item->len = strlen(name) + 1;
4006         item->attrtype = DEVLINK_ATTR_FMSG_OBJ_NAME;
4007         memcpy(&item->value, name, item->len);
4008         list_add_tail(&item->list, &fmsg->item_list);
4009
4010         return 0;
4011 }
4012
4013 int devlink_fmsg_pair_nest_start(struct devlink_fmsg *fmsg, const char *name)
4014 {
4015         int err;
4016
4017         err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_PAIR_NEST_START);
4018         if (err)
4019                 return err;
4020
4021         err = devlink_fmsg_put_name(fmsg, name);
4022         if (err)
4023                 return err;
4024
4025         return 0;
4026 }
4027 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_start);
4028
4029 int devlink_fmsg_pair_nest_end(struct devlink_fmsg *fmsg)
4030 {
4031         return devlink_fmsg_nest_end(fmsg);
4032 }
4033 EXPORT_SYMBOL_GPL(devlink_fmsg_pair_nest_end);
4034
4035 int devlink_fmsg_arr_pair_nest_start(struct devlink_fmsg *fmsg,
4036                                      const char *name)
4037 {
4038         int err;
4039
4040         err = devlink_fmsg_pair_nest_start(fmsg, name);
4041         if (err)
4042                 return err;
4043
4044         err = devlink_fmsg_nest_common(fmsg, DEVLINK_ATTR_FMSG_ARR_NEST_START);
4045         if (err)
4046                 return err;
4047
4048         return 0;
4049 }
4050 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_start);
4051
4052 int devlink_fmsg_arr_pair_nest_end(struct devlink_fmsg *fmsg)
4053 {
4054         int err;
4055
4056         err = devlink_fmsg_nest_end(fmsg);
4057         if (err)
4058                 return err;
4059
4060         err = devlink_fmsg_nest_end(fmsg);
4061         if (err)
4062                 return err;
4063
4064         return 0;
4065 }
4066 EXPORT_SYMBOL_GPL(devlink_fmsg_arr_pair_nest_end);
4067
4068 static int devlink_fmsg_put_value(struct devlink_fmsg *fmsg,
4069                                   const void *value, u16 value_len,
4070                                   u8 value_nla_type)
4071 {
4072         struct devlink_fmsg_item *item;
4073
4074         if (value_len > DEVLINK_FMSG_MAX_SIZE)
4075                 return -EMSGSIZE;
4076
4077         item = kzalloc(sizeof(*item) + value_len, GFP_KERNEL);
4078         if (!item)
4079                 return -ENOMEM;
4080
4081         item->nla_type = value_nla_type;
4082         item->len = value_len;
4083         item->attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4084         memcpy(&item->value, value, item->len);
4085         list_add_tail(&item->list, &fmsg->item_list);
4086
4087         return 0;
4088 }
4089
4090 int devlink_fmsg_bool_put(struct devlink_fmsg *fmsg, bool value)
4091 {
4092         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_FLAG);
4093 }
4094 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_put);
4095
4096 int devlink_fmsg_u8_put(struct devlink_fmsg *fmsg, u8 value)
4097 {
4098         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U8);
4099 }
4100 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_put);
4101
4102 int devlink_fmsg_u32_put(struct devlink_fmsg *fmsg, u32 value)
4103 {
4104         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U32);
4105 }
4106 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_put);
4107
4108 int devlink_fmsg_u64_put(struct devlink_fmsg *fmsg, u64 value)
4109 {
4110         return devlink_fmsg_put_value(fmsg, &value, sizeof(value), NLA_U64);
4111 }
4112 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_put);
4113
4114 int devlink_fmsg_string_put(struct devlink_fmsg *fmsg, const char *value)
4115 {
4116         return devlink_fmsg_put_value(fmsg, value, strlen(value) + 1,
4117                                       NLA_NUL_STRING);
4118 }
4119 EXPORT_SYMBOL_GPL(devlink_fmsg_string_put);
4120
4121 int devlink_fmsg_binary_put(struct devlink_fmsg *fmsg, const void *value,
4122                             u16 value_len)
4123 {
4124         return devlink_fmsg_put_value(fmsg, value, value_len, NLA_BINARY);
4125 }
4126 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_put);
4127
4128 int devlink_fmsg_bool_pair_put(struct devlink_fmsg *fmsg, const char *name,
4129                                bool value)
4130 {
4131         int err;
4132
4133         err = devlink_fmsg_pair_nest_start(fmsg, name);
4134         if (err)
4135                 return err;
4136
4137         err = devlink_fmsg_bool_put(fmsg, value);
4138         if (err)
4139                 return err;
4140
4141         err = devlink_fmsg_pair_nest_end(fmsg);
4142         if (err)
4143                 return err;
4144
4145         return 0;
4146 }
4147 EXPORT_SYMBOL_GPL(devlink_fmsg_bool_pair_put);
4148
4149 int devlink_fmsg_u8_pair_put(struct devlink_fmsg *fmsg, const char *name,
4150                              u8 value)
4151 {
4152         int err;
4153
4154         err = devlink_fmsg_pair_nest_start(fmsg, name);
4155         if (err)
4156                 return err;
4157
4158         err = devlink_fmsg_u8_put(fmsg, value);
4159         if (err)
4160                 return err;
4161
4162         err = devlink_fmsg_pair_nest_end(fmsg);
4163         if (err)
4164                 return err;
4165
4166         return 0;
4167 }
4168 EXPORT_SYMBOL_GPL(devlink_fmsg_u8_pair_put);
4169
4170 int devlink_fmsg_u32_pair_put(struct devlink_fmsg *fmsg, const char *name,
4171                               u32 value)
4172 {
4173         int err;
4174
4175         err = devlink_fmsg_pair_nest_start(fmsg, name);
4176         if (err)
4177                 return err;
4178
4179         err = devlink_fmsg_u32_put(fmsg, value);
4180         if (err)
4181                 return err;
4182
4183         err = devlink_fmsg_pair_nest_end(fmsg);
4184         if (err)
4185                 return err;
4186
4187         return 0;
4188 }
4189 EXPORT_SYMBOL_GPL(devlink_fmsg_u32_pair_put);
4190
4191 int devlink_fmsg_u64_pair_put(struct devlink_fmsg *fmsg, const char *name,
4192                               u64 value)
4193 {
4194         int err;
4195
4196         err = devlink_fmsg_pair_nest_start(fmsg, name);
4197         if (err)
4198                 return err;
4199
4200         err = devlink_fmsg_u64_put(fmsg, value);
4201         if (err)
4202                 return err;
4203
4204         err = devlink_fmsg_pair_nest_end(fmsg);
4205         if (err)
4206                 return err;
4207
4208         return 0;
4209 }
4210 EXPORT_SYMBOL_GPL(devlink_fmsg_u64_pair_put);
4211
4212 int devlink_fmsg_string_pair_put(struct devlink_fmsg *fmsg, const char *name,
4213                                  const char *value)
4214 {
4215         int err;
4216
4217         err = devlink_fmsg_pair_nest_start(fmsg, name);
4218         if (err)
4219                 return err;
4220
4221         err = devlink_fmsg_string_put(fmsg, value);
4222         if (err)
4223                 return err;
4224
4225         err = devlink_fmsg_pair_nest_end(fmsg);
4226         if (err)
4227                 return err;
4228
4229         return 0;
4230 }
4231 EXPORT_SYMBOL_GPL(devlink_fmsg_string_pair_put);
4232
4233 int devlink_fmsg_binary_pair_put(struct devlink_fmsg *fmsg, const char *name,
4234                                  const void *value, u16 value_len)
4235 {
4236         int err;
4237
4238         err = devlink_fmsg_pair_nest_start(fmsg, name);
4239         if (err)
4240                 return err;
4241
4242         err = devlink_fmsg_binary_put(fmsg, value, value_len);
4243         if (err)
4244                 return err;
4245
4246         err = devlink_fmsg_pair_nest_end(fmsg);
4247         if (err)
4248                 return err;
4249
4250         return 0;
4251 }
4252 EXPORT_SYMBOL_GPL(devlink_fmsg_binary_pair_put);
4253
4254 static int
4255 devlink_fmsg_item_fill_type(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4256 {
4257         switch (msg->nla_type) {
4258         case NLA_FLAG:
4259         case NLA_U8:
4260         case NLA_U32:
4261         case NLA_U64:
4262         case NLA_NUL_STRING:
4263         case NLA_BINARY:
4264                 return nla_put_u8(skb, DEVLINK_ATTR_FMSG_OBJ_VALUE_TYPE,
4265                                   msg->nla_type);
4266         default:
4267                 return -EINVAL;
4268         }
4269 }
4270
4271 static int
4272 devlink_fmsg_item_fill_data(struct devlink_fmsg_item *msg, struct sk_buff *skb)
4273 {
4274         int attrtype = DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA;
4275         u8 tmp;
4276
4277         switch (msg->nla_type) {
4278         case NLA_FLAG:
4279                 /* Always provide flag data, regardless of its value */
4280                 tmp = *(bool *) msg->value;
4281
4282                 return nla_put_u8(skb, attrtype, tmp);
4283         case NLA_U8:
4284                 return nla_put_u8(skb, attrtype, *(u8 *) msg->value);
4285         case NLA_U32:
4286                 return nla_put_u32(skb, attrtype, *(u32 *) msg->value);
4287         case NLA_U64:
4288                 return nla_put_u64_64bit(skb, attrtype, *(u64 *) msg->value,
4289                                          DEVLINK_ATTR_PAD);
4290         case NLA_NUL_STRING:
4291                 return nla_put_string(skb, attrtype, (char *) &msg->value);
4292         case NLA_BINARY:
4293                 return nla_put(skb, attrtype, msg->len, (void *) &msg->value);
4294         default:
4295                 return -EINVAL;
4296         }
4297 }
4298
4299 static int
4300 devlink_fmsg_prepare_skb(struct devlink_fmsg *fmsg, struct sk_buff *skb,
4301                          int *start)
4302 {
4303         struct devlink_fmsg_item *item;
4304         struct nlattr *fmsg_nlattr;
4305         int i = 0;
4306         int err;
4307
4308         fmsg_nlattr = nla_nest_start(skb, DEVLINK_ATTR_FMSG);
4309         if (!fmsg_nlattr)
4310                 return -EMSGSIZE;
4311
4312         list_for_each_entry(item, &fmsg->item_list, list) {
4313                 if (i < *start) {
4314                         i++;
4315                         continue;
4316                 }
4317
4318                 switch (item->attrtype) {
4319                 case DEVLINK_ATTR_FMSG_OBJ_NEST_START:
4320                 case DEVLINK_ATTR_FMSG_PAIR_NEST_START:
4321                 case DEVLINK_ATTR_FMSG_ARR_NEST_START:
4322                 case DEVLINK_ATTR_FMSG_NEST_END:
4323                         err = nla_put_flag(skb, item->attrtype);
4324                         break;
4325                 case DEVLINK_ATTR_FMSG_OBJ_VALUE_DATA:
4326                         err = devlink_fmsg_item_fill_type(item, skb);
4327                         if (err)
4328                                 break;
4329                         err = devlink_fmsg_item_fill_data(item, skb);
4330                         break;
4331                 case DEVLINK_ATTR_FMSG_OBJ_NAME:
4332                         err = nla_put_string(skb, item->attrtype,
4333                                              (char *) &item->value);
4334                         break;
4335                 default:
4336                         err = -EINVAL;
4337                         break;
4338                 }
4339                 if (!err)
4340                         *start = ++i;
4341                 else
4342                         break;
4343         }
4344
4345         nla_nest_end(skb, fmsg_nlattr);
4346         return err;
4347 }
4348
4349 static int devlink_fmsg_snd(struct devlink_fmsg *fmsg,
4350                             struct genl_info *info,
4351                             enum devlink_command cmd, int flags)
4352 {
4353         struct nlmsghdr *nlh;
4354         struct sk_buff *skb;
4355         bool last = false;
4356         int index = 0;
4357         void *hdr;
4358         int err;
4359
4360         while (!last) {
4361                 int tmp_index = index;
4362
4363                 skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4364                 if (!skb)
4365                         return -ENOMEM;
4366
4367                 hdr = genlmsg_put(skb, info->snd_portid, info->snd_seq,
4368                                   &devlink_nl_family, flags | NLM_F_MULTI, cmd);
4369                 if (!hdr) {
4370                         err = -EMSGSIZE;
4371                         goto nla_put_failure;
4372                 }
4373
4374                 err = devlink_fmsg_prepare_skb(fmsg, skb, &index);
4375                 if (!err)
4376                         last = true;
4377                 else if (err != -EMSGSIZE || tmp_index == index)
4378                         goto nla_put_failure;
4379
4380                 genlmsg_end(skb, hdr);
4381                 err = genlmsg_reply(skb, info);
4382                 if (err)
4383                         return err;
4384         }
4385
4386         skb = genlmsg_new(GENLMSG_DEFAULT_SIZE, GFP_KERNEL);
4387         if (!skb)
4388                 return -ENOMEM;
4389         nlh = nlmsg_put(skb, info->snd_portid, info->snd_seq,
4390                         NLMSG_DONE, 0, flags | NLM_F_MULTI);
4391         if (!nlh) {
4392                 err = -EMSGSIZE;
4393                 goto nla_put_failure;
4394         }
4395
4396         return genlmsg_reply(skb, info);
4397
4398 nla_put_failure:
4399         nlmsg_free(skb);
4400         return err;
4401 }
4402
4403 struct devlink_health_reporter {
4404         struct list_head list;
4405         void *priv;
4406         const struct devlink_health_reporter_ops *ops;
4407         struct devlink *devlink;
4408         struct devlink_fmsg *dump_fmsg;
4409         struct mutex dump_lock; /* lock parallel read/write from dump buffers */
4410         u64 graceful_period;
4411         bool auto_recover;
4412         u8 health_state;
4413         u64 dump_ts;
4414         u64 error_count;
4415         u64 recovery_count;
4416         u64 last_recovery_ts;
4417 };
4418
4419 enum devlink_health_reporter_state {
4420         DEVLINK_HEALTH_REPORTER_STATE_HEALTHY,
4421         DEVLINK_HEALTH_REPORTER_STATE_ERROR,
4422 };
4423
4424 void *
4425 devlink_health_reporter_priv(struct devlink_health_reporter *reporter)
4426 {
4427         return reporter->priv;
4428 }
4429 EXPORT_SYMBOL_GPL(devlink_health_reporter_priv);
4430
4431 static struct devlink_health_reporter *
4432 devlink_health_reporter_find_by_name(struct devlink *devlink,
4433                                      const char *reporter_name)
4434 {
4435         struct devlink_health_reporter *reporter;
4436
4437         list_for_each_entry(reporter, &devlink->reporter_list, list)
4438                 if (!strcmp(reporter->ops->name, reporter_name))
4439                         return reporter;
4440         return NULL;
4441 }
4442
4443 /**
4444  *      devlink_health_reporter_create - create devlink health reporter
4445  *
4446  *      @devlink: devlink
4447  *      @ops: ops
4448  *      @graceful_period: to avoid recovery loops, in msecs
4449  *      @auto_recover: auto recover when error occurs
4450  *      @priv: priv
4451  */
4452 struct devlink_health_reporter *
4453 devlink_health_reporter_create(struct devlink *devlink,
4454                                const struct devlink_health_reporter_ops *ops,
4455                                u64 graceful_period, bool auto_recover,
4456                                void *priv)
4457 {
4458         struct devlink_health_reporter *reporter;
4459
4460         mutex_lock(&devlink->lock);
4461         if (devlink_health_reporter_find_by_name(devlink, ops->name)) {
4462                 reporter = ERR_PTR(-EEXIST);
4463                 goto unlock;
4464         }
4465
4466         if (WARN_ON(auto_recover && !ops->recover) ||
4467             WARN_ON(graceful_period && !ops->recover)) {
4468                 reporter = ERR_PTR(-EINVAL);
4469                 goto unlock;
4470         }
4471
4472         reporter = kzalloc(sizeof(*reporter), GFP_KERNEL);
4473         if (!reporter) {
4474                 reporter = ERR_PTR(-ENOMEM);
4475                 goto unlock;
4476         }
4477
4478         reporter->priv = priv;
4479         reporter->ops = ops;
4480         reporter->devlink = devlink;
4481         reporter->graceful_period = graceful_period;
4482         reporter->auto_recover = auto_recover;
4483         mutex_init(&reporter->dump_lock);
4484         list_add_tail(&reporter->list, &devlink->reporter_list);
4485 unlock:
4486         mutex_unlock(&devlink->lock);
4487         return reporter;
4488 }
4489 EXPORT_SYMBOL_GPL(devlink_health_reporter_create);
4490
4491 /**
4492  *      devlink_health_reporter_destroy - destroy devlink health reporter
4493  *
4494  *      @reporter: devlink health reporter to destroy
4495  */
4496 void
4497 devlink_health_reporter_destroy(struct devlink_health_reporter *reporter)
4498 {
4499         mutex_lock(&reporter->devlink->lock);
4500         list_del(&reporter->list);
4501         mutex_unlock(&reporter->devlink->lock);
4502         if (reporter->dump_fmsg)
4503                 devlink_fmsg_free(reporter->dump_fmsg);
4504         kfree(reporter);
4505 }
4506 EXPORT_SYMBOL_GPL(devlink_health_reporter_destroy);
4507
4508 static int
4509 devlink_health_reporter_recover(struct devlink_health_reporter *reporter,
4510                                 void *priv_ctx)
4511 {
4512         int err;
4513
4514         if (!reporter->ops->recover)
4515                 return -EOPNOTSUPP;
4516
4517         err = reporter->ops->recover(reporter, priv_ctx);
4518         if (err)
4519                 return err;
4520
4521         reporter->recovery_count++;
4522         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_HEALTHY;
4523         reporter->last_recovery_ts = jiffies;
4524
4525         return 0;
4526 }
4527
4528 static void
4529 devlink_health_dump_clear(struct devlink_health_reporter *reporter)
4530 {
4531         if (!reporter->dump_fmsg)
4532                 return;
4533         devlink_fmsg_free(reporter->dump_fmsg);
4534         reporter->dump_fmsg = NULL;
4535 }
4536
4537 static int devlink_health_do_dump(struct devlink_health_reporter *reporter,
4538                                   void *priv_ctx)
4539 {
4540         int err;
4541
4542         if (!reporter->ops->dump)
4543                 return 0;
4544
4545         if (reporter->dump_fmsg)
4546                 return 0;
4547
4548         reporter->dump_fmsg = devlink_fmsg_alloc();
4549         if (!reporter->dump_fmsg) {
4550                 err = -ENOMEM;
4551                 return err;
4552         }
4553
4554         err = devlink_fmsg_obj_nest_start(reporter->dump_fmsg);
4555         if (err)
4556                 goto dump_err;
4557
4558         err = reporter->ops->dump(reporter, reporter->dump_fmsg,
4559                                   priv_ctx);
4560         if (err)
4561                 goto dump_err;
4562
4563         err = devlink_fmsg_obj_nest_end(reporter->dump_fmsg);
4564         if (err)
4565                 goto dump_err;
4566
4567         reporter->dump_ts = jiffies;
4568
4569         return 0;
4570
4571 dump_err:
4572         devlink_health_dump_clear(reporter);
4573         return err;
4574 }
4575
4576 int devlink_health_report(struct devlink_health_reporter *reporter,
4577                           const char *msg, void *priv_ctx)
4578 {
4579         struct devlink *devlink = reporter->devlink;
4580
4581         /* write a log message of the current error */
4582         WARN_ON(!msg);
4583         trace_devlink_health_report(devlink, reporter->ops->name, msg);
4584         reporter->error_count++;
4585
4586         /* abort if the previous error wasn't recovered */
4587         if (reporter->auto_recover &&
4588             (reporter->health_state != DEVLINK_HEALTH_REPORTER_STATE_HEALTHY ||
4589              jiffies - reporter->last_recovery_ts <
4590              msecs_to_jiffies(reporter->graceful_period))) {
4591                 trace_devlink_health_recover_aborted(devlink,
4592                                                      reporter->ops->name,
4593                                                      reporter->health_state,
4594                                                      jiffies -
4595                                                      reporter->last_recovery_ts);
4596                 return -ECANCELED;
4597         }
4598
4599         reporter->health_state = DEVLINK_HEALTH_REPORTER_STATE_ERROR;
4600
4601         mutex_lock(&reporter->dump_lock);
4602         /* store current dump of current error, for later analysis */
4603         devlink_health_do_dump(reporter, priv_ctx);
4604         mutex_unlock(&reporter->dump_lock);
4605
4606         if (reporter->auto_recover)
4607                 return devlink_health_reporter_recover(reporter, priv_ctx);
4608
4609         return 0;
4610 }
4611 EXPORT_SYMBOL_GPL(devlink_health_report);
4612
4613 static struct devlink_health_reporter *
4614 devlink_health_reporter_get_from_info(struct devlink *devlink,
4615                                       struct genl_info *info)
4616 {
4617         char *reporter_name;
4618
4619         if (!info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME])
4620                 return NULL;
4621
4622         reporter_name =
4623                 nla_data(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_NAME]);
4624         return devlink_health_reporter_find_by_name(devlink, reporter_name);
4625 }
4626
4627 static int
4628 devlink_nl_health_reporter_fill(struct sk_buff *msg,
4629                                 struct devlink *devlink,
4630                                 struct devlink_health_reporter *reporter,
4631                                 enum devlink_command cmd, u32 portid,
4632                                 u32 seq, int flags)
4633 {
4634         struct nlattr *reporter_attr;
4635         void *hdr;
4636
4637         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
4638         if (!hdr)
4639                 return -EMSGSIZE;
4640
4641         if (devlink_nl_put_handle(msg, devlink))
4642                 goto genlmsg_cancel;
4643
4644         reporter_attr = nla_nest_start(msg, DEVLINK_ATTR_HEALTH_REPORTER);
4645         if (!reporter_attr)
4646                 goto genlmsg_cancel;
4647         if (nla_put_string(msg, DEVLINK_ATTR_HEALTH_REPORTER_NAME,
4648                            reporter->ops->name))
4649                 goto reporter_nest_cancel;
4650         if (nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_STATE,
4651                        reporter->health_state))
4652                 goto reporter_nest_cancel;
4653         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_ERR_COUNT,
4654                               reporter->error_count, DEVLINK_ATTR_PAD))
4655                 goto reporter_nest_cancel;
4656         if (nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_RECOVER_COUNT,
4657                               reporter->recovery_count, DEVLINK_ATTR_PAD))
4658                 goto reporter_nest_cancel;
4659         if (reporter->ops->recover &&
4660             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD,
4661                               reporter->graceful_period,
4662                               DEVLINK_ATTR_PAD))
4663                 goto reporter_nest_cancel;
4664         if (reporter->ops->recover &&
4665             nla_put_u8(msg, DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER,
4666                        reporter->auto_recover))
4667                 goto reporter_nest_cancel;
4668         if (reporter->dump_fmsg &&
4669             nla_put_u64_64bit(msg, DEVLINK_ATTR_HEALTH_REPORTER_DUMP_TS,
4670                               jiffies_to_msecs(reporter->dump_ts),
4671                               DEVLINK_ATTR_PAD))
4672                 goto reporter_nest_cancel;
4673
4674         nla_nest_end(msg, reporter_attr);
4675         genlmsg_end(msg, hdr);
4676         return 0;
4677
4678 reporter_nest_cancel:
4679         nla_nest_end(msg, reporter_attr);
4680 genlmsg_cancel:
4681         genlmsg_cancel(msg, hdr);
4682         return -EMSGSIZE;
4683 }
4684
4685 static int devlink_nl_cmd_health_reporter_get_doit(struct sk_buff *skb,
4686                                                    struct genl_info *info)
4687 {
4688         struct devlink *devlink = info->user_ptr[0];
4689         struct devlink_health_reporter *reporter;
4690         struct sk_buff *msg;
4691         int err;
4692
4693         reporter = devlink_health_reporter_get_from_info(devlink, info);
4694         if (!reporter)
4695                 return -EINVAL;
4696
4697         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
4698         if (!msg)
4699                 return -ENOMEM;
4700
4701         err = devlink_nl_health_reporter_fill(msg, devlink, reporter,
4702                                               DEVLINK_CMD_HEALTH_REPORTER_GET,
4703                                               info->snd_portid, info->snd_seq,
4704                                               0);
4705         if (err) {
4706                 nlmsg_free(msg);
4707                 return err;
4708         }
4709
4710         return genlmsg_reply(msg, info);
4711 }
4712
4713 static int
4714 devlink_nl_cmd_health_reporter_get_dumpit(struct sk_buff *msg,
4715                                           struct netlink_callback *cb)
4716 {
4717         struct devlink_health_reporter *reporter;
4718         struct devlink *devlink;
4719         int start = cb->args[0];
4720         int idx = 0;
4721         int err;
4722
4723         mutex_lock(&devlink_mutex);
4724         list_for_each_entry(devlink, &devlink_list, list) {
4725                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
4726                         continue;
4727                 mutex_lock(&devlink->lock);
4728                 list_for_each_entry(reporter, &devlink->reporter_list,
4729                                     list) {
4730                         if (idx < start) {
4731                                 idx++;
4732                                 continue;
4733                         }
4734                         err = devlink_nl_health_reporter_fill(msg, devlink,
4735                                                               reporter,
4736                                                               DEVLINK_CMD_HEALTH_REPORTER_GET,
4737                                                               NETLINK_CB(cb->skb).portid,
4738                                                               cb->nlh->nlmsg_seq,
4739                                                               NLM_F_MULTI);
4740                         if (err) {
4741                                 mutex_unlock(&devlink->lock);
4742                                 goto out;
4743                         }
4744                         idx++;
4745                 }
4746                 mutex_unlock(&devlink->lock);
4747         }
4748 out:
4749         mutex_unlock(&devlink_mutex);
4750
4751         cb->args[0] = idx;
4752         return msg->len;
4753 }
4754
4755 static int
4756 devlink_nl_cmd_health_reporter_set_doit(struct sk_buff *skb,
4757                                         struct genl_info *info)
4758 {
4759         struct devlink *devlink = info->user_ptr[0];
4760         struct devlink_health_reporter *reporter;
4761
4762         reporter = devlink_health_reporter_get_from_info(devlink, info);
4763         if (!reporter)
4764                 return -EINVAL;
4765
4766         if (!reporter->ops->recover &&
4767             (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] ||
4768              info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]))
4769                 return -EOPNOTSUPP;
4770
4771         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD])
4772                 reporter->graceful_period =
4773                         nla_get_u64(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD]);
4774
4775         if (info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER])
4776                 reporter->auto_recover =
4777                         nla_get_u8(info->attrs[DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER]);
4778
4779         return 0;
4780 }
4781
4782 static int devlink_nl_cmd_health_reporter_recover_doit(struct sk_buff *skb,
4783                                                        struct genl_info *info)
4784 {
4785         struct devlink *devlink = info->user_ptr[0];
4786         struct devlink_health_reporter *reporter;
4787
4788         reporter = devlink_health_reporter_get_from_info(devlink, info);
4789         if (!reporter)
4790                 return -EINVAL;
4791
4792         return devlink_health_reporter_recover(reporter, NULL);
4793 }
4794
4795 static int devlink_nl_cmd_health_reporter_diagnose_doit(struct sk_buff *skb,
4796                                                         struct genl_info *info)
4797 {
4798         struct devlink *devlink = info->user_ptr[0];
4799         struct devlink_health_reporter *reporter;
4800         struct devlink_fmsg *fmsg;
4801         int err;
4802
4803         reporter = devlink_health_reporter_get_from_info(devlink, info);
4804         if (!reporter)
4805                 return -EINVAL;
4806
4807         if (!reporter->ops->diagnose)
4808                 return -EOPNOTSUPP;
4809
4810         fmsg = devlink_fmsg_alloc();
4811         if (!fmsg)
4812                 return -ENOMEM;
4813
4814         err = devlink_fmsg_obj_nest_start(fmsg);
4815         if (err)
4816                 goto out;
4817
4818         err = reporter->ops->diagnose(reporter, fmsg);
4819         if (err)
4820                 goto out;
4821
4822         err = devlink_fmsg_obj_nest_end(fmsg);
4823         if (err)
4824                 goto out;
4825
4826         err = devlink_fmsg_snd(fmsg, info,
4827                                DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE, 0);
4828
4829 out:
4830         devlink_fmsg_free(fmsg);
4831         return err;
4832 }
4833
4834 static int devlink_nl_cmd_health_reporter_dump_get_doit(struct sk_buff *skb,
4835                                                         struct genl_info *info)
4836 {
4837         struct devlink *devlink = info->user_ptr[0];
4838         struct devlink_health_reporter *reporter;
4839         int err;
4840
4841         reporter = devlink_health_reporter_get_from_info(devlink, info);
4842         if (!reporter)
4843                 return -EINVAL;
4844
4845         if (!reporter->ops->dump)
4846                 return -EOPNOTSUPP;
4847
4848         mutex_lock(&reporter->dump_lock);
4849         err = devlink_health_do_dump(reporter, NULL);
4850         if (err)
4851                 goto out;
4852
4853         err = devlink_fmsg_snd(reporter->dump_fmsg, info,
4854                                DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET, 0);
4855
4856 out:
4857         mutex_unlock(&reporter->dump_lock);
4858         return err;
4859 }
4860
4861 static int
4862 devlink_nl_cmd_health_reporter_dump_clear_doit(struct sk_buff *skb,
4863                                                struct genl_info *info)
4864 {
4865         struct devlink *devlink = info->user_ptr[0];
4866         struct devlink_health_reporter *reporter;
4867
4868         reporter = devlink_health_reporter_get_from_info(devlink, info);
4869         if (!reporter)
4870                 return -EINVAL;
4871
4872         if (!reporter->ops->dump)
4873                 return -EOPNOTSUPP;
4874
4875         mutex_lock(&reporter->dump_lock);
4876         devlink_health_dump_clear(reporter);
4877         mutex_unlock(&reporter->dump_lock);
4878         return 0;
4879 }
4880
4881 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
4882         [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
4883         [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
4884         [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
4885         [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
4886         [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
4887         [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
4888         [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
4889         [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
4890         [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
4891         [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
4892         [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
4893         [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
4894         [DEVLINK_ATTR_ESWITCH_MODE] = { .type = NLA_U16 },
4895         [DEVLINK_ATTR_ESWITCH_INLINE_MODE] = { .type = NLA_U8 },
4896         [DEVLINK_ATTR_ESWITCH_ENCAP_MODE] = { .type = NLA_U8 },
4897         [DEVLINK_ATTR_DPIPE_TABLE_NAME] = { .type = NLA_NUL_STRING },
4898         [DEVLINK_ATTR_DPIPE_TABLE_COUNTERS_ENABLED] = { .type = NLA_U8 },
4899         [DEVLINK_ATTR_RESOURCE_ID] = { .type = NLA_U64},
4900         [DEVLINK_ATTR_RESOURCE_SIZE] = { .type = NLA_U64},
4901         [DEVLINK_ATTR_PARAM_NAME] = { .type = NLA_NUL_STRING },
4902         [DEVLINK_ATTR_PARAM_TYPE] = { .type = NLA_U8 },
4903         [DEVLINK_ATTR_PARAM_VALUE_CMODE] = { .type = NLA_U8 },
4904         [DEVLINK_ATTR_REGION_NAME] = { .type = NLA_NUL_STRING },
4905         [DEVLINK_ATTR_REGION_SNAPSHOT_ID] = { .type = NLA_U32 },
4906         [DEVLINK_ATTR_HEALTH_REPORTER_NAME] = { .type = NLA_NUL_STRING },
4907         [DEVLINK_ATTR_HEALTH_REPORTER_GRACEFUL_PERIOD] = { .type = NLA_U64 },
4908         [DEVLINK_ATTR_HEALTH_REPORTER_AUTO_RECOVER] = { .type = NLA_U8 },
4909         [DEVLINK_ATTR_FLASH_UPDATE_FILE_NAME] = { .type = NLA_NUL_STRING },
4910         [DEVLINK_ATTR_FLASH_UPDATE_COMPONENT] = { .type = NLA_NUL_STRING },
4911 };
4912
4913 static const struct genl_ops devlink_nl_ops[] = {
4914         {
4915                 .cmd = DEVLINK_CMD_GET,
4916                 .doit = devlink_nl_cmd_get_doit,
4917                 .dumpit = devlink_nl_cmd_get_dumpit,
4918                 .policy = devlink_nl_policy,
4919                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
4920                 /* can be retrieved by unprivileged users */
4921         },
4922         {
4923                 .cmd = DEVLINK_CMD_PORT_GET,
4924                 .doit = devlink_nl_cmd_port_get_doit,
4925                 .dumpit = devlink_nl_cmd_port_get_dumpit,
4926                 .policy = devlink_nl_policy,
4927                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
4928                 /* can be retrieved by unprivileged users */
4929         },
4930         {
4931                 .cmd = DEVLINK_CMD_PORT_SET,
4932                 .doit = devlink_nl_cmd_port_set_doit,
4933                 .policy = devlink_nl_policy,
4934                 .flags = GENL_ADMIN_PERM,
4935                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
4936         },
4937         {
4938                 .cmd = DEVLINK_CMD_PORT_SPLIT,
4939                 .doit = devlink_nl_cmd_port_split_doit,
4940                 .policy = devlink_nl_policy,
4941                 .flags = GENL_ADMIN_PERM,
4942                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
4943                                   DEVLINK_NL_FLAG_NO_LOCK,
4944         },
4945         {
4946                 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
4947                 .doit = devlink_nl_cmd_port_unsplit_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_SB_GET,
4955                 .doit = devlink_nl_cmd_sb_get_doit,
4956                 .dumpit = devlink_nl_cmd_sb_get_dumpit,
4957                 .policy = devlink_nl_policy,
4958                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
4959                                   DEVLINK_NL_FLAG_NEED_SB,
4960                 /* can be retrieved by unprivileged users */
4961         },
4962         {
4963                 .cmd = DEVLINK_CMD_SB_POOL_GET,
4964                 .doit = devlink_nl_cmd_sb_pool_get_doit,
4965                 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
4966                 .policy = devlink_nl_policy,
4967                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
4968                                   DEVLINK_NL_FLAG_NEED_SB,
4969                 /* can be retrieved by unprivileged users */
4970         },
4971         {
4972                 .cmd = DEVLINK_CMD_SB_POOL_SET,
4973                 .doit = devlink_nl_cmd_sb_pool_set_doit,
4974                 .policy = devlink_nl_policy,
4975                 .flags = GENL_ADMIN_PERM,
4976                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
4977                                   DEVLINK_NL_FLAG_NEED_SB,
4978         },
4979         {
4980                 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
4981                 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
4982                 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
4983                 .policy = devlink_nl_policy,
4984                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
4985                                   DEVLINK_NL_FLAG_NEED_SB,
4986                 /* can be retrieved by unprivileged users */
4987         },
4988         {
4989                 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
4990                 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
4991                 .policy = devlink_nl_policy,
4992                 .flags = GENL_ADMIN_PERM,
4993                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
4994                                   DEVLINK_NL_FLAG_NEED_SB,
4995         },
4996         {
4997                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
4998                 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
4999                 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
5000                 .policy = devlink_nl_policy,
5001                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5002                                   DEVLINK_NL_FLAG_NEED_SB,
5003                 /* can be retrieved by unprivileged users */
5004         },
5005         {
5006                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
5007                 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
5008                 .policy = devlink_nl_policy,
5009                 .flags = GENL_ADMIN_PERM,
5010                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
5011                                   DEVLINK_NL_FLAG_NEED_SB,
5012         },
5013         {
5014                 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
5015                 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
5016                 .policy = devlink_nl_policy,
5017                 .flags = GENL_ADMIN_PERM,
5018                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5019                                   DEVLINK_NL_FLAG_NEED_SB,
5020         },
5021         {
5022                 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
5023                 .doit = devlink_nl_cmd_sb_occ_max_clear_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_ESWITCH_GET,
5031                 .doit = devlink_nl_cmd_eswitch_get_doit,
5032                 .policy = devlink_nl_policy,
5033                 .flags = GENL_ADMIN_PERM,
5034                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5035         },
5036         {
5037                 .cmd = DEVLINK_CMD_ESWITCH_SET,
5038                 .doit = devlink_nl_cmd_eswitch_set_doit,
5039                 .policy = devlink_nl_policy,
5040                 .flags = GENL_ADMIN_PERM,
5041                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5042                                   DEVLINK_NL_FLAG_NO_LOCK,
5043         },
5044         {
5045                 .cmd = DEVLINK_CMD_DPIPE_TABLE_GET,
5046                 .doit = devlink_nl_cmd_dpipe_table_get,
5047                 .policy = devlink_nl_policy,
5048                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5049                 /* can be retrieved by unprivileged users */
5050         },
5051         {
5052                 .cmd = DEVLINK_CMD_DPIPE_ENTRIES_GET,
5053                 .doit = devlink_nl_cmd_dpipe_entries_get,
5054                 .policy = devlink_nl_policy,
5055                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5056                 /* can be retrieved by unprivileged users */
5057         },
5058         {
5059                 .cmd = DEVLINK_CMD_DPIPE_HEADERS_GET,
5060                 .doit = devlink_nl_cmd_dpipe_headers_get,
5061                 .policy = devlink_nl_policy,
5062                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5063                 /* can be retrieved by unprivileged users */
5064         },
5065         {
5066                 .cmd = DEVLINK_CMD_DPIPE_TABLE_COUNTERS_SET,
5067                 .doit = devlink_nl_cmd_dpipe_table_counters_set,
5068                 .policy = devlink_nl_policy,
5069                 .flags = GENL_ADMIN_PERM,
5070                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5071         },
5072         {
5073                 .cmd = DEVLINK_CMD_RESOURCE_SET,
5074                 .doit = devlink_nl_cmd_resource_set,
5075                 .policy = devlink_nl_policy,
5076                 .flags = GENL_ADMIN_PERM,
5077                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5078         },
5079         {
5080                 .cmd = DEVLINK_CMD_RESOURCE_DUMP,
5081                 .doit = devlink_nl_cmd_resource_dump,
5082                 .policy = devlink_nl_policy,
5083                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5084                 /* can be retrieved by unprivileged users */
5085         },
5086         {
5087                 .cmd = DEVLINK_CMD_RELOAD,
5088                 .doit = devlink_nl_cmd_reload,
5089                 .policy = devlink_nl_policy,
5090                 .flags = GENL_ADMIN_PERM,
5091                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5092                                   DEVLINK_NL_FLAG_NO_LOCK,
5093         },
5094         {
5095                 .cmd = DEVLINK_CMD_PARAM_GET,
5096                 .doit = devlink_nl_cmd_param_get_doit,
5097                 .dumpit = devlink_nl_cmd_param_get_dumpit,
5098                 .policy = devlink_nl_policy,
5099                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5100                 /* can be retrieved by unprivileged users */
5101         },
5102         {
5103                 .cmd = DEVLINK_CMD_PARAM_SET,
5104                 .doit = devlink_nl_cmd_param_set_doit,
5105                 .policy = devlink_nl_policy,
5106                 .flags = GENL_ADMIN_PERM,
5107                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5108         },
5109         {
5110                 .cmd = DEVLINK_CMD_PORT_PARAM_GET,
5111                 .doit = devlink_nl_cmd_port_param_get_doit,
5112                 .dumpit = devlink_nl_cmd_port_param_get_dumpit,
5113                 .policy = devlink_nl_policy,
5114                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5115                 /* can be retrieved by unprivileged users */
5116         },
5117         {
5118                 .cmd = DEVLINK_CMD_PORT_PARAM_SET,
5119                 .doit = devlink_nl_cmd_port_param_set_doit,
5120                 .policy = devlink_nl_policy,
5121                 .flags = GENL_ADMIN_PERM,
5122                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
5123         },
5124         {
5125                 .cmd = DEVLINK_CMD_REGION_GET,
5126                 .doit = devlink_nl_cmd_region_get_doit,
5127                 .dumpit = devlink_nl_cmd_region_get_dumpit,
5128                 .policy = devlink_nl_policy,
5129                 .flags = GENL_ADMIN_PERM,
5130                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5131         },
5132         {
5133                 .cmd = DEVLINK_CMD_REGION_DEL,
5134                 .doit = devlink_nl_cmd_region_del,
5135                 .policy = devlink_nl_policy,
5136                 .flags = GENL_ADMIN_PERM,
5137                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5138         },
5139         {
5140                 .cmd = DEVLINK_CMD_REGION_READ,
5141                 .dumpit = devlink_nl_cmd_region_read_dumpit,
5142                 .policy = devlink_nl_policy,
5143                 .flags = GENL_ADMIN_PERM,
5144                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5145         },
5146         {
5147                 .cmd = DEVLINK_CMD_INFO_GET,
5148                 .doit = devlink_nl_cmd_info_get_doit,
5149                 .dumpit = devlink_nl_cmd_info_get_dumpit,
5150                 .policy = devlink_nl_policy,
5151                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5152                 /* can be retrieved by unprivileged users */
5153         },
5154         {
5155                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_GET,
5156                 .doit = devlink_nl_cmd_health_reporter_get_doit,
5157                 .dumpit = devlink_nl_cmd_health_reporter_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_SET,
5164                 .doit = devlink_nl_cmd_health_reporter_set_doit,
5165                 .policy = devlink_nl_policy,
5166                 .flags = GENL_ADMIN_PERM,
5167                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5168         },
5169         {
5170                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_RECOVER,
5171                 .doit = devlink_nl_cmd_health_reporter_recover_doit,
5172                 .policy = devlink_nl_policy,
5173                 .flags = GENL_ADMIN_PERM,
5174                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5175         },
5176         {
5177                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DIAGNOSE,
5178                 .doit = devlink_nl_cmd_health_reporter_diagnose_doit,
5179                 .policy = devlink_nl_policy,
5180                 .flags = GENL_ADMIN_PERM,
5181                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5182         },
5183         {
5184                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_GET,
5185                 .doit = devlink_nl_cmd_health_reporter_dump_get_doit,
5186                 .policy = devlink_nl_policy,
5187                 .flags = GENL_ADMIN_PERM,
5188                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
5189                                   DEVLINK_NL_FLAG_NO_LOCK,
5190         },
5191         {
5192                 .cmd = DEVLINK_CMD_HEALTH_REPORTER_DUMP_CLEAR,
5193                 .doit = devlink_nl_cmd_health_reporter_dump_clear_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_FLASH_UPDATE,
5201                 .doit = devlink_nl_cmd_flash_update,
5202                 .policy = devlink_nl_policy,
5203                 .flags = GENL_ADMIN_PERM,
5204                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
5205         },
5206 };
5207
5208 static struct genl_family devlink_nl_family __ro_after_init = {
5209         .name           = DEVLINK_GENL_NAME,
5210         .version        = DEVLINK_GENL_VERSION,
5211         .maxattr        = DEVLINK_ATTR_MAX,
5212         .netnsok        = true,
5213         .pre_doit       = devlink_nl_pre_doit,
5214         .post_doit      = devlink_nl_post_doit,
5215         .module         = THIS_MODULE,
5216         .ops            = devlink_nl_ops,
5217         .n_ops          = ARRAY_SIZE(devlink_nl_ops),
5218         .mcgrps         = devlink_nl_mcgrps,
5219         .n_mcgrps       = ARRAY_SIZE(devlink_nl_mcgrps),
5220 };
5221
5222 /**
5223  *      devlink_alloc - Allocate new devlink instance resources
5224  *
5225  *      @ops: ops
5226  *      @priv_size: size of user private data
5227  *
5228  *      Allocate new devlink instance resources, including devlink index
5229  *      and name.
5230  */
5231 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
5232 {
5233         struct devlink *devlink;
5234
5235         devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
5236         if (!devlink)
5237                 return NULL;
5238         devlink->ops = ops;
5239         devlink_net_set(devlink, &init_net);
5240         INIT_LIST_HEAD(&devlink->port_list);
5241         INIT_LIST_HEAD(&devlink->sb_list);
5242         INIT_LIST_HEAD_RCU(&devlink->dpipe_table_list);
5243         INIT_LIST_HEAD(&devlink->resource_list);
5244         INIT_LIST_HEAD(&devlink->param_list);
5245         INIT_LIST_HEAD(&devlink->region_list);
5246         INIT_LIST_HEAD(&devlink->reporter_list);
5247         mutex_init(&devlink->lock);
5248         return devlink;
5249 }
5250 EXPORT_SYMBOL_GPL(devlink_alloc);
5251
5252 /**
5253  *      devlink_register - Register devlink instance
5254  *
5255  *      @devlink: devlink
5256  */
5257 int devlink_register(struct devlink *devlink, struct device *dev)
5258 {
5259         mutex_lock(&devlink_mutex);
5260         devlink->dev = dev;
5261         list_add_tail(&devlink->list, &devlink_list);
5262         devlink_notify(devlink, DEVLINK_CMD_NEW);
5263         mutex_unlock(&devlink_mutex);
5264         return 0;
5265 }
5266 EXPORT_SYMBOL_GPL(devlink_register);
5267
5268 /**
5269  *      devlink_unregister - Unregister devlink instance
5270  *
5271  *      @devlink: devlink
5272  */
5273 void devlink_unregister(struct devlink *devlink)
5274 {
5275         mutex_lock(&devlink_mutex);
5276         devlink_notify(devlink, DEVLINK_CMD_DEL);
5277         list_del(&devlink->list);
5278         mutex_unlock(&devlink_mutex);
5279 }
5280 EXPORT_SYMBOL_GPL(devlink_unregister);
5281
5282 /**
5283  *      devlink_free - Free devlink instance resources
5284  *
5285  *      @devlink: devlink
5286  */
5287 void devlink_free(struct devlink *devlink)
5288 {
5289         WARN_ON(!list_empty(&devlink->reporter_list));
5290         WARN_ON(!list_empty(&devlink->region_list));
5291         WARN_ON(!list_empty(&devlink->param_list));
5292         WARN_ON(!list_empty(&devlink->resource_list));
5293         WARN_ON(!list_empty(&devlink->dpipe_table_list));
5294         WARN_ON(!list_empty(&devlink->sb_list));
5295         WARN_ON(!list_empty(&devlink->port_list));
5296
5297         kfree(devlink);
5298 }
5299 EXPORT_SYMBOL_GPL(devlink_free);
5300
5301 /**
5302  *      devlink_port_register - Register devlink port
5303  *
5304  *      @devlink: devlink
5305  *      @devlink_port: devlink port
5306  *      @port_index
5307  *
5308  *      Register devlink port with provided port index. User can use
5309  *      any indexing, even hw-related one. devlink_port structure
5310  *      is convenient to be embedded inside user driver private structure.
5311  *      Note that the caller should take care of zeroing the devlink_port
5312  *      structure.
5313  */
5314 int devlink_port_register(struct devlink *devlink,
5315                           struct devlink_port *devlink_port,
5316                           unsigned int port_index)
5317 {
5318         mutex_lock(&devlink->lock);
5319         if (devlink_port_index_exists(devlink, port_index)) {
5320                 mutex_unlock(&devlink->lock);
5321                 return -EEXIST;
5322         }
5323         devlink_port->devlink = devlink;
5324         devlink_port->index = port_index;
5325         devlink_port->registered = true;
5326         list_add_tail(&devlink_port->list, &devlink->port_list);
5327         INIT_LIST_HEAD(&devlink_port->param_list);
5328         mutex_unlock(&devlink->lock);
5329         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
5330         return 0;
5331 }
5332 EXPORT_SYMBOL_GPL(devlink_port_register);
5333
5334 /**
5335  *      devlink_port_unregister - Unregister devlink port
5336  *
5337  *      @devlink_port: devlink port
5338  */
5339 void devlink_port_unregister(struct devlink_port *devlink_port)
5340 {
5341         struct devlink *devlink = devlink_port->devlink;
5342
5343         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
5344         mutex_lock(&devlink->lock);
5345         list_del(&devlink_port->list);
5346         mutex_unlock(&devlink->lock);
5347 }
5348 EXPORT_SYMBOL_GPL(devlink_port_unregister);
5349
5350 static void __devlink_port_type_set(struct devlink_port *devlink_port,
5351                                     enum devlink_port_type type,
5352                                     void *type_dev)
5353 {
5354         devlink_port->type = type;
5355         devlink_port->type_dev = type_dev;
5356         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
5357 }
5358
5359 /**
5360  *      devlink_port_type_eth_set - Set port type to Ethernet
5361  *
5362  *      @devlink_port: devlink port
5363  *      @netdev: related netdevice
5364  */
5365 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
5366                                struct net_device *netdev)
5367 {
5368         return __devlink_port_type_set(devlink_port,
5369                                        DEVLINK_PORT_TYPE_ETH, netdev);
5370 }
5371 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
5372
5373 /**
5374  *      devlink_port_type_ib_set - Set port type to InfiniBand
5375  *
5376  *      @devlink_port: devlink port
5377  *      @ibdev: related IB device
5378  */
5379 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
5380                               struct ib_device *ibdev)
5381 {
5382         return __devlink_port_type_set(devlink_port,
5383                                        DEVLINK_PORT_TYPE_IB, ibdev);
5384 }
5385 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
5386
5387 /**
5388  *      devlink_port_type_clear - Clear port type
5389  *
5390  *      @devlink_port: devlink port
5391  */
5392 void devlink_port_type_clear(struct devlink_port *devlink_port)
5393 {
5394         return __devlink_port_type_set(devlink_port,
5395                                        DEVLINK_PORT_TYPE_NOTSET, NULL);
5396 }
5397 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
5398
5399 /**
5400  *      devlink_port_attrs_set - Set port attributes
5401  *
5402  *      @devlink_port: devlink port
5403  *      @flavour: flavour of the port
5404  *      @port_number: number of the port that is facing user, for example
5405  *                    the front panel port number
5406  *      @split: indicates if this is split port
5407  *      @split_subport_number: if the port is split, this is the number
5408  *                             of subport.
5409  */
5410 void devlink_port_attrs_set(struct devlink_port *devlink_port,
5411                             enum devlink_port_flavour flavour,
5412                             u32 port_number, bool split,
5413                             u32 split_subport_number)
5414 {
5415         struct devlink_port_attrs *attrs = &devlink_port->attrs;
5416
5417         attrs->set = true;
5418         attrs->flavour = flavour;
5419         attrs->port_number = port_number;
5420         attrs->split = split;
5421         attrs->split_subport_number = split_subport_number;
5422         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
5423 }
5424 EXPORT_SYMBOL_GPL(devlink_port_attrs_set);
5425
5426 int devlink_port_get_phys_port_name(struct devlink_port *devlink_port,
5427                                     char *name, size_t len)
5428 {
5429         struct devlink_port_attrs *attrs = &devlink_port->attrs;
5430         int n = 0;
5431
5432         if (!attrs->set)
5433                 return -EOPNOTSUPP;
5434
5435         switch (attrs->flavour) {
5436         case DEVLINK_PORT_FLAVOUR_PHYSICAL:
5437                 if (!attrs->split)
5438                         n = snprintf(name, len, "p%u", attrs->port_number);
5439                 else
5440                         n = snprintf(name, len, "p%us%u", attrs->port_number,
5441                                      attrs->split_subport_number);
5442                 break;
5443         case DEVLINK_PORT_FLAVOUR_CPU:
5444         case DEVLINK_PORT_FLAVOUR_DSA:
5445                 /* As CPU and DSA ports do not have a netdevice associated
5446                  * case should not ever happen.
5447                  */
5448                 WARN_ON(1);
5449                 return -EINVAL;
5450         }
5451
5452         if (n >= len)
5453                 return -EINVAL;
5454
5455         return 0;
5456 }
5457 EXPORT_SYMBOL_GPL(devlink_port_get_phys_port_name);
5458
5459 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
5460                         u32 size, u16 ingress_pools_count,
5461                         u16 egress_pools_count, u16 ingress_tc_count,
5462                         u16 egress_tc_count)
5463 {
5464         struct devlink_sb *devlink_sb;
5465         int err = 0;
5466
5467         mutex_lock(&devlink->lock);
5468         if (devlink_sb_index_exists(devlink, sb_index)) {
5469                 err = -EEXIST;
5470                 goto unlock;
5471         }
5472
5473         devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
5474         if (!devlink_sb) {
5475                 err = -ENOMEM;
5476                 goto unlock;
5477         }
5478         devlink_sb->index = sb_index;
5479         devlink_sb->size = size;
5480         devlink_sb->ingress_pools_count = ingress_pools_count;
5481         devlink_sb->egress_pools_count = egress_pools_count;
5482         devlink_sb->ingress_tc_count = ingress_tc_count;
5483         devlink_sb->egress_tc_count = egress_tc_count;
5484         list_add_tail(&devlink_sb->list, &devlink->sb_list);
5485 unlock:
5486         mutex_unlock(&devlink->lock);
5487         return err;
5488 }
5489 EXPORT_SYMBOL_GPL(devlink_sb_register);
5490
5491 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
5492 {
5493         struct devlink_sb *devlink_sb;
5494
5495         mutex_lock(&devlink->lock);
5496         devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
5497         WARN_ON(!devlink_sb);
5498         list_del(&devlink_sb->list);
5499         mutex_unlock(&devlink->lock);
5500         kfree(devlink_sb);
5501 }
5502 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
5503
5504 /**
5505  *      devlink_dpipe_headers_register - register dpipe headers
5506  *
5507  *      @devlink: devlink
5508  *      @dpipe_headers: dpipe header array
5509  *
5510  *      Register the headers supported by hardware.
5511  */
5512 int devlink_dpipe_headers_register(struct devlink *devlink,
5513                                    struct devlink_dpipe_headers *dpipe_headers)
5514 {
5515         mutex_lock(&devlink->lock);
5516         devlink->dpipe_headers = dpipe_headers;
5517         mutex_unlock(&devlink->lock);
5518         return 0;
5519 }
5520 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_register);
5521
5522 /**
5523  *      devlink_dpipe_headers_unregister - unregister dpipe headers
5524  *
5525  *      @devlink: devlink
5526  *
5527  *      Unregister the headers supported by hardware.
5528  */
5529 void devlink_dpipe_headers_unregister(struct devlink *devlink)
5530 {
5531         mutex_lock(&devlink->lock);
5532         devlink->dpipe_headers = NULL;
5533         mutex_unlock(&devlink->lock);
5534 }
5535 EXPORT_SYMBOL_GPL(devlink_dpipe_headers_unregister);
5536
5537 /**
5538  *      devlink_dpipe_table_counter_enabled - check if counter allocation
5539  *                                            required
5540  *      @devlink: devlink
5541  *      @table_name: tables name
5542  *
5543  *      Used by driver to check if counter allocation is required.
5544  *      After counter allocation is turned on the table entries
5545  *      are updated to include counter statistics.
5546  *
5547  *      After that point on the driver must respect the counter
5548  *      state so that each entry added to the table is added
5549  *      with a counter.
5550  */
5551 bool devlink_dpipe_table_counter_enabled(struct devlink *devlink,
5552                                          const char *table_name)
5553 {
5554         struct devlink_dpipe_table *table;
5555         bool enabled;
5556
5557         rcu_read_lock();
5558         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
5559                                          table_name);
5560         enabled = false;
5561         if (table)
5562                 enabled = table->counters_enabled;
5563         rcu_read_unlock();
5564         return enabled;
5565 }
5566 EXPORT_SYMBOL_GPL(devlink_dpipe_table_counter_enabled);
5567
5568 /**
5569  *      devlink_dpipe_table_register - register dpipe table
5570  *
5571  *      @devlink: devlink
5572  *      @table_name: table name
5573  *      @table_ops: table ops
5574  *      @priv: priv
5575  *      @counter_control_extern: external control for counters
5576  */
5577 int devlink_dpipe_table_register(struct devlink *devlink,
5578                                  const char *table_name,
5579                                  struct devlink_dpipe_table_ops *table_ops,
5580                                  void *priv, bool counter_control_extern)
5581 {
5582         struct devlink_dpipe_table *table;
5583
5584         if (devlink_dpipe_table_find(&devlink->dpipe_table_list, table_name))
5585                 return -EEXIST;
5586
5587         if (WARN_ON(!table_ops->size_get))
5588                 return -EINVAL;
5589
5590         table = kzalloc(sizeof(*table), GFP_KERNEL);
5591         if (!table)
5592                 return -ENOMEM;
5593
5594         table->name = table_name;
5595         table->table_ops = table_ops;
5596         table->priv = priv;
5597         table->counter_control_extern = counter_control_extern;
5598
5599         mutex_lock(&devlink->lock);
5600         list_add_tail_rcu(&table->list, &devlink->dpipe_table_list);
5601         mutex_unlock(&devlink->lock);
5602         return 0;
5603 }
5604 EXPORT_SYMBOL_GPL(devlink_dpipe_table_register);
5605
5606 /**
5607  *      devlink_dpipe_table_unregister - unregister dpipe table
5608  *
5609  *      @devlink: devlink
5610  *      @table_name: table name
5611  */
5612 void devlink_dpipe_table_unregister(struct devlink *devlink,
5613                                     const char *table_name)
5614 {
5615         struct devlink_dpipe_table *table;
5616
5617         mutex_lock(&devlink->lock);
5618         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
5619                                          table_name);
5620         if (!table)
5621                 goto unlock;
5622         list_del_rcu(&table->list);
5623         mutex_unlock(&devlink->lock);
5624         kfree_rcu(table, rcu);
5625         return;
5626 unlock:
5627         mutex_unlock(&devlink->lock);
5628 }
5629 EXPORT_SYMBOL_GPL(devlink_dpipe_table_unregister);
5630
5631 /**
5632  *      devlink_resource_register - devlink resource register
5633  *
5634  *      @devlink: devlink
5635  *      @resource_name: resource's name
5636  *      @top_hierarchy: top hierarchy
5637  *      @reload_required: reload is required for new configuration to
5638  *                        apply
5639  *      @resource_size: resource's size
5640  *      @resource_id: resource's id
5641  *      @parent_reosurce_id: resource's parent id
5642  *      @size params: size parameters
5643  */
5644 int devlink_resource_register(struct devlink *devlink,
5645                               const char *resource_name,
5646                               u64 resource_size,
5647                               u64 resource_id,
5648                               u64 parent_resource_id,
5649                               const struct devlink_resource_size_params *size_params)
5650 {
5651         struct devlink_resource *resource;
5652         struct list_head *resource_list;
5653         bool top_hierarchy;
5654         int err = 0;
5655
5656         top_hierarchy = parent_resource_id == DEVLINK_RESOURCE_ID_PARENT_TOP;
5657
5658         mutex_lock(&devlink->lock);
5659         resource = devlink_resource_find(devlink, NULL, resource_id);
5660         if (resource) {
5661                 err = -EINVAL;
5662                 goto out;
5663         }
5664
5665         resource = kzalloc(sizeof(*resource), GFP_KERNEL);
5666         if (!resource) {
5667                 err = -ENOMEM;
5668                 goto out;
5669         }
5670
5671         if (top_hierarchy) {
5672                 resource_list = &devlink->resource_list;
5673         } else {
5674                 struct devlink_resource *parent_resource;
5675
5676                 parent_resource = devlink_resource_find(devlink, NULL,
5677                                                         parent_resource_id);
5678                 if (parent_resource) {
5679                         resource_list = &parent_resource->resource_list;
5680                         resource->parent = parent_resource;
5681                 } else {
5682                         kfree(resource);
5683                         err = -EINVAL;
5684                         goto out;
5685                 }
5686         }
5687
5688         resource->name = resource_name;
5689         resource->size = resource_size;
5690         resource->size_new = resource_size;
5691         resource->id = resource_id;
5692         resource->size_valid = true;
5693         memcpy(&resource->size_params, size_params,
5694                sizeof(resource->size_params));
5695         INIT_LIST_HEAD(&resource->resource_list);
5696         list_add_tail(&resource->list, resource_list);
5697 out:
5698         mutex_unlock(&devlink->lock);
5699         return err;
5700 }
5701 EXPORT_SYMBOL_GPL(devlink_resource_register);
5702
5703 /**
5704  *      devlink_resources_unregister - free all resources
5705  *
5706  *      @devlink: devlink
5707  *      @resource: resource
5708  */
5709 void devlink_resources_unregister(struct devlink *devlink,
5710                                   struct devlink_resource *resource)
5711 {
5712         struct devlink_resource *tmp, *child_resource;
5713         struct list_head *resource_list;
5714
5715         if (resource)
5716                 resource_list = &resource->resource_list;
5717         else
5718                 resource_list = &devlink->resource_list;
5719
5720         if (!resource)
5721                 mutex_lock(&devlink->lock);
5722
5723         list_for_each_entry_safe(child_resource, tmp, resource_list, list) {
5724                 devlink_resources_unregister(devlink, child_resource);
5725                 list_del(&child_resource->list);
5726                 kfree(child_resource);
5727         }
5728
5729         if (!resource)
5730                 mutex_unlock(&devlink->lock);
5731 }
5732 EXPORT_SYMBOL_GPL(devlink_resources_unregister);
5733
5734 /**
5735  *      devlink_resource_size_get - get and update size
5736  *
5737  *      @devlink: devlink
5738  *      @resource_id: the requested resource id
5739  *      @p_resource_size: ptr to update
5740  */
5741 int devlink_resource_size_get(struct devlink *devlink,
5742                               u64 resource_id,
5743                               u64 *p_resource_size)
5744 {
5745         struct devlink_resource *resource;
5746         int err = 0;
5747
5748         mutex_lock(&devlink->lock);
5749         resource = devlink_resource_find(devlink, NULL, resource_id);
5750         if (!resource) {
5751                 err = -EINVAL;
5752                 goto out;
5753         }
5754         *p_resource_size = resource->size_new;
5755         resource->size = resource->size_new;
5756 out:
5757         mutex_unlock(&devlink->lock);
5758         return err;
5759 }
5760 EXPORT_SYMBOL_GPL(devlink_resource_size_get);
5761
5762 /**
5763  *      devlink_dpipe_table_resource_set - set the resource id
5764  *
5765  *      @devlink: devlink
5766  *      @table_name: table name
5767  *      @resource_id: resource id
5768  *      @resource_units: number of resource's units consumed per table's entry
5769  */
5770 int devlink_dpipe_table_resource_set(struct devlink *devlink,
5771                                      const char *table_name, u64 resource_id,
5772                                      u64 resource_units)
5773 {
5774         struct devlink_dpipe_table *table;
5775         int err = 0;
5776
5777         mutex_lock(&devlink->lock);
5778         table = devlink_dpipe_table_find(&devlink->dpipe_table_list,
5779                                          table_name);
5780         if (!table) {
5781                 err = -EINVAL;
5782                 goto out;
5783         }
5784         table->resource_id = resource_id;
5785         table->resource_units = resource_units;
5786         table->resource_valid = true;
5787 out:
5788         mutex_unlock(&devlink->lock);
5789         return err;
5790 }
5791 EXPORT_SYMBOL_GPL(devlink_dpipe_table_resource_set);
5792
5793 /**
5794  *      devlink_resource_occ_get_register - register occupancy getter
5795  *
5796  *      @devlink: devlink
5797  *      @resource_id: resource id
5798  *      @occ_get: occupancy getter callback
5799  *      @occ_get_priv: occupancy getter callback priv
5800  */
5801 void devlink_resource_occ_get_register(struct devlink *devlink,
5802                                        u64 resource_id,
5803                                        devlink_resource_occ_get_t *occ_get,
5804                                        void *occ_get_priv)
5805 {
5806         struct devlink_resource *resource;
5807
5808         mutex_lock(&devlink->lock);
5809         resource = devlink_resource_find(devlink, NULL, resource_id);
5810         if (WARN_ON(!resource))
5811                 goto out;
5812         WARN_ON(resource->occ_get);
5813
5814         resource->occ_get = occ_get;
5815         resource->occ_get_priv = occ_get_priv;
5816 out:
5817         mutex_unlock(&devlink->lock);
5818 }
5819 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_register);
5820
5821 /**
5822  *      devlink_resource_occ_get_unregister - unregister occupancy getter
5823  *
5824  *      @devlink: devlink
5825  *      @resource_id: resource id
5826  */
5827 void devlink_resource_occ_get_unregister(struct devlink *devlink,
5828                                          u64 resource_id)
5829 {
5830         struct devlink_resource *resource;
5831
5832         mutex_lock(&devlink->lock);
5833         resource = devlink_resource_find(devlink, NULL, resource_id);
5834         if (WARN_ON(!resource))
5835                 goto out;
5836         WARN_ON(!resource->occ_get);
5837
5838         resource->occ_get = NULL;
5839         resource->occ_get_priv = NULL;
5840 out:
5841         mutex_unlock(&devlink->lock);
5842 }
5843 EXPORT_SYMBOL_GPL(devlink_resource_occ_get_unregister);
5844
5845 static int devlink_param_verify(const struct devlink_param *param)
5846 {
5847         if (!param || !param->name || !param->supported_cmodes)
5848                 return -EINVAL;
5849         if (param->generic)
5850                 return devlink_param_generic_verify(param);
5851         else
5852                 return devlink_param_driver_verify(param);
5853 }
5854
5855 static int __devlink_params_register(struct devlink *devlink,
5856                                      unsigned int port_index,
5857                                      struct list_head *param_list,
5858                                      const struct devlink_param *params,
5859                                      size_t params_count,
5860                                      enum devlink_command reg_cmd,
5861                                      enum devlink_command unreg_cmd)
5862 {
5863         const struct devlink_param *param = params;
5864         int i;
5865         int err;
5866
5867         mutex_lock(&devlink->lock);
5868         for (i = 0; i < params_count; i++, param++) {
5869                 err = devlink_param_verify(param);
5870                 if (err)
5871                         goto rollback;
5872
5873                 err = devlink_param_register_one(devlink, port_index,
5874                                                  param_list, param, reg_cmd);
5875                 if (err)
5876                         goto rollback;
5877         }
5878
5879         mutex_unlock(&devlink->lock);
5880         return 0;
5881
5882 rollback:
5883         if (!i)
5884                 goto unlock;
5885         for (param--; i > 0; i--, param--)
5886                 devlink_param_unregister_one(devlink, port_index, param_list,
5887                                              param, unreg_cmd);
5888 unlock:
5889         mutex_unlock(&devlink->lock);
5890         return err;
5891 }
5892
5893 static void __devlink_params_unregister(struct devlink *devlink,
5894                                         unsigned int port_index,
5895                                         struct list_head *param_list,
5896                                         const struct devlink_param *params,
5897                                         size_t params_count,
5898                                         enum devlink_command cmd)
5899 {
5900         const struct devlink_param *param = params;
5901         int i;
5902
5903         mutex_lock(&devlink->lock);
5904         for (i = 0; i < params_count; i++, param++)
5905                 devlink_param_unregister_one(devlink, 0, param_list, param,
5906                                              cmd);
5907         mutex_unlock(&devlink->lock);
5908 }
5909
5910 /**
5911  *      devlink_params_register - register configuration parameters
5912  *
5913  *      @devlink: devlink
5914  *      @params: configuration parameters array
5915  *      @params_count: number of parameters provided
5916  *
5917  *      Register the configuration parameters supported by the driver.
5918  */
5919 int devlink_params_register(struct devlink *devlink,
5920                             const struct devlink_param *params,
5921                             size_t params_count)
5922 {
5923         return __devlink_params_register(devlink, 0, &devlink->param_list,
5924                                          params, params_count,
5925                                          DEVLINK_CMD_PARAM_NEW,
5926                                          DEVLINK_CMD_PARAM_DEL);
5927 }
5928 EXPORT_SYMBOL_GPL(devlink_params_register);
5929
5930 /**
5931  *      devlink_params_unregister - unregister configuration parameters
5932  *      @devlink: devlink
5933  *      @params: configuration parameters to unregister
5934  *      @params_count: number of parameters provided
5935  */
5936 void devlink_params_unregister(struct devlink *devlink,
5937                                const struct devlink_param *params,
5938                                size_t params_count)
5939 {
5940         return __devlink_params_unregister(devlink, 0, &devlink->param_list,
5941                                            params, params_count,
5942                                            DEVLINK_CMD_PARAM_DEL);
5943 }
5944 EXPORT_SYMBOL_GPL(devlink_params_unregister);
5945
5946 /**
5947  *      devlink_params_publish - publish configuration parameters
5948  *
5949  *      @devlink: devlink
5950  *
5951  *      Publish previously registered configuration parameters.
5952  */
5953 void devlink_params_publish(struct devlink *devlink)
5954 {
5955         struct devlink_param_item *param_item;
5956
5957         list_for_each_entry(param_item, &devlink->param_list, list) {
5958                 if (param_item->published)
5959                         continue;
5960                 param_item->published = true;
5961                 devlink_param_notify(devlink, 0, param_item,
5962                                      DEVLINK_CMD_PARAM_NEW);
5963         }
5964 }
5965 EXPORT_SYMBOL_GPL(devlink_params_publish);
5966
5967 /**
5968  *      devlink_params_unpublish - unpublish configuration parameters
5969  *
5970  *      @devlink: devlink
5971  *
5972  *      Unpublish previously registered configuration parameters.
5973  */
5974 void devlink_params_unpublish(struct devlink *devlink)
5975 {
5976         struct devlink_param_item *param_item;
5977
5978         list_for_each_entry(param_item, &devlink->param_list, list) {
5979                 if (!param_item->published)
5980                         continue;
5981                 param_item->published = false;
5982                 devlink_param_notify(devlink, 0, param_item,
5983                                      DEVLINK_CMD_PARAM_DEL);
5984         }
5985 }
5986 EXPORT_SYMBOL_GPL(devlink_params_unpublish);
5987
5988 /**
5989  *      devlink_port_params_register - register port configuration parameters
5990  *
5991  *      @devlink_port: devlink port
5992  *      @params: configuration parameters array
5993  *      @params_count: number of parameters provided
5994  *
5995  *      Register the configuration parameters supported by the port.
5996  */
5997 int devlink_port_params_register(struct devlink_port *devlink_port,
5998                                  const struct devlink_param *params,
5999                                  size_t params_count)
6000 {
6001         return __devlink_params_register(devlink_port->devlink,
6002                                          devlink_port->index,
6003                                          &devlink_port->param_list, params,
6004                                          params_count,
6005                                          DEVLINK_CMD_PORT_PARAM_NEW,
6006                                          DEVLINK_CMD_PORT_PARAM_DEL);
6007 }
6008 EXPORT_SYMBOL_GPL(devlink_port_params_register);
6009
6010 /**
6011  *      devlink_port_params_unregister - unregister port configuration
6012  *      parameters
6013  *
6014  *      @devlink_port: devlink port
6015  *      @params: configuration parameters array
6016  *      @params_count: number of parameters provided
6017  */
6018 void devlink_port_params_unregister(struct devlink_port *devlink_port,
6019                                     const struct devlink_param *params,
6020                                     size_t params_count)
6021 {
6022         return __devlink_params_unregister(devlink_port->devlink,
6023                                            devlink_port->index,
6024                                            &devlink_port->param_list,
6025                                            params, params_count,
6026                                            DEVLINK_CMD_PORT_PARAM_DEL);
6027 }
6028 EXPORT_SYMBOL_GPL(devlink_port_params_unregister);
6029
6030 static int
6031 __devlink_param_driverinit_value_get(struct list_head *param_list, u32 param_id,
6032                                      union devlink_param_value *init_val)
6033 {
6034         struct devlink_param_item *param_item;
6035
6036         param_item = devlink_param_find_by_id(param_list, param_id);
6037         if (!param_item)
6038                 return -EINVAL;
6039
6040         if (!param_item->driverinit_value_valid ||
6041             !devlink_param_cmode_is_supported(param_item->param,
6042                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
6043                 return -EOPNOTSUPP;
6044
6045         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
6046                 strcpy(init_val->vstr, param_item->driverinit_value.vstr);
6047         else
6048                 *init_val = param_item->driverinit_value;
6049
6050         return 0;
6051 }
6052
6053 static int
6054 __devlink_param_driverinit_value_set(struct devlink *devlink,
6055                                      unsigned int port_index,
6056                                      struct list_head *param_list, u32 param_id,
6057                                      union devlink_param_value init_val,
6058                                      enum devlink_command cmd)
6059 {
6060         struct devlink_param_item *param_item;
6061
6062         param_item = devlink_param_find_by_id(param_list, param_id);
6063         if (!param_item)
6064                 return -EINVAL;
6065
6066         if (!devlink_param_cmode_is_supported(param_item->param,
6067                                               DEVLINK_PARAM_CMODE_DRIVERINIT))
6068                 return -EOPNOTSUPP;
6069
6070         if (param_item->param->type == DEVLINK_PARAM_TYPE_STRING)
6071                 strcpy(param_item->driverinit_value.vstr, init_val.vstr);
6072         else
6073                 param_item->driverinit_value = init_val;
6074         param_item->driverinit_value_valid = true;
6075
6076         devlink_param_notify(devlink, port_index, param_item, cmd);
6077         return 0;
6078 }
6079
6080 /**
6081  *      devlink_param_driverinit_value_get - get configuration parameter
6082  *                                           value for driver initializing
6083  *
6084  *      @devlink: devlink
6085  *      @param_id: parameter ID
6086  *      @init_val: value of parameter in driverinit configuration mode
6087  *
6088  *      This function should be used by the driver to get driverinit
6089  *      configuration for initialization after reload command.
6090  */
6091 int devlink_param_driverinit_value_get(struct devlink *devlink, u32 param_id,
6092                                        union devlink_param_value *init_val)
6093 {
6094         if (!devlink->ops || !devlink->ops->reload)
6095                 return -EOPNOTSUPP;
6096
6097         return __devlink_param_driverinit_value_get(&devlink->param_list,
6098                                                     param_id, init_val);
6099 }
6100 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_get);
6101
6102 /**
6103  *      devlink_param_driverinit_value_set - set value of configuration
6104  *                                           parameter for driverinit
6105  *                                           configuration mode
6106  *
6107  *      @devlink: devlink
6108  *      @param_id: parameter ID
6109  *      @init_val: value of parameter to set for driverinit configuration mode
6110  *
6111  *      This function should be used by the driver to set driverinit
6112  *      configuration mode default value.
6113  */
6114 int devlink_param_driverinit_value_set(struct devlink *devlink, u32 param_id,
6115                                        union devlink_param_value init_val)
6116 {
6117         return __devlink_param_driverinit_value_set(devlink, 0,
6118                                                     &devlink->param_list,
6119                                                     param_id, init_val,
6120                                                     DEVLINK_CMD_PARAM_NEW);
6121 }
6122 EXPORT_SYMBOL_GPL(devlink_param_driverinit_value_set);
6123
6124 /**
6125  *      devlink_port_param_driverinit_value_get - get configuration parameter
6126  *                                              value for driver initializing
6127  *
6128  *      @devlink_port: devlink_port
6129  *      @param_id: parameter ID
6130  *      @init_val: value of parameter in driverinit configuration mode
6131  *
6132  *      This function should be used by the driver to get driverinit
6133  *      configuration for initialization after reload command.
6134  */
6135 int devlink_port_param_driverinit_value_get(struct devlink_port *devlink_port,
6136                                             u32 param_id,
6137                                             union devlink_param_value *init_val)
6138 {
6139         struct devlink *devlink = devlink_port->devlink;
6140
6141         if (!devlink->ops || !devlink->ops->reload)
6142                 return -EOPNOTSUPP;
6143
6144         return __devlink_param_driverinit_value_get(&devlink_port->param_list,
6145                                                     param_id, init_val);
6146 }
6147 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_get);
6148
6149 /**
6150  *     devlink_port_param_driverinit_value_set - set value of configuration
6151  *                                               parameter for driverinit
6152  *                                               configuration mode
6153  *
6154  *     @devlink_port: devlink_port
6155  *     @param_id: parameter ID
6156  *     @init_val: value of parameter to set for driverinit configuration mode
6157  *
6158  *     This function should be used by the driver to set driverinit
6159  *     configuration mode default value.
6160  */
6161 int devlink_port_param_driverinit_value_set(struct devlink_port *devlink_port,
6162                                             u32 param_id,
6163                                             union devlink_param_value init_val)
6164 {
6165         return __devlink_param_driverinit_value_set(devlink_port->devlink,
6166                                                     devlink_port->index,
6167                                                     &devlink_port->param_list,
6168                                                     param_id, init_val,
6169                                                     DEVLINK_CMD_PORT_PARAM_NEW);
6170 }
6171 EXPORT_SYMBOL_GPL(devlink_port_param_driverinit_value_set);
6172
6173 /**
6174  *      devlink_param_value_changed - notify devlink on a parameter's value
6175  *                                    change. Should be called by the driver
6176  *                                    right after the change.
6177  *
6178  *      @devlink: devlink
6179  *      @param_id: parameter ID
6180  *
6181  *      This function should be used by the driver to notify devlink on value
6182  *      change, excluding driverinit configuration mode.
6183  *      For driverinit configuration mode driver should use the function
6184  */
6185 void devlink_param_value_changed(struct devlink *devlink, u32 param_id)
6186 {
6187         struct devlink_param_item *param_item;
6188
6189         param_item = devlink_param_find_by_id(&devlink->param_list, param_id);
6190         WARN_ON(!param_item);
6191
6192         devlink_param_notify(devlink, 0, param_item, DEVLINK_CMD_PARAM_NEW);
6193 }
6194 EXPORT_SYMBOL_GPL(devlink_param_value_changed);
6195
6196 /**
6197  *     devlink_port_param_value_changed - notify devlink on a parameter's value
6198  *                                      change. Should be called by the driver
6199  *                                      right after the change.
6200  *
6201  *     @devlink_port: devlink_port
6202  *     @param_id: parameter ID
6203  *
6204  *     This function should be used by the driver to notify devlink on value
6205  *     change, excluding driverinit configuration mode.
6206  *     For driverinit configuration mode driver should use the function
6207  *     devlink_port_param_driverinit_value_set() instead.
6208  */
6209 void devlink_port_param_value_changed(struct devlink_port *devlink_port,
6210                                       u32 param_id)
6211 {
6212         struct devlink_param_item *param_item;
6213
6214         param_item = devlink_param_find_by_id(&devlink_port->param_list,
6215                                               param_id);
6216         WARN_ON(!param_item);
6217
6218         devlink_param_notify(devlink_port->devlink, devlink_port->index,
6219                              param_item, DEVLINK_CMD_PORT_PARAM_NEW);
6220 }
6221 EXPORT_SYMBOL_GPL(devlink_port_param_value_changed);
6222
6223 /**
6224  *      devlink_param_value_str_fill - Safely fill-up the string preventing
6225  *                                     from overflow of the preallocated buffer
6226  *
6227  *      @dst_val: destination devlink_param_value
6228  *      @src: source buffer
6229  */
6230 void devlink_param_value_str_fill(union devlink_param_value *dst_val,
6231                                   const char *src)
6232 {
6233         size_t len;
6234
6235         len = strlcpy(dst_val->vstr, src, __DEVLINK_PARAM_MAX_STRING_VALUE);
6236         WARN_ON(len >= __DEVLINK_PARAM_MAX_STRING_VALUE);
6237 }
6238 EXPORT_SYMBOL_GPL(devlink_param_value_str_fill);
6239
6240 /**
6241  *      devlink_region_create - create a new address region
6242  *
6243  *      @devlink: devlink
6244  *      @region_name: region name
6245  *      @region_max_snapshots: Maximum supported number of snapshots for region
6246  *      @region_size: size of region
6247  */
6248 struct devlink_region *devlink_region_create(struct devlink *devlink,
6249                                              const char *region_name,
6250                                              u32 region_max_snapshots,
6251                                              u64 region_size)
6252 {
6253         struct devlink_region *region;
6254         int err = 0;
6255
6256         mutex_lock(&devlink->lock);
6257
6258         if (devlink_region_get_by_name(devlink, region_name)) {
6259                 err = -EEXIST;
6260                 goto unlock;
6261         }
6262
6263         region = kzalloc(sizeof(*region), GFP_KERNEL);
6264         if (!region) {
6265                 err = -ENOMEM;
6266                 goto unlock;
6267         }
6268
6269         region->devlink = devlink;
6270         region->max_snapshots = region_max_snapshots;
6271         region->name = region_name;
6272         region->size = region_size;
6273         INIT_LIST_HEAD(&region->snapshot_list);
6274         list_add_tail(&region->list, &devlink->region_list);
6275         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_NEW);
6276
6277         mutex_unlock(&devlink->lock);
6278         return region;
6279
6280 unlock:
6281         mutex_unlock(&devlink->lock);
6282         return ERR_PTR(err);
6283 }
6284 EXPORT_SYMBOL_GPL(devlink_region_create);
6285
6286 /**
6287  *      devlink_region_destroy - destroy address region
6288  *
6289  *      @region: devlink region to destroy
6290  */
6291 void devlink_region_destroy(struct devlink_region *region)
6292 {
6293         struct devlink *devlink = region->devlink;
6294         struct devlink_snapshot *snapshot, *ts;
6295
6296         mutex_lock(&devlink->lock);
6297
6298         /* Free all snapshots of region */
6299         list_for_each_entry_safe(snapshot, ts, &region->snapshot_list, list)
6300                 devlink_region_snapshot_del(snapshot);
6301
6302         list_del(&region->list);
6303
6304         devlink_nl_region_notify(region, NULL, DEVLINK_CMD_REGION_DEL);
6305         mutex_unlock(&devlink->lock);
6306         kfree(region);
6307 }
6308 EXPORT_SYMBOL_GPL(devlink_region_destroy);
6309
6310 /**
6311  *      devlink_region_shapshot_id_get - get snapshot ID
6312  *
6313  *      This callback should be called when adding a new snapshot,
6314  *      Driver should use the same id for multiple snapshots taken
6315  *      on multiple regions at the same time/by the same trigger.
6316  *
6317  *      @devlink: devlink
6318  */
6319 u32 devlink_region_shapshot_id_get(struct devlink *devlink)
6320 {
6321         u32 id;
6322
6323         mutex_lock(&devlink->lock);
6324         id = ++devlink->snapshot_id;
6325         mutex_unlock(&devlink->lock);
6326
6327         return id;
6328 }
6329 EXPORT_SYMBOL_GPL(devlink_region_shapshot_id_get);
6330
6331 /**
6332  *      devlink_region_snapshot_create - create a new snapshot
6333  *      This will add a new snapshot of a region. The snapshot
6334  *      will be stored on the region struct and can be accessed
6335  *      from devlink. This is useful for future analyses of snapshots.
6336  *      Multiple snapshots can be created on a region.
6337  *      The @snapshot_id should be obtained using the getter function.
6338  *
6339  *      @devlink_region: devlink region of the snapshot
6340  *      @data_len: size of snapshot data
6341  *      @data: snapshot data
6342  *      @snapshot_id: snapshot id to be created
6343  *      @data_destructor: pointer to destructor function to free data
6344  */
6345 int devlink_region_snapshot_create(struct devlink_region *region, u64 data_len,
6346                                    u8 *data, u32 snapshot_id,
6347                                    devlink_snapshot_data_dest_t *data_destructor)
6348 {
6349         struct devlink *devlink = region->devlink;
6350         struct devlink_snapshot *snapshot;
6351         int err;
6352
6353         mutex_lock(&devlink->lock);
6354
6355         /* check if region can hold one more snapshot */
6356         if (region->cur_snapshots == region->max_snapshots) {
6357                 err = -ENOMEM;
6358                 goto unlock;
6359         }
6360
6361         if (devlink_region_snapshot_get_by_id(region, snapshot_id)) {
6362                 err = -EEXIST;
6363                 goto unlock;
6364         }
6365
6366         snapshot = kzalloc(sizeof(*snapshot), GFP_KERNEL);
6367         if (!snapshot) {
6368                 err = -ENOMEM;
6369                 goto unlock;
6370         }
6371
6372         snapshot->id = snapshot_id;
6373         snapshot->region = region;
6374         snapshot->data = data;
6375         snapshot->data_len = data_len;
6376         snapshot->data_destructor = data_destructor;
6377
6378         list_add_tail(&snapshot->list, &region->snapshot_list);
6379
6380         region->cur_snapshots++;
6381
6382         devlink_nl_region_notify(region, snapshot, DEVLINK_CMD_REGION_NEW);
6383         mutex_unlock(&devlink->lock);
6384         return 0;
6385
6386 unlock:
6387         mutex_unlock(&devlink->lock);
6388         return err;
6389 }
6390 EXPORT_SYMBOL_GPL(devlink_region_snapshot_create);
6391
6392 static void __devlink_compat_running_version(struct devlink *devlink,
6393                                              char *buf, size_t len)
6394 {
6395         const struct nlattr *nlattr;
6396         struct devlink_info_req req;
6397         struct sk_buff *msg;
6398         int rem, err;
6399
6400         if (!devlink->ops->info_get)
6401                 return;
6402
6403         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
6404         if (!msg)
6405                 return;
6406
6407         req.msg = msg;
6408         err = devlink->ops->info_get(devlink, &req, NULL);
6409         if (err)
6410                 goto free_msg;
6411
6412         nla_for_each_attr(nlattr, (void *)msg->data, msg->len, rem) {
6413                 const struct nlattr *kv;
6414                 int rem_kv;
6415
6416                 if (nla_type(nlattr) != DEVLINK_ATTR_INFO_VERSION_RUNNING)
6417                         continue;
6418
6419                 nla_for_each_nested(kv, nlattr, rem_kv) {
6420                         if (nla_type(kv) != DEVLINK_ATTR_INFO_VERSION_VALUE)
6421                                 continue;
6422
6423                         strlcat(buf, nla_data(kv), len);
6424                         strlcat(buf, " ", len);
6425                 }
6426         }
6427 free_msg:
6428         nlmsg_free(msg);
6429 }
6430
6431 void devlink_compat_running_version(struct net_device *dev,
6432                                     char *buf, size_t len)
6433 {
6434         struct devlink_port *devlink_port;
6435         struct devlink *devlink;
6436
6437         mutex_lock(&devlink_mutex);
6438         list_for_each_entry(devlink, &devlink_list, list) {
6439                 mutex_lock(&devlink->lock);
6440                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
6441                         if (devlink_port->type == DEVLINK_PORT_TYPE_ETH &&
6442                             devlink_port->type_dev == dev) {
6443                                 __devlink_compat_running_version(devlink,
6444                                                                  buf, len);
6445                                 mutex_unlock(&devlink->lock);
6446                                 goto out;
6447                         }
6448                 }
6449                 mutex_unlock(&devlink->lock);
6450         }
6451 out:
6452         mutex_unlock(&devlink_mutex);
6453 }
6454
6455 int devlink_compat_flash_update(struct net_device *dev, const char *file_name)
6456 {
6457         struct devlink_port *devlink_port;
6458         struct devlink *devlink;
6459
6460         mutex_lock(&devlink_mutex);
6461         list_for_each_entry(devlink, &devlink_list, list) {
6462                 mutex_lock(&devlink->lock);
6463                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
6464                         int ret = -EOPNOTSUPP;
6465
6466                         if (devlink_port->type != DEVLINK_PORT_TYPE_ETH ||
6467                             devlink_port->type_dev != dev)
6468                                 continue;
6469
6470                         mutex_unlock(&devlink_mutex);
6471                         if (devlink->ops->flash_update)
6472                                 ret = devlink->ops->flash_update(devlink,
6473                                                                  file_name,
6474                                                                  NULL, NULL);
6475                         mutex_unlock(&devlink->lock);
6476                         return ret;
6477                 }
6478                 mutex_unlock(&devlink->lock);
6479         }
6480         mutex_unlock(&devlink_mutex);
6481
6482         return -EOPNOTSUPP;
6483 }
6484
6485 static int __init devlink_module_init(void)
6486 {
6487         return genl_register_family(&devlink_nl_family);
6488 }
6489
6490 static void __exit devlink_module_exit(void)
6491 {
6492         genl_unregister_family(&devlink_nl_family);
6493 }
6494
6495 module_init(devlink_module_init);
6496 module_exit(devlink_module_exit);
6497
6498 MODULE_LICENSE("GPL v2");
6499 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
6500 MODULE_DESCRIPTION("Network physical device Netlink interface");
6501 MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);