/*
 **************************************************************************
 * Copyright (c) 2016-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.
 **************************************************************************
 */

/*
 * nss_bridge_mgr.c
 *	NSS to HLOS Bridge Interface manager
 */
#include <linux/sysctl.h>
#include <linux/etherdevice.h>
#include <linux/if_vlan.h>
#include <linux/of.h>
#include <linux/if_bridge.h>
#include <net/bonding.h>
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
#include <ref/ref_vsi.h>
#include <nss_vlan_mgr.h>
#include <fal/fal_fdb.h>
#include <fal/fal_stp.h>
#include <fal/fal_acl.h>
#include <fal/fal_api.h>
#include <fal/fal_port_ctrl.h>
#endif
#include <nss_api_if.h>

#if defined(NSS_BRIDGE_MGR_OVS_ENABLE)
#include <ovsmgr.h>
#endif

#include "nss_bridge_mgr_priv.h"

/*
 * Module parameter to enable/disable OVS bridge.
 */
static bool ovs_enabled = false;

static struct nss_bridge_mgr_context br_mgr_ctx;

/*
 * nss_bridge_mgr_create_instance()
 *	Create a bridge instance.
 */
static struct nss_bridge_pvt *nss_bridge_mgr_create_instance(struct net_device *dev)
{
	struct nss_bridge_pvt *br;

#if !defined(NSS_BRIDGE_MGR_OVS_ENABLE)
	if (!netif_is_bridge_master(dev))
		return NULL;
#else
	/*
	 * When OVS is enabled, we have to check for both bridge master
	 * and OVS master.
	 */
	if (!netif_is_bridge_master(dev) && !ovsmgr_is_ovs_master(dev))
		return NULL;
#endif

	br = kzalloc(sizeof(*br), GFP_KERNEL);
	if (!br)
		return NULL;

	INIT_LIST_HEAD(&br->list);

	return br;
}

/*
 * nss_bridge_mgr_delete_instance()
 *	Delete a bridge instance from bridge list and free the bridge instance.
 */
static void nss_bridge_mgr_delete_instance(struct nss_bridge_pvt *br)
{
	spin_lock(&br_mgr_ctx.lock);
	if (!list_empty(&br->list))
		list_del(&br->list);

	spin_unlock(&br_mgr_ctx.lock);

	kfree(br);
}

/*
 * nss_bridge_mgr_find_instance()
 *	Find a bridge instance from bridge list.
 */
struct nss_bridge_pvt *nss_bridge_mgr_find_instance(struct net_device *dev)
{
	struct nss_bridge_pvt *br;

#if !defined(NSS_BRIDGE_MGR_OVS_ENABLE)
	if (!netif_is_bridge_master(dev))
		return NULL;
#else
	/*
	 * When OVS is enabled, we have to check for both bridge master
	 * and OVS master.
	 */
	if (!netif_is_bridge_master(dev) && !ovsmgr_is_ovs_master(dev))
		return NULL;
#endif
	/*
	 * Do we have it on record?
	 */
	spin_lock(&br_mgr_ctx.lock);
	list_for_each_entry(br, &br_mgr_ctx.list, list) {
		if (br->dev == dev) {
			spin_unlock(&br_mgr_ctx.lock);
			return br;
		}
	}

	spin_unlock(&br_mgr_ctx.lock);
	return NULL;
}

#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
/*
 * nss_bridge_mgr_enable_fdb_learning()
 *	Enable fdb learning in PPE.
 */
static int nss_bridge_mgr_enable_fdb_learning(struct nss_bridge_pvt *br)
{
	fal_vsi_newaddr_lrn_t newaddr_lrn;
	fal_vsi_stamove_t sta_move;

	/*
	 * Enable station move
	 */
	sta_move.stamove_en = 1;
	sta_move.action = FAL_MAC_FRWRD;
	if (fal_vsi_stamove_set(NSS_BRIDGE_MGR_SWITCH_ID, br->vsi, &sta_move)) {
		nss_bridge_mgr_warn("%px: Failed to enable station move for Bridge vsi\n", br);
		return -1;
	}

	/*
	 * Enable FDB learning in PPE
	 */
	newaddr_lrn.lrn_en = 1;
	newaddr_lrn.action = FAL_MAC_FRWRD;
	if (fal_vsi_newaddr_lrn_set(NSS_BRIDGE_MGR_SWITCH_ID, br->vsi, &newaddr_lrn)) {
		nss_bridge_mgr_warn("%px: Failed to enable FDB learning for Bridge vsi\n", br);
		goto disable_sta_move;
	}

	/*
	 * Send a notification to NSS for FDB learning enable.
	 */
	if (nss_bridge_tx_set_fdb_learn_msg(br->ifnum, NSS_BRIDGE_FDB_LEARN_ENABLE) != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: Tx message failed for FDB learning status\n", br);
		goto disable_fdb_learning;
	}

	return 0;

disable_fdb_learning:
	newaddr_lrn.lrn_en = 0;
	newaddr_lrn.action = FAL_MAC_FRWRD;
	if (fal_vsi_newaddr_lrn_set(NSS_BRIDGE_MGR_SWITCH_ID, br->vsi, &newaddr_lrn))
		nss_bridge_mgr_warn("%px: Failed to disable FDB learning for Bridge vsi\n", br);

disable_sta_move:
	sta_move.stamove_en = 0;
	sta_move.action = FAL_MAC_FRWRD;
	if (fal_vsi_stamove_set(NSS_BRIDGE_MGR_SWITCH_ID, br->vsi, &sta_move))
		nss_bridge_mgr_warn("%px: Failed to disable station move for Bridge vsi\n", br);

	return -1;
}

/*
 * nss_bridge_mgr_disable_fdb_learning()
 *	Disable fdb learning in PPE
 *
 * For the first time a bond interface join bridge, we need to use flow based rule.
 * FDB learing/station move need to be disabled.
 */
static int nss_bridge_mgr_disable_fdb_learning(struct nss_bridge_pvt *br)
{
	fal_vsi_newaddr_lrn_t newaddr_lrn;
	fal_vsi_stamove_t sta_move;

	/*
	 * Disable station move
	 */
	sta_move.stamove_en = 0;
	sta_move.action = FAL_MAC_FRWRD;
	if (fal_vsi_stamove_set(NSS_BRIDGE_MGR_SWITCH_ID, br->vsi, &sta_move)) {
		nss_bridge_mgr_warn("%px: Failed to disable station move for Bridge vsi\n", br);
		return -1;
	}

	/*
	 * Disable FDB learning in PPE
	 */
	newaddr_lrn.lrn_en = 0;
	newaddr_lrn.action = FAL_MAC_FRWRD;
	if (fal_vsi_newaddr_lrn_set(NSS_BRIDGE_MGR_SWITCH_ID, br->vsi, &newaddr_lrn)) {
		nss_bridge_mgr_warn("%px: Failed to disable FDB learning for Bridge vsi\n", br);
		goto enable_sta_move;
	}

	/*
	 * Flush FDB table for the bridge vsi
	 */
	if (fal_fdb_entry_del_byfid(NSS_BRIDGE_MGR_SWITCH_ID, br->vsi, FAL_FDB_DEL_STATIC)) {
		nss_bridge_mgr_warn("%px: Failed to flush FDB table for vsi:%d in PPE\n", br, br->vsi);
		goto enable_fdb_learning;
	}

	/*
	 * Send a notification to NSS for FDB learning disable.
	 */
	if (nss_bridge_tx_set_fdb_learn_msg(br->ifnum, NSS_BRIDGE_FDB_LEARN_DISABLE) != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: Tx message failed for FDB learning status\n", br);
		goto enable_fdb_learning;
	}

	return 0;

enable_fdb_learning:
	newaddr_lrn.lrn_en = 1;
	newaddr_lrn.action = FAL_MAC_FRWRD;
	if (fal_vsi_newaddr_lrn_set(NSS_BRIDGE_MGR_SWITCH_ID, br->vsi, &newaddr_lrn))
		nss_bridge_mgr_warn("%px: Failed to enable FDB learning for Bridge vsi\n", br);

enable_sta_move:
	sta_move.stamove_en = 1;
	sta_move.action = FAL_MAC_FRWRD;
	if (fal_vsi_stamove_set(NSS_BRIDGE_MGR_SWITCH_ID, br->vsi, &sta_move))
		nss_bridge_mgr_warn("%px: Failed to enable station move for Bridge vsi\n", br);

	return -1;
}

