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