/* Copyright 2011-2013 Autronica Fire and Security AS
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the Free
 * Software Foundation; either version 2 of the License, or (at your option)
 * any later version.
 *
 * Author(s):
 *	2011-2013 Arvid Brodin, arvid.brodin@xdin.com
 *
 * This file contains device methods for creating, using and destroying
 * virtual HSR devices.
 */

#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/etherdevice.h>
#include <linux/if_arp.h>
#include <linux/rtnetlink.h>
#include <linux/pkt_sched.h>
#include "hsr_device.h"
#include "hsr_framereg.h"
#include "hsr_main.h"


static bool is_admin_up(struct net_device *dev)
{
	return dev && (dev->flags & IFF_UP);
}

static bool is_slave_up(struct net_device *dev)
{
	return dev && is_admin_up(dev) && netif_oper_up(dev);
}

static void __hsr_set_operstate(struct net_device *dev, int transition)
{
	write_lock_bh(&dev_base_lock);
	if (dev->operstate != transition) {
		dev->operstate = transition;
		write_unlock_bh(&dev_base_lock);
		netdev_state_change(dev);
	} else {
		write_unlock_bh(&dev_base_lock);
	}
}

void hsr_set_operstate(struct net_device *hsr_dev, struct net_device *slave1,
		       struct net_device *slave2)
{
	if (!is_admin_up(hsr_dev)) {
		__hsr_set_operstate(hsr_dev, IF_OPER_DOWN);
		return;
	}

	if (is_slave_up(slave1) || is_slave_up(slave2))
		__hsr_set_operstate(hsr_dev, IF_OPER_UP);
	else
		__hsr_set_operstate(hsr_dev, IF_OPER_LOWERLAYERDOWN);
}

void hsr_set_carrier(struct net_device *hsr_dev, struct net_device *slave1,
		     struct net_device *slave2)
{
	if (is_slave_up(slave1) || is_slave_up(slave2))
		netif_carrier_on(hsr_dev);
	else
		netif_carrier_off(hsr_dev);
}


void hsr_check_announce(struct net_device *hsr_dev, int old_operstate)
{
	struct hsr_priv *hsr_priv;

	hsr_priv = netdev_priv(hsr_dev);

	if ((hsr_dev->operstate == IF_OPER_UP) && (old_operstate != IF_OPER_UP)) {
		/* Went up */
		hsr_priv->announce_count = 0;
		hsr_priv->announce_timer.expires = jiffies +
				msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL);
		add_timer(&hsr_priv->announce_timer);
	}

	if ((hsr_dev->operstate != IF_OPER_UP) && (old_operstate == IF_OPER_UP))
		/* Went down */
		del_timer(&hsr_priv->announce_timer);
}


int hsr_get_max_mtu(struct hsr_priv *hsr_priv)
{
	int mtu_max;

	if (hsr_priv->slave[0] && hsr_priv->slave[1])
		mtu_max = min(hsr_priv->slave[0]->mtu, hsr_priv->slave[1]->mtu);
	else if (hsr_priv->slave[0])
		mtu_max = hsr_priv->slave[0]->mtu;
	else if (hsr_priv->slave[1])
		mtu_max = hsr_priv->slave[1]->mtu;
	else
		mtu_max = HSR_TAGLEN;

	return mtu_max - HSR_TAGLEN;
}

static int hsr_dev_change_mtu(struct net_device *dev, int new_mtu)
{
	struct hsr_priv *hsr_priv;

	hsr_priv = netdev_priv(dev);

	if (new_mtu > hsr_get_max_mtu(hsr_priv)) {
		netdev_info(hsr_priv->dev, "A HSR master's MTU cannot be greater than the smallest MTU of its slaves minus the HSR Tag length (%d octets).\n",
			    HSR_TAGLEN);
		return -EINVAL;
	}

	dev->mtu = new_mtu;

	return 0;
}

static int hsr_dev_open(struct net_device *dev)
{
	struct hsr_priv *hsr_priv;
	int i;
	char *slave_name;

	hsr_priv = netdev_priv(dev);

	for (i = 0; i < HSR_MAX_SLAVE; i++) {
		if (hsr_priv->slave[i])
			slave_name = hsr_priv->slave[i]->name;
		else
			slave_name = "null";

		if (!is_slave_up(hsr_priv->slave[i]))
			netdev_warn(dev, "Slave %c (%s) is not up; please bring it up to get a working HSR network\n",
				    'A' + i, slave_name);
	}

	return 0;
}