/*
 * nss_bridge_mgr_add_bond_slave()
 *	A slave interface being added to a bond master that belongs to a bridge.
 */
static int nss_bridge_mgr_add_bond_slave(struct net_device *bond_master,
		struct net_device *slave, struct nss_bridge_pvt *b_pvt)
{
	uint32_t *port_vsi;
	int32_t port_id;
	int32_t ifnum;
	int32_t lagid = 0;
	int32_t bondid = -1;

	/*
	 * Figure out the aggregation id of this slave
	 */
#if defined(BONDING_SUPPORT)
	bondid = bond_get_id(bond_master);
#endif
	if (bondid < 0) {
		nss_bridge_mgr_warn("%px: Invalid LAG group id 0x%x\n",
				b_pvt, bondid);
		return -1;
	}

	lagid = bondid + NSS_LAG0_INTERFACE_NUM;

	nss_bridge_mgr_trace("%px: Bond Slave %s is added bridge\n",
			b_pvt, slave->name);

	ifnum = nss_cmn_get_interface_number_by_dev(slave);

	/*
	 * Hardware supports only PHYSICAL Ports as trunk ports
	 */
	if (!NSS_BRIDGE_MGR_IF_IS_TYPE_PHYSICAL(ifnum)) {
		nss_bridge_mgr_warn("%px: Interface %s is not Physical Interface\n",
				b_pvt, slave->name);
		return -1;
	}

	nss_bridge_mgr_trace("%px: Interface %s adding into bridge\n",
			b_pvt, slave->name);
	port_id = ifnum;

	/*
	 * Take bridge lock as we are updating vsi and port forwarding
	 * details in PPE Hardware
	 */
	spin_lock(&br_mgr_ctx.lock);
	port_vsi = &b_pvt->port_vsi[port_id - 1];

	if (ppe_port_vsi_get(NSS_BRIDGE_MGR_SWITCH_ID, port_id, port_vsi)) {
		spin_unlock(&br_mgr_ctx.lock);
		nss_bridge_mgr_warn("%px: Couldn't get VSI for port %d\n",
				b_pvt, port_id);
		return -1;
	}

	if (ppe_port_vsi_set(NSS_BRIDGE_MGR_SWITCH_ID, port_id, b_pvt->vsi)) {
		spin_unlock(&br_mgr_ctx.lock);
		nss_bridge_mgr_warn("%px: Couldn't set bridge VSI for port %d\n",
				b_pvt, port_id);
		return -1;
	}
	spin_unlock(&br_mgr_ctx.lock);

	if (nss_bridge_tx_join_msg(b_pvt->ifnum,
				slave) != NSS_TX_SUCCESS) {
		if (ppe_port_vsi_set(NSS_BRIDGE_MGR_SWITCH_ID, port_id, *port_vsi))
			nss_bridge_mgr_warn("%px: Couldn't set bridge VSI for port %d\n", b_pvt, port_id);
		nss_bridge_mgr_warn("%px: Couldn't add port %d in bridge",
				b_pvt, port_id);
		return -1;
	}

	spin_lock(&br_mgr_ctx.lock);
	b_pvt->lag_ports[port_id - 1] = lagid;
	spin_unlock(&br_mgr_ctx.lock);

	return 0;
}

/*
 * nss_bridge_mgr_del_bond_slave()
 *	A slave interface being removed from a bond master that belongs to a bridge.
 */
static int nss_bridge_mgr_del_bond_slave(struct net_device *bond_master,
		struct net_device *slave, struct nss_bridge_pvt *b_pvt)
{
	uint32_t *port_vsi;
	int32_t port_id;
	int32_t ifnum;
	int32_t lagid = 0;
	int32_t bondid = -1;

	/*
	 * Figure out the aggregation id of this slave
	 */
#if defined(BONDING_SUPPORT)
	bondid = bond_get_id(bond_master);
#endif
	if (bondid < 0) {
		nss_bridge_mgr_warn("%px: Invalid LAG group id 0x%x\n",
				b_pvt, bondid);
		return -1;
	}

	lagid = bondid + NSS_LAG0_INTERFACE_NUM;

	nss_bridge_mgr_trace("%px: Bond Slave %s leaving bridge\n",
			b_pvt, slave->name);

	ifnum = nss_cmn_get_interface_number_by_dev(slave);

	/*
	 * Hardware supports only PHYSICAL Ports as trunk ports
	 */
	if (!NSS_BRIDGE_MGR_IF_IS_TYPE_PHYSICAL(ifnum)) {
		nss_bridge_mgr_warn("%px: Interface %s is not Physical Interface\n",
				b_pvt, slave->name);
		return -1;
	}

	nss_bridge_mgr_trace("%px: Interface %s leaving from bridge\n",
			b_pvt, slave->name);

	port_id = (fal_port_t)ifnum;

	/*
	 * Take bridge lock as we are updating vsi and port forwarding
	 * details in PPE Hardware
	 */
	spin_lock(&br_mgr_ctx.lock);
	port_vsi = &b_pvt->port_vsi[port_id - 1];

	if (b_pvt->lag_ports[port_id - 1] != lagid) {
		spin_unlock(&br_mgr_ctx.lock);
		return -1;
	}

	if (ppe_port_vsi_set(NSS_BRIDGE_MGR_SWITCH_ID, port_id, *port_vsi)) {
		spin_unlock(&br_mgr_ctx.lock);
		nss_bridge_mgr_warn("%px: failed to restore port VSI for port %d\n", b_pvt, port_id);
		return -1;
	}
	spin_unlock(&br_mgr_ctx.lock);

	if (nss_bridge_tx_leave_msg(b_pvt->ifnum,
				slave) != NSS_TX_SUCCESS) {
		ppe_port_vsi_set(NSS_BRIDGE_MGR_SWITCH_ID, port_id, b_pvt->vsi);
		nss_bridge_mgr_trace("%px: Failed to remove port %d from bridge\n",
				b_pvt, port_id);
		return -1;
	}

	spin_lock(&br_mgr_ctx.lock);
	b_pvt->lag_ports[port_id - 1] = 0;
	spin_unlock(&br_mgr_ctx.lock);

