/*
 **************************************************************************
 * Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
 *
 * Permission to use, copy, modify, and/or distribute this software for
 * any purpose with or without fee is hereby granted, provided that the
 * above copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT
 * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 **************************************************************************
 */

#include <linux/if_bridge.h>
#include <linux/if_vlan.h>
#include <linux/version.h>
#include <net/switchdev.h>

#include "nss_dp_dev.h"
#include "fal/fal_stp.h"
#include "fal/fal_ctrlpkt.h"

#define NSS_DP_SWITCH_ID		0
#define NSS_DP_SW_ETHTYPE_PID		0 /* PPE ethtype profile ID for slow protocols */
#define ETH_P_NONE			0

/*
 * nss_dp_set_slow_proto_filter()
 * 	Enable/Disable filter to allow Ethernet slow-protocol
 */
static void nss_dp_set_slow_proto_filter(struct nss_dp_dev *dp_priv, bool filter_enable)
{
	sw_error_t ret = 0;
	fal_ctrlpkt_profile_t profile;
	fal_ctrlpkt_action_t action;

	memset(&profile, 0, sizeof(profile));

	/*
	 * Action is redirect cpu
	 */
	action.action = FAL_MAC_RDT_TO_CPU;
	action.sg_bypass = A_FALSE;

	/*
	 * Bypass stp
	 */
	action.in_stp_bypass = A_TRUE;
	action.in_vlan_fltr_bypass = A_FALSE;
	action.l2_filter_bypass = A_FALSE;
	profile.action = action;
	profile.ethtype_profile_bitmap = 0x1;

	/*
	 * Set port map
	 */
	profile.port_map = (1 << dp_priv->macid);
	if (filter_enable) {
		ret = fal_mgmtctrl_ctrlpkt_profile_add(NSS_DP_SWITCH_ID, &profile);
		if (ret != SW_OK) {
			netdev_dbg(dp_priv->netdev, "failed to add profile for port_map: 0x%x, ret: %d\n", profile.port_map, ret);
			return;
		}

		/*
		 * Enable filter to allow ethernet slow-protocol,
		 * if this is the first port being disabled by STP
		 */
		if (!dp_priv->ctx->slowproto_acl_bm) {
			ret = fal_mgmtctrl_ethtype_profile_set(NSS_DP_SWITCH_ID, NSS_DP_SW_ETHTYPE_PID, ETH_P_SLOW);
			if (ret != SW_OK) {
				netdev_dbg(dp_priv->netdev, "failed to set ethertype profile: 0x%x, ret: %d\n", ETH_P_SLOW, ret);
				ret = fal_mgmtctrl_ctrlpkt_profile_del(NSS_DP_SWITCH_ID, &profile);
				if (ret != SW_OK) {
					netdev_dbg(dp_priv->netdev, "failed to delete profile for port_map: 0x%x, ret: %d\n", profile.port_map, ret);
				}
				return;
			}
		}

		/*
		 * Add port to port bitmap
		 */
		dp_priv->ctx->slowproto_acl_bm = dp_priv->ctx->slowproto_acl_bm | (1 << dp_priv->macid);
	} else {

		ret = fal_mgmtctrl_ctrlpkt_profile_del(NSS_DP_SWITCH_ID, &profile);
		if (ret != SW_OK) {
			netdev_dbg(dp_priv->netdev, "failed to delete profile for port_map: 0x%x, ret: %d\n", profile.port_map, ret);
			return;
		}

		/*
		 * Delete port from port bitmap
		 */
		dp_priv->ctx->slowproto_acl_bm = dp_priv->ctx->slowproto_acl_bm & (~(1 << dp_priv->macid));

		/*
		 * If all ports are in STP-enabled state, then we do not need
		 * the filter to allow ethernet slow protocol packets
		 */
		if (!dp_priv->ctx->slowproto_acl_bm) {
			ret = fal_mgmtctrl_ethtype_profile_set(NSS_DP_SWITCH_ID, NSS_DP_SW_ETHTYPE_PID, ETH_P_NONE);
			if (ret != SW_OK) {
				netdev_dbg(dp_priv->netdev, "failed to reset ethertype profile: 0x%x ret: %d\n", ETH_P_NONE, ret);
			}
		}
	}
}