static int hsr_dev_close(struct net_device *dev)
{
	/* Nothing to do here. We could try to restore the state of the slaves
	 * to what they were before being changed by the hsr master dev's state,
	 * but they might have been changed manually in the mean time too, so
	 * taking them up or down here might be confusing and is probably not a
	 * good idea.
	 */
	return 0;
}


static void hsr_fill_tag(struct hsr_ethhdr *hsr_ethhdr, struct hsr_priv *hsr_priv)
{
	unsigned long irqflags;

	/* IEC 62439-1:2010, p 48, says the 4-bit "path" field can take values
	 * between 0001-1001 ("ring identifier", for regular HSR frames),
	 * or 1111 ("HSR management", supervision frames). Unfortunately, the
	 * spec writers forgot to explain what a "ring identifier" is, or
	 * how it is used. So we just set this to 0001 for regular frames,
	 * and 1111 for supervision frames.
	 */
	set_hsr_tag_path(&hsr_ethhdr->hsr_tag, 0x1);

	/* IEC 62439-1:2010, p 12: "The link service data unit in an Ethernet
	 * frame is the content of the frame located between the Length/Type
	 * field and the Frame Check Sequence."
	 *
	 * IEC 62439-3, p 48, specifies the "original LPDU" to include the
	 * original "LT" field (what "LT" means is not explained anywhere as
	 * far as I can see - perhaps "Length/Type"?). So LSDU_size might
	 * equal original length + 2.
	 *   Also, the fact that this field is not used anywhere (might be used
	 * by a RedBox connecting HSR and PRP nets?) means I cannot test its
	 * correctness. Instead of guessing, I set this to 0 here, to make any
	 * problems immediately apparent. Anyone using this driver with PRP/HSR
	 * RedBoxes might need to fix this...
	 */
	set_hsr_tag_LSDU_size(&hsr_ethhdr->hsr_tag, 0);

	spin_lock_irqsave(&hsr_priv->seqnr_lock, irqflags);
	hsr_ethhdr->hsr_tag.sequence_nr = htons(hsr_priv->sequence_nr);
	hsr_priv->sequence_nr++;
	spin_unlock_irqrestore(&hsr_priv->seqnr_lock, irqflags);

	hsr_ethhdr->hsr_tag.encap_proto = hsr_ethhdr->ethhdr.h_proto;

	hsr_ethhdr->ethhdr.h_proto = htons(ETH_P_PRP);
}

static int slave_xmit(struct sk_buff *skb, struct hsr_priv *hsr_priv,
		      enum hsr_dev_idx dev_idx)
{
	struct hsr_ethhdr *hsr_ethhdr;

	hsr_ethhdr = (struct hsr_ethhdr *) skb->data;

	skb->dev = hsr_priv->slave[dev_idx];

	hsr_addr_subst_dest(hsr_priv, &hsr_ethhdr->ethhdr, dev_idx);

	/* Address substitution (IEC62439-3 pp 26, 50): replace mac
	 * address of outgoing frame with that of the outgoing slave's.
	 */
	ether_addr_copy(hsr_ethhdr->ethhdr.h_source, skb->dev->dev_addr);

	return dev_queue_xmit(skb);
}