	/*
	 * Set STP state to forwarding after bond physical port leaves bridge
	 */
	fal_stp_port_state_set(NSS_BRIDGE_MGR_SWITCH_ID, NSS_BRIDGE_MGR_SPANNING_TREE_ID,
					port_id, FAL_STP_FORWARDING);
	return 0;
}

/*
 * nss_bridge_mgr_bond_master_join()
 *	Add a bond interface to bridge
 */
static int nss_bridge_mgr_bond_master_join(struct net_device *bond_master,
		struct nss_bridge_pvt *b_pvt)
{
	struct net_device *slave;

	/*
	 * bond enslave/release path is protected by rtnl lock
	 */
	ASSERT_RTNL();

	/*
	 * Wait for RCU QS
	 */
	synchronize_rcu();

	/*
	 * Join each of the bonded slaves to the VSI group
	 */
	for_each_netdev(&init_net, slave) {
		if (netdev_master_upper_dev_get(slave) != bond_master) {
			continue;
		}

		if (nss_bridge_mgr_add_bond_slave(bond_master, slave, b_pvt)) {
			nss_bridge_mgr_warn("%px: Failed to add slave (%s) state in Bridge\n", b_pvt, slave->name);
			goto cleanup;
		}
	}

	/*
	 * If already other bond devices are attached to bridge,
	 * only increment bond_slave_num,
	 */
	spin_lock(&br_mgr_ctx.lock);
	if (b_pvt->bond_slave_num) {
		b_pvt->bond_slave_num++;
		spin_unlock(&br_mgr_ctx.lock);
		return NOTIFY_DONE;
	}
	spin_unlock(&br_mgr_ctx.lock);

	/*
	 * This is the first bond device being attached to bridge. In order to enforce Linux
	 * bond slave selection in bridge flows involving bond interfaces, we need to disable
	 * fdb learning on this bridge master to allow flow based bridging.
	 */
	if (!nss_bridge_mgr_disable_fdb_learning(b_pvt)) {
		spin_lock(&br_mgr_ctx.lock);
		b_pvt->bond_slave_num = 1;
		spin_unlock(&br_mgr_ctx.lock);

		return NOTIFY_DONE;
	}

cleanup:

	for_each_netdev(&init_net, slave) {
		if (netdev_master_upper_dev_get(slave) != bond_master) {
			continue;
		}

		if (nss_bridge_mgr_del_bond_slave(bond_master, slave, b_pvt)) {
			nss_bridge_mgr_warn("%px: Failed to remove slave (%s) from Bridge\n", b_pvt, slave->name);
		}
	}

	return NOTIFY_BAD;
}

/*
 * nss_bridge_mgr_bond_master_leave()
 *	Remove a bond interface from bridge
 */
static int nss_bridge_mgr_bond_master_leave(struct net_device *bond_master,
		struct nss_bridge_pvt *b_pvt)
{
	struct net_device *slave;

	nss_bridge_mgr_assert(b_pvt->bond_slave_num == 0);

	ASSERT_RTNL();

	synchronize_rcu();

	/*
	 * Remove each of the bonded slaves from the VSI group
	 */
	for_each_netdev(&init_net, slave) {
		if (netdev_master_upper_dev_get(slave) != bond_master) {
			continue;
		}

		if (nss_bridge_mgr_del_bond_slave(bond_master, slave, b_pvt)) {
			nss_bridge_mgr_warn("%px: Failed to remove slave (%s) from Bridge\n", b_pvt, slave->name);
			goto cleanup;
		}
	}

	/*
	 * If more than one bond devices are attached to bridge,
	 * only decrement the bond_slave_num
	 */
	spin_lock(&br_mgr_ctx.lock);
	if (b_pvt->bond_slave_num > 1) {
		b_pvt->bond_slave_num--;
		spin_unlock(&br_mgr_ctx.lock);
		return NOTIFY_DONE;
	}
	spin_unlock(&br_mgr_ctx.lock);

	/*
	 * The last bond interface is removed from bridge, we can switch back to FDB
	 * learning mode.
	 */
	if (!nss_bridge_mgr_enable_fdb_learning(b_pvt)) {
		spin_lock(&br_mgr_ctx.lock);
		b_pvt->bond_slave_num = 0;
		spin_unlock(&br_mgr_ctx.lock);

		return NOTIFY_DONE;
	}

cleanup:
	for_each_netdev(&init_net, slave) {
		if (netdev_master_upper_dev_get(slave) != bond_master) {
			continue;
		}

		if (nss_bridge_mgr_add_bond_slave(bond_master, slave, b_pvt)) {
			nss_bridge_mgr_warn("%px: Failed to add slave (%s) state in Bridge\n", b_pvt, slave->name);
		}
	}

	return NOTIFY_BAD;
}

/*
 * nss_bridge_mgr_l2_exception_acl_enable()
 *	Create ACL rule to enable L2 exception.
 */
static bool nss_bridge_mgr_l2_exception_acl_enable(void)
{
	sw_error_t error;
	fal_acl_rule_t rule;

	memset(&rule, 0, sizeof(rule));
	error = fal_acl_list_creat(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_LIST_PRIORITY);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("List creation failed with error = %d\n", error);
		return false;
	}

	/*
	 * Enable excpetion for packets with fragments.
	 */
	rule.rule_type = FAL_ACL_RULE_IP4;
	rule.is_fragement_mask = 1;
	rule.is_fragement_val = A_TRUE;
	FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_L3_FRAGMENT);
	FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_RDTCPU);

	error = fal_acl_rule_add(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_FRAG_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR, &rule);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("Could not add fragment acl rule, error = %d\n", error);
		goto frag_fail;
	}

	/*
	 * Enable excpetion for TCP FIN.
	 */
	memset(&rule, 0, sizeof(rule));

	rule.rule_type = FAL_ACL_RULE_IP4;
	rule.tcp_flag_val = 0x1 & 0x3f;
	rule.tcp_flag_mask = 0x1 & 0x3f;
	FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_TCP_FLAG);
	FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_RDTCPU);

	error = fal_acl_rule_add(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_FIN_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR, &rule);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("Could not add TCP FIN rule, error = %d\n", error);
		goto fin_fail;
	}

	/*
	 * Enable excpetion for TCP SYN.
	 */
	memset(&rule, 0, sizeof(rule));

	rule.rule_type = FAL_ACL_RULE_IP4;
	rule.tcp_flag_val = 0x2 & 0x3f;
	rule.tcp_flag_mask = 0x2 & 0x3f;
	FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_TCP_FLAG);
	FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_RDTCPU);

	error = fal_acl_rule_add(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_SYN_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR, &rule);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("Could not add TCP SYN rule, error = %d\n", error);
		goto syn_fail;
	}

	/*
	 * Enable excpetion for TCP RST.
	 */
	memset(&rule, 0, sizeof(rule));

	rule.rule_type = FAL_ACL_RULE_IP4;
	rule.tcp_flag_val = 0x4 & 0x3f;
	rule.tcp_flag_mask = 0x4 & 0x3f;
	FAL_FIELD_FLG_SET(rule.field_flg, FAL_ACL_FIELD_TCP_FLAG);
	FAL_ACTION_FLG_SET(rule.action_flg, FAL_ACL_ACTION_RDTCPU);

	error = fal_acl_rule_add(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_RST_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR, &rule);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("Could not add TCP RST rule, error = %d\n", error);
		goto rst_fail;
	}

	/*
	 * Bind ACL list with service code
	 */
	error = fal_acl_list_bind(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				FAL_ACL_DIREC_IN, FAL_ACL_BIND_SERVICE_CODE, NSS_PPE_SC_VLAN_FILTER_BYPASS);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("Could not bind ACL list, error = %d\n", error);
		goto bind_fail;
	}

	nss_bridge_mgr_info("Created ACL rule\n");
	return true;

