// SPDX-License-Identifier: GPL-2.0
/* Copyright 2011-2014 Autronica Fire and Security AS
 *
 * Author(s):
 *	2011-2014 Arvid Brodin, arvid.brodin@alten.se
 *
 * Event handling for HSR and PRP devices.
 */

#include <linux/netdevice.h>
#include <net/rtnetlink.h>
#include <linux/rculist.h>
#include <linux/timer.h>
#include <linux/etherdevice.h>
#include "hsr_main.h"
#include "hsr_device.h"
#include "hsr_netlink.h"
#include "hsr_framereg.h"
#include "hsr_slave.h"

static bool hsr_slave_empty(struct hsr_priv *hsr)
{
	struct hsr_port *port;

	hsr_for_each_port(hsr, port)
		if (port->type != HSR_PT_MASTER)
			return false;
	return true;
}

static int hsr_netdev_notify(struct notifier_block *nb, unsigned long event,
			     void *ptr)
{
	struct hsr_port *port, *master;
	struct net_device *dev;
	struct hsr_priv *hsr;
	LIST_HEAD(list_kill);
	int mtu_max;
	int res;

	dev = netdev_notifier_info_to_dev(ptr);
	port = hsr_port_get_rtnl(dev);
	if (!port) {
		if (!is_hsr_master(dev))
			return NOTIFY_DONE;	/* Not an HSR device */
		hsr = netdev_priv(dev);
		port = hsr_port_get_hsr(hsr, HSR_PT_MASTER);
		if (!port) {
			/* Resend of notification concerning removed device? */
			return NOTIFY_DONE;
		}
	} else {
		hsr = port->hsr;
	}

	switch (event) {
	case NETDEV_UP:		/* Administrative state DOWN */
	case NETDEV_DOWN:	/* Administrative state UP */
	case NETDEV_CHANGE:	/* Link (carrier) state changes */
		hsr_check_carrier_and_operstate(hsr);
		break;
	case NETDEV_CHANGENAME:
		if (is_hsr_master(dev))
			hsr_debugfs_rename(dev);
		break;
	case NETDEV_CHANGEADDR:
		if (port->type == HSR_PT_MASTER) {
			/* This should not happen since there's no
			 * ndo_set_mac_address() for HSR devices - i.e. not
			 * supported.
			 */
			break;
		}

		master = hsr_port_get_hsr(hsr, HSR_PT_MASTER);

		if (port->type == HSR_PT_SLAVE_A) {
			eth_hw_addr_set(master->dev, dev->dev_addr);
			call_netdevice_notifiers(NETDEV_CHANGEADDR,
						 master->dev);
		}

		/* Make sure we recognize frames from ourselves in hsr_rcv() */
		port = hsr_port_get_hsr(hsr, HSR_PT_SLAVE_B);
		res = hsr_create_self_node(hsr,
					   master->dev->dev_addr,
					   port ?
						port->dev->dev_addr :
						master->dev->dev_addr);
		if (res)
			netdev_warn(master->dev,
				    "Could not update HSR node address.\n");
		break;
	case NETDEV_CHANGEMTU:
		if (port->type == HSR_PT_MASTER)
			break; /* Handled in ndo_change_mtu() */
		mtu_max = hsr_get_max_mtu(port->hsr);
		master = hsr_port_get_hsr(port->hsr, HSR_PT_MASTER);
		WRITE_ONCE(master->dev->mtu, mtu_max);
		break;
	case NETDEV_UNREGISTER:
		if (!is_hsr_master(dev)) {
			master = hsr_port_get_hsr(port->hsr, HSR_PT_MASTER);
			hsr_del_port(port);
			if (hsr_slave_empty(master->hsr)) {
				const struct rtnl_link_ops *ops;

				ops = master->dev->rtnl_link_ops;
				ops->dellink(master->dev, &list_kill);
				unregister_netdevice_many(&list_kill);
			}
		}
		break;
	case NETDEV_PRE_TYPE_CHANGE:
		/* HSR works only on Ethernet devices. Refuse slave to change
		 * its type.
		 */
		return NOTIFY_BAD;
	}

	return NOTIFY_DONE;
}

struct hsr_port *hsr_port_get_hsr(struct hsr_priv *hsr, enum hsr_port_type pt)
{
	struct hsr_port *port;

	hsr_for_each_port(hsr, port)
		if (port->type == pt)
			return port;
	return NULL;
}

int hsr_get_version(struct net_device *dev, enum hsr_version *ver)
{
	struct hsr_priv *hsr;

	hsr = netdev_priv(dev);
	*ver = hsr->prot_version;

	return 0;
}
EXPORT_SYMBOL(hsr_get_version);

static struct notifier_block hsr_nb = {
	.notifier_call = hsr_netdev_notify,	/* Slave event notifications */
};

static int __init hsr_init(void)
{
	int err;

	BUILD_BUG_ON(sizeof(struct hsr_tag) != HSR_HLEN);

	err = register_netdevice_notifier(&hsr_nb);
	if (err)
		return err;

	err = hsr_netlink_init();
	if (err) {
		unregister_netdevice_notifier(&hsr_nb);
		return err;
	}

	return 0;
}

static void __exit hsr_exit(void)
{
	hsr_netlink_exit();
	hsr_debugfs_remove_root();
	unregister_netdevice_notifier(&hsr_nb);
}

module_init(hsr_init);
module_exit(hsr_exit);
MODULE_DESCRIPTION("High-availability Seamless Redundancy (HSR) driver");
MODULE_LICENSE("GPL");