static int hsr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{
	struct hsr_priv *hsr_priv;
	struct hsr_ethhdr *hsr_ethhdr;
	struct sk_buff *skb2;
	int res1, res2;

	hsr_priv = netdev_priv(dev);
	hsr_ethhdr = (struct hsr_ethhdr *) skb->data;

	if ((skb->protocol != htons(ETH_P_PRP)) ||
	    (hsr_ethhdr->ethhdr.h_proto != htons(ETH_P_PRP))) {
		hsr_fill_tag(hsr_ethhdr, hsr_priv);
		skb->protocol = htons(ETH_P_PRP);
	}

	skb2 = pskb_copy(skb, GFP_ATOMIC);

	res1 = NET_XMIT_DROP;
	if (likely(hsr_priv->slave[HSR_DEV_SLAVE_A]))
		res1 = slave_xmit(skb, hsr_priv, HSR_DEV_SLAVE_A);

	res2 = NET_XMIT_DROP;
	if (likely(skb2 && hsr_priv->slave[HSR_DEV_SLAVE_B]))
		res2 = slave_xmit(skb2, hsr_priv, HSR_DEV_SLAVE_B);

	if (likely(res1 == NET_XMIT_SUCCESS || res1 == NET_XMIT_CN ||
		   res2 == NET_XMIT_SUCCESS || res2 == NET_XMIT_CN)) {
		hsr_priv->dev->stats.tx_packets++;
		hsr_priv->dev->stats.tx_bytes += skb->len;
	} else {
		hsr_priv->dev->stats.tx_dropped++;
	}

	return NETDEV_TX_OK;
}


static int hsr_header_create(struct sk_buff *skb, struct net_device *dev,
			     unsigned short type, const void *daddr,
			     const void *saddr, unsigned int len)
{
	int res;

	/* Make room for the HSR tag now. We will fill it in later (in
	 * hsr_dev_xmit)
	 */
	if (skb_headroom(skb) < HSR_TAGLEN + ETH_HLEN)
		return -ENOBUFS;
	skb_push(skb, HSR_TAGLEN);

	/* To allow VLAN/HSR combos we should probably use
	 * res = dev_hard_header(skb, dev, type, daddr, saddr, len + HSR_TAGLEN);
	 * here instead. It would require other changes too, though - e.g.
	 * separate headers for each slave etc...
	 */
	res = eth_header(skb, dev, type, daddr, saddr, len + HSR_TAGLEN);
	if (res <= 0)
		return res;
	skb_reset_mac_header(skb);

	return res + HSR_TAGLEN;
}


static const struct header_ops hsr_header_ops = {
	.create	 = hsr_header_create,
	.parse	 = eth_header_parse,
};


/* HSR:2010 supervision frames should be padded so that the whole frame,
 * including headers and FCS, is 64 bytes (without VLAN).
 */
static int hsr_pad(int size)
{
	const int min_size = ETH_ZLEN - HSR_TAGLEN - ETH_HLEN;

	if (size >= min_size)
		return size;
	return min_size;
}

static void send_hsr_supervision_frame(struct net_device *hsr_dev, u8 type)
{
	struct hsr_priv *hsr_priv;
	struct sk_buff *skb;
	int hlen, tlen;
	struct hsr_sup_tag *hsr_stag;
	struct hsr_sup_payload *hsr_sp;
	unsigned long irqflags;

	hlen = LL_RESERVED_SPACE(hsr_dev);
	tlen = hsr_dev->needed_tailroom;
	skb = alloc_skb(hsr_pad(sizeof(struct hsr_sup_payload)) + hlen + tlen,
			GFP_ATOMIC);

	if (skb == NULL)
		return;

	hsr_priv = netdev_priv(hsr_dev);

	skb_reserve(skb, hlen);

	skb->dev = hsr_dev;
	skb->protocol = htons(ETH_P_PRP);
	skb->priority = TC_PRIO_CONTROL;

	if (dev_hard_header(skb, skb->dev, ETH_P_PRP,
			    hsr_priv->sup_multicast_addr,
			    skb->dev->dev_addr, skb->len) < 0)
		goto out;

	skb_pull(skb, sizeof(struct ethhdr));
	hsr_stag = (typeof(hsr_stag)) skb->data;

	set_hsr_stag_path(hsr_stag, 0xf);
	set_hsr_stag_HSR_Ver(hsr_stag, 0);

	spin_lock_irqsave(&hsr_priv->seqnr_lock, irqflags);
	hsr_stag->sequence_nr = htons(hsr_priv->sequence_nr);
	hsr_priv->sequence_nr++;
	spin_unlock_irqrestore(&hsr_priv->seqnr_lock, irqflags);

	hsr_stag->HSR_TLV_Type = type;
	hsr_stag->HSR_TLV_Length = 12;

	skb_push(skb, sizeof(struct ethhdr));

	/* Payload: MacAddressA */
	hsr_sp = (typeof(hsr_sp)) skb_put(skb, sizeof(*hsr_sp));
	ether_addr_copy(hsr_sp->MacAddressA, hsr_dev->dev_addr);

	dev_queue_xmit(skb);
	return;

out:
	kfree_skb(skb);
}


