1 // SPDX-License-Identifier: GPL-2.0 2 /* Copyright 2011-2014 Autronica Fire and Security AS 3 * 4 * Author(s): 5 * 2011-2014 Arvid Brodin, arvid.brodin@alten.se 6 */ 7 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> 13 #include "hsr_main.h" 14 #include "hsr_device.h" 15 #include "hsr_netlink.h" 16 #include "hsr_framereg.h" 17 #include "hsr_slave.h" 18 19 static bool hsr_slave_empty(struct hsr_priv *hsr) 20 { 21 struct hsr_port *port; 22 23 hsr_for_each_port(hsr, port) 24 if (port->type != HSR_PT_MASTER) 25 return false; 26 return true; 27 } 28 29 static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event, 30 void *ptr) 31 { 32 struct hsr_port *port, *master; 33 struct net_device *dev; 34 struct hsr_priv *hsr; 35 LIST_HEAD(list_kill); 36 int mtu_max; 37 int res; 38 39 dev = netdev_notifier_info_to_dev(ptr); 40 port = hsr_port_get_rtnl(dev); 41 if (!port) { 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); 46 if (!port) { 47 /* Resend of notification concerning removed device? */ 48 return NOTIFY_DONE; 49 } 50 } else { 51 hsr = port->hsr; 52 } 53 54 switch (event) { 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); 59 break; 60 case NETDEV_CHANGENAME: 61 if (is_hsr_master(dev)) 62 hsr_debugfs_rename(dev); 63 break; 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 68 * supported. 69 */ 70 break; 71 } 72 73 master = hsr_port_get_hsr(hsr, HSR_PT_MASTER); 74 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, 78 master->dev); 79 } 80 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, 85 port ? 86 port->dev->dev_addr : 87 master->dev->dev_addr); 88 if (res) 89 netdev_warn(master->dev, 90 "Could not update HSR node address.\n"); 91 break; 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; 98 break; 99 case NETDEV_UNREGISTER: 100 if (!is_hsr_master(dev)) { 101 master = hsr_port_get_hsr(port->hsr, HSR_PT_MASTER); 102 hsr_del_port(port); 103 if (hsr_slave_empty(master->hsr)) { 104 const struct rtnl_link_ops *ops; 105 106 ops = master->dev->rtnl_link_ops; 107 ops->dellink(master->dev, &list_kill); 108 unregister_netdevice_many(&list_kill); 109 } 110 } 111 break; 112 case NETDEV_PRE_TYPE_CHANGE: 113 /* HSR works only on Ethernet devices. Refuse slave to change 114 * its type. 115 */ 116 return NOTIFY_BAD; 117 } 118 119 return NOTIFY_DONE; 120 } 121 122 struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt) 123 { 124 struct hsr_port *port; 125 126 hsr_for_each_port(hsr, port) 127 if (port->type == pt) 128 return port; 129 return NULL; 130 } 131 132 static struct notifier_block hsr_nb = { 133 .notifier_call = hsr_netdev_notify, /* Slave event notifications */ 134 }; 135 136 static int __init hsr_init(void) 137 { 138 int res; 139 140 BUILD_BUG_ON(sizeof(struct hsr_tag) != HSR_HLEN); 141 142 register_netdevice_notifier(&hsr_nb); 143 res = hsr_netlink_init(); 144 145 return res; 146 } 147 148 static void __exit hsr_exit(void) 149 { 150 hsr_netlink_exit(); 151 hsr_debugfs_remove_root(); 152 unregister_netdevice_notifier(&hsr_nb); 153 } 154 155 module_init(hsr_init); 156 module_exit(hsr_exit); 157 MODULE_LICENSE("GPL"); 158