xref: /linux-6.15/net/switchdev/switchdev.c (revision 03bf0c28)
1007f790cSJiri Pirko /*
2007f790cSJiri Pirko  * net/switchdev/switchdev.c - Switch device API
3007f790cSJiri Pirko  * Copyright (c) 2014 Jiri Pirko <[email protected]>
4007f790cSJiri Pirko  *
5007f790cSJiri Pirko  * This program is free software; you can redistribute it and/or modify
6007f790cSJiri Pirko  * it under the terms of the GNU General Public License as published by
7007f790cSJiri Pirko  * the Free Software Foundation; either version 2 of the License, or
8007f790cSJiri Pirko  * (at your option) any later version.
9007f790cSJiri Pirko  */
10007f790cSJiri Pirko 
11007f790cSJiri Pirko #include <linux/kernel.h>
12007f790cSJiri Pirko #include <linux/types.h>
13007f790cSJiri Pirko #include <linux/init.h>
14*03bf0c28SJiri Pirko #include <linux/mutex.h>
15*03bf0c28SJiri Pirko #include <linux/notifier.h>
16007f790cSJiri Pirko #include <linux/netdevice.h>
17007f790cSJiri Pirko #include <net/switchdev.h>
18007f790cSJiri Pirko 
19007f790cSJiri Pirko /**
20007f790cSJiri Pirko  *	netdev_switch_parent_id_get - Get ID of a switch
21007f790cSJiri Pirko  *	@dev: port device
22007f790cSJiri Pirko  *	@psid: switch ID
23007f790cSJiri Pirko  *
24007f790cSJiri Pirko  *	Get ID of a switch this port is part of.
25007f790cSJiri Pirko  */
26007f790cSJiri Pirko int netdev_switch_parent_id_get(struct net_device *dev,
27007f790cSJiri Pirko 				struct netdev_phys_item_id *psid)
28007f790cSJiri Pirko {
29007f790cSJiri Pirko 	const struct net_device_ops *ops = dev->netdev_ops;
30007f790cSJiri Pirko 
31007f790cSJiri Pirko 	if (!ops->ndo_switch_parent_id_get)
32007f790cSJiri Pirko 		return -EOPNOTSUPP;
33007f790cSJiri Pirko 	return ops->ndo_switch_parent_id_get(dev, psid);
34007f790cSJiri Pirko }
35007f790cSJiri Pirko EXPORT_SYMBOL(netdev_switch_parent_id_get);
3638dcf357SScott Feldman 
3738dcf357SScott Feldman /**
3838dcf357SScott Feldman  *	netdev_switch_port_stp_update - Notify switch device port of STP
3938dcf357SScott Feldman  *					state change
4038dcf357SScott Feldman  *	@dev: port device
4138dcf357SScott Feldman  *	@state: port STP state
4238dcf357SScott Feldman  *
4338dcf357SScott Feldman  *	Notify switch device port of bridge port STP state change.
4438dcf357SScott Feldman  */
4538dcf357SScott Feldman int netdev_switch_port_stp_update(struct net_device *dev, u8 state)
4638dcf357SScott Feldman {
4738dcf357SScott Feldman 	const struct net_device_ops *ops = dev->netdev_ops;
4838dcf357SScott Feldman 
4938dcf357SScott Feldman 	if (!ops->ndo_switch_port_stp_update)
5038dcf357SScott Feldman 		return -EOPNOTSUPP;
5138dcf357SScott Feldman 	WARN_ON(!ops->ndo_switch_parent_id_get);
5238dcf357SScott Feldman 	return ops->ndo_switch_port_stp_update(dev, state);
5338dcf357SScott Feldman }
5438dcf357SScott Feldman EXPORT_SYMBOL(netdev_switch_port_stp_update);
55*03bf0c28SJiri Pirko 
56*03bf0c28SJiri Pirko static DEFINE_MUTEX(netdev_switch_mutex);
57*03bf0c28SJiri Pirko static RAW_NOTIFIER_HEAD(netdev_switch_notif_chain);
58*03bf0c28SJiri Pirko 
59*03bf0c28SJiri Pirko /**
60*03bf0c28SJiri Pirko  *	register_netdev_switch_notifier - Register nofifier
61*03bf0c28SJiri Pirko  *	@nb: notifier_block
62*03bf0c28SJiri Pirko  *
63*03bf0c28SJiri Pirko  *	Register switch device notifier. This should be used by code
64*03bf0c28SJiri Pirko  *	which needs to monitor events happening in particular device.
65*03bf0c28SJiri Pirko  *	Return values are same as for atomic_notifier_chain_register().
66*03bf0c28SJiri Pirko  */
67*03bf0c28SJiri Pirko int register_netdev_switch_notifier(struct notifier_block *nb)
68*03bf0c28SJiri Pirko {
69*03bf0c28SJiri Pirko 	int err;
70*03bf0c28SJiri Pirko 
71*03bf0c28SJiri Pirko 	mutex_lock(&netdev_switch_mutex);
72*03bf0c28SJiri Pirko 	err = raw_notifier_chain_register(&netdev_switch_notif_chain, nb);
73*03bf0c28SJiri Pirko 	mutex_unlock(&netdev_switch_mutex);
74*03bf0c28SJiri Pirko 	return err;
75*03bf0c28SJiri Pirko }
76*03bf0c28SJiri Pirko EXPORT_SYMBOL(register_netdev_switch_notifier);
77*03bf0c28SJiri Pirko 
78*03bf0c28SJiri Pirko /**
79*03bf0c28SJiri Pirko  *	unregister_netdev_switch_notifier - Unregister nofifier
80*03bf0c28SJiri Pirko  *	@nb: notifier_block
81*03bf0c28SJiri Pirko  *
82*03bf0c28SJiri Pirko  *	Unregister switch device notifier.
83*03bf0c28SJiri Pirko  *	Return values are same as for atomic_notifier_chain_unregister().
84*03bf0c28SJiri Pirko  */
85*03bf0c28SJiri Pirko int unregister_netdev_switch_notifier(struct notifier_block *nb)
86*03bf0c28SJiri Pirko {
87*03bf0c28SJiri Pirko 	int err;
88*03bf0c28SJiri Pirko 
89*03bf0c28SJiri Pirko 	mutex_lock(&netdev_switch_mutex);
90*03bf0c28SJiri Pirko 	err = raw_notifier_chain_unregister(&netdev_switch_notif_chain, nb);
91*03bf0c28SJiri Pirko 	mutex_unlock(&netdev_switch_mutex);
92*03bf0c28SJiri Pirko 	return err;
93*03bf0c28SJiri Pirko }
94*03bf0c28SJiri Pirko EXPORT_SYMBOL(unregister_netdev_switch_notifier);
95*03bf0c28SJiri Pirko 
96*03bf0c28SJiri Pirko /**
97*03bf0c28SJiri Pirko  *	call_netdev_switch_notifiers - Call nofifiers
98*03bf0c28SJiri Pirko  *	@val: value passed unmodified to notifier function
99*03bf0c28SJiri Pirko  *	@dev: port device
100*03bf0c28SJiri Pirko  *	@info: notifier information data
101*03bf0c28SJiri Pirko  *
102*03bf0c28SJiri Pirko  *	Call all network notifier blocks. This should be called by driver
103*03bf0c28SJiri Pirko  *	when it needs to propagate hardware event.
104*03bf0c28SJiri Pirko  *	Return values are same as for atomic_notifier_call_chain().
105*03bf0c28SJiri Pirko  */
106*03bf0c28SJiri Pirko int call_netdev_switch_notifiers(unsigned long val, struct net_device *dev,
107*03bf0c28SJiri Pirko 				 struct netdev_switch_notifier_info *info)
108*03bf0c28SJiri Pirko {
109*03bf0c28SJiri Pirko 	int err;
110*03bf0c28SJiri Pirko 
111*03bf0c28SJiri Pirko 	info->dev = dev;
112*03bf0c28SJiri Pirko 	mutex_lock(&netdev_switch_mutex);
113*03bf0c28SJiri Pirko 	err = raw_notifier_call_chain(&netdev_switch_notif_chain, val, info);
114*03bf0c28SJiri Pirko 	mutex_unlock(&netdev_switch_mutex);
115*03bf0c28SJiri Pirko 	return err;
116*03bf0c28SJiri Pirko }
117*03bf0c28SJiri Pirko EXPORT_SYMBOL(call_netdev_switch_notifiers);
118