/* Announce (supervision frame) timer function
 */
static void hsr_announce(unsigned long data)
{
	struct hsr_priv *hsr_priv;

	hsr_priv = (struct hsr_priv *) data;

	if (hsr_priv->announce_count < 3) {
		send_hsr_supervision_frame(hsr_priv->dev, HSR_TLV_ANNOUNCE);
		hsr_priv->announce_count++;
	} else {
		send_hsr_supervision_frame(hsr_priv->dev, HSR_TLV_LIFE_CHECK);
	}

	if (hsr_priv->announce_count < 3)
		hsr_priv->announce_timer.expires = jiffies +
				msecs_to_jiffies(HSR_ANNOUNCE_INTERVAL);
	else
		hsr_priv->announce_timer.expires = jiffies +
				msecs_to_jiffies(HSR_LIFE_CHECK_INTERVAL);

	if (is_admin_up(hsr_priv->dev))
		add_timer(&hsr_priv->announce_timer);
}


static void restore_slaves(struct net_device *hsr_dev)
{
	struct hsr_priv *hsr_priv;
	int i;
	int res;

	hsr_priv = netdev_priv(hsr_dev);

	rtnl_lock();

	/* Restore promiscuity */
	for (i = 0; i < HSR_MAX_SLAVE; i++) {
		if (!hsr_priv->slave[i])
			continue;
		res = dev_set_promiscuity(hsr_priv->slave[i], -1);
		if (res)
			netdev_info(hsr_dev,
				    "Cannot restore slave promiscuity (%s, %d)\n",
				    hsr_priv->slave[i]->name, res);
	}

	rtnl_unlock();
}

static void reclaim_hsr_dev(struct rcu_head *rh)
{
	struct hsr_priv *hsr_priv;

	hsr_priv = container_of(rh, struct hsr_priv, rcu_head);
	free_netdev(hsr_priv->dev);
}


/* According to comments in the declaration of struct net_device, this function
 * is "Called from unregister, can be used to call free_netdev". Ok then...
 */
static void hsr_dev_destroy(struct net_device *hsr_dev)
{
	struct hsr_priv *hsr_priv;

	hsr_priv = netdev_priv(hsr_dev);

	del_timer(&hsr_priv->announce_timer);
	unregister_hsr_master(hsr_priv);    /* calls list_del_rcu on hsr_priv */
	restore_slaves(hsr_dev);
	call_rcu(&hsr_priv->rcu_head, reclaim_hsr_dev);   /* reclaim hsr_priv */
}

static const struct net_device_ops hsr_device_ops = {
	.ndo_change_mtu = hsr_dev_change_mtu,
	.ndo_open = hsr_dev_open,
	.ndo_stop = hsr_dev_close,
	.ndo_start_xmit = hsr_dev_xmit,
};


void hsr_dev_setup(struct net_device *dev)
{
	random_ether_addr(dev->dev_addr);

	ether_setup(dev);
	dev->header_ops		 = &hsr_header_ops;
	dev->netdev_ops		 = &hsr_device_ops;
	dev->tx_queue_len	 = 0;

	dev->destructor = hsr_dev_destroy;
}


/* Return true if dev is a HSR master; return false otherwise.
 */
bool is_hsr_master(struct net_device *dev)
{
	return (dev->netdev_ops->ndo_start_xmit == hsr_dev_xmit);
}

static int check_slave_ok(struct net_device *dev)
{
	/* Don't allow HSR on non-ethernet like devices */
	if ((dev->flags & IFF_LOOPBACK) || (dev->type != ARPHRD_ETHER) ||
	    (dev->addr_len != ETH_ALEN)) {
		netdev_info(dev, "Cannot use loopback or non-ethernet device as HSR slave.\n");
		return -EINVAL;
	}

	/* Don't allow enslaving hsr devices */
	if (is_hsr_master(dev)) {
		netdev_info(dev, "Cannot create trees of HSR devices.\n");
		return -EINVAL;
	}

	if (is_hsr_slave(dev)) {
		netdev_info(dev, "This device is already a HSR slave.\n");
		return -EINVAL;
	}

	if (dev->priv_flags & IFF_802_1Q_VLAN) {
		netdev_info(dev, "HSR on top of VLAN is not yet supported in this driver.\n");
		return -EINVAL;
	}

	/* HSR over bonded devices has not been tested, but I'm not sure it
	 * won't work...
	 */

	return 0;
}