bind_fail:
	error = fal_acl_rule_delete(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_RST_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("TCP RST rule deletion failed, error %d\n", error);
	}

rst_fail:
	error = fal_acl_rule_delete(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_SYN_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("TCP SYN rule deletion failed, error %d\n", error);
	}

syn_fail:
	error = fal_acl_rule_delete(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_FIN_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("TCP FIN rule deletion failed, error %d\n", error);
	}

fin_fail:
	error = fal_acl_rule_delete(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_FRAG_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("IP fragmentation rule deletion failed, error %d\n", error);
	}

frag_fail:
	error = fal_acl_list_destroy(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("ACL list destroy failed, error %d\n", error);
	}

	return false;
}

/*
 * nss_bridge_mgr_l2_exception_acl_disable()
 *	Destroy ACL list and rule created by the driver.
 */
static void nss_bridge_mgr_l2_exception_acl_disable(void)
{
	sw_error_t error;

	error = fal_acl_rule_delete(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_SYN_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("TCP SYN rule deletion failed, error %d\n", error);
	}

	error = fal_acl_rule_delete(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_FIN_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("TCP FIN rule deletion failed, error %d\n", error);
	}

	error = fal_acl_rule_delete(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_RST_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("TCP RST rule deletion failed, error %d\n", error);
	}

	error = fal_acl_rule_delete(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID,
				NSS_BRIDGE_MGR_ACL_FRAG_RULE_ID, NSS_BRIDGE_MGR_ACL_RULE_NR);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("IP fragmentation rule deletion failed, error %d\n", error);
	}

	error = fal_acl_list_destroy(NSS_BRIDGE_MGR_ACL_DEV_ID, NSS_BRIDGE_MGR_ACL_LIST_ID);
	if (error != SW_OK) {
		nss_bridge_mgr_warn("ACL list destroy failed, error %d\n", error);
	}
}

#endif

/*
 * nss_bridge_mgr_join_bridge()
 *	Netdevice join bridge and send netdevice joining bridge message to NSS FW.
 */
int nss_bridge_mgr_join_bridge(struct net_device *dev, struct nss_bridge_pvt *br)
{
	int32_t ifnum;

	ifnum = nss_cmn_get_interface_number_by_dev(dev);
	if (ifnum < 0) {
		nss_bridge_mgr_warn("%s: failed to find interface number\n", dev->name);
		return -EINVAL;
	}

#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
	if (NSS_BRIDGE_MGR_IF_IS_TYPE_PHYSICAL(ifnum)) {
		fal_port_t port_num = (fal_port_t)ifnum;

		/*
		 * If there is a wan interface added in bridge, create a
		 * separate VSI for it, hence avoiding FDB based forwarding.
		 * This is done by not sending join message to the bridge in NSS.
		 */
		if (br_mgr_ctx.wan_if_num == ifnum) {
			br->wan_if_enabled = true;
			br->wan_if_num = ifnum;
			nss_bridge_mgr_info("if_num %d is added as WAN interface \n", ifnum);
			return 0;
		}

		if (ppe_port_vsi_get(NSS_BRIDGE_MGR_SWITCH_ID, port_num, &br->port_vsi[port_num - 1])) {
			nss_bridge_mgr_warn("%px: failed to save port VSI of physical interface\n", br);
			return -EIO;
		}

		if (ppe_port_vsi_set(NSS_BRIDGE_MGR_SWITCH_ID, port_num, br->vsi)) {
			nss_bridge_mgr_warn("%px: failed to set bridge VSI for physical interface\n", br);
			return -EIO;
		}
	} else if (is_vlan_dev(dev)) {
		struct net_device *real_dev;

		/*
		 * Find real_dev associated with the VLAN
		 */
		real_dev = nss_vlan_mgr_get_real_dev(dev);
		if (real_dev && is_vlan_dev(real_dev))
			real_dev = nss_vlan_mgr_get_real_dev(real_dev);
		if (real_dev == NULL) {
			nss_bridge_mgr_warn("%px: real dev for the vlan: %s in NULL\n", br, dev->name);
			return -EINVAL;
		}

		/*
		 * This is a valid vlan dev, add the vlan dev to bridge
		 */
		if (nss_vlan_mgr_join_bridge(dev, br->vsi)) {
			nss_bridge_mgr_warn("%px: vlan device failed to join bridge\n", br);
			return -ENODEV;
		}

		/*
		 * dev is a bond with VLAN and VLAN is added to bridge
		 */
		if (netif_is_bond_master(real_dev)) {
			if (nss_bridge_tx_join_msg(br->ifnum, dev) != NSS_TX_SUCCESS) {
				nss_bridge_mgr_warn("%px: Interface %s join bridge failed\n", br, dev->name);
				nss_vlan_mgr_leave_bridge(dev, br->vsi);
				return -ENOENT;
			}

			/*
			 * Add the bond_master to bridge.
			 */
			if (nss_bridge_mgr_bond_master_join(real_dev, br) != NOTIFY_DONE) {
				nss_bridge_mgr_warn("%px: Slaves of bond interface %s join bridge failed\n", br, real_dev->name);
				nss_bridge_tx_leave_msg(br->ifnum, dev);
				nss_vlan_mgr_leave_bridge(dev, br->vsi);
				return -EINVAL;
			}

			return 0;
		}
	}
#endif

	if (nss_bridge_tx_join_msg(br->ifnum, dev) != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: Interface %s join bridge failed\n", br, dev->name);
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
		if (NSS_BRIDGE_MGR_IF_IS_TYPE_PHYSICAL(ifnum)) {
			fal_port_t port_num = (fal_port_t)ifnum;
			ppe_port_vsi_set(NSS_BRIDGE_MGR_SWITCH_ID, port_num, br->port_vsi[port_num - 1]);
		}
#endif
		return -EIO;
	}

	return 0;
}

/*
 * nss_bridge_mgr_leave_bridge()
 *	Netdevice leave bridge and send netdevice leaving bridge message to NSS FW.
 */
