tracing: add sched_set_prio tracepoint
[deliverable/linux.git] / net / core / devlink.c
CommitLineData
bfcd3a46
JP
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
30static 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 */
38static DEFINE_MUTEX(devlink_mutex);
39
40/* devlink_port_mutex
41 *
42 * Shared lock to guard lists of ports in all devlink devices.
43 */
44static DEFINE_MUTEX(devlink_port_mutex);
45
46static struct net *devlink_net(const struct devlink *devlink)
47{
48 return read_pnet(&devlink->_net);
49}
50
51static void devlink_net_set(struct devlink *devlink, struct net *net)
52{
53 write_pnet(&devlink->_net, net);
54}
55
56static 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
79static 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
84static 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
96static bool devlink_port_index_exists(struct devlink *devlink, int port_index)
97{
98 return devlink_port_get_by_index(devlink, port_index);
99}
100
101static 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
116static 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#define DEVLINK_NL_FLAG_NEED_PORT BIT(0)
123
124static int devlink_nl_pre_doit(const struct genl_ops *ops,
125 struct sk_buff *skb, struct genl_info *info)
126{
127 struct devlink *devlink;
128
129 mutex_lock(&devlink_mutex);
130 devlink = devlink_get_from_info(info);
131 if (IS_ERR(devlink)) {
132 mutex_unlock(&devlink_mutex);
133 return PTR_ERR(devlink);
134 }
135 info->user_ptr[0] = devlink;
136 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT) {
137 struct devlink_port *devlink_port;
138
139 mutex_lock(&devlink_port_mutex);
140 devlink_port = devlink_port_get_from_info(devlink, info);
141 if (IS_ERR(devlink_port)) {
142 mutex_unlock(&devlink_port_mutex);
143 mutex_unlock(&devlink_mutex);
144 return PTR_ERR(devlink_port);
145 }
146 info->user_ptr[1] = devlink_port;
147 }
148 return 0;
149}
150
151static void devlink_nl_post_doit(const struct genl_ops *ops,
152 struct sk_buff *skb, struct genl_info *info)
153{
154 if (ops->internal_flags & DEVLINK_NL_FLAG_NEED_PORT)
155 mutex_unlock(&devlink_port_mutex);
156 mutex_unlock(&devlink_mutex);
157}
158
159static struct genl_family devlink_nl_family = {
160 .id = GENL_ID_GENERATE,
161 .name = DEVLINK_GENL_NAME,
162 .version = DEVLINK_GENL_VERSION,
163 .maxattr = DEVLINK_ATTR_MAX,
164 .netnsok = true,
165 .pre_doit = devlink_nl_pre_doit,
166 .post_doit = devlink_nl_post_doit,
167};
168
169enum devlink_multicast_groups {
170 DEVLINK_MCGRP_CONFIG,
171};
172
173static const struct genl_multicast_group devlink_nl_mcgrps[] = {
174 [DEVLINK_MCGRP_CONFIG] = { .name = DEVLINK_GENL_MCGRP_CONFIG_NAME },
175};
176
177static int devlink_nl_put_handle(struct sk_buff *msg, struct devlink *devlink)
178{
179 if (nla_put_string(msg, DEVLINK_ATTR_BUS_NAME, devlink->dev->bus->name))
180 return -EMSGSIZE;
181 if (nla_put_string(msg, DEVLINK_ATTR_DEV_NAME, dev_name(devlink->dev)))
182 return -EMSGSIZE;
183 return 0;
184}
185
186static int devlink_nl_fill(struct sk_buff *msg, struct devlink *devlink,
187 enum devlink_command cmd, u32 portid,
188 u32 seq, int flags)
189{
190 void *hdr;
191
192 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
193 if (!hdr)
194 return -EMSGSIZE;
195
196 if (devlink_nl_put_handle(msg, devlink))
197 goto nla_put_failure;
198
199 genlmsg_end(msg, hdr);
200 return 0;
201
202nla_put_failure:
203 genlmsg_cancel(msg, hdr);
204 return -EMSGSIZE;
205}
206
207static void devlink_notify(struct devlink *devlink, enum devlink_command cmd)
208{
209 struct sk_buff *msg;
210 int err;
211
212 WARN_ON(cmd != DEVLINK_CMD_NEW && cmd != DEVLINK_CMD_DEL);
213
214 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
215 if (!msg)
216 return;
217
218 err = devlink_nl_fill(msg, devlink, cmd, 0, 0, 0);
219 if (err) {
220 nlmsg_free(msg);
221 return;
222 }
223
224 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
225 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
226}
227
228static int devlink_nl_port_fill(struct sk_buff *msg, struct devlink *devlink,
229 struct devlink_port *devlink_port,
230 enum devlink_command cmd, u32 portid,
231 u32 seq, int flags)
232{
233 void *hdr;
234
235 hdr = genlmsg_put(msg, portid, seq, &devlink_nl_family, flags, cmd);
236 if (!hdr)
237 return -EMSGSIZE;
238
239 if (devlink_nl_put_handle(msg, devlink))
240 goto nla_put_failure;
241 if (nla_put_u32(msg, DEVLINK_ATTR_PORT_INDEX, devlink_port->index))
242 goto nla_put_failure;
243 if (nla_put_u16(msg, DEVLINK_ATTR_PORT_TYPE, devlink_port->type))
244 goto nla_put_failure;
245 if (devlink_port->desired_type != DEVLINK_PORT_TYPE_NOTSET &&
246 nla_put_u16(msg, DEVLINK_ATTR_PORT_DESIRED_TYPE,
247 devlink_port->desired_type))
248 goto nla_put_failure;
249 if (devlink_port->type == DEVLINK_PORT_TYPE_ETH) {
250 struct net_device *netdev = devlink_port->type_dev;
251
252 if (netdev &&
253 (nla_put_u32(msg, DEVLINK_ATTR_PORT_NETDEV_IFINDEX,
254 netdev->ifindex) ||
255 nla_put_string(msg, DEVLINK_ATTR_PORT_NETDEV_NAME,
256 netdev->name)))
257 goto nla_put_failure;
258 }
259 if (devlink_port->type == DEVLINK_PORT_TYPE_IB) {
260 struct ib_device *ibdev = devlink_port->type_dev;
261
262 if (ibdev &&
263 nla_put_string(msg, DEVLINK_ATTR_PORT_IBDEV_NAME,
264 ibdev->name))
265 goto nla_put_failure;
266 }
267 if (devlink_port->split &&
268 nla_put_u32(msg, DEVLINK_ATTR_PORT_SPLIT_GROUP,
269 devlink_port->split_group))
270 goto nla_put_failure;
271
272 genlmsg_end(msg, hdr);
273 return 0;
274
275nla_put_failure:
276 genlmsg_cancel(msg, hdr);
277 return -EMSGSIZE;
278}
279
280static void devlink_port_notify(struct devlink_port *devlink_port,
281 enum devlink_command cmd)
282{
283 struct devlink *devlink = devlink_port->devlink;
284 struct sk_buff *msg;
285 int err;
286
287 if (!devlink_port->registered)
288 return;
289
290 WARN_ON(cmd != DEVLINK_CMD_PORT_NEW && cmd != DEVLINK_CMD_PORT_DEL);
291
292 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
293 if (!msg)
294 return;
295
296 err = devlink_nl_port_fill(msg, devlink, devlink_port, cmd, 0, 0, 0);
297 if (err) {
298 nlmsg_free(msg);
299 return;
300 }
301
302 genlmsg_multicast_netns(&devlink_nl_family, devlink_net(devlink),
303 msg, 0, DEVLINK_MCGRP_CONFIG, GFP_KERNEL);
304}
305
306static int devlink_nl_cmd_get_doit(struct sk_buff *skb, struct genl_info *info)
307{
308 struct devlink *devlink = info->user_ptr[0];
309 struct sk_buff *msg;
310 int err;
311
312 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
313 if (!msg)
314 return -ENOMEM;
315
316 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
317 info->snd_portid, info->snd_seq, 0);
318 if (err) {
319 nlmsg_free(msg);
320 return err;
321 }
322
323 return genlmsg_reply(msg, info);
324}
325
326static int devlink_nl_cmd_get_dumpit(struct sk_buff *msg,
327 struct netlink_callback *cb)
328{
329 struct devlink *devlink;
330 int start = cb->args[0];
331 int idx = 0;
332 int err;
333
334 mutex_lock(&devlink_mutex);
335 list_for_each_entry(devlink, &devlink_list, list) {
336 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
337 continue;
338 if (idx < start) {
339 idx++;
340 continue;
341 }
342 err = devlink_nl_fill(msg, devlink, DEVLINK_CMD_NEW,
343 NETLINK_CB(cb->skb).portid,
344 cb->nlh->nlmsg_seq, NLM_F_MULTI);
345 if (err)
346 goto out;
347 idx++;
348 }
349out:
350 mutex_unlock(&devlink_mutex);
351
352 cb->args[0] = idx;
353 return msg->len;
354}
355
356static int devlink_nl_cmd_port_get_doit(struct sk_buff *skb,
357 struct genl_info *info)
358{
359 struct devlink *devlink = info->user_ptr[0];
360 struct devlink_port *devlink_port = info->user_ptr[1];
361 struct sk_buff *msg;
362 int err;
363
364 msg = nlmsg_new(NLMSG_DEFAULT_SIZE, GFP_KERNEL);
365 if (!msg)
366 return -ENOMEM;
367
368 err = devlink_nl_port_fill(msg, devlink, devlink_port,
369 DEVLINK_CMD_PORT_NEW,
370 info->snd_portid, info->snd_seq, 0);
371 if (err) {
372 nlmsg_free(msg);
373 return err;
374 }
375
376 return genlmsg_reply(msg, info);
377}
378
379static int devlink_nl_cmd_port_get_dumpit(struct sk_buff *msg,
380 struct netlink_callback *cb)
381{
382 struct devlink *devlink;
383 struct devlink_port *devlink_port;
384 int start = cb->args[0];
385 int idx = 0;
386 int err;
387
388 mutex_lock(&devlink_mutex);
389 mutex_lock(&devlink_port_mutex);
390 list_for_each_entry(devlink, &devlink_list, list) {
391 if (!net_eq(devlink_net(devlink), sock_net(msg->sk)))
392 continue;
393 list_for_each_entry(devlink_port, &devlink->port_list, list) {
394 if (idx < start) {
395 idx++;
396 continue;
397 }
398 err = devlink_nl_port_fill(msg, devlink, devlink_port,
399 DEVLINK_CMD_NEW,
400 NETLINK_CB(cb->skb).portid,
401 cb->nlh->nlmsg_seq,
402 NLM_F_MULTI);
403 if (err)
404 goto out;
405 idx++;
406 }
407 }
408out:
409 mutex_unlock(&devlink_port_mutex);
410 mutex_unlock(&devlink_mutex);
411
412 cb->args[0] = idx;
413 return msg->len;
414}
415
416static int devlink_port_type_set(struct devlink *devlink,
417 struct devlink_port *devlink_port,
418 enum devlink_port_type port_type)
419
420{
421 int err;
422
423 if (devlink->ops && devlink->ops->port_type_set) {
424 if (port_type == DEVLINK_PORT_TYPE_NOTSET)
425 return -EINVAL;
426 err = devlink->ops->port_type_set(devlink_port, port_type);
427 if (err)
428 return err;
429 devlink_port->desired_type = port_type;
430 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
431 return 0;
432 }
433 return -EOPNOTSUPP;
434}
435
436static int devlink_nl_cmd_port_set_doit(struct sk_buff *skb,
437 struct genl_info *info)
438{
439 struct devlink *devlink = info->user_ptr[0];
440 struct devlink_port *devlink_port = info->user_ptr[1];
441 int err;
442
443 if (info->attrs[DEVLINK_ATTR_PORT_TYPE]) {
444 enum devlink_port_type port_type;
445
446 port_type = nla_get_u16(info->attrs[DEVLINK_ATTR_PORT_TYPE]);
447 err = devlink_port_type_set(devlink, devlink_port, port_type);
448 if (err)
449 return err;
450 }
451 return 0;
452}
453
454static int devlink_port_split(struct devlink *devlink,
455 u32 port_index, u32 count)
456
457{
458 if (devlink->ops && devlink->ops->port_split)
459 return devlink->ops->port_split(devlink, port_index, count);
460 return -EOPNOTSUPP;
461}
462
463static int devlink_nl_cmd_port_split_doit(struct sk_buff *skb,
464 struct genl_info *info)
465{
466 struct devlink *devlink = info->user_ptr[0];
467 u32 port_index;
468 u32 count;
469
470 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX] ||
471 !info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT])
472 return -EINVAL;
473
474 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
475 count = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_SPLIT_COUNT]);
476 return devlink_port_split(devlink, port_index, count);
477}
478
479static int devlink_port_unsplit(struct devlink *devlink, u32 port_index)
480
481{
482 if (devlink->ops && devlink->ops->port_unsplit)
483 return devlink->ops->port_unsplit(devlink, port_index);
484 return -EOPNOTSUPP;
485}
486
487static int devlink_nl_cmd_port_unsplit_doit(struct sk_buff *skb,
488 struct genl_info *info)
489{
490 struct devlink *devlink = info->user_ptr[0];
491 u32 port_index;
492
493 if (!info->attrs[DEVLINK_ATTR_PORT_INDEX])
494 return -EINVAL;
495
496 port_index = nla_get_u32(info->attrs[DEVLINK_ATTR_PORT_INDEX]);
497 return devlink_port_unsplit(devlink, port_index);
498}
499
500static const struct nla_policy devlink_nl_policy[DEVLINK_ATTR_MAX + 1] = {
501 [DEVLINK_ATTR_BUS_NAME] = { .type = NLA_NUL_STRING },
502 [DEVLINK_ATTR_DEV_NAME] = { .type = NLA_NUL_STRING },
503 [DEVLINK_ATTR_PORT_INDEX] = { .type = NLA_U32 },
504 [DEVLINK_ATTR_PORT_TYPE] = { .type = NLA_U16 },
505 [DEVLINK_ATTR_PORT_SPLIT_COUNT] = { .type = NLA_U32 },
506};
507
508static const struct genl_ops devlink_nl_ops[] = {
509 {
510 .cmd = DEVLINK_CMD_GET,
511 .doit = devlink_nl_cmd_get_doit,
512 .dumpit = devlink_nl_cmd_get_dumpit,
513 .policy = devlink_nl_policy,
514 /* can be retrieved by unprivileged users */
515 },
516 {
517 .cmd = DEVLINK_CMD_PORT_GET,
518 .doit = devlink_nl_cmd_port_get_doit,
519 .dumpit = devlink_nl_cmd_port_get_dumpit,
520 .policy = devlink_nl_policy,
521 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
522 /* can be retrieved by unprivileged users */
523 },
524 {
525 .cmd = DEVLINK_CMD_PORT_SET,
526 .doit = devlink_nl_cmd_port_set_doit,
527 .policy = devlink_nl_policy,
528 .flags = GENL_ADMIN_PERM,
529 .internal_flags = DEVLINK_NL_FLAG_NEED_PORT,
530 },
531 {
532 .cmd = DEVLINK_CMD_PORT_SPLIT,
533 .doit = devlink_nl_cmd_port_split_doit,
534 .policy = devlink_nl_policy,
535 .flags = GENL_ADMIN_PERM,
536 },
537 {
538 .cmd = DEVLINK_CMD_PORT_UNSPLIT,
539 .doit = devlink_nl_cmd_port_unsplit_doit,
540 .policy = devlink_nl_policy,
541 .flags = GENL_ADMIN_PERM,
542 },
543};
544
545/**
546 * devlink_alloc - Allocate new devlink instance resources
547 *
548 * @ops: ops
549 * @priv_size: size of user private data
550 *
551 * Allocate new devlink instance resources, including devlink index
552 * and name.
553 */
554struct devlink *devlink_alloc(const struct devlink_ops *ops, size_t priv_size)
555{
556 struct devlink *devlink;
557
558 devlink = kzalloc(sizeof(*devlink) + priv_size, GFP_KERNEL);
559 if (!devlink)
560 return NULL;
561 devlink->ops = ops;
562 devlink_net_set(devlink, &init_net);
563 INIT_LIST_HEAD(&devlink->port_list);
564 return devlink;
565}
566EXPORT_SYMBOL_GPL(devlink_alloc);
567
568/**
569 * devlink_register - Register devlink instance
570 *
571 * @devlink: devlink
572 */
573int devlink_register(struct devlink *devlink, struct device *dev)
574{
575 mutex_lock(&devlink_mutex);
576 devlink->dev = dev;
577 list_add_tail(&devlink->list, &devlink_list);
578 devlink_notify(devlink, DEVLINK_CMD_NEW);
579 mutex_unlock(&devlink_mutex);
580 return 0;
581}
582EXPORT_SYMBOL_GPL(devlink_register);
583
584/**
585 * devlink_unregister - Unregister devlink instance
586 *
587 * @devlink: devlink
588 */
589void devlink_unregister(struct devlink *devlink)
590{
591 mutex_lock(&devlink_mutex);
592 devlink_notify(devlink, DEVLINK_CMD_DEL);
593 list_del(&devlink->list);
594 mutex_unlock(&devlink_mutex);
595}
596EXPORT_SYMBOL_GPL(devlink_unregister);
597
598/**
599 * devlink_free - Free devlink instance resources
600 *
601 * @devlink: devlink
602 */
603void devlink_free(struct devlink *devlink)
604{
605 kfree(devlink);
606}
607EXPORT_SYMBOL_GPL(devlink_free);
608
609/**
610 * devlink_port_register - Register devlink port
611 *
612 * @devlink: devlink
613 * @devlink_port: devlink port
614 * @port_index
615 *
616 * Register devlink port with provided port index. User can use
617 * any indexing, even hw-related one. devlink_port structure
618 * is convenient to be embedded inside user driver private structure.
619 * Note that the caller should take care of zeroing the devlink_port
620 * structure.
621 */
622int devlink_port_register(struct devlink *devlink,
623 struct devlink_port *devlink_port,
624 unsigned int port_index)
625{
626 mutex_lock(&devlink_port_mutex);
627 if (devlink_port_index_exists(devlink, port_index)) {
628 mutex_unlock(&devlink_port_mutex);
629 return -EEXIST;
630 }
631 devlink_port->devlink = devlink;
632 devlink_port->index = port_index;
633 devlink_port->type = DEVLINK_PORT_TYPE_NOTSET;
634 devlink_port->registered = true;
635 list_add_tail(&devlink_port->list, &devlink->port_list);
636 mutex_unlock(&devlink_port_mutex);
637 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
638 return 0;
639}
640EXPORT_SYMBOL_GPL(devlink_port_register);
641
642/**
643 * devlink_port_unregister - Unregister devlink port
644 *
645 * @devlink_port: devlink port
646 */
647void devlink_port_unregister(struct devlink_port *devlink_port)
648{
649 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_DEL);
650 mutex_lock(&devlink_port_mutex);
651 list_del(&devlink_port->list);
652 mutex_unlock(&devlink_port_mutex);
653}
654EXPORT_SYMBOL_GPL(devlink_port_unregister);
655
656static void __devlink_port_type_set(struct devlink_port *devlink_port,
657 enum devlink_port_type type,
658 void *type_dev)
659{
660 devlink_port->type = type;
661 devlink_port->type_dev = type_dev;
662 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
663}
664
665/**
666 * devlink_port_type_eth_set - Set port type to Ethernet
667 *
668 * @devlink_port: devlink port
669 * @netdev: related netdevice
670 */
671void devlink_port_type_eth_set(struct devlink_port *devlink_port,
672 struct net_device *netdev)
673{
674 return __devlink_port_type_set(devlink_port,
675 DEVLINK_PORT_TYPE_ETH, netdev);
676}
677EXPORT_SYMBOL_GPL(devlink_port_type_eth_set);
678
679/**
680 * devlink_port_type_ib_set - Set port type to InfiniBand
681 *
682 * @devlink_port: devlink port
683 * @ibdev: related IB device
684 */
685void devlink_port_type_ib_set(struct devlink_port *devlink_port,
686 struct ib_device *ibdev)
687{
688 return __devlink_port_type_set(devlink_port,
689 DEVLINK_PORT_TYPE_IB, ibdev);
690}
691EXPORT_SYMBOL_GPL(devlink_port_type_ib_set);
692
693/**
694 * devlink_port_type_clear - Clear port type
695 *
696 * @devlink_port: devlink port
697 */
698void devlink_port_type_clear(struct devlink_port *devlink_port)
699{
700 return __devlink_port_type_set(devlink_port,
701 DEVLINK_PORT_TYPE_NOTSET, NULL);
702}
703EXPORT_SYMBOL_GPL(devlink_port_type_clear);
704
705/**
706 * devlink_port_split_set - Set port is split
707 *
708 * @devlink_port: devlink port
709 * @split_group: split group - identifies group split port is part of
710 */
711void devlink_port_split_set(struct devlink_port *devlink_port,
712 u32 split_group)
713{
714 devlink_port->split = true;
715 devlink_port->split_group = split_group;
716 devlink_port_notify(devlink_port, DEVLINK_CMD_PORT_NEW);
717}
718EXPORT_SYMBOL_GPL(devlink_port_split_set);
719
720static int __init devlink_module_init(void)
721{
722 return genl_register_family_with_ops_groups(&devlink_nl_family,
723 devlink_nl_ops,
724 devlink_nl_mcgrps);
725}
726
727static void __exit devlink_module_exit(void)
728{
729 genl_unregister_family(&devlink_nl_family);
730}
731
732module_init(devlink_module_init);
733module_exit(devlink_module_exit);
734
735MODULE_LICENSE("GPL v2");
736MODULE_AUTHOR("Jiri Pirko <jiri@mellanox.com>");
737MODULE_DESCRIPTION("Network physical device Netlink interface");
738MODULE_ALIAS_GENL_FAMILY(DEVLINK_GENL_NAME);
This page took 0.086558 seconds and 5 git commands to generate.