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