int nss_bridge_mgr_leave_bridge(struct net_device *dev, struct nss_bridge_pvt *br)
{
	int32_t ifnum;

	ifnum = nss_cmn_get_interface_number_by_dev(dev);
	if (ifnum < 0) {
		nss_bridge_mgr_warn("%s: failed to find interface number\n", dev->name);
		return -1;
	}

#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
	if (NSS_BRIDGE_MGR_IF_IS_TYPE_PHYSICAL(ifnum)) {
		fal_port_t port_num = (fal_port_t)ifnum;

		if (fal_stp_port_state_set(NSS_BRIDGE_MGR_SWITCH_ID, NSS_BRIDGE_MGR_SPANNING_TREE_ID, port_num, FAL_STP_FORWARDING)) {
			nss_bridge_mgr_warn("%px: faied to set the STP state to forwarding\n", br);
			return -1;
		}

		/*
		 * If there is a wan interface added in bridge, a separate
		 * VSI is created for it by not sending join message to NSS.
		 * Hence a leave message should also be avaoided.
		 */
		if ((br->wan_if_enabled) && (br->wan_if_num == ifnum)) {
			br->wan_if_enabled = false;
			br->wan_if_num = -1;
			nss_bridge_mgr_info("if_num %d is added as WAN interface\n", ifnum);
			return 0;
		}

		if (ppe_port_vsi_set(NSS_BRIDGE_MGR_SWITCH_ID, port_num, br->port_vsi[port_num - 1])) {
			nss_bridge_mgr_warn("%px: failed to restore port VSI of physical interface\n", br);
			fal_stp_port_state_set(NSS_BRIDGE_MGR_SWITCH_ID, NSS_BRIDGE_MGR_SPANNING_TREE_ID, port_num, FAL_STP_DISABLED);
			return -1;
		}
	} else if (is_vlan_dev(dev)) {
		struct net_device *real_dev;

		/*
		 * Find real_dev associated with the VLAN.
		 */
		real_dev = nss_vlan_mgr_get_real_dev(dev);
		if (real_dev && is_vlan_dev(real_dev))
			real_dev = nss_vlan_mgr_get_real_dev(real_dev);
		if (real_dev == NULL) {
			nss_bridge_mgr_warn("%px: real dev for the vlan: %s in NULL\n", br, dev->name);
			return -1;
		}

		/*
		 * This is a valid vlan dev, remove the vlan dev from bridge.
		 */
		if (nss_vlan_mgr_leave_bridge(dev, br->vsi)) {
			nss_bridge_mgr_warn("%px: vlan device failed to leave bridge\n", br);
			return -1;
		}

		/*
		 * dev is a bond with VLAN and VLAN is removed from bridge
		 */
		if (netif_is_bond_master(real_dev)) {
			if (nss_bridge_tx_leave_msg(br->ifnum, dev) != NSS_TX_SUCCESS) {
				nss_bridge_mgr_warn("%px: Interface %s leave bridge failed\n", br, dev->name);
				nss_vlan_mgr_join_bridge(dev, br->vsi);
				nss_bridge_tx_join_msg(br->ifnum, dev);
				return -1;
			}

			/*
			 * Remove the bond_master from bridge.
			 */
			if (nss_bridge_mgr_bond_master_leave(real_dev, br) != NOTIFY_DONE) {
				nss_bridge_mgr_warn("%px: Slaves of bond interface %s leave bridge failed\n", br, real_dev->name);
				nss_vlan_mgr_join_bridge(dev, br->vsi);
				nss_bridge_tx_join_msg(br->ifnum, dev);
				return -1;
			}

			return 0;
		}
	}
#endif

	if (nss_bridge_tx_leave_msg(br->ifnum, dev) != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: Interface %s leave bridge failed\n", br, dev->name);
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
		if (is_vlan_dev(dev)) {
			nss_vlan_mgr_join_bridge(dev, br->vsi);
			nss_bridge_tx_join_msg(br->ifnum, dev);
		} else if (NSS_BRIDGE_MGR_IF_IS_TYPE_PHYSICAL(ifnum)) {
			fal_port_t port_num = (fal_port_t)ifnum;

			fal_stp_port_state_set(NSS_BRIDGE_MGR_SWITCH_ID, NSS_BRIDGE_MGR_SPANNING_TREE_ID, port_num, FAL_STP_DISABLED);
			ppe_port_vsi_set(NSS_BRIDGE_MGR_SWITCH_ID, port_num, br->vsi);
		}
#endif
		return -1;
	}

	return 0;
}

/*
 * nss_bridge_mgr_unregister_br()
 *	Unregister bridge device, dev, from bridge manager database.
 */
int nss_bridge_mgr_unregister_br(struct net_device *dev)
{
	struct nss_bridge_pvt *b_pvt;

	/*
	 * Do we have it on record?
	 */
	b_pvt = nss_bridge_mgr_find_instance(dev);
	if (!b_pvt)
		return -1;

	/*
	 * sequence of free:
	 * 1. issue VSI unassign to NSS
	 * 2. free VSI
	 * 3. flush bridge FDB table
	 * 4. unregister bridge netdevice from data plane
	 * 5. deallocate dynamic interface associated with bridge netdevice
	 * 6. free bridge netdevice
	 */
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
	/*
	 * VSI unassign function in NSS firmware only returns
	 * CNODE_SEND_NACK in the beginning of the function when it
	 * detects that bridge VSI is not assigned for the bridge.
	 * Please refer to the function bridge_configure_vsi_unassign
	 * in NSS firmware for detailed operation.
	 */
	if (nss_bridge_tx_vsi_unassign_msg(b_pvt->ifnum, b_pvt->vsi) != NSS_TX_SUCCESS)
		nss_bridge_mgr_warn("%px: failed to unassign vsi\n", b_pvt);

	ppe_vsi_free(NSS_BRIDGE_MGR_SWITCH_ID, b_pvt->vsi);

	/*
	 * It may happen that the same VSI is allocated again,
	 * so there is a need to flush bridge FDB table.
	 */
	if (fal_fdb_entry_del_byfid(NSS_BRIDGE_MGR_SWITCH_ID, b_pvt->vsi, FAL_FDB_DEL_STATIC)) {
		nss_bridge_mgr_warn("%px: Failed to flush FDB table for vsi:%d in PPE\n", b_pvt, b_pvt->vsi);
	}
#endif

	nss_bridge_mgr_trace("%px: Bridge %s unregsitered. Freeing bridge di %d\n", b_pvt, dev->name, b_pvt->ifnum);

	nss_bridge_unregister(b_pvt->ifnum);

	if (nss_dynamic_interface_dealloc_node(b_pvt->ifnum, NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE) != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: dealloc bridge di failed\n", b_pvt);
	}

	nss_bridge_mgr_delete_instance(b_pvt);
	return 0;
}

/*
 * nss_bridge_mgr_register_br()
 *	Register new bridge instance in bridge manager database.
 */
int nss_bridge_mgr_register_br(struct net_device *dev)
{
	struct nss_bridge_pvt *b_pvt;
	int ifnum;
	int err;
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
	uint32_t vsi_id = 0;
#endif

	nss_bridge_mgr_info("%px: Bridge register: %s\n", dev, dev->name);

	b_pvt = nss_bridge_mgr_create_instance(dev);
	if (!b_pvt)
		return -EINVAL;

	b_pvt->dev = dev;

	ifnum = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE);
	if (ifnum < 0) {
		nss_bridge_mgr_warn("%px: failed to alloc bridge di\n", b_pvt);
		nss_bridge_mgr_delete_instance(b_pvt);
		return -EFAULT;
	}

	if (!nss_bridge_register(ifnum, dev, NULL, NULL, 0, b_pvt)) {
		nss_bridge_mgr_warn("%px: failed to register bridge di to NSS\n", b_pvt);
		goto fail;
	}