/*
 * nss_dp_stp_state_set()
 *	Set bridge port STP state to the port of NSS data plane.
 */
static int nss_dp_stp_state_set(struct nss_dp_dev *dp_priv, u8 state)
{
	sw_error_t err;
	fal_stp_state_t stp_state;

	switch (state) {
	case BR_STATE_DISABLED:
		stp_state = FAL_STP_DISABLED;

		/*
		 * Dynamic bond interfaces which are bridge slaves need to receive
		 * ethernet slow protocol packets for LACP protocol even in STP
		 * disabled state
		 */
		nss_dp_set_slow_proto_filter(dp_priv, true);
		break;
	case BR_STATE_LISTENING:
		stp_state = FAL_STP_LISTENING;
		break;
	case BR_STATE_BLOCKING:
		stp_state = FAL_STP_BLOCKING;
		break;
	case BR_STATE_LEARNING:
		stp_state = FAL_STP_LEARNING;
		break;
	case BR_STATE_FORWARDING:
		stp_state = FAL_STP_FORWARDING;

		/*
		 * Remove the filter for allowing ethernet slow protocol packets
		 * for bond interfaces
		 */
		nss_dp_set_slow_proto_filter(dp_priv, false);
		break;
	default:
		return -EOPNOTSUPP;
	}

	err = fal_stp_port_state_set(NSS_DP_SWITCH_ID, 0, dp_priv->macid,
				     stp_state);
	if (err) {
		netdev_dbg(dp_priv->netdev, "failed to set ftp state\n");

		/*
		 * Restore the slow proto filters
		 */
		if (state == BR_STATE_DISABLED)
			nss_dp_set_slow_proto_filter(dp_priv, false);
		else if (state == BR_STATE_FORWARDING)
			nss_dp_set_slow_proto_filter(dp_priv, true);

		return -EINVAL;
	}

	return 0;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 5, 0))
/*
 * nss_dp_attr_get()
 *	Get port information to update switchdev attribute for NSS data plane.
 */
static int nss_dp_attr_get(struct net_device *dev, struct switchdev_attr *attr)
{
	struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(dev);

	switch (attr->id) {
	case SWITCHDEV_ATTR_ID_PORT_PARENT_ID:
		attr->u.ppid.id_len = 1;
		attr->u.ppid.id[0] = NSS_DP_SWITCH_ID;
		break;

	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
		attr->u.brport_flags = dp_priv->brport_flags;
		break;
	default:
		return -EOPNOTSUPP;
	}

	return 0;
}

/*
 * nss_dp_attr_set()
 *	Get switchdev attribute and set to the device of NSS data plane.
 */
static int nss_dp_attr_set(struct net_device *dev,
				const struct switchdev_attr *attr,
				struct switchdev_trans *trans)
{
	struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(dev);
	struct net_device *upper_dev;
	struct vlan_dev_priv *vlan;
	struct list_head *iter;
	uint32_t stp_state = attr->u.stp_state;

	if (switchdev_trans_ph_prepare(trans))
		return 0;

	switch (attr->id) {
	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
		dp_priv->brport_flags = attr->u.brport_flags;
		netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags);
		return 0;
	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
		/*
		 * The stp state is not changed to FAL_STP_DISABLED if
		 * the net_device (dev) has any vlan configured. Otherwise
		 * traffic on other vlan(s) will not work.
		 *
		 * Note: STP for VLANs is not supported by PPE.
		 */
		if ((stp_state == BR_STATE_DISABLED) ||
			(stp_state == BR_STATE_BLOCKING)) {
			rcu_read_lock();
			netdev_for_each_upper_dev_rcu(dev, upper_dev, iter) {
				if (!is_vlan_dev(upper_dev))
					continue;

				vlan = vlan_dev_priv(upper_dev);
				if (vlan->real_dev == dev) {
					rcu_read_unlock();
					netdev_dbg(dev, "Do not update stp state to: %u since vlan id: %d is configured on netdevice: %s\n",
							stp_state, vlan->vlan_id, vlan->real_dev->name);
					return 0;
				}
			}

			rcu_read_unlock();
		}