/* Default multicast address for HSR Supervision frames */
static const unsigned char def_multicast_addr[ETH_ALEN] __aligned(2) = {
	0x01, 0x15, 0x4e, 0x00, 0x01, 0x00
};

int hsr_dev_finalize(struct net_device *hsr_dev, struct net_device *slave[2],
		     unsigned char multicast_spec)
{
	struct hsr_priv *hsr_priv;
	int i;
	int res;

	hsr_priv = netdev_priv(hsr_dev);
	hsr_priv->dev = hsr_dev;
	INIT_LIST_HEAD(&hsr_priv->node_db);
	INIT_LIST_HEAD(&hsr_priv->self_node_db);
	for (i = 0; i < HSR_MAX_SLAVE; i++)
		hsr_priv->slave[i] = slave[i];

	spin_lock_init(&hsr_priv->seqnr_lock);
	/* Overflow soon to find bugs easier: */
	hsr_priv->sequence_nr = USHRT_MAX - 1024;

	init_timer(&hsr_priv->announce_timer);
	hsr_priv->announce_timer.function = hsr_announce;
	hsr_priv->announce_timer.data = (unsigned long) hsr_priv;

	ether_addr_copy(hsr_priv->sup_multicast_addr, def_multicast_addr);
	hsr_priv->sup_multicast_addr[ETH_ALEN - 1] = multicast_spec;

/* FIXME: should I modify the value of these?
 *
 * - hsr_dev->flags - i.e.
 *			IFF_MASTER/SLAVE?
 * - hsr_dev->priv_flags - i.e.
 *			IFF_EBRIDGE?
 *			IFF_TX_SKB_SHARING?
 *			IFF_HSR_MASTER/SLAVE?
 */

	for (i = 0; i < HSR_MAX_SLAVE; i++) {
		res = check_slave_ok(slave[i]);
		if (res)
			return res;
	}

	hsr_dev->features = slave[0]->features & slave[1]->features;
	/* Prevent recursive tx locking */
	hsr_dev->features |= NETIF_F_LLTX;
	/* VLAN on top of HSR needs testing and probably some work on
	 * hsr_header_create() etc.
	 */
	hsr_dev->features |= NETIF_F_VLAN_CHALLENGED;

	/* Set hsr_dev's MAC address to that of mac_slave1 */
	ether_addr_copy(hsr_dev->dev_addr, hsr_priv->slave[0]->dev_addr);

	/* Set required header length */
	for (i = 0; i < HSR_MAX_SLAVE; i++) {
		if (slave[i]->hard_header_len + HSR_TAGLEN >
						hsr_dev->hard_header_len)
			hsr_dev->hard_header_len =
					slave[i]->hard_header_len + HSR_TAGLEN;
	}

	/* MTU */
	for (i = 0; i < HSR_MAX_SLAVE; i++)
		if (slave[i]->mtu - HSR_TAGLEN < hsr_dev->mtu)
			hsr_dev->mtu = slave[i]->mtu - HSR_TAGLEN;

	/* Make sure the 1st call to netif_carrier_on() gets through */
	netif_carrier_off(hsr_dev);

	/* Promiscuity */
	for (i = 0; i < HSR_MAX_SLAVE; i++) {
		res = dev_set_promiscuity(slave[i], 1);
		if (res) {
			netdev_info(hsr_dev, "Cannot set slave promiscuity (%s, %d)\n",
				    slave[i]->name, res);
			goto fail;
		}
	}

	/* Make sure we recognize frames from ourselves in hsr_rcv() */
	res = hsr_create_self_node(&hsr_priv->self_node_db,
					hsr_dev->dev_addr,
					hsr_priv->slave[1]->dev_addr);
	if (res < 0)
		goto fail;

	res = register_netdevice(hsr_dev);
	if (res)
		goto fail;

	register_hsr_master(hsr_priv);

	return 0;

fail:
	restore_slaves(hsr_dev);
	return res;
}
