Merge branch 'pm-sleep'
[cascardo/linux.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
30 static LIST_HEAD(devlink_list);
31
32 /* devlink_mutex
33  *
34  * An overall lock guarding every operation coming from userspace.
35  * It also guards devlink devices list and it is taken when
36  * driver registers/unregisters it.
37  */
38 static DEFINE_MUTEX(devlink_mutex);
39
40 /* devlink_port_mutex
41  *
42  * Shared lock to guard lists of ports in all devlink devices.
43  */
44 static DEFINE_MUTEX(devlink_port_mutex);
45
46 static struct net *devlink_net(const struct devlink *devlink)
47 {
48         return read_pnet(&devlink->_net);
49 }
50
51 static void devlink_net_set(struct devlink *devlink, struct net *net)
52 {
53         write_pnet(&devlink->_net, net);
54 }
55
56 static struct devlink *devlink_get_from_attrs(struct net *net,
57                                               struct nlattr **attrs)
58 {
59         struct devlink *devlink;
60         char *busname;
61         char *devname;
62
63         if (!attrs[DEVLINK_ATTR_BUS_NAME] || !attrs[DEVLINK_ATTR_DEV_NAME])
64                 return ERR_PTR(-EINVAL);
65
66         busname = nla_data(attrs[DEVLINK_ATTR_BUS_NAME]);
67         devname = nla_data(attrs[DEVLINK_ATTR_DEV_NAME]);
68
69         list_for_each_entry(devlink, &devlink_list, list) {
70                 if (strcmp(devlink->dev->bus->name, busname) == 0 &&
71                     strcmp(dev_name(devlink->dev), devname) == 0 &&
72                     net_eq(devlink_net(devlink), net))
73                         return devlink;
74         }
75
76         return ERR_PTR(-ENODEV);
77 }
78
79 static struct devlink *devlink_get_from_info(struct genl_info *info)
80 {
81         return devlink_get_from_attrs(genl_info_net(info), info->attrs);
82 }
83
84 static struct devlink_port *devlink_port_get_by_index(struct devlink *devlink,
85                                                       int port_index)
86 {
87         struct devlink_port *devlink_port;
88
89         list_for_each_entry(devlink_port, &devlink->port_list, list) {
90                 if (devlink_port->index == port_index)
91                         return devlink_port;
92         }
93         return NULL;
94 }
95
96 static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
97 {
98         return devlink_port_get_by_index(devlink, port_index);
99 }
100
101 static struct devlink_port *devlink_port_get_from_attrs(struct devlink *devlink,
102                                                         struct nlattr **attrs)
103 {
104         if (attrs[DEVLINK_ATTR_PORT_INDEX]) {
105                 u32 port_index = nla_get_u32(attrs[DEVLINK_ATTR_PORT_INDEX]);
106                 struct devlink_port *devlink_port;
107
108                 devlink_port = devlink_port_get_by_index(devlink, port_index);
109                 if (!devlink_port)
110                         return ERR_PTR(-ENODEV);
111                 return devlink_port;
112         }
113         return ERR_PTR(-EINVAL);
114 }
115
116 static struct devlink_port *devlink_port_get_from_info(struct devlink *devlink,
117                                                        struct genl_info *info)
118 {
119         return devlink_port_get_from_attrs(devlink, info->attrs);
120 }
121
122 struct devlink_sb {
123         struct list_head list;
124         unsigned int index;
125         u32 size;
126         u16 ingress_pools_count;
127         u16 egress_pools_count;
128         u16 ingress_tc_count;
129         u16 egress_tc_count;
130 };
131
132 static u16 devlink_sb_pool_count(struct devlink_sb *devlink_sb)
133 {
134         return devlink_sb->ingress_pools_count + devlink_sb->egress_pools_count;
135 }
136
137 static struct devlink_sb *devlink_sb_get_by_index(struct devlink *devlink,
138                                                   unsigned int sb_index)
139 {
140         struct devlink_sb *devlink_sb;
141
142         list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
143                 if (devlink_sb->index == sb_index)
144                         return devlink_sb;
145         }
146         return NULL;
147 }
148
149 static bool devlink_sb_index_exists(struct devlink *devlink,
150                                     unsigned int sb_index)
151 {
152         return devlink_sb_get_by_index(devlink, sb_index);
153 }
154
155 static struct devlink_sb *devlink_sb_get_from_attrs(struct devlink *devlink,
156                                                     struct nlattr **attrs)
157 {
158         if (attrs[DEVLINK_ATTR_SB_INDEX]) {
159                 u32 sb_index = nla_get_u32(attrs[DEVLINK_ATTR_SB_INDEX]);
160                 struct devlink_sb *devlink_sb;
161
162                 devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
163                 if (!devlink_sb)
164                         return ERR_PTR(-ENODEV);
165                 return devlink_sb;
166         }
167         return ERR_PTR(-EINVAL);
168 }
169
170 static struct devlink_sb *devlink_sb_get_from_info(struct devlink *devlink,
171                                                    struct genl_info *info)
172 {
173         return devlink_sb_get_from_attrs(devlink, info->attrs);
174 }
175
176 static int devlink_sb_pool_index_get_from_attrs(struct devlink_sb *devlink_sb,
177                                                 struct nlattr **attrs,
178                                                 u16 *p_pool_index)
179 {
180         u16 val;
181
182         if (!attrs[DEVLINK_ATTR_SB_POOL_INDEX])
183                 return -EINVAL;
184
185         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_POOL_INDEX]);
186         if (val >= devlink_sb_pool_count(devlink_sb))
187                 return -EINVAL;
188         *p_pool_index = val;
189         return 0;
190 }
191
192 static int devlink_sb_pool_index_get_from_info(struct devlink_sb *devlink_sb,
193                                                struct genl_info *info,
194                                                u16 *p_pool_index)
195 {
196         return devlink_sb_pool_index_get_from_attrs(devlink_sb, info->attrs,
197                                                     p_pool_index);
198 }
199
200 static int
201 devlink_sb_pool_type_get_from_attrs(struct nlattr **attrs,
202                                     enum devlink_sb_pool_type *p_pool_type)
203 {
204         u8 val;
205
206         if (!attrs[DEVLINK_ATTR_SB_POOL_TYPE])
207                 return -EINVAL;
208
209         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_TYPE]);
210         if (val != DEVLINK_SB_POOL_TYPE_INGRESS &&
211             val != DEVLINK_SB_POOL_TYPE_EGRESS)
212                 return -EINVAL;
213         *p_pool_type = val;
214         return 0;
215 }
216
217 static int
218 devlink_sb_pool_type_get_from_info(struct genl_info *info,
219                                    enum devlink_sb_pool_type *p_pool_type)
220 {
221         return devlink_sb_pool_type_get_from_attrs(info->attrs, p_pool_type);
222 }
223
224 static int
225 devlink_sb_th_type_get_from_attrs(struct nlattr **attrs,
226                                   enum devlink_sb_threshold_type *p_th_type)
227 {
228         u8 val;
229
230         if (!attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE])
231                 return -EINVAL;
232
233         val = nla_get_u8(attrs[DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE]);
234         if (val != DEVLINK_SB_THRESHOLD_TYPE_STATIC &&
235             val != DEVLINK_SB_THRESHOLD_TYPE_DYNAMIC)
236                 return -EINVAL;
237         *p_th_type = val;
238         return 0;
239 }
240
241 static int
242 devlink_sb_th_type_get_from_info(struct genl_info *info,
243                                  enum devlink_sb_threshold_type *p_th_type)
244 {
245         return devlink_sb_th_type_get_from_attrs(info->attrs, p_th_type);
246 }
247
248 static int
249 devlink_sb_tc_index_get_from_attrs(struct devlink_sb *devlink_sb,
250                                    struct nlattr **attrs,
251                                    enum devlink_sb_pool_type pool_type,
252                                    u16 *p_tc_index)
253 {
254         u16 val;
255
256         if (!attrs[DEVLINK_ATTR_SB_TC_INDEX])
257                 return -EINVAL;
258
259         val = nla_get_u16(attrs[DEVLINK_ATTR_SB_TC_INDEX]);
260         if (pool_type == DEVLINK_SB_POOL_TYPE_INGRESS &&
261             val >= devlink_sb->ingress_tc_count)
262                 return -EINVAL;
263         if (pool_type == DEVLINK_SB_POOL_TYPE_EGRESS &&
264             val >= devlink_sb->egress_tc_count)
265                 return -EINVAL;
266         *p_tc_index = val;
267         return 0;
268 }
269
270 static int
271 devlink_sb_tc_index_get_from_info(struct devlink_sb *devlink_sb,
272                                   struct genl_info *info,
273                                   enum devlink_sb_pool_type pool_type,
274                                   u16 *p_tc_index)
275 {
276         return devlink_sb_tc_index_get_from_attrs(devlink_sb, info->attrs,
277                                                   pool_type, p_tc_index);
278 }
279
280 #define DEVLINK_NL_FLAG_NEED_DEVLINK    BIT(0)
281 #define DEVLINK_NL_FLAG_NEED_PORT       BIT(1)
282 #define DEVLINK_NL_FLAG_NEED_SB         BIT(2)
283 #define DEVLINK_NL_FLAG_LOCK_PORTS      BIT(3)
284         /* port is not needed but we need to ensure they don't
285          * change in the middle of command
286          */
287
288 static int devlink_nl_pre_doit(const struct genl_ops *ops,
289                                struct sk_buff *skb, struct genl_info *info)
290 {
291         struct devlink *devlink;
292
293         mutex_lock(&devlink_mutex);
294         devlink = devlink_get_from_info(info);
295         if (IS_ERR(devlink)) {
296                 mutex_unlock(&devlink_mutex);
297                 return PTR_ERR(devlink);
298         }
299         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_DEVLINK) {
300                 info->user_ptr[0] = devlink;
301         } else if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
302                 struct devlink_port *devlink_port;
303
304                 mutex_lock(&devlink_port_mutex);
305                 devlink_port = devlink_port_get_from_info(devlink, info);
306                 if (IS_ERR(devlink_port)) {
307                         mutex_unlock(&devlink_port_mutex);
308                         mutex_unlock(&devlink_mutex);
309                         return PTR_ERR(devlink_port);
310                 }
311                 info->user_ptr[0] = devlink_port;
312         }
313         if (ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS) {
314                 mutex_lock(&devlink_port_mutex);
315         }
316         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_SB) {
317                 struct devlink_sb *devlink_sb;
318
319                 devlink_sb = devlink_sb_get_from_info(devlink, info);
320                 if (IS_ERR(devlink_sb)) {
321                         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
322                                 mutex_unlock(&devlink_port_mutex);
323                         mutex_unlock(&devlink_mutex);
324                         return PTR_ERR(devlink_sb);
325                 }
326                 info->user_ptr[1] = devlink_sb;
327         }
328         return 0;
329 }
330
331 static void devlink_nl_post_doit(const struct genl_ops *ops,
332                                  struct sk_buff *skb, struct genl_info *info)
333 {
334         if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT ||
335             ops->internal_flags & DEVLINK_NL_FLAG_LOCK_PORTS)
336                 mutex_unlock(&devlink_port_mutex);
337         mutex_unlock(&devlink_mutex);
338 }
339
340 static struct genl_family devlink_nl_family = {
341         .id             = GENL_ID_GENERATE,
342         .name           = DEVLINK_GENL_NAME,
343         .version        = DEVLINK_GENL_VERSION,
344         .maxattr        = DEVLINK_ATTR_MAX,
345         .netnsok        = true,
346         .pre_doit       = devlink_nl_pre_doit,
347         .post_doit      = devlink_nl_post_doit,
348 };
349
350 enum devlink_multicast_groups {
351         DEVLINK_MCGRP_CONFIG,
352 };
353
354 static const struct genl_multicast_group devlink_nl_mcgrps[] = {
355         [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
356 };
357
358 static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
359 {
360         if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
361                 return -EMSGSIZE;
362         if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
363                 return -EMSGSIZE;
364         return 0;
365 }
366
367 static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
368                            enum devlink_command cmd, u32 portid,
369                            u32 seq, int flags)
370 {
371         void *hdr;
372
373         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
374         if (!hdr)
375                 return -EMSGSIZE;
376
377         if (devlink_nl_put_handle(msg, devlink))
378                 goto nla_put_failure;
379
380         genlmsg_end(msg, hdr);
381         return 0;
382
383 nla_put_failure:
384         genlmsg_cancel(msg, hdr);
385         return -EMSGSIZE;
386 }
387
388 static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
389 {
390         struct sk_buff *msg;
391         int err;
392
393         WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
394
395         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
396         if (!msg)
397                 return;
398
399         err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
400         if (err) {
401                 nlmsg_free(msg);
402                 return;
403         }
404
405         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
406                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
407 }
408
409 static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
410                                 struct devlink_port *devlink_port,
411                                 enum devlink_command cmd, u32 portid,
412                                 u32 seq, int flags)
413 {
414         void *hdr;
415
416         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
417         if (!hdr)
418                 return -EMSGSIZE;
419
420         if (devlink_nl_put_handle(msg, devlink))
421                 goto nla_put_failure;
422         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
423                 goto nla_put_failure;
424         if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
425                 goto nla_put_failure;
426         if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
427             nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
428                         devlink_port->desired_type))
429                 goto nla_put_failure;
430         if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
431                 struct net_device *netdev = devlink_port->type_dev;
432
433                 if (netdev &&
434                     (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
435                                  netdev->ifindex) ||
436                      nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
437                                     netdev->name)))
438                         goto nla_put_failure;
439         }
440         if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
441                 struct ib_device *ibdev = devlink_port->type_dev;
442
443                 if (ibdev &&
444                     nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
445                                    ibdev->name))
446                         goto nla_put_failure;
447         }
448         if (devlink_port->split &&
449             nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
450                         devlink_port->split_group))
451                 goto nla_put_failure;
452
453         genlmsg_end(msg, hdr);
454         return 0;
455
456 nla_put_failure:
457         genlmsg_cancel(msg, hdr);
458         return -EMSGSIZE;
459 }
460
461 static void devlink_port_notify(struct devlink_port *devlink_port,
462                                 enum devlink_command cmd)
463 {
464         struct devlink *devlink = devlink_port->devlink;
465         struct sk_buff *msg;
466         int err;
467
468         if (!devlink_port->registered)
469                 return;
470
471         WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
472
473         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
474         if (!msg)
475                 return;
476
477         err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
478         if (err) {
479                 nlmsg_free(msg);
480                 return;
481         }
482
483         genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
484                                 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
485 }
486
487 static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
488 {
489         struct devlink *devlink = info->user_ptr[0];
490         struct sk_buff *msg;
491         int err;
492
493         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
494         if (!msg)
495                 return -ENOMEM;
496
497         err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
498                               info->snd_portid, info->snd_seq, 0);
499         if (err) {
500                 nlmsg_free(msg);
501                 return err;
502         }
503
504         return genlmsg_reply(msg, info);
505 }
506
507 static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
508                                      struct netlink_callback *cb)
509 {
510         struct devlink *devlink;
511         int start = cb->args[0];
512         int idx = 0;
513         int err;
514
515         mutex_lock(&devlink_mutex);
516         list_for_each_entry(devlink, &devlink_list, list) {
517                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
518                         continue;
519                 if (idx < start) {
520                         idx++;
521                         continue;
522                 }
523                 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
524                                       NETLINK_CB(cb->skb).portid,
525                                       cb->nlh->nlmsg_seq, NLM_F_MULTI);
526                 if (err)
527                         goto out;
528                 idx++;
529         }
530 out:
531         mutex_unlock(&devlink_mutex);
532
533         cb->args[0] = idx;
534         return msg->len;
535 }
536
537 static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
538                                         struct genl_info *info)
539 {
540         struct devlink_port *devlink_port = info->user_ptr[0];
541         struct devlink *devlink = devlink_port->devlink;
542         struct sk_buff *msg;
543         int err;
544
545         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
546         if (!msg)
547                 return -ENOMEM;
548
549         err = devlink_nl_port_fill(msg, devlink, devlink_port,
550                                    DEVLINK_CMD_PORT_NEW,
551                                    info->snd_portid, info->snd_seq, 0);
552         if (err) {
553                 nlmsg_free(msg);
554                 return err;
555         }
556
557         return genlmsg_reply(msg, info);
558 }
559
560 static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
561                                           struct netlink_callback *cb)
562 {
563         struct devlink *devlink;
564         struct devlink_port *devlink_port;
565         int start = cb->args[0];
566         int idx = 0;
567         int err;
568
569         mutex_lock(&devlink_mutex);
570         mutex_lock(&devlink_port_mutex);
571         list_for_each_entry(devlink, &devlink_list, list) {
572                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
573                         continue;
574                 list_for_each_entry(devlink_port, &devlink->port_list, list) {
575                         if (idx < start) {
576                                 idx++;
577                                 continue;
578                         }
579                         err = devlink_nl_port_fill(msg, devlink, devlink_port,
580                                                    DEVLINK_CMD_NEW,
581                                                    NETLINK_CB(cb->skb).portid,
582                                                    cb->nlh->nlmsg_seq,
583                                                    NLM_F_MULTI);
584                         if (err)
585                                 goto out;
586                         idx++;
587                 }
588         }
589 out:
590         mutex_unlock(&devlink_port_mutex);
591         mutex_unlock(&devlink_mutex);
592
593         cb->args[0] = idx;
594         return msg->len;
595 }
596
597 static int devlink_port_type_set(struct devlink *devlink,
598                                  struct devlink_port *devlink_port,
599                                  enum devlink_port_type port_type)
600
601 {
602         int err;
603
604         if (devlink->ops && devlink->ops->port_type_set) {
605                 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
606                         return -EINVAL;
607                 err = devlink->ops->port_type_set(devlink_port, port_type);
608                 if (err)
609                         return err;
610                 devlink_port->desired_type = port_type;
611                 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
612                 return 0;
613         }
614         return -EOPNOTSUPP;
615 }
616
617 static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
618                                         struct genl_info *info)
619 {
620         struct devlink_port *devlink_port = info->user_ptr[0];
621         struct devlink *devlink = devlink_port->devlink;
622         int err;
623
624         if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
625                 enum devlink_port_type port_type;
626
627                 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
628                 err = devlink_port_type_set(devlink, devlink_port, port_type);
629                 if (err)
630                         return err;
631         }
632         return 0;
633 }
634
635 static int devlink_port_split(struct devlink *devlink,
636                               u32 port_index, u32 count)
637
638 {
639         if (devlink->ops && devlink->ops->port_split)
640                 return devlink->ops->port_split(devlink, port_index, count);
641         return -EOPNOTSUPP;
642 }
643
644 static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
645                                           struct genl_info *info)
646 {
647         struct devlink *devlink = info->user_ptr[0];
648         u32 port_index;
649         u32 count;
650
651         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
652             !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
653                 return -EINVAL;
654
655         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
656         count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
657         return devlink_port_split(devlink, port_index, count);
658 }
659
660 static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
661
662 {
663         if (devlink->ops && devlink->ops->port_unsplit)
664                 return devlink->ops->port_unsplit(devlink, port_index);
665         return -EOPNOTSUPP;
666 }
667
668 static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
669                                             struct genl_info *info)
670 {
671         struct devlink *devlink = info->user_ptr[0];
672         u32 port_index;
673
674         if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
675                 return -EINVAL;
676
677         port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
678         return devlink_port_unsplit(devlink, port_index);
679 }
680
681 static int devlink_nl_sb_fill(struct sk_buff *msg, struct devlink *devlink,
682                               struct devlink_sb *devlink_sb,
683                               enum devlink_command cmd, u32 portid,
684                               u32 seq, int flags)
685 {
686         void *hdr;
687
688         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
689         if (!hdr)
690                 return -EMSGSIZE;
691
692         if (devlink_nl_put_handle(msg, devlink))
693                 goto nla_put_failure;
694         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
695                 goto nla_put_failure;
696         if (nla_put_u32(msg, DEVLINK_ATTR_SB_SIZE, devlink_sb->size))
697                 goto nla_put_failure;
698         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_POOL_COUNT,
699                         devlink_sb->ingress_pools_count))
700                 goto nla_put_failure;
701         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_POOL_COUNT,
702                         devlink_sb->egress_pools_count))
703                 goto nla_put_failure;
704         if (nla_put_u16(msg, DEVLINK_ATTR_SB_INGRESS_TC_COUNT,
705                         devlink_sb->ingress_tc_count))
706                 goto nla_put_failure;
707         if (nla_put_u16(msg, DEVLINK_ATTR_SB_EGRESS_TC_COUNT,
708                         devlink_sb->egress_tc_count))
709                 goto nla_put_failure;
710
711         genlmsg_end(msg, hdr);
712         return 0;
713
714 nla_put_failure:
715         genlmsg_cancel(msg, hdr);
716         return -EMSGSIZE;
717 }
718
719 static int devlink_nl_cmd_sb_get_doit(struct sk_buff *skb,
720                                       struct genl_info *info)
721 {
722         struct devlink *devlink = info->user_ptr[0];
723         struct devlink_sb *devlink_sb = info->user_ptr[1];
724         struct sk_buff *msg;
725         int err;
726
727         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
728         if (!msg)
729                 return -ENOMEM;
730
731         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
732                                  DEVLINK_CMD_SB_NEW,
733                                  info->snd_portid, info->snd_seq, 0);
734         if (err) {
735                 nlmsg_free(msg);
736                 return err;
737         }
738
739         return genlmsg_reply(msg, info);
740 }
741
742 static int devlink_nl_cmd_sb_get_dumpit(struct sk_buff *msg,
743                                         struct netlink_callback *cb)
744 {
745         struct devlink *devlink;
746         struct devlink_sb *devlink_sb;
747         int start = cb->args[0];
748         int idx = 0;
749         int err;
750
751         mutex_lock(&devlink_mutex);
752         list_for_each_entry(devlink, &devlink_list, list) {
753                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
754                         continue;
755                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
756                         if (idx < start) {
757                                 idx++;
758                                 continue;
759                         }
760                         err = devlink_nl_sb_fill(msg, devlink, devlink_sb,
761                                                  DEVLINK_CMD_SB_NEW,
762                                                  NETLINK_CB(cb->skb).portid,
763                                                  cb->nlh->nlmsg_seq,
764                                                  NLM_F_MULTI);
765                         if (err)
766                                 goto out;
767                         idx++;
768                 }
769         }
770 out:
771         mutex_unlock(&devlink_mutex);
772
773         cb->args[0] = idx;
774         return msg->len;
775 }
776
777 static int devlink_nl_sb_pool_fill(struct sk_buff *msg, struct devlink *devlink,
778                                    struct devlink_sb *devlink_sb,
779                                    u16 pool_index, enum devlink_command cmd,
780                                    u32 portid, u32 seq, int flags)
781 {
782         struct devlink_sb_pool_info pool_info;
783         void *hdr;
784         int err;
785
786         err = devlink->ops->sb_pool_get(devlink, devlink_sb->index,
787                                         pool_index, &pool_info);
788         if (err)
789                 return err;
790
791         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
792         if (!hdr)
793                 return -EMSGSIZE;
794
795         if (devlink_nl_put_handle(msg, devlink))
796                 goto nla_put_failure;
797         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
798                 goto nla_put_failure;
799         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
800                 goto nla_put_failure;
801         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_info.pool_type))
802                 goto nla_put_failure;
803         if (nla_put_u32(msg, DEVLINK_ATTR_SB_POOL_SIZE, pool_info.size))
804                 goto nla_put_failure;
805         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE,
806                        pool_info.threshold_type))
807                 goto nla_put_failure;
808
809         genlmsg_end(msg, hdr);
810         return 0;
811
812 nla_put_failure:
813         genlmsg_cancel(msg, hdr);
814         return -EMSGSIZE;
815 }
816
817 static int devlink_nl_cmd_sb_pool_get_doit(struct sk_buff *skb,
818                                            struct genl_info *info)
819 {
820         struct devlink *devlink = info->user_ptr[0];
821         struct devlink_sb *devlink_sb = info->user_ptr[1];
822         struct sk_buff *msg;
823         u16 pool_index;
824         int err;
825
826         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
827                                                   &pool_index);
828         if (err)
829                 return err;
830
831         if (!devlink->ops || !devlink->ops->sb_pool_get)
832                 return -EOPNOTSUPP;
833
834         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
835         if (!msg)
836                 return -ENOMEM;
837
838         err = devlink_nl_sb_pool_fill(msg, devlink, devlink_sb, pool_index,
839                                       DEVLINK_CMD_SB_POOL_NEW,
840                                       info->snd_portid, info->snd_seq, 0);
841         if (err) {
842                 nlmsg_free(msg);
843                 return err;
844         }
845
846         return genlmsg_reply(msg, info);
847 }
848
849 static int __sb_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
850                                 struct devlink *devlink,
851                                 struct devlink_sb *devlink_sb,
852                                 u32 portid, u32 seq)
853 {
854         u16 pool_count = devlink_sb_pool_count(devlink_sb);
855         u16 pool_index;
856         int err;
857
858         for (pool_index = 0; pool_index < pool_count; pool_index++) {
859                 if (*p_idx < start) {
860                         (*p_idx)++;
861                         continue;
862                 }
863                 err = devlink_nl_sb_pool_fill(msg, devlink,
864                                               devlink_sb,
865                                               pool_index,
866                                               DEVLINK_CMD_SB_POOL_NEW,
867                                               portid, seq, NLM_F_MULTI);
868                 if (err)
869                         return err;
870                 (*p_idx)++;
871         }
872         return 0;
873 }
874
875 static int devlink_nl_cmd_sb_pool_get_dumpit(struct sk_buff *msg,
876                                              struct netlink_callback *cb)
877 {
878         struct devlink *devlink;
879         struct devlink_sb *devlink_sb;
880         int start = cb->args[0];
881         int idx = 0;
882         int err;
883
884         mutex_lock(&devlink_mutex);
885         list_for_each_entry(devlink, &devlink_list, list) {
886                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
887                     !devlink->ops || !devlink->ops->sb_pool_get)
888                         continue;
889                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
890                         err = __sb_pool_get_dumpit(msg, start, &idx, devlink,
891                                                    devlink_sb,
892                                                    NETLINK_CB(cb->skb).portid,
893                                                    cb->nlh->nlmsg_seq);
894                         if (err && err != -EOPNOTSUPP)
895                                 goto out;
896                 }
897         }
898 out:
899         mutex_unlock(&devlink_mutex);
900
901         cb->args[0] = idx;
902         return msg->len;
903 }
904
905 static int devlink_sb_pool_set(struct devlink *devlink, unsigned int sb_index,
906                                u16 pool_index, u32 size,
907                                enum devlink_sb_threshold_type threshold_type)
908
909 {
910         const struct devlink_ops *ops = devlink->ops;
911
912         if (ops && ops->sb_pool_set)
913                 return ops->sb_pool_set(devlink, sb_index, pool_index,
914                                         size, threshold_type);
915         return -EOPNOTSUPP;
916 }
917
918 static int devlink_nl_cmd_sb_pool_set_doit(struct sk_buff *skb,
919                                            struct genl_info *info)
920 {
921         struct devlink *devlink = info->user_ptr[0];
922         struct devlink_sb *devlink_sb = info->user_ptr[1];
923         enum devlink_sb_threshold_type threshold_type;
924         u16 pool_index;
925         u32 size;
926         int err;
927
928         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
929                                                   &pool_index);
930         if (err)
931                 return err;
932
933         err = devlink_sb_th_type_get_from_info(info, &threshold_type);
934         if (err)
935                 return err;
936
937         if (!info->attrs[DEVLINK_ATTR_SB_POOL_SIZE])
938                 return -EINVAL;
939
940         size = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_POOL_SIZE]);
941         return devlink_sb_pool_set(devlink, devlink_sb->index,
942                                    pool_index, size, threshold_type);
943 }
944
945 static int devlink_nl_sb_port_pool_fill(struct sk_buff *msg,
946                                         struct devlink *devlink,
947                                         struct devlink_port *devlink_port,
948                                         struct devlink_sb *devlink_sb,
949                                         u16 pool_index,
950                                         enum devlink_command cmd,
951                                         u32 portid, u32 seq, int flags)
952 {
953         const struct devlink_ops *ops = devlink->ops;
954         u32 threshold;
955         void *hdr;
956         int err;
957
958         err = ops->sb_port_pool_get(devlink_port, devlink_sb->index,
959                                     pool_index, &threshold);
960         if (err)
961                 return err;
962
963         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
964         if (!hdr)
965                 return -EMSGSIZE;
966
967         if (devlink_nl_put_handle(msg, devlink))
968                 goto nla_put_failure;
969         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
970                 goto nla_put_failure;
971         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
972                 goto nla_put_failure;
973         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
974                 goto nla_put_failure;
975         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
976                 goto nla_put_failure;
977
978         if (ops->sb_occ_port_pool_get) {
979                 u32 cur;
980                 u32 max;
981
982                 err = ops->sb_occ_port_pool_get(devlink_port, devlink_sb->index,
983                                                 pool_index, &cur, &max);
984                 if (err && err != -EOPNOTSUPP)
985                         return err;
986                 if (!err) {
987                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
988                                 goto nla_put_failure;
989                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
990                                 goto nla_put_failure;
991                 }
992         }
993
994         genlmsg_end(msg, hdr);
995         return 0;
996
997 nla_put_failure:
998         genlmsg_cancel(msg, hdr);
999         return -EMSGSIZE;
1000 }
1001
1002 static int devlink_nl_cmd_sb_port_pool_get_doit(struct sk_buff *skb,
1003                                                 struct genl_info *info)
1004 {
1005         struct devlink_port *devlink_port = info->user_ptr[0];
1006         struct devlink *devlink = devlink_port->devlink;
1007         struct devlink_sb *devlink_sb = info->user_ptr[1];
1008         struct sk_buff *msg;
1009         u16 pool_index;
1010         int err;
1011
1012         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1013                                                   &pool_index);
1014         if (err)
1015                 return err;
1016
1017         if (!devlink->ops || !devlink->ops->sb_port_pool_get)
1018                 return -EOPNOTSUPP;
1019
1020         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1021         if (!msg)
1022                 return -ENOMEM;
1023
1024         err = devlink_nl_sb_port_pool_fill(msg, devlink, devlink_port,
1025                                            devlink_sb, pool_index,
1026                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1027                                            info->snd_portid, info->snd_seq, 0);
1028         if (err) {
1029                 nlmsg_free(msg);
1030                 return err;
1031         }
1032
1033         return genlmsg_reply(msg, info);
1034 }
1035
1036 static int __sb_port_pool_get_dumpit(struct sk_buff *msg, int start, int *p_idx,
1037                                      struct devlink *devlink,
1038                                      struct devlink_sb *devlink_sb,
1039                                      u32 portid, u32 seq)
1040 {
1041         struct devlink_port *devlink_port;
1042         u16 pool_count = devlink_sb_pool_count(devlink_sb);
1043         u16 pool_index;
1044         int err;
1045
1046         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1047                 for (pool_index = 0; pool_index < pool_count; pool_index++) {
1048                         if (*p_idx < start) {
1049                                 (*p_idx)++;
1050                                 continue;
1051                         }
1052                         err = devlink_nl_sb_port_pool_fill(msg, devlink,
1053                                                            devlink_port,
1054                                                            devlink_sb,
1055                                                            pool_index,
1056                                                            DEVLINK_CMD_SB_PORT_POOL_NEW,
1057                                                            portid, seq,
1058                                                            NLM_F_MULTI);
1059                         if (err)
1060                                 return err;
1061                         (*p_idx)++;
1062                 }
1063         }
1064         return 0;
1065 }
1066
1067 static int devlink_nl_cmd_sb_port_pool_get_dumpit(struct sk_buff *msg,
1068                                                   struct netlink_callback *cb)
1069 {
1070         struct devlink *devlink;
1071         struct devlink_sb *devlink_sb;
1072         int start = cb->args[0];
1073         int idx = 0;
1074         int err;
1075
1076         mutex_lock(&devlink_mutex);
1077         mutex_lock(&devlink_port_mutex);
1078         list_for_each_entry(devlink, &devlink_list, list) {
1079                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1080                     !devlink->ops || !devlink->ops->sb_port_pool_get)
1081                         continue;
1082                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1083                         err = __sb_port_pool_get_dumpit(msg, start, &idx,
1084                                                         devlink, devlink_sb,
1085                                                         NETLINK_CB(cb->skb).portid,
1086                                                         cb->nlh->nlmsg_seq);
1087                         if (err && err != -EOPNOTSUPP)
1088                                 goto out;
1089                 }
1090         }
1091 out:
1092         mutex_unlock(&devlink_port_mutex);
1093         mutex_unlock(&devlink_mutex);
1094
1095         cb->args[0] = idx;
1096         return msg->len;
1097 }
1098
1099 static int devlink_sb_port_pool_set(struct devlink_port *devlink_port,
1100                                     unsigned int sb_index, u16 pool_index,
1101                                     u32 threshold)
1102
1103 {
1104         const struct devlink_ops *ops = devlink_port->devlink->ops;
1105
1106         if (ops && ops->sb_port_pool_set)
1107                 return ops->sb_port_pool_set(devlink_port, sb_index,
1108                                              pool_index, threshold);
1109         return -EOPNOTSUPP;
1110 }
1111
1112 static int devlink_nl_cmd_sb_port_pool_set_doit(struct sk_buff *skb,
1113                                                 struct genl_info *info)
1114 {
1115         struct devlink_port *devlink_port = info->user_ptr[0];
1116         struct devlink_sb *devlink_sb = info->user_ptr[1];
1117         u16 pool_index;
1118         u32 threshold;
1119         int err;
1120
1121         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1122                                                   &pool_index);
1123         if (err)
1124                 return err;
1125
1126         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1127                 return -EINVAL;
1128
1129         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1130         return devlink_sb_port_pool_set(devlink_port, devlink_sb->index,
1131                                         pool_index, threshold);
1132 }
1133
1134 static int
1135 devlink_nl_sb_tc_pool_bind_fill(struct sk_buff *msg, struct devlink *devlink,
1136                                 struct devlink_port *devlink_port,
1137                                 struct devlink_sb *devlink_sb, u16 tc_index,
1138                                 enum devlink_sb_pool_type pool_type,
1139                                 enum devlink_command cmd,
1140                                 u32 portid, u32 seq, int flags)
1141 {
1142         const struct devlink_ops *ops = devlink->ops;
1143         u16 pool_index;
1144         u32 threshold;
1145         void *hdr;
1146         int err;
1147
1148         err = ops->sb_tc_pool_bind_get(devlink_port, devlink_sb->index,
1149                                        tc_index, pool_type,
1150                                        &pool_index, &threshold);
1151         if (err)
1152                 return err;
1153
1154         hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
1155         if (!hdr)
1156                 return -EMSGSIZE;
1157
1158         if (devlink_nl_put_handle(msg, devlink))
1159                 goto nla_put_failure;
1160         if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
1161                 goto nla_put_failure;
1162         if (nla_put_u32(msg, DEVLINK_ATTR_SB_INDEX, devlink_sb->index))
1163                 goto nla_put_failure;
1164         if (nla_put_u16(msg, DEVLINK_ATTR_SB_TC_INDEX, tc_index))
1165                 goto nla_put_failure;
1166         if (nla_put_u8(msg, DEVLINK_ATTR_SB_POOL_TYPE, pool_type))
1167                 goto nla_put_failure;
1168         if (nla_put_u16(msg, DEVLINK_ATTR_SB_POOL_INDEX, pool_index))
1169                 goto nla_put_failure;
1170         if (nla_put_u32(msg, DEVLINK_ATTR_SB_THRESHOLD, threshold))
1171                 goto nla_put_failure;
1172
1173         if (ops->sb_occ_tc_port_bind_get) {
1174                 u32 cur;
1175                 u32 max;
1176
1177                 err = ops->sb_occ_tc_port_bind_get(devlink_port,
1178                                                    devlink_sb->index,
1179                                                    tc_index, pool_type,
1180                                                    &cur, &max);
1181                 if (err && err != -EOPNOTSUPP)
1182                         return err;
1183                 if (!err) {
1184                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_CUR, cur))
1185                                 goto nla_put_failure;
1186                         if (nla_put_u32(msg, DEVLINK_ATTR_SB_OCC_MAX, max))
1187                                 goto nla_put_failure;
1188                 }
1189         }
1190
1191         genlmsg_end(msg, hdr);
1192         return 0;
1193
1194 nla_put_failure:
1195         genlmsg_cancel(msg, hdr);
1196         return -EMSGSIZE;
1197 }
1198
1199 static int devlink_nl_cmd_sb_tc_pool_bind_get_doit(struct sk_buff *skb,
1200                                                    struct genl_info *info)
1201 {
1202         struct devlink_port *devlink_port = info->user_ptr[0];
1203         struct devlink *devlink = devlink_port->devlink;
1204         struct devlink_sb *devlink_sb = info->user_ptr[1];
1205         struct sk_buff *msg;
1206         enum devlink_sb_pool_type pool_type;
1207         u16 tc_index;
1208         int err;
1209
1210         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1211         if (err)
1212                 return err;
1213
1214         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1215                                                 pool_type, &tc_index);
1216         if (err)
1217                 return err;
1218
1219         if (!devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1220                 return -EOPNOTSUPP;
1221
1222         msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
1223         if (!msg)
1224                 return -ENOMEM;
1225
1226         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink, devlink_port,
1227                                               devlink_sb, tc_index, pool_type,
1228                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1229                                               info->snd_portid,
1230                                               info->snd_seq, 0);
1231         if (err) {
1232                 nlmsg_free(msg);
1233                 return err;
1234         }
1235
1236         return genlmsg_reply(msg, info);
1237 }
1238
1239 static int __sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1240                                         int start, int *p_idx,
1241                                         struct devlink *devlink,
1242                                         struct devlink_sb *devlink_sb,
1243                                         u32 portid, u32 seq)
1244 {
1245         struct devlink_port *devlink_port;
1246         u16 tc_index;
1247         int err;
1248
1249         list_for_each_entry(devlink_port, &devlink->port_list, list) {
1250                 for (tc_index = 0;
1251                      tc_index < devlink_sb->ingress_tc_count; tc_index++) {
1252                         if (*p_idx < start) {
1253                                 (*p_idx)++;
1254                                 continue;
1255                         }
1256                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1257                                                               devlink_port,
1258                                                               devlink_sb,
1259                                                               tc_index,
1260                                                               DEVLINK_SB_POOL_TYPE_INGRESS,
1261                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1262                                                               portid, seq,
1263                                                               NLM_F_MULTI);
1264                         if (err)
1265                                 return err;
1266                         (*p_idx)++;
1267                 }
1268                 for (tc_index = 0;
1269                      tc_index < devlink_sb->egress_tc_count; tc_index++) {
1270                         if (*p_idx < start) {
1271                                 (*p_idx)++;
1272                                 continue;
1273                         }
1274                         err = devlink_nl_sb_tc_pool_bind_fill(msg, devlink,
1275                                                               devlink_port,
1276                                                               devlink_sb,
1277                                                               tc_index,
1278                                                               DEVLINK_SB_POOL_TYPE_EGRESS,
1279                                                               DEVLINK_CMD_SB_TC_POOL_BIND_NEW,
1280                                                               portid, seq,
1281                                                               NLM_F_MULTI);
1282                         if (err)
1283                                 return err;
1284                         (*p_idx)++;
1285                 }
1286         }
1287         return 0;
1288 }
1289
1290 static int
1291 devlink_nl_cmd_sb_tc_pool_bind_get_dumpit(struct sk_buff *msg,
1292                                           struct netlink_callback *cb)
1293 {
1294         struct devlink *devlink;
1295         struct devlink_sb *devlink_sb;
1296         int start = cb->args[0];
1297         int idx = 0;
1298         int err;
1299
1300         mutex_lock(&devlink_mutex);
1301         mutex_lock(&devlink_port_mutex);
1302         list_for_each_entry(devlink, &devlink_list, list) {
1303                 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)) ||
1304                     !devlink->ops || !devlink->ops->sb_tc_pool_bind_get)
1305                         continue;
1306                 list_for_each_entry(devlink_sb, &devlink->sb_list, list) {
1307                         err = __sb_tc_pool_bind_get_dumpit(msg, start, &idx,
1308                                                            devlink,
1309                                                            devlink_sb,
1310                                                            NETLINK_CB(cb->skb).portid,
1311                                                            cb->nlh->nlmsg_seq);
1312                         if (err && err != -EOPNOTSUPP)
1313                                 goto out;
1314                 }
1315         }
1316 out:
1317         mutex_unlock(&devlink_port_mutex);
1318         mutex_unlock(&devlink_mutex);
1319
1320         cb->args[0] = idx;
1321         return msg->len;
1322 }
1323
1324 static int devlink_sb_tc_pool_bind_set(struct devlink_port *devlink_port,
1325                                        unsigned int sb_index, u16 tc_index,
1326                                        enum devlink_sb_pool_type pool_type,
1327                                        u16 pool_index, u32 threshold)
1328
1329 {
1330         const struct devlink_ops *ops = devlink_port->devlink->ops;
1331
1332         if (ops && ops->sb_tc_pool_bind_set)
1333                 return ops->sb_tc_pool_bind_set(devlink_port, sb_index,
1334                                                 tc_index, pool_type,
1335                                                 pool_index, threshold);
1336         return -EOPNOTSUPP;
1337 }
1338
1339 static int devlink_nl_cmd_sb_tc_pool_bind_set_doit(struct sk_buff *skb,
1340                                                    struct genl_info *info)
1341 {
1342         struct devlink_port *devlink_port = info->user_ptr[0];
1343         struct devlink_sb *devlink_sb = info->user_ptr[1];
1344         enum devlink_sb_pool_type pool_type;
1345         u16 tc_index;
1346         u16 pool_index;
1347         u32 threshold;
1348         int err;
1349
1350         err = devlink_sb_pool_type_get_from_info(info, &pool_type);
1351         if (err)
1352                 return err;
1353
1354         err = devlink_sb_tc_index_get_from_info(devlink_sb, info,
1355                                                 pool_type, &tc_index);
1356         if (err)
1357                 return err;
1358
1359         err = devlink_sb_pool_index_get_from_info(devlink_sb, info,
1360                                                   &pool_index);
1361         if (err)
1362                 return err;
1363
1364         if (!info->attrs[DEVLINK_ATTR_SB_THRESHOLD])
1365                 return -EINVAL;
1366
1367         threshold = nla_get_u32(info->attrs[DEVLINK_ATTR_SB_THRESHOLD]);
1368         return devlink_sb_tc_pool_bind_set(devlink_port, devlink_sb->index,
1369                                            tc_index, pool_type,
1370                                            pool_index, threshold);
1371 }
1372
1373 static int devlink_nl_cmd_sb_occ_snapshot_doit(struct sk_buff *skb,
1374                                                struct genl_info *info)
1375 {
1376         struct devlink *devlink = info->user_ptr[0];
1377         struct devlink_sb *devlink_sb = info->user_ptr[1];
1378         const struct devlink_ops *ops = devlink->ops;
1379
1380         if (ops && ops->sb_occ_snapshot)
1381                 return ops->sb_occ_snapshot(devlink, devlink_sb->index);
1382         return -EOPNOTSUPP;
1383 }
1384
1385 static int devlink_nl_cmd_sb_occ_max_clear_doit(struct sk_buff *skb,
1386                                                 struct genl_info *info)
1387 {
1388         struct devlink *devlink = info->user_ptr[0];
1389         struct devlink_sb *devlink_sb = info->user_ptr[1];
1390         const struct devlink_ops *ops = devlink->ops;
1391
1392         if (ops && ops->sb_occ_max_clear)
1393                 return ops->sb_occ_max_clear(devlink, devlink_sb->index);
1394         return -EOPNOTSUPP;
1395 }
1396
1397 static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
1398         [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
1399         [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
1400         [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
1401         [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
1402         [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
1403         [DEVLINK_ATTR_SB_INDEX] = { .type = NLA_U32 },
1404         [DEVLINK_ATTR_SB_POOL_INDEX] = { .type = NLA_U16 },
1405         [DEVLINK_ATTR_SB_POOL_TYPE] = { .type = NLA_U8 },
1406         [DEVLINK_ATTR_SB_POOL_SIZE] = { .type = NLA_U32 },
1407         [DEVLINK_ATTR_SB_POOL_THRESHOLD_TYPE] = { .type = NLA_U8 },
1408         [DEVLINK_ATTR_SB_THRESHOLD] = { .type = NLA_U32 },
1409         [DEVLINK_ATTR_SB_TC_INDEX] = { .type = NLA_U16 },
1410 };
1411
1412 static const struct genl_ops devlink_nl_ops[] = {
1413         {
1414                 .cmd = DEVLINK_CMD_GET,
1415                 .doit = devlink_nl_cmd_get_doit,
1416                 .dumpit = devlink_nl_cmd_get_dumpit,
1417                 .policy = devlink_nl_policy,
1418                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1419                 /* can be retrieved by unprivileged users */
1420         },
1421         {
1422                 .cmd = DEVLINK_CMD_PORT_GET,
1423                 .doit = devlink_nl_cmd_port_get_doit,
1424                 .dumpit = devlink_nl_cmd_port_get_dumpit,
1425                 .policy = devlink_nl_policy,
1426                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
1427                 /* can be retrieved by unprivileged users */
1428         },
1429         {
1430                 .cmd = DEVLINK_CMD_PORT_SET,
1431                 .doit = devlink_nl_cmd_port_set_doit,
1432                 .policy = devlink_nl_policy,
1433                 .flags = GENL_ADMIN_PERM,
1434                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
1435         },
1436         {
1437                 .cmd = DEVLINK_CMD_PORT_SPLIT,
1438                 .doit = devlink_nl_cmd_port_split_doit,
1439                 .policy = devlink_nl_policy,
1440                 .flags = GENL_ADMIN_PERM,
1441                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1442         },
1443         {
1444                 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
1445                 .doit = devlink_nl_cmd_port_unsplit_doit,
1446                 .policy = devlink_nl_policy,
1447                 .flags = GENL_ADMIN_PERM,
1448                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK,
1449         },
1450         {
1451                 .cmd = DEVLINK_CMD_SB_GET,
1452                 .doit = devlink_nl_cmd_sb_get_doit,
1453                 .dumpit = devlink_nl_cmd_sb_get_dumpit,
1454                 .policy = devlink_nl_policy,
1455                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1456                                   DEVLINK_NL_FLAG_NEED_SB,
1457                 /* can be retrieved by unprivileged users */
1458         },
1459         {
1460                 .cmd = DEVLINK_CMD_SB_POOL_GET,
1461                 .doit = devlink_nl_cmd_sb_pool_get_doit,
1462                 .dumpit = devlink_nl_cmd_sb_pool_get_dumpit,
1463                 .policy = devlink_nl_policy,
1464                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1465                                   DEVLINK_NL_FLAG_NEED_SB,
1466                 /* can be retrieved by unprivileged users */
1467         },
1468         {
1469                 .cmd = DEVLINK_CMD_SB_POOL_SET,
1470                 .doit = devlink_nl_cmd_sb_pool_set_doit,
1471                 .policy = devlink_nl_policy,
1472                 .flags = GENL_ADMIN_PERM,
1473                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1474                                   DEVLINK_NL_FLAG_NEED_SB,
1475         },
1476         {
1477                 .cmd = DEVLINK_CMD_SB_PORT_POOL_GET,
1478                 .doit = devlink_nl_cmd_sb_port_pool_get_doit,
1479                 .dumpit = devlink_nl_cmd_sb_port_pool_get_dumpit,
1480                 .policy = devlink_nl_policy,
1481                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1482                                   DEVLINK_NL_FLAG_NEED_SB,
1483                 /* can be retrieved by unprivileged users */
1484         },
1485         {
1486                 .cmd = DEVLINK_CMD_SB_PORT_POOL_SET,
1487                 .doit = devlink_nl_cmd_sb_port_pool_set_doit,
1488                 .policy = devlink_nl_policy,
1489                 .flags = GENL_ADMIN_PERM,
1490                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1491                                   DEVLINK_NL_FLAG_NEED_SB,
1492         },
1493         {
1494                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_GET,
1495                 .doit = devlink_nl_cmd_sb_tc_pool_bind_get_doit,
1496                 .dumpit = devlink_nl_cmd_sb_tc_pool_bind_get_dumpit,
1497                 .policy = devlink_nl_policy,
1498                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1499                                   DEVLINK_NL_FLAG_NEED_SB,
1500                 /* can be retrieved by unprivileged users */
1501         },
1502         {
1503                 .cmd = DEVLINK_CMD_SB_TC_POOL_BIND_SET,
1504                 .doit = devlink_nl_cmd_sb_tc_pool_bind_set_doit,
1505                 .policy = devlink_nl_policy,
1506                 .flags = GENL_ADMIN_PERM,
1507                 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT |
1508                                   DEVLINK_NL_FLAG_NEED_SB,
1509         },
1510         {
1511                 .cmd = DEVLINK_CMD_SB_OCC_SNAPSHOT,
1512                 .doit = devlink_nl_cmd_sb_occ_snapshot_doit,
1513                 .policy = devlink_nl_policy,
1514                 .flags = GENL_ADMIN_PERM,
1515                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1516                                   DEVLINK_NL_FLAG_NEED_SB |
1517                                   DEVLINK_NL_FLAG_LOCK_PORTS,
1518         },
1519         {
1520                 .cmd = DEVLINK_CMD_SB_OCC_MAX_CLEAR,
1521                 .doit = devlink_nl_cmd_sb_occ_max_clear_doit,
1522                 .policy = devlink_nl_policy,
1523                 .flags = GENL_ADMIN_PERM,
1524                 .internal_flags = DEVLINK_NL_FLAG_NEED_DEVLINK |
1525                                   DEVLINK_NL_FLAG_NEED_SB |
1526                                   DEVLINK_NL_FLAG_LOCK_PORTS,
1527         },
1528 };
1529
1530 /**
1531  *      devlink_alloc - Allocate new devlink instance resources
1532  *
1533  *      @ops: ops
1534  *      @priv_size: size of user private data
1535  *
1536  *      Allocate new devlink instance resources, including devlink index
1537  *      and name.
1538  */
1539 struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
1540 {
1541         struct devlink *devlink;
1542
1543         devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
1544         if (!devlink)
1545                 return NULL;
1546         devlink->ops = ops;
1547         devlink_net_set(devlink, &init_net);
1548         INIT_LIST_HEAD(&devlink->port_list);
1549         INIT_LIST_HEAD(&devlink->sb_list);
1550         return devlink;
1551 }
1552 EXPORT_SYMBOL_GPL(devlink_alloc);
1553
1554 /**
1555  *      devlink_register - Register devlink instance
1556  *
1557  *      @devlink: devlink
1558  */
1559 int devlink_register(struct devlink *devlink, struct device *dev)
1560 {
1561         mutex_lock(&devlink_mutex);
1562         devlink->dev = dev;
1563         list_add_tail(&devlink->list, &devlink_list);
1564         devlink_notify(devlink, DEVLINK_CMD_NEW);
1565         mutex_unlock(&devlink_mutex);
1566         return 0;
1567 }
1568 EXPORT_SYMBOL_GPL(devlink_register);
1569
1570 /**
1571  *      devlink_unregister - Unregister devlink instance
1572  *
1573  *      @devlink: devlink
1574  */
1575 void devlink_unregister(struct devlink *devlink)
1576 {
1577         mutex_lock(&devlink_mutex);
1578         devlink_notify(devlink, DEVLINK_CMD_DEL);
1579         list_del(&devlink->list);
1580         mutex_unlock(&devlink_mutex);
1581 }
1582 EXPORT_SYMBOL_GPL(devlink_unregister);
1583
1584 /**
1585  *      devlink_free - Free devlink instance resources
1586  *
1587  *      @devlink: devlink
1588  */
1589 void devlink_free(struct devlink *devlink)
1590 {
1591         kfree(devlink);
1592 }
1593 EXPORT_SYMBOL_GPL(devlink_free);
1594
1595 /**
1596  *      devlink_port_register - Register devlink port
1597  *
1598  *      @devlink: devlink
1599  *      @devlink_port: devlink port
1600  *      @port_index
1601  *
1602  *      Register devlink port with provided port index. User can use
1603  *      any indexing, even hw-related one. devlink_port structure
1604  *      is convenient to be embedded inside user driver private structure.
1605  *      Note that the caller should take care of zeroing the devlink_port
1606  *      structure.
1607  */
1608 int devlink_port_register(struct devlink *devlink,
1609                           struct devlink_port *devlink_port,
1610                           unsigned int port_index)
1611 {
1612         mutex_lock(&devlink_port_mutex);
1613         if (devlink_port_index_exists(devlink, port_index)) {
1614                 mutex_unlock(&devlink_port_mutex);
1615                 return -EEXIST;
1616         }
1617         devlink_port->devlink = devlink;
1618         devlink_port->index = port_index;
1619         devlink_port->registered = true;
1620         list_add_tail(&devlink_port->list, &devlink->port_list);
1621         mutex_unlock(&devlink_port_mutex);
1622         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1623         return 0;
1624 }
1625 EXPORT_SYMBOL_GPL(devlink_port_register);
1626
1627 /**
1628  *      devlink_port_unregister - Unregister devlink port
1629  *
1630  *      @devlink_port: devlink port
1631  */
1632 void devlink_port_unregister(struct devlink_port *devlink_port)
1633 {
1634         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
1635         mutex_lock(&devlink_port_mutex);
1636         list_del(&devlink_port->list);
1637         mutex_unlock(&devlink_port_mutex);
1638 }
1639 EXPORT_SYMBOL_GPL(devlink_port_unregister);
1640
1641 static void __devlink_port_type_set(struct devlink_port *devlink_port,
1642                                     enum devlink_port_type type,
1643                                     void *type_dev)
1644 {
1645         devlink_port->type = type;
1646         devlink_port->type_dev = type_dev;
1647         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1648 }
1649
1650 /**
1651  *      devlink_port_type_eth_set - Set port type to Ethernet
1652  *
1653  *      @devlink_port: devlink port
1654  *      @netdev: related netdevice
1655  */
1656 void devlink_port_type_eth_set(struct devlink_port *devlink_port,
1657                                struct net_device *netdev)
1658 {
1659         return __devlink_port_type_set(devlink_port,
1660                                        DEVLINK_PORT_TYPE_ETH, netdev);
1661 }
1662 EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
1663
1664 /**
1665  *      devlink_port_type_ib_set - Set port type to InfiniBand
1666  *
1667  *      @devlink_port: devlink port
1668  *      @ibdev: related IB device
1669  */
1670 void devlink_port_type_ib_set(struct devlink_port *devlink_port,
1671                               struct ib_device *ibdev)
1672 {
1673         return __devlink_port_type_set(devlink_port,
1674                                        DEVLINK_PORT_TYPE_IB, ibdev);
1675 }
1676 EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
1677
1678 /**
1679  *      devlink_port_type_clear - Clear port type
1680  *
1681  *      @devlink_port: devlink port
1682  */
1683 void devlink_port_type_clear(struct devlink_port *devlink_port)
1684 {
1685         return __devlink_port_type_set(devlink_port,
1686                                        DEVLINK_PORT_TYPE_NOTSET, NULL);
1687 }
1688 EXPORT_SYMBOL_GPL(devlink_port_type_clear);
1689
1690 /**
1691  *      devlink_port_split_set - Set port is split
1692  *
1693  *      @devlink_port: devlink port
1694  *      @split_group: split group - identifies group split port is part of
1695  */
1696 void devlink_port_split_set(struct devlink_port *devlink_port,
1697                             u32 split_group)
1698 {
1699         devlink_port->split = true;
1700         devlink_port->split_group = split_group;
1701         devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
1702 }
1703 EXPORT_SYMBOL_GPL(devlink_port_split_set);
1704
1705 int devlink_sb_register(struct devlink *devlink, unsigned int sb_index,
1706                         u32 size, u16 ingress_pools_count,
1707                         u16 egress_pools_count, u16 ingress_tc_count,
1708                         u16 egress_tc_count)
1709 {
1710         struct devlink_sb *devlink_sb;
1711         int err = 0;
1712
1713         mutex_lock(&devlink_mutex);
1714         if (devlink_sb_index_exists(devlink, sb_index)) {
1715                 err = -EEXIST;
1716                 goto unlock;
1717         }
1718
1719         devlink_sb = kzalloc(sizeof(*devlink_sb), GFP_KERNEL);
1720         if (!devlink_sb) {
1721                 err = -ENOMEM;
1722                 goto unlock;
1723         }
1724         devlink_sb->index = sb_index;
1725         devlink_sb->size = size;
1726         devlink_sb->ingress_pools_count = ingress_pools_count;
1727         devlink_sb->egress_pools_count = egress_pools_count;
1728         devlink_sb->ingress_tc_count = ingress_tc_count;
1729         devlink_sb->egress_tc_count = egress_tc_count;
1730         list_add_tail(&devlink_sb->list, &devlink->sb_list);
1731 unlock:
1732         mutex_unlock(&devlink_mutex);
1733         return err;
1734 }
1735 EXPORT_SYMBOL_GPL(devlink_sb_register);
1736
1737 void devlink_sb_unregister(struct devlink *devlink, unsigned int sb_index)
1738 {
1739         struct devlink_sb *devlink_sb;
1740
1741         mutex_lock(&devlink_mutex);
1742         devlink_sb = devlink_sb_get_by_index(devlink, sb_index);
1743         WARN_ON(!devlink_sb);
1744         list_del(&devlink_sb->list);
1745         mutex_unlock(&devlink_mutex);
1746         kfree(devlink_sb);
1747 }
1748 EXPORT_SYMBOL_GPL(devlink_sb_unregister);
1749
1750 static int __init devlink_module_init(void)
1751 {
1752         return genl_register_family_with_ops_groups(&devlink_nl_family,
1753                                                     devlink_nl_ops,
1754                                                     devlink_nl_mcgrps);
1755 }
1756
1757 static void __exit devlink_module_exit(void)
1758 {
1759         genl_unregister_family(&devlink_nl_family);
1760 }
1761
1762 module_init(devlink_module_init);
1763 module_exit(devlink_module_exit);
1764
1765 MODULE_LICENSE("GPL v2");
1766 MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
1767 MODULE_DESCRIPTION("Network physical device Netlink interface");
1768 MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);