Linux Audio

Check our new training course

Loading...
Note: File does not exist in v3.1.
  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);