#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
	err = ppe_vsi_alloc(NSS_BRIDGE_MGR_SWITCH_ID, &vsi_id);
	if (err) {
		nss_bridge_mgr_warn("%px: failed to alloc bridge vsi, error = %d\n", b_pvt, err);
		goto fail_1;
	}

	b_pvt->vsi = vsi_id;

	err = nss_bridge_tx_vsi_assign_msg(ifnum, vsi_id);
	if (err != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: failed to assign vsi msg, error = %d\n", b_pvt, err);
		goto fail_2;
	}
#endif

	err = nss_bridge_tx_set_mac_addr_msg(ifnum, dev->dev_addr);
	if (err != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: failed to set mac_addr msg, error = %d\n", b_pvt, err);
		goto fail_3;
	}

	err = nss_bridge_tx_set_mtu_msg(ifnum, dev->mtu);
	if (err != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: failed to set mtu msg, error = %d\n", b_pvt, err);
		goto fail_3;
	}

	/*
	 * All done, take a snapshot of the current mtu and mac addrees
	 */
	b_pvt->ifnum = ifnum;
	b_pvt->mtu = dev->mtu;
	b_pvt->wan_if_num = -1;
	b_pvt->wan_if_enabled = false;
	ether_addr_copy(b_pvt->dev_addr, dev->dev_addr);
	spin_lock(&br_mgr_ctx.lock);
	list_add(&b_pvt->list, &br_mgr_ctx.list);
	spin_unlock(&br_mgr_ctx.lock);

#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
	/*
	 * Disable FDB learning if OVS is enabled for
	 * all bridges (including Linux bridge).
	 */
	if (ovs_enabled) {
		nss_bridge_mgr_disable_fdb_learning(b_pvt);
	}
#endif
	return 0;

fail_3:
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
	if (nss_bridge_tx_vsi_unassign_msg(ifnum, vsi_id) != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: failed to unassign vsi\n", b_pvt);
	}

fail_2:
	ppe_vsi_free(NSS_BRIDGE_MGR_SWITCH_ID, vsi_id);

fail_1:
#endif
	nss_bridge_unregister(ifnum);

fail:
	if (nss_dynamic_interface_dealloc_node(ifnum, NSS_DYNAMIC_INTERFACE_TYPE_BRIDGE) != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: failed to dealloc bridge di\n", b_pvt);
	}

	nss_bridge_mgr_delete_instance(b_pvt);
	return -EFAULT;
}

/*
 * nss_bridge_mgr_bond_slave_changeupper()
 *	Add bond slave to bridge VSI
 */
static int nss_bridge_mgr_bond_slave_changeupper(struct netdev_notifier_changeupper_info *cu_info,
		struct net_device *bond_slave)
{
	struct net_device *master;
	struct nss_bridge_pvt *b_pvt;

	/*
	 * Checking if our bond master is part of a bridge
	 */
	master = netdev_master_upper_dev_get(cu_info->upper_dev);
	if (!master)
		return NOTIFY_DONE;

	b_pvt = nss_bridge_mgr_find_instance(master);
	if (!b_pvt) {
		nss_bridge_mgr_warn("The bond master is not part of Bridge dev:%s\n", master->name);
		return NOTIFY_DONE;
	}

	/*
	 * Add or remove the slave based based on linking event
	 */
	if (cu_info->linking) {
		if (nss_bridge_mgr_add_bond_slave(cu_info->upper_dev, bond_slave, b_pvt)) {
			nss_bridge_mgr_warn("%px: Failed to add slave (%s) state in Bridge %s\n", b_pvt,
					cu_info->upper_dev->name, master->name);
		}
	} else {
		if (nss_bridge_mgr_del_bond_slave(cu_info->upper_dev, bond_slave, b_pvt)) {
			nss_bridge_mgr_warn("%px: Failed to remove slave (%s) state in Bridge %s\n", b_pvt,
					cu_info->upper_dev->name, master->name);
		}
	}

	return NOTIFY_DONE;
}

/*
 * nss_bridge_mgr_changemtu_event()
 *	Change bridge MTU and send change bridge MTU message to NSS FW.
 */
static int nss_bridge_mgr_changemtu_event(struct netdev_notifier_info *info)
{
	struct net_device *dev = netdev_notifier_info_to_dev(info);
	struct nss_bridge_pvt *b_pvt = nss_bridge_mgr_find_instance(dev);

	if (!b_pvt)
		return NOTIFY_DONE;

	spin_lock(&br_mgr_ctx.lock);
	if (b_pvt->mtu == dev->mtu) {
		spin_unlock(&br_mgr_ctx.lock);
		return NOTIFY_DONE;
	}
	spin_unlock(&br_mgr_ctx.lock);

	nss_bridge_mgr_trace("%px: MTU changed to %d, send message to NSS\n", b_pvt, dev->mtu);

	if (nss_bridge_tx_set_mtu_msg(b_pvt->ifnum, dev->mtu) != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: Failed to send change MTU message to NSS\n", b_pvt);
		return NOTIFY_DONE;
	}

	spin_lock(&br_mgr_ctx.lock);
	b_pvt->mtu = dev->mtu;
	spin_unlock(&br_mgr_ctx.lock);

	return NOTIFY_DONE;
}

/*
 * nss_bridge_mgr_changeaddr_event()
 *	Change bridge MAC address and send change bridge address message to NSS FW.
 */
static int nss_bridge_mgr_changeaddr_event(struct netdev_notifier_info *info)
{
	struct net_device *dev = netdev_notifier_info_to_dev(info);
	struct nss_bridge_pvt *b_pvt = nss_bridge_mgr_find_instance(dev);

	if (!b_pvt)
		return NOTIFY_DONE;

	spin_lock(&br_mgr_ctx.lock);
	if (!memcmp(b_pvt->dev_addr, dev->dev_addr, ETH_ALEN)) {
		spin_unlock(&br_mgr_ctx.lock);
		nss_bridge_mgr_trace("%px: MAC are the same..skip processing it\n", b_pvt);
		return NOTIFY_DONE;
	}
	spin_unlock(&br_mgr_ctx.lock);

	nss_bridge_mgr_trace("%px: MAC changed to %pM, update NSS\n", b_pvt, dev->dev_addr);

	if (nss_bridge_tx_set_mac_addr_msg(b_pvt->ifnum, dev->dev_addr) != NSS_TX_SUCCESS) {
		nss_bridge_mgr_warn("%px: Failed to send change MAC address message to NSS\n", b_pvt);
		return NOTIFY_DONE;
	}

	spin_lock(&br_mgr_ctx.lock);
	ether_addr_copy(b_pvt->dev_addr, dev->dev_addr);
	spin_unlock(&br_mgr_ctx.lock);

	return NOTIFY_DONE;
}

/*
 * nss_bridge_mgr_changeupper_event()
 *	Bridge manager handles netdevice joining or leaving bridge notification.
 */