		return nss_dp_stp_state_set(dp_priv, stp_state);
	default:
		return -EOPNOTSUPP;
	}
}

/*
 * nss_dp_switchdev_ops
 *	Switchdev operations of NSS data plane.
 */
static const struct switchdev_ops nss_dp_switchdev_ops = {
	.switchdev_port_attr_get	= nss_dp_attr_get,
	.switchdev_port_attr_set	= nss_dp_attr_set,
};

/*
 * nss_dp_switchdev_setup()
 *	Set up NSS data plane switchdev operations.
 */
void nss_dp_switchdev_setup(struct net_device *dev)
{
	dev->switchdev_ops = &nss_dp_switchdev_ops;
	switchdev_port_fwd_mark_set(dev, NULL, false);
}
#else

/*
 * nss_dp_port_attr_set()
 *	Sets attributes
 */
static int nss_dp_port_attr_set(struct net_device *dev,
				const struct switchdev_attr *attr,
				struct switchdev_trans *trans)
{
	struct nss_dp_dev *dp_priv = (struct nss_dp_dev *)netdev_priv(dev);

	if (switchdev_trans_ph_prepare(trans))
		return 0;

	switch (attr->id) {
	case SWITCHDEV_ATTR_ID_PORT_BRIDGE_FLAGS:
		dp_priv->brport_flags = attr->u.brport_flags;
		netdev_dbg(dev, "set brport_flags %lu\n", attr->u.brport_flags);
		return 0;
	case SWITCHDEV_ATTR_ID_PORT_STP_STATE:
		return nss_dp_stp_state_set(dp_priv, attr->u.stp_state);
	default:
		return -EOPNOTSUPP;
	}

}

/*
 * nss_dp_switchdev_port_attr_set_event()
 *	Attribute set event
 */
static int nss_dp_switchdev_port_attr_set_event(struct net_device *netdev,
		struct switchdev_notifier_port_attr_info *port_attr_info)
{
	int err;

	err = nss_dp_port_attr_set(netdev, port_attr_info->attr,
				   port_attr_info->trans);

	port_attr_info->handled = true;
	return notifier_from_errno(err);
}

/*
 * nss_dp_switchdev_event()
 *	Switch dev event on netdevice
 */
static int nss_dp_switchdev_event(struct notifier_block *unused,
				  unsigned long event, void *ptr)
{
	struct net_device *dev = switchdev_notifier_info_to_dev(ptr);

	/*
	 * Handle switchdev event only for physical devices
	 */
	if (!nss_dp_is_phy_dev(dev)) {
		return NOTIFY_DONE;
	}

	if (event == SWITCHDEV_PORT_ATTR_SET)
		nss_dp_switchdev_port_attr_set_event(dev, ptr);

	return NOTIFY_DONE;
}

static struct notifier_block nss_dp_switchdev_notifier = {
	.notifier_call = nss_dp_switchdev_event,
};

static bool switch_init_done;

/*
 * nss_dp_switchdev_setup()
 *	Setup switch dev
 */
void nss_dp_switchdev_setup(struct net_device *dev)
{
	int err;

	if (switch_init_done) {
		return;
	}

	err = register_switchdev_blocking_notifier(&nss_dp_switchdev_notifier);
	if (err) {
		netdev_dbg(dev, "%px:Failed to register switchdev notifier\n", dev);
	}

	switch_init_done = true;

}
#endif
