1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright 2011-2014 Autronica Fire and Security AS
5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se
8 #include <linux/netdevice.h>
9 #include <net/rtnetlink.h>
10 #include <linux/rculist.h>
11 #include <linux/timer.h>
12 #include <linux/etherdevice.h>
14 #include "hsr_device.h"
15 #include "hsr_netlink.h"
16 #include "hsr_framereg.h"
17 #include "hsr_slave.h"
19 static bool hsr_slave_empty(struct hsr_priv *hsr)
21 struct hsr_port *port;
23 hsr_for_each_port(hsr, port)
24 if (port->type != HSR_PT_MASTER)
29 static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
32 struct hsr_port *port, *master;
33 struct net_device *dev;
39 dev = netdev_notifier_info_to_dev(ptr);
40 port = hsr_port_get_rtnl(dev);
42 if (!is_hsr_master(dev))
43 return NOTIFY_DONE; /* Not an HSR device */
44 hsr = netdev_priv(dev);
45 port = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
47 /* Resend of notification concerning removed device? */
55 case NETDEV_UP: /* Administrative state DOWN */
56 case NETDEV_DOWN: /* Administrative state UP */
57 case NETDEV_CHANGE: /* Link (carrier) state changes */
58 hsr_check_carrier_and_operstate(hsr);
60 case NETDEV_CHANGENAME:
61 if (is_hsr_master(dev))
62 hsr_debugfs_rename(dev);
64 case NETDEV_CHANGEADDR:
65 if (port->type == HSR_PT_MASTER) {
66 /* This should not happen since there's no
67 * ndo_set_mac_address() for HSR devices - i.e. not
73 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
75 if (port->type == HSR_PT_SLAVE_A) {
76 ether_addr_copy(master->dev->dev_addr, dev->dev_addr);
77 call_netdevice_notifiers(NETDEV_CHANGEADDR,
81 /* Make sure we recognize frames from ourselves in hsr_rcv() */
82 port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
83 res = hsr_create_self_node(hsr,
84 master->dev->dev_addr,
87 master->dev->dev_addr);
89 netdev_warn(master->dev,
90 "Could not update HSR node address.\n");
92 case NETDEV_CHANGEMTU:
93 if (port->type == HSR_PT_MASTER)
94 break; /* Handled in ndo_change_mtu() */
95 mtu_max = hsr_get_max_mtu(port->hsr);
96 master = hsr_port_get_hsr(port->hsr, HSR_PT_MASTER);
97 master->dev->mtu = mtu_max;
99 case NETDEV_UNREGISTER:
100 if (!is_hsr_master(dev)) {
101 master = hsr_port_get_hsr(port->hsr, HSR_PT_MASTER);
103 if (hsr_slave_empty(master->hsr)) {
104 const struct rtnl_link_ops *ops;
106 ops = master->dev->rtnl_link_ops;
107 ops->dellink(master->dev, &list_kill);
108 unregister_netdevice_many(&list_kill);
112 case NETDEV_PRE_TYPE_CHANGE:
113 /* HSR works only on Ethernet devices. Refuse slave to change
122 struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt)
124 struct hsr_port *port;
126 hsr_for_each_port(hsr, port)
127 if (port->type == pt)
132 static struct notifier_block hsr_nb = {
133 .notifier_call = hsr_netdev_notify, /* Slave event notifications */
136 static int __init hsr_init(void)
140 BUILD_BUG_ON(sizeof(struct hsr_tag) != HSR_HLEN);
142 register_netdevice_notifier(&hsr_nb);
143 res = hsr_netlink_init();
148 static void __exit hsr_exit(void)
151 hsr_debugfs_remove_root();
152 unregister_netdevice_notifier(&hsr_nb);
155 module_init(hsr_init);
156 module_exit(hsr_exit);
157 MODULE_LICENSE("GPL");