static int nss_bridge_mgr_changeupper_event(struct netdev_notifier_info *info)
{
	struct net_device *dev = netdev_notifier_info_to_dev(info);
	struct net_device *master_dev;
	struct netdev_notifier_changeupper_info *cu_info;
	struct nss_bridge_pvt *b_pvt;

	cu_info = (struct netdev_notifier_changeupper_info *)info;

	/*
	 * Check if the master pointer is valid
	 */
	if (!cu_info->master)
		return NOTIFY_DONE;

	/*
	 * The master is a bond that we don't need to process, but the bond might be part of a bridge.
	 */
	if (netif_is_bond_slave(dev))
		return nss_bridge_mgr_bond_slave_changeupper(cu_info, dev);

	master_dev = cu_info->upper_dev;

	/*
	 * Check if upper_dev is a known bridge.
	 */
	b_pvt = nss_bridge_mgr_find_instance(master_dev);
	if (!b_pvt)
		return NOTIFY_DONE;

	/*
	 * Slave device is bond master and it is added/removed to/from bridge
	 */
	if (netif_is_bond_master(dev)) {
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
		if (cu_info->linking)
			return nss_bridge_mgr_bond_master_join(dev, b_pvt);
		else
			return nss_bridge_mgr_bond_master_leave(dev, b_pvt);
#endif
	}

	if (cu_info->linking) {
		nss_bridge_mgr_trace("%px: Interface %s joining bridge %s\n", b_pvt, dev->name, master_dev->name);
		if (nss_bridge_mgr_join_bridge(dev, b_pvt)) {
			nss_bridge_mgr_warn("%px: Interface %s failed to join bridge %s\n", b_pvt, dev->name, master_dev->name);
		}

		return NOTIFY_DONE;
	}

	nss_bridge_mgr_trace("%px: Interface %s leaving bridge %s\n", b_pvt, dev->name, master_dev->name);
	if (nss_bridge_mgr_leave_bridge(dev, b_pvt)) {
		nss_bridge_mgr_warn("%px: Interface %s failed to leave bridge %s\n", b_pvt, dev->name, master_dev->name);
	}

	return NOTIFY_DONE;
}

/*
 * nss_bridge_mgr_register_event()
 *	Bridge manager handles bridge registration notification.
 */
static int nss_bridge_mgr_register_event(struct netdev_notifier_info *info)
{
	nss_bridge_mgr_register_br(netdev_notifier_info_to_dev(info));
	return NOTIFY_DONE;
}

/*
 * nss_bridge_mgr_unregister_event()
 *	Bridge manager handles bridge unregistration notification.
 */
static int nss_bridge_mgr_unregister_event(struct netdev_notifier_info *info)
{
	nss_bridge_mgr_unregister_br(netdev_notifier_info_to_dev(info));
	return NOTIFY_DONE;
}

/*
 * nss_bridge_mgr_netdevice_event()
 *	Bridge manager handles bridge operation notifications.
 */
static int nss_bridge_mgr_netdevice_event(struct notifier_block *unused,
				unsigned long event, void *ptr)
{
	struct netdev_notifier_info *info = (struct netdev_notifier_info *)ptr;

	switch (event) {
	case NETDEV_CHANGEUPPER:
		return nss_bridge_mgr_changeupper_event(info);
	case NETDEV_CHANGEADDR:
		return nss_bridge_mgr_changeaddr_event(info);
	case NETDEV_CHANGEMTU:
		return nss_bridge_mgr_changemtu_event(info);
	case NETDEV_REGISTER:
		return nss_bridge_mgr_register_event(info);
	case NETDEV_UNREGISTER:
		return nss_bridge_mgr_unregister_event(info);
	}

	/*
	 * Notify done for all the events we don't care
	 */
	return NOTIFY_DONE;
}

static struct notifier_block nss_bridge_mgr_netdevice_nb __read_mostly = {
	.notifier_call = nss_bridge_mgr_netdevice_event,
};

#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
/*
 * nss_bridge_mgr_is_physical_dev()
 *	Check if the device is on physical device.
 */
static bool nss_bridge_mgr_is_physical_dev(struct net_device *dev)
{
	struct net_device *root_dev = dev;
	uint32_t ifnum;

	if (!dev)
		return false;

	/*
	 * Check if it is VLAN first because VLAN can be over bond interface.
	 * However, the bond over VLAN is not supported in our driver.
	 */
	if (is_vlan_dev(dev)) {
		root_dev = nss_vlan_mgr_get_real_dev(dev);
		if (!root_dev)
			goto error;

		if (is_vlan_dev(root_dev))
			root_dev = nss_vlan_mgr_get_real_dev(root_dev);

		if (!root_dev)
			goto error;
	}

	/*
	 * Don't consider bond interface because FDB learning is disabled.
	 */
	if (netif_is_bond_master(root_dev))
		return false;

	ifnum = nss_cmn_get_interface_number_by_dev(root_dev);
	if (!NSS_BRIDGE_MGR_IF_IS_TYPE_PHYSICAL(ifnum)) {
		nss_bridge_mgr_warn("%px: interface %s is not physical interface\n",
				root_dev, root_dev->name);
		return false;
	}

	return true;

error:
	nss_bridge_mgr_warn("%px: cannot find the real device for VLAN %s\n", dev, dev->name);
	return false;
}

/*
 * nss_bridge_mgr_fdb_update_callback()
 *	Get invoked when there is a FDB update.
 */
static int nss_bridge_mgr_fdb_update_callback(struct notifier_block *notifier,
					      unsigned long val, void *ctx)
{
	struct br_fdb_event *event = (struct br_fdb_event *)ctx;
	struct nss_bridge_pvt *b_pvt = NULL;
	struct net_device *br_dev = NULL;
	fal_fdb_entry_t entry;

	if (!event->br)
		return NOTIFY_DONE;

	br_dev = br_fdb_bridge_dev_get_and_hold(event->br);
	if (!br_dev) {
		nss_bridge_mgr_warn("%px: bridge device not found\n", event->br);
		return NOTIFY_DONE;
	}

	nss_bridge_mgr_trace("%px: MAC: %pM, original source: %s, new source: %s, bridge: %s\n",
			event, event->addr, event->orig_dev->name, event->dev->name, br_dev->name);

	/*
	 * When a MAC address move from a physical interface to a non-physical
	 * interface, the FDB entry in the PPE needs to be flushed.
	 */
	if (!nss_bridge_mgr_is_physical_dev(event->orig_dev)) {
		nss_bridge_mgr_trace("%px: original source is not a physical interface\n", event->orig_dev);
		dev_put(br_dev);
		return NOTIFY_DONE;
	}

	if (nss_bridge_mgr_is_physical_dev(event->dev)) {
		nss_bridge_mgr_trace("%px: new source is not a non-physical interface\n", event->dev);
		dev_put(br_dev);
		return NOTIFY_DONE;
	}

	b_pvt = nss_bridge_mgr_find_instance(br_dev);
	dev_put(br_dev);
	if (!b_pvt) {
		nss_bridge_mgr_warn("%px: bridge instance not found\n", event->br);
		return NOTIFY_DONE;
	}

	memset(&entry, 0, sizeof(entry));
	memcpy(&entry.addr, event->addr, ETH_ALEN);
	entry.fid = b_pvt->vsi;
	if (SW_OK != fal_fdb_entry_del_bymac(NSS_BRIDGE_MGR_SWITCH_ID, &entry)) {
		nss_bridge_mgr_warn("%px: FDB entry delete failed with MAC %pM and fid %d\n",
				    b_pvt, &entry.addr, entry.fid);
		return NOTIFY_DONE;
	}
	return NOTIFY_OK;
}

/*
 * Notifier block for FDB update
 */
static struct notifier_block nss_bridge_mgr_fdb_update_notifier = {
	.notifier_call = nss_bridge_mgr_fdb_update_callback,
};

/*
 * nss_bridge_mgr_wan_inf_add_handler
 *	Marks an interface as a WAN interface for special handling by bridge.
 */
static int nss_bridge_mgr_wan_intf_add_handler(struct ctl_table *table,
						int write, void __user *buffer,
						size_t *lenp, loff_t *ppos)
{
	struct net_device *dev;
	char *dev_name;
	char *if_name;
	int32_t if_num;
	int ret;

	/*
	 * Find the string, return an error if not found
	 */
	ret = proc_dostring(table, write, buffer, lenp, ppos);
	if (ret || !write) {
		return ret;
	}

	if_name = br_mgr_ctx.wan_ifname;
	dev_name = strsep(&if_name, " ");
	dev = dev_get_by_name(&init_net, dev_name);
	if (!dev) {
		nss_bridge_mgr_warn("Cannot find the net device associated with %s\n", dev_name);
		return -ENODEV;
	}

	if_num = nss_cmn_get_interface_number_by_dev(dev);
	if (!NSS_BRIDGE_MGR_IF_IS_TYPE_PHYSICAL(if_num)) {
		dev_put(dev);
		nss_bridge_mgr_warn("Only physical interfaces can be marked as WAN interface: if_num %d\n", if_num);
		return -ENOMSG;
	}

	if (br_mgr_ctx.wan_if_num != -1) {
		dev_put(dev);
		nss_bridge_mgr_warn("Cannot overwrite a pre-existing wan interface\n");
		return -ENOMSG;
	}

	br_mgr_ctx.wan_if_num = if_num;
	dev_put(dev);
	nss_bridge_mgr_always("For adding if_num: %d as WAN interface, do a network restart\n", if_num);
	return ret;
}

/*
 * nss_bridge_mgr_wan_inf_del_handler
 *	Un-marks an interface as a WAN interface.
 */
static int nss_bridge_mgr_wan_intf_del_handler(struct ctl_table *table,
						int write, void __user *buffer,
						size_t *lenp, loff_t *ppos)
{
	struct net_device *dev;
	char *dev_name;
	char *if_name;
	int32_t if_num;
	int ret;

	ret = proc_dostring(table, write, buffer, lenp, ppos);
	if (ret)
		return ret;

	if (!write)
		return ret;

	if_name = br_mgr_ctx.wan_ifname;
	dev_name = strsep(&if_name, " ");
	dev = dev_get_by_name(&init_net, dev_name);
	if (!dev) {
		nss_bridge_mgr_warn("Cannot find the net device associated with %s\n", dev_name);
		return -ENODEV;
	}

	if_num = nss_cmn_get_interface_number_by_dev(dev);
	if (!NSS_BRIDGE_MGR_IF_IS_TYPE_PHYSICAL(if_num)) {
		dev_put(dev);
		nss_bridge_mgr_warn("Only physical interfaces can be marked/unmarked, if_num: %d\n", if_num);
		return -ENOMSG;
	}

	if (br_mgr_ctx.wan_if_num != if_num) {
		dev_put(dev);
		nss_bridge_mgr_warn("This interface is not marked as a WAN interface\n");
		return -ENOMSG;
	}

	br_mgr_ctx.wan_if_num = -1;
	dev_put(dev);
	nss_bridge_mgr_always("For deleting if_num: %d as WAN interface, do a network restart\n", if_num);
	return ret;
}

static struct ctl_table nss_bridge_mgr_table[] = {
	{
		.procname	= "add_wanif",
		.data           = &br_mgr_ctx.wan_ifname,
		.maxlen         = sizeof(char) * IFNAMSIZ,
		.mode           = 0644,
		.proc_handler   = &nss_bridge_mgr_wan_intf_add_handler,
	},
	{
		.procname	= "del_wanif",
		.data           = &br_mgr_ctx.wan_ifname,
		.maxlen         = sizeof(char) * IFNAMSIZ,
		.mode           = 0644,
		.proc_handler   = &nss_bridge_mgr_wan_intf_del_handler,
	},
	{ }
};

static struct ctl_table nss_bridge_mgr_dir[] = {
	{
		.procname	= "bridge_mgr",
		.mode		= 0555,
		.child		= nss_bridge_mgr_table,
	},
	{ }
};

static struct ctl_table nss_bridge_mgr_root_dir[] = {
	{
		.procname	= "nss",
		.mode		= 0555,
		.child		= nss_bridge_mgr_dir,
	},
	{ }
};
#endif

/*
 * nss_bridge_mgr_init_module()
 *	bridge_mgr module init function
 */
int __init nss_bridge_mgr_init_module(void)
{
	/*
	 * Monitor bridge activity only on supported platform
	 */
	if (!of_machine_is_compatible("qcom,ipq807x") && !of_machine_is_compatible("qcom,ipq6018") && !of_machine_is_compatible("qcom,ipq8074"))
		return 0;

	INIT_LIST_HEAD(&br_mgr_ctx.list);
	spin_lock_init(&br_mgr_ctx.lock);
	register_netdevice_notifier(&nss_bridge_mgr_netdevice_nb);
	nss_bridge_mgr_info("Module (Build %s) loaded\n", NSS_CLIENT_BUILD_ID);
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
	br_mgr_ctx.wan_if_num = -1;
	br_fdb_update_register_notify(&nss_bridge_mgr_fdb_update_notifier);
	br_mgr_ctx.nss_bridge_mgr_header = register_sysctl_table(nss_bridge_mgr_root_dir);

	/*
	 * Enable ACL rule to enable L2 exception. This is needed if PPE Virtual ports is added to bridge.
	 *  It is assumed that VP is using flow based bridging, hence L2 exceptions will need to be enabled on PPE bridge.
	 */
	if (!nss_bridge_mgr_l2_exception_acl_enable()) {
		nss_bridge_mgr_warn("Failed to enable ACL\n");
	}
#endif
#if defined (NSS_BRIDGE_MGR_OVS_ENABLE)
	nss_bridge_mgr_ovs_init();
#endif
	return 0;
}

/*
 * nss_bridge_mgr_exit_module()
 *	bridge_mgr module exit function
 */
void __exit nss_bridge_mgr_exit_module(void)
{
	unregister_netdevice_notifier(&nss_bridge_mgr_netdevice_nb);
	nss_bridge_mgr_info("Module unloaded\n");
#if defined(NSS_BRIDGE_MGR_PPE_SUPPORT)
	br_fdb_update_unregister_notify(&nss_bridge_mgr_fdb_update_notifier);

	if (br_mgr_ctx.nss_bridge_mgr_header) {
		unregister_sysctl_table(br_mgr_ctx.nss_bridge_mgr_header);
	}

	/*
	 * Disable the PPE L2 exceptions which were enabled during module init for PPE virtual ports.
	 */
	nss_bridge_mgr_l2_exception_acl_disable();

#endif
#if defined (NSS_BRIDGE_MGR_OVS_ENABLE)
	nss_bridge_mgr_ovs_exit();
#endif
}

module_init(nss_bridge_mgr_init_module);
module_exit(nss_bridge_mgr_exit_module);

MODULE_LICENSE("Dual BSD/GPL");
MODULE_DESCRIPTION("NSS bridge manager");

module_param(ovs_enabled, bool, 0644);
MODULE_PARM_DESC(ovs_enabled, "OVS bridge is enabled");
