Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /* Copyright 2011-2014 Autronica Fire and Security AS
0003  *
0004  * Author(s):
0005  *  2011-2014 Arvid Brodin, arvid.brodin@alten.se
0006  *
0007  * Event handling for HSR and PRP devices.
0008  */
0009 
0010 #include <linux/netdevice.h>
0011 #include <net/rtnetlink.h>
0012 #include <linux/rculist.h>
0013 #include <linux/timer.h>
0014 #include <linux/etherdevice.h>
0015 #include "hsr_main.h"
0016 #include "hsr_device.h"
0017 #include "hsr_netlink.h"
0018 #include "hsr_framereg.h"
0019 #include "hsr_slave.h"
0020 
0021 static bool hsr_slave_empty(struct hsr_priv *hsr)
0022 {
0023     struct hsr_port *port;
0024 
0025     hsr_for_each_port(hsr, port)
0026         if (port->type != HSR_PT_MASTER)
0027             return false;
0028     return true;
0029 }
0030 
0031 static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
0032                  void *ptr)
0033 {
0034     struct hsr_port *port, *master;
0035     struct net_device *dev;
0036     struct hsr_priv *hsr;
0037     LIST_HEAD(list_kill);
0038     int mtu_max;
0039     int res;
0040 
0041     dev = netdev_notifier_info_to_dev(ptr);
0042     port = hsr_port_get_rtnl(dev);
0043     if (!port) {
0044         if (!is_hsr_master(dev))
0045             return NOTIFY_DONE; /* Not an HSR device */
0046         hsr = netdev_priv(dev);
0047         port = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
0048         if (!port) {
0049             /* Resend of notification concerning removed device? */
0050             return NOTIFY_DONE;
0051         }
0052     } else {
0053         hsr = port->hsr;
0054     }
0055 
0056     switch (event) {
0057     case NETDEV_UP:     /* Administrative state DOWN */
0058     case NETDEV_DOWN:   /* Administrative state UP */
0059     case NETDEV_CHANGE: /* Link (carrier) state changes */
0060         hsr_check_carrier_and_operstate(hsr);
0061         break;
0062     case NETDEV_CHANGENAME:
0063         if (is_hsr_master(dev))
0064             hsr_debugfs_rename(dev);
0065         break;
0066     case NETDEV_CHANGEADDR:
0067         if (port->type == HSR_PT_MASTER) {
0068             /* This should not happen since there's no
0069              * ndo_set_mac_address() for HSR devices - i.e. not
0070              * supported.
0071              */
0072             break;
0073         }
0074 
0075         master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
0076 
0077         if (port->type == HSR_PT_SLAVE_A) {
0078             eth_hw_addr_set(master->dev, dev->dev_addr);
0079             call_netdevice_notifiers(NETDEV_CHANGEADDR,
0080                          master->dev);
0081         }
0082 
0083         /* Make sure we recognize frames from ourselves in hsr_rcv() */
0084         port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
0085         res = hsr_create_self_node(hsr,
0086                        master->dev->dev_addr,
0087                        port ?
0088                         port->dev->dev_addr :
0089                         master->dev->dev_addr);
0090         if (res)
0091             netdev_warn(master->dev,
0092                     "Could not update HSR node address.\n");
0093         break;
0094     case NETDEV_CHANGEMTU:
0095         if (port->type == HSR_PT_MASTER)
0096             break; /* Handled in ndo_change_mtu() */
0097         mtu_max = hsr_get_max_mtu(port->hsr);
0098         master = hsr_port_get_hsr(port->hsr, HSR_PT_MASTER);
0099         master->dev->mtu = mtu_max;
0100         break;
0101     case NETDEV_UNREGISTER:
0102         if (!is_hsr_master(dev)) {
0103             master = hsr_port_get_hsr(port->hsr, HSR_PT_MASTER);
0104             hsr_del_port(port);
0105             if (hsr_slave_empty(master->hsr)) {
0106                 const struct rtnl_link_ops *ops;
0107 
0108                 ops = master->dev->rtnl_link_ops;
0109                 ops->dellink(master->dev, &list_kill);
0110                 unregister_netdevice_many(&list_kill);
0111             }
0112         }
0113         break;
0114     case NETDEV_PRE_TYPE_CHANGE:
0115         /* HSR works only on Ethernet devices. Refuse slave to change
0116          * its type.
0117          */
0118         return NOTIFY_BAD;
0119     }
0120 
0121     return NOTIFY_DONE;
0122 }
0123 
0124 struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt)
0125 {
0126     struct hsr_port *port;
0127 
0128     hsr_for_each_port(hsr, port)
0129         if (port->type == pt)
0130             return port;
0131     return NULL;
0132 }
0133 
0134 int hsr_get_version(struct net_device *dev, enum hsr_version *ver)
0135 {
0136     struct hsr_priv *hsr;
0137 
0138     hsr = netdev_priv(dev);
0139     *ver = hsr->prot_version;
0140 
0141     return 0;
0142 }
0143 EXPORT_SYMBOL(hsr_get_version);
0144 
0145 static struct notifier_block hsr_nb = {
0146     .notifier_call = hsr_netdev_notify, /* Slave event notifications */
0147 };
0148 
0149 static int __init hsr_init(void)
0150 {
0151     int res;
0152 
0153     BUILD_BUG_ON(sizeof(struct hsr_tag) != HSR_HLEN);
0154 
0155     register_netdevice_notifier(&hsr_nb);
0156     res = hsr_netlink_init();
0157 
0158     return res;
0159 }
0160 
0161 static void __exit hsr_exit(void)
0162 {
0163     hsr_netlink_exit();
0164     hsr_debugfs_remove_root();
0165     unregister_netdevice_notifier(&hsr_nb);
0166 }
0167 
0168 module_init(hsr_init);
0169 module_exit(hsr_exit);
0170 MODULE_LICENSE("GPL");