hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/net/hsr/hsr_main.c
....@@ -1,15 +1,14 @@
1
+// SPDX-License-Identifier: GPL-2.0
12 /* Copyright 2011-2014 Autronica Fire and Security AS
2
- *
3
- * This program is free software; you can redistribute it and/or modify it
4
- * under the terms of the GNU General Public License as published by the Free
5
- * Software Foundation; either version 2 of the License, or (at your option)
6
- * any later version.
73 *
84 * Author(s):
95 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se
6
+ *
7
+ * Event handling for HSR and PRP devices.
108 */
119
1210 #include <linux/netdevice.h>
11
+#include <net/rtnetlink.h>
1312 #include <linux/rculist.h>
1413 #include <linux/timer.h>
1514 #include <linux/etherdevice.h>
....@@ -19,24 +18,34 @@
1918 #include "hsr_framereg.h"
2019 #include "hsr_slave.h"
2120
21
+static bool hsr_slave_empty(struct hsr_priv *hsr)
22
+{
23
+ struct hsr_port *port;
24
+
25
+ hsr_for_each_port(hsr, port)
26
+ if (port->type != HSR_PT_MASTER)
27
+ return false;
28
+ return true;
29
+}
2230
2331 static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
2432 void *ptr)
2533 {
26
- struct net_device *dev;
2734 struct hsr_port *port, *master;
35
+ struct net_device *dev;
2836 struct hsr_priv *hsr;
37
+ LIST_HEAD(list_kill);
2938 int mtu_max;
3039 int res;
3140
3241 dev = netdev_notifier_info_to_dev(ptr);
3342 port = hsr_port_get_rtnl(dev);
34
- if (port == NULL) {
43
+ if (!port) {
3544 if (!is_hsr_master(dev))
3645 return NOTIFY_DONE; /* Not an HSR device */
3746 hsr = netdev_priv(dev);
3847 port = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
39
- if (port == NULL) {
48
+ if (!port) {
4049 /* Resend of notification concerning removed device? */
4150 return NOTIFY_DONE;
4251 }
....@@ -49,6 +58,10 @@
4958 case NETDEV_DOWN: /* Administrative state UP */
5059 case NETDEV_CHANGE: /* Link (carrier) state changes */
5160 hsr_check_carrier_and_operstate(hsr);
61
+ break;
62
+ case NETDEV_CHANGENAME:
63
+ if (is_hsr_master(dev))
64
+ hsr_debugfs_rename(dev);
5265 break;
5366 case NETDEV_CHANGEADDR:
5467 if (port->type == HSR_PT_MASTER) {
....@@ -63,12 +76,13 @@
6376
6477 if (port->type == HSR_PT_SLAVE_A) {
6578 ether_addr_copy(master->dev->dev_addr, dev->dev_addr);
66
- call_netdevice_notifiers(NETDEV_CHANGEADDR, master->dev);
79
+ call_netdevice_notifiers(NETDEV_CHANGEADDR,
80
+ master->dev);
6781 }
6882
6983 /* Make sure we recognize frames from ourselves in hsr_rcv() */
7084 port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
71
- res = hsr_create_self_node(&hsr->self_node_db,
85
+ res = hsr_create_self_node(hsr,
7286 master->dev->dev_addr,
7387 port ?
7488 port->dev->dev_addr :
....@@ -85,7 +99,17 @@
8599 master->dev->mtu = mtu_max;
86100 break;
87101 case NETDEV_UNREGISTER:
88
- hsr_del_port(port);
102
+ if (!is_hsr_master(dev)) {
103
+ master = hsr_port_get_hsr(port->hsr, HSR_PT_MASTER);
104
+ hsr_del_port(port);
105
+ if (hsr_slave_empty(master->hsr)) {
106
+ const struct rtnl_link_ops *ops;
107
+
108
+ ops = master->dev->rtnl_link_ops;
109
+ ops->dellink(master->dev, &list_kill);
110
+ unregister_netdevice_many(&list_kill);
111
+ }
112
+ }
89113 break;
90114 case NETDEV_PRE_TYPE_CHANGE:
91115 /* HSR works only on Ethernet devices. Refuse slave to change
....@@ -96,7 +120,6 @@
96120
97121 return NOTIFY_DONE;
98122 }
99
-
100123
101124 struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt)
102125 {
....@@ -112,7 +135,6 @@
112135 .notifier_call = hsr_netdev_notify, /* Slave event notifications */
113136 };
114137
115
-
116138 static int __init hsr_init(void)
117139 {
118140 int res;
....@@ -127,8 +149,9 @@
127149
128150 static void __exit hsr_exit(void)
129151 {
130
- unregister_netdevice_notifier(&hsr_nb);
131152 hsr_netlink_exit();
153
+ hsr_debugfs_remove_root();
154
+ unregister_netdevice_notifier(&hsr_nb);
132155 }
133156
134157 module_init(hsr_init);