/*
 **************************************************************************
 * Copyright (c) 2019-2020 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_clmapmgr.c
 *  This file implements client for CLient map manager.
 */

#include <linux/version.h>
#include <linux/types.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
#include <linux/if_ether.h>
#include <linux/if_vlan.h>

#include <nss_api_if.h>
#include <nss_dynamic_interface.h>

#include "nss_clmapmgr_private.h"
#include "nss_clmapmgr.h"
#include "nss_eogremgr.h"

#define NSS_CLMAPMGR_CMD_MAX_RETRY_COUNT 3
#define NSS_CLMAP_MAX_HEADROOM NSS_EOGREMGR_MAX_HEADROOM

/*
 * nss_clmapmgr_dev_xmit()
 *	Netdev ops function to send packet to NSS.
 */
static netdev_tx_t nss_clmapmgr_dev_xmit(struct sk_buff *skb, struct net_device *dev)
{
	nss_tx_status_t status;
	int if_number;
	struct nss_ctx_instance *clmap_ctx;
	struct nss_clmapmgr_priv_t *priv = netdev_priv(dev);

	if_number = priv->nss_if_number_us;
	if (unlikely(if_number <= 0)) {
		nss_clmapmgr_info("%px: clmapmgr dev is not registered with nss\n", dev);
		goto fail;
	}

	clmap_ctx = nss_clmap_get_ctx();
	if (unlikely(!clmap_ctx)) {
		nss_clmapmgr_info("%px: NSS clmapmgr context not found.\n", dev);
		goto fail;
	}

	status = nss_clmap_tx_buf(clmap_ctx, skb, (uint32_t)if_number);
	if (unlikely(status != NSS_TX_SUCCESS)) {
		if (likely(status == NSS_TX_FAILURE_QUEUE)) {
			nss_clmapmgr_warning("%px: netdev :%px queue is full", dev, dev);
			if (!netif_queue_stopped(dev)) {
				netif_stop_queue(dev);
			}
			nss_clmapmgr_warning("%px: (CLMAP packet) Failed to xmit the packet because of tx queue full, status: %d\n", dev, status);
			return NETDEV_TX_BUSY;
		}
		nss_clmapmgr_info("%px: NSS clmapmgr could not send packet to NSS %d\n", dev, if_number);
		goto fail;
	}

	return NETDEV_TX_OK;

fail:
	dev->stats.tx_dropped++;
	dev_kfree_skb_any(skb);
	return NETDEV_TX_OK;
}

/*
 * nss_clmapmgr_get_dev_stats64()
 *	Netdev ops function to retrieve stats.
 */
static struct rtnl_link_stats64 *nss_clmapmgr_get_dev_stats64(struct net_device *dev,
						struct rtnl_link_stats64 *stats)
{
	struct nss_clmapmgr_priv_t *priv;

	if (!stats) {
		nss_clmapmgr_warning("%px: invalid rtnl structure\n", dev);
		return stats;
	}

	dev_hold(dev);

	/*
	 * Netdev seems to be incrementing rx_dropped because we don't give IP header.
	 * So reset it as it's of no use for us.
	 */
	atomic_long_set(&dev->rx_dropped, 0);
	priv = netdev_priv(dev);
	memset(stats, 0, sizeof(struct rtnl_link_stats64));
	memcpy(stats, &priv->stats, sizeof(struct rtnl_link_stats64));
	dev_put(dev);

	return stats;
}

#if (LINUX_VERSION_CODE < KERNEL_VERSION(4, 6, 0))
/*
 * nss_clmapmgr_dev_stats64()
 *	Netdev ops function to retrieve stats for kernel version < 4.6
 */
static struct rtnl_link_stats64 *nss_clmapmgr_dev_stats64(struct net_device *dev,
						struct rtnl_link_stats64 *tot)
{
	return nss_clmapmgr_get_dev_stats64(dev, tot);
}
#else
/*
 * nss_clmapmgr_dev_stats64()
 *	Netdev ops function to retrieve stats for kernel version >= 4.6
 */
static void nss_clmapmgr_dev_stats64(struct net_device *dev,
				struct rtnl_link_stats64 *tot)
{
	nss_clmapmgr_get_dev_stats64(dev, tot);
}
#endif

/*
 * nss_clmapmgr_dev_init()
 *	Netdev ops function to intialize netdevice.
 */
static int nss_clmapmgr_dev_init(struct net_device *dev)
{
	dev->mtu = ETH_DATA_LEN;
	dev->needed_headroom = NSS_CLMAP_MAX_HEADROOM;
	return 0;
}

/*
 * nss_clmapmgr_dev_open()
 *	Netdev ops function to open netdevice.
 */
static int nss_clmapmgr_dev_open(struct net_device *dev)
{
	netif_start_queue(dev);
	return 0;
}

/*
 * nss_clmapmgr_dev_close()
 *	Netdevice ops function to close netdevice.
 */
static int nss_clmapmgr_dev_close(struct net_device *dev)
{
	netif_stop_queue(dev);
	return 0;
}

/*
 * clmap netdevice ops
 */
static const struct net_device_ops nss_clmapmgr_ops = {
	.ndo_init = nss_clmapmgr_dev_init,
	.ndo_open = nss_clmapmgr_dev_open,
	.ndo_stop = nss_clmapmgr_dev_close,
	.ndo_set_mac_address = eth_mac_addr,
	.ndo_validate_addr = eth_validate_addr,
	.ndo_start_xmit = nss_clmapmgr_dev_xmit,
	.ndo_get_stats64 = nss_clmapmgr_dev_stats64,
};

/*
 * nss_clmapmgr_setup()
 */
static void nss_clmapmgr_setup(struct net_device *dev)
{
	char name[IFNAMSIZ] = {0};

	strlcpy(name, "nssclmap%d", IFNAMSIZ);
	memcpy(dev->name, name, IFNAMSIZ);
	dev->netdev_ops = &nss_clmapmgr_ops;
	eth_hw_addr_random(dev);
}

/*
 * nss_clmapmgr_ds_exception()
 *	Client map manager ds exception handler to receive packet from NSS.
 */
static void nss_clmapmgr_ds_exception(struct net_device *dev, struct sk_buff *skb,
				       __attribute__((unused)) struct napi_struct *napi)
{
	/*
	 * Note: preheader needs to be processed by the user
	 * before processing the ethernet packet
	 */
	skb->protocol = eth_type_trans(skb, dev);
	netif_receive_skb(skb);
}

/*
 * nss_clmapmgr_us_exception()
 *	Client map manager us exception handler to receive packet from NSS.
 */
static void nss_clmapmgr_us_exception(struct net_device *dev, struct sk_buff *skb,
				       __attribute__((unused)) struct napi_struct *napi)
{
	/*
	 * This is an error packet and needs to be dropped.
	 */
	nss_clmapmgr_warning("%px: upstream packet got exceptioned, dropping the packet..", dev);
	dev_kfree_skb_any(skb);
}

/*
 * nss_clmapmgr_event_receive()
 *	Event Callback to receive events from NSS
 */
static void nss_clmapmgr_event_receive(void *if_ctx, struct nss_cmn_msg *cmsg)
{
	struct net_device *dev = (struct net_device *)if_ctx;
	struct nss_clmapmgr_priv_t *priv;
	struct nss_clmap_msg *clmsg = (struct nss_clmap_msg *)cmsg;
	struct nss_clmap_stats_msg *stats = &clmsg->msg.stats;
	struct rtnl_link_stats64 *netdev_stats;
	enum nss_dynamic_interface_type interface_type;
	uint64_t dropped = 0;

	dev_hold(dev);
	priv = netdev_priv(dev);
	netdev_stats = &priv->stats;

	switch (clmsg->cm.type) {
	case NSS_CLMAP_MSG_TYPE_SYNC_STATS:
		interface_type = nss_dynamic_interface_get_type(nss_clmap_get_ctx(), clmsg->cm.interface);
		if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US) {
			netdev_stats->tx_packets += stats->node_stats.tx_packets;
			netdev_stats->tx_bytes += stats->node_stats.tx_bytes;
			dropped += stats->dropped_macdb_lookup_failed;
			dropped += stats->dropped_invalid_packet_size;
			dropped += stats->dropped_low_hroom;
		} else if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS) {
			netdev_stats->rx_packets += stats->node_stats.rx_packets;
			netdev_stats->rx_bytes += stats->node_stats.rx_bytes;
			dropped += stats->dropped_pbuf_alloc_failed;
			dropped += stats->dropped_linear_failed;
			dropped += stats->shared_packet_count;
			dropped += stats->ethernet_frame_error;
		}
		dropped += stats->dropped_next_node_queue_full;
		netdev_stats->tx_dropped += dropped;
		if (interface_type == NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS) {
			netdev_stats->rx_dropped += nss_cmn_rx_dropped_sum(&stats->node_stats);
		}
		break;

	default:
		nss_clmapmgr_info("%px: Unknown Event from NSS\n", dev);
		break;
	}

	dev_put(dev);
}

/*
 * nss_clmapmgr_us_get_if_num
 * 	return us NSS interface number
 */
int nss_clmapmgr_us_get_if_num(struct net_device *dev)
{
	struct nss_clmapmgr_priv_t *priv;

	if (!dev) {
		nss_clmapmgr_info("Netdev is NULL");
		return -1;
	}

	priv = (struct nss_clmapmgr_priv_t *)netdev_priv(dev);
	return priv->nss_if_number_us;
}
EXPORT_SYMBOL(nss_clmapmgr_us_get_if_num);

/*
 * nss_clmapmgr_ds_get_if_num
 * 	return ds NSS interface number
 */
int nss_clmapmgr_ds_get_if_num(struct net_device *dev)
{
	struct nss_clmapmgr_priv_t *priv;

	if (!dev) {
		nss_clmapmgr_info("Netdev is NULL");
		return -1;
	}

	priv = (struct nss_clmapmgr_priv_t *)netdev_priv(dev);
	return priv->nss_if_number_ds;
}
EXPORT_SYMBOL(nss_clmapmgr_ds_get_if_num);

/*
 * nss_clmapmgr_mac_add()
 * 	API to send notification to NSS to add the MAC entry.
 */
nss_clmapmgr_status_t nss_clmapmgr_mac_add(struct net_device *dev, struct nss_clmapmgr_msg *clmapmsg)
{
	struct nss_clmap_msg req;
	struct nss_clmap_mac_msg *mmsg;
	int us_if, next_ifnum;
	struct nss_ctx_instance *nss_ctx = NULL;
	nss_tx_status_t status;

	if (!dev) {
		nss_clmapmgr_info("Netdev is NULL !!\n");
		return NSS_CLMAPMGR_ERR_BAD_PARAM;
	}

	if (!clmapmsg) {
		nss_clmapmgr_info("%px: nss_clmapmgr_msg is NULL !!\n", dev);
		return NSS_CLMAPMGR_ERR_BAD_PARAM;
	}

	/*
	 * Get Interface number, based on tunnel type
	 */
	switch (clmapmsg->tunnel_type) {
	case NSS_CLMAPMGR_TUNNEL_EOGRE:
		/*
		 * For EoGRE tunnel, the next node for the packet from clmap node in NSS
		 * would be GRE inner node. Get the GRE inner interface.
		 */
		next_ifnum = nss_eogremgr_get_if_num_inner(clmapmsg->tunnel_id);
		if (next_ifnum < 0) {
			nss_clmapmgr_info("%px: No NSS interface registered for the tunnel id: %d\n", dev, clmapmsg->tunnel_id);
			return NSS_CLMAPMGR_ERR_TUNNEL_NOT_FOUND;
		}
		break;
	default:
		nss_clmapmgr_info("%px: Invalid tunnel type: %d\n", dev, clmapmsg->tunnel_type);
		return NSS_CLMAPMGR_ERR_BAD_PARAM;
	}

	nss_ctx = nss_clmap_get_ctx();

	/*
	 * Check if upstream clmap interface is registered with NSS.
	 */
	us_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US);
	if (us_if < 0) {
		nss_clmapmgr_info("%px: Net device is not registered with nss\n", dev);
		dev_put(dev);
		return NSS_CLMAPMGR_ERR_NETDEV_UNKNOWN;
	}

	memset(&req, 0, sizeof(struct nss_clmap_msg));
	mmsg = &req.msg.mac_add;

	/*
	 * Set mac_add message.
	 */
	memcpy(mmsg->mac_addr, clmapmsg->mac_addr, ETH_ALEN);
	mmsg->flags = clmapmsg->flags;
	mmsg->vlan_id = clmapmsg->vlan_id;
	mmsg->needed_headroom = clmapmsg->needed_headroom;
	mmsg->nexthop_ifnum = next_ifnum;
	nss_clmap_msg_init(&req, us_if, NSS_CLMAP_MSG_TYPE_MAC_ADD, sizeof(struct nss_clmap_mac_msg), NULL, NULL);
	status = nss_clmap_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_warning("%px: nss clmap mac add command error:%d if_num: %d\n", dev, status, us_if);
		dev_put(dev);
		return NSS_CLMAPMGR_ERR_MAC_ADD_FAILED;
	}

	return NSS_CLMAPMGR_SUCCESS;
}
EXPORT_SYMBOL(nss_clmapmgr_mac_add);

/*
 * nss_clmapmgr_mac_remove()
 * 	API to send notification to NSS to delete the MAC entry.
 */
nss_clmapmgr_status_t nss_clmapmgr_mac_remove(struct net_device *dev, uint8_t *mac_addr)
{
	struct nss_clmap_msg req;
	struct nss_clmap_mac_msg *mmsg;
	int us_if;
	struct nss_ctx_instance *nss_ctx = NULL;
	nss_tx_status_t status;

	if (!dev) {
		nss_clmapmgr_info("Netdev is NULL !!\n");
		return NSS_CLMAPMGR_ERR_BAD_PARAM;
	}

	if (!mac_addr) {
		nss_clmapmgr_info("%px: mac address is NULL !!\n", dev);
		return NSS_CLMAPMGR_ERR_BAD_PARAM;
	}

	nss_ctx = nss_clmap_get_ctx();

	/*
	 * Check if upstream clmap interface is registered with NSS
	 */
	us_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US);
	if (us_if < 0) {
		nss_clmapmgr_info("%px: Net device is not registered with nss\n", dev);
		dev_put(dev);
		return NSS_CLMAPMGR_ERR_NETDEV_UNKNOWN;
	}

	memset(&req, 0, sizeof(struct nss_clmap_msg));
	mmsg = &req.msg.mac_add;

	/*
	 * Set mac_del message. Only MAC address is required, the other
	 * fields as set to 0.
	 *
	 */
	memcpy(mmsg->mac_addr, mac_addr, ETH_ALEN);
	nss_clmap_msg_init(&req, us_if, NSS_CLMAP_MSG_TYPE_MAC_DEL, sizeof(struct nss_clmap_mac_msg), NULL, NULL);
	status = nss_clmap_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_warning("%px: NSS clmap mac del command error:%d if_num: %d\n", dev, status, us_if);
		dev_put(dev);
		return NSS_CLMAPMGR_ERR_MAC_DEL_FAILED;
	}

	return NSS_CLMAPMGR_SUCCESS;
}
EXPORT_SYMBOL(nss_clmapmgr_mac_remove);

/*
 * nss_clmapmgr_mac_flush()
 * 	API to send notification to NSS to flush MAC entry.
 */
nss_clmapmgr_status_t nss_clmapmgr_mac_flush(struct net_device *dev, uint32_t tunnel_id, nss_clmapmgr_tunnel_type_t tunnel_type)
{
	struct nss_clmap_msg req;
	struct nss_clmap_flush_mac_msg *mmsg = &req.msg.mac_flush;
	int us_if, next_ifnum;
	struct nss_ctx_instance *nss_ctx = NULL;
	nss_tx_status_t status;

	if (!dev) {
		nss_clmapmgr_info("Netdev is NULL !!\n");
		return NSS_CLMAPMGR_ERR_BAD_PARAM;
	}

	switch (tunnel_type) {
	case NSS_CLMAPMGR_TUNNEL_EOGRE:
		/*
		 * Get GRE inner interface number
		 */
		next_ifnum = nss_eogremgr_get_if_num_inner(tunnel_id);
		if (next_ifnum < 0) {
			nss_clmapmgr_info("%px: No NSS interface registered for the tunnel id: %d\n", dev, tunnel_id);
			return NSS_CLMAPMGR_ERR_TUNNEL_NOT_FOUND;
		}
		break;
	default:
		nss_clmapmgr_info("%px: Invalid tunnel type: %d\n", dev, tunnel_type);
		return NSS_CLMAPMGR_ERR_BAD_PARAM;
	}

	nss_ctx = nss_clmap_get_ctx();

	/*
	 * Check if upstream clmap interface is registered with NSS
	 */
	us_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US);
	if (us_if < 0) {
		nss_clmapmgr_info("%px: Net device is not registered with nss\n", dev);
		dev_put(dev);
		return NSS_CLMAPMGR_ERR_NETDEV_UNKNOWN;
	}

	/*
	 * Set mac_flush message
	 */
	mmsg->nexthop_ifnum = next_ifnum;
	nss_clmap_msg_init(&req, us_if, NSS_CLMAP_MSG_TYPE_MAC_FLUSH, sizeof(struct nss_clmap_mac_msg), NULL, NULL);
	status = nss_clmap_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_warning("%px: NSS clmap mac flush command error:%d if_num: %d\n", dev, status, us_if);
		dev_put(dev);
		return NSS_CLMAPMGR_ERR_MAC_FLUSH_FAILED;
	}

	return NSS_CLMAPMGR_SUCCESS;
}
EXPORT_SYMBOL(nss_clmapmgr_mac_flush);

/*
 * nss_clmapmgr_netdev_enable()
 *	Call back to enable NSS for clmap device.
 */
int nss_clmapmgr_netdev_enable(struct net_device *dev)
{
	struct nss_clmap_msg req;
	int us_if, ds_if;
	struct nss_ctx_instance *nss_ctx = NULL;
	struct nss_clmapmgr_priv_t *priv;
	nss_tx_status_t status;

	if (!dev) {
		nss_clmapmgr_info("Netdev is NULL !!\n");
		return NOTIFY_DONE;
	}

	nss_ctx = nss_clmap_get_ctx();

	/*
	 * Check if upstream clmap interface is registered with NSS
	 */
	us_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US);
	if (us_if < 0) {
		nss_clmapmgr_info("%px: Net device is not registered with nss\n", dev);
		goto release_ref;
	}

	/*
	 * Check if downstream clmap interface is registered with NSS
	 */
	ds_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS);
	if (ds_if < 0) {
		nss_clmapmgr_info("%px: Net device is not registered with nss\n", dev);
		goto release_ref;
	}

	/*
	 * Send enable session command for upstream interface
	 */
	nss_clmap_msg_init(&req, us_if, NSS_CLMAP_MSG_TYPE_INTERFACE_ENABLE, 0, NULL, NULL);
	status = nss_clmap_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_warning("%px: NSS clmap enable command error:%d if_num: %d\n", dev, status, us_if);
		goto release_ref;
	}

	/*
	 * Send enable session command for downstream interface
	 */
	nss_clmap_msg_init(&req, ds_if, NSS_CLMAP_MSG_TYPE_INTERFACE_ENABLE, 0, NULL, NULL);
	status = nss_clmap_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_warning("%px: NSS clmap enable command error:%d if_num: %d\n", dev, status, ds_if);
		goto disable_us;
	}

	/*
	 * Open the netdev to accept packets
	 */
	priv = (struct nss_clmapmgr_priv_t *)netdev_priv(dev);
	priv->clmap_enabled = true;
	nss_clmapmgr_dev_open(dev);

	return NOTIFY_OK;

disable_us:
	nss_clmap_msg_init(&req, us_if, NSS_CLMAP_MSG_TYPE_INTERFACE_DISABLE, 0, NULL, NULL);
	status = nss_clmap_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_warning("%px: NSS clmap enable command error:%d if_num: %d\n", dev, status, us_if);
	}

release_ref:
	return NOTIFY_DONE;
}
EXPORT_SYMBOL(nss_clmapmgr_netdev_enable);

/*
 * nss_clmapmgr_netdev_disable()
 *	Call back to disable clmap interface in NSS.
 */
int nss_clmapmgr_netdev_disable(struct net_device *dev)
{
	struct nss_clmap_msg req;
	int us_if, ds_if;
	struct nss_ctx_instance *nss_ctx = NULL;
	struct nss_clmapmgr_priv_t *priv;
	nss_tx_status_t status;

	if (!dev) {
		nss_clmapmgr_info("Netdev is NULL !!\n");
		return NOTIFY_DONE;
	}

	nss_ctx = nss_clmap_get_ctx();

	/*
	 * Check if upstream clmap interface is registered with NSS
	 */
	us_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US);
	if (us_if < 0) {
		nss_clmapmgr_info("%px: Net device is not registered with NSS\n", dev);
		goto release_ref;
	}

	/*
	 * Check if downstream clmap interface is registered with NSS
	 */
	ds_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS);
	if (ds_if < 0) {
		nss_clmapmgr_info("%px: Net device is not registered with NSS\n", dev);
		goto release_ref;
	}

	/*
	 * Send disable session command for upstream interface
	 */
	nss_clmap_msg_init(&req, us_if, NSS_CLMAP_MSG_TYPE_INTERFACE_DISABLE, 0, NULL, NULL);
	status = nss_clmap_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_warning("%px: NSS clmap disable command error:%d if_num: %d\n", dev, status, us_if);
		goto release_ref;
	}

	/*
	 * Send disable session command for downstream interface
	 */
	nss_clmap_msg_init(&req, ds_if, NSS_CLMAP_MSG_TYPE_INTERFACE_DISABLE, 0, NULL, NULL);
	status = nss_clmap_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_warning("%px: NSS clmap disable command error:%d if_num: %d\n", dev, status, ds_if);
		goto enable_us;
	}

	/*
	 * Close the netdev
	 */
	priv = (struct nss_clmapmgr_priv_t *)netdev_priv(dev);
	priv->clmap_enabled = false;
	nss_clmapmgr_dev_close(dev);

	return NOTIFY_OK;

enable_us:
	nss_clmap_msg_init(&req, us_if, NSS_CLMAP_MSG_TYPE_INTERFACE_ENABLE, 0, NULL, NULL);
	status = nss_clmap_tx_msg_sync(nss_ctx, &req);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_warning("%px: NSS clmap disable command error:%d if_num: %d\n", dev, status, us_if);
	}

release_ref:
	return NOTIFY_DONE;
}
EXPORT_SYMBOL(nss_clmapmgr_netdev_disable);

/*
 * nss_clmapmgr_dev_event()
 *	Netdevice notifier call back function.
 */
static int nss_clmapmgr_dev_event(struct notifier_block  *nb,
		unsigned long event, void  *dev)
{
	struct net_device *netdev;
	netdev = netdev_notifier_info_to_dev(dev);

	switch (event) {
	case NETDEV_UP:
		return nss_clmapmgr_netdev_enable(netdev);

	case NETDEV_DOWN:
		return nss_clmapmgr_netdev_disable(netdev);

	default:
		break;
	}

	return NOTIFY_DONE;
}

/*
 * nss_clmapmgr_destroy_us_interface()
 *	Destroy upstream clmap interface.
 */
static nss_clmapmgr_status_t nss_clmapmgr_destroy_us_interface(struct net_device *dev, int interface_num)
{
	nss_tx_status_t status;
	int retry = 0;

	if (!nss_clmap_unregister(interface_num)) {
		nss_clmapmgr_warning("%px: clmap NSS upstream interface unregister failed\n.", dev);
		return NSS_CLMAPMGR_ERR_NSSIF_UNREGISTER_FAILED;
	}

dealloc_us:
	status = nss_dynamic_interface_dealloc_node(interface_num, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_info("%px: clmap dealloc node failure for interface_num = %d\n", dev, interface_num);
		if (++retry <= NSS_CLMAPMGR_CMD_MAX_RETRY_COUNT) {
			goto dealloc_us;
		}

		nss_clmapmgr_error("%px: fatal Error, failed to dealloc upstream clmap NSS interface.\n", dev);
		return NSS_CLMAPMGR_ERR_NSSIF_DEALLOC_FAILED;
	}

	return NSS_CLMAPMGR_SUCCESS;
}

/*
 * nss_clmapmgr_destroy_ds_interface()
 *	Destroy downstream clmap interface.
 */
static nss_clmapmgr_status_t nss_clmapmgr_destroy_ds_interface(struct net_device *dev, int interface_num)
{
	nss_tx_status_t status;
	int retry = 0;

	if (!nss_clmap_unregister(interface_num)) {
		nss_clmapmgr_warning("%px: clmap NSS downstream interface unregister failed\n.", dev);
		return NSS_CLMAPMGR_ERR_NSSIF_UNREGISTER_FAILED;
	}

dealloc_ds:
	status = nss_dynamic_interface_dealloc_node(interface_num, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS);
	if (status != NSS_TX_SUCCESS) {
		nss_clmapmgr_info("%px: clmap dealloc node failure for ds_if = %d\n", dev, interface_num);
		if (++retry <= NSS_CLMAPMGR_CMD_MAX_RETRY_COUNT) {
			goto dealloc_ds;
		}

		nss_clmapmgr_error("%px: fatal Error, failed to dealloc downstream clmap NSS interface.\n", dev);
		return NSS_CLMAPMGR_ERR_NSSIF_DEALLOC_FAILED;
	}

	return NSS_CLMAPMGR_SUCCESS;
}

/*
 * nss_clmapmgr_decongestion_callback()
 * 	Wakeup netif queue if we were stopped by start_xmit
 */
static void nss_clmapmgr_decongestion_callback(void *arg) {
	struct net_device *dev = arg;
	struct nss_clmapmgr_priv_t *priv;

	priv = (struct nss_clmapmgr_priv_t *)netdev_priv(dev);
	if (unlikely(!priv->clmap_enabled)) {
		return;
	}

	if (netif_queue_stopped(dev)) {
		netif_wake_queue(dev);
	}
}

/*
 * nss_clmapmgr_netdev_destroy()
 * 	API for destroying a netdevice.
 * 	Note: User needs to flush all MAC entries in the clmap before destroying the clmap netdevice
 */
nss_clmapmgr_status_t nss_clmapmgr_netdev_destroy(struct net_device *dev)
{
	int us_if, ds_if;
	nss_clmapmgr_status_t ret;

	netif_tx_disable(dev);

	/*
	 * Deregister decongestion callback
	 */
	if (nss_cmn_unregister_queue_decongestion(nss_clmap_get_ctx(), nss_clmapmgr_decongestion_callback) != NSS_CB_UNREGISTER_SUCCESS) {
		nss_clmapmgr_info("%px: failed to unregister decongestion callback\n", dev);
	}

	/*
	 * Check if upstream clmap interface is registered with NSS
	 */
	us_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US);
	if (us_if < 0) {
		nss_clmapmgr_info("%px: Net device is not registered with NSS\n", dev);
		return NSS_CLMAPMGR_ERR_NETDEV_UNKNOWN;
	}

	/*
	 * Check if downstream clmap interface is registered with NSS
	 */
	ds_if = nss_cmn_get_interface_number_by_dev_and_type(dev, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS);
	if (ds_if < 0) {
		nss_clmapmgr_info("%px: Net device is not registered with NSS\n", dev);
		return NSS_CLMAPMGR_ERR_NETDEV_UNKNOWN;
	}

	ret = nss_clmapmgr_destroy_us_interface(dev, us_if);
	if (ret != NSS_CLMAPMGR_SUCCESS) {
		nss_clmapmgr_warning("%px: failed to destroy clmap upstream interface: %d\n", dev, us_if);
		return ret;
	}

	ret = nss_clmapmgr_destroy_ds_interface(dev, ds_if);
	if (ret != NSS_CLMAPMGR_SUCCESS) {
		nss_clmapmgr_warning("%px: failed to destroy clmap downstream interface: %d\n", dev, ds_if);
		return ret;
	}

	nss_clmapmgr_info("%px: deleted clmap instance, us_if = %d ds_if = %d\n",
			dev, us_if, ds_if);

	unregister_netdev(dev);
	free_netdev(dev);
	return NSS_CLMAPMGR_SUCCESS;
}
EXPORT_SYMBOL(nss_clmapmgr_netdev_destroy);

/*
 * nss_clmapmgr_netdev_create()
 *	User API to create clmap interface
 */
struct net_device *nss_clmapmgr_netdev_create(void)
{
	struct nss_ctx_instance *nss_ctx;
	struct net_device *dev = NULL;
	struct nss_clmapmgr_priv_t *priv;
	nss_tx_status_t status;
	uint32_t features = 0;
	int32_t us_if, ds_if;
	int ret = -1, retry = 0;

	dev = alloc_etherdev(sizeof(struct nss_clmapmgr_priv_t));
	if (!dev) {
		nss_clmapmgr_warning("Allocation of netdev failed\n");
		return NULL;
	}

	nss_clmapmgr_setup(dev);

	/*
	 * Register net_device
	 */
	ret = register_netdev(dev);
	if (ret) {
		nss_clmapmgr_warning("%px: Netdevice registration failed\n", dev);
		free_netdev(dev);
		return NULL;
	}

	/*
	 * Create NSS clmap downstream dynamic interface
	 */
	ds_if = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS);
	if (ds_if < 0) {
		nss_clmapmgr_warning("%px: NSS dynamic interface alloc failed for clmap downstream\n", dev);
		goto deregister_netdev;
	}

	/*
	 * Create NSS clmap upstream dynamic interface
	 */
	us_if = nss_dynamic_interface_alloc_node(NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US);
	if (us_if < 0) {
		nss_clmapmgr_warning("%px: NSS dynamic interface alloc failed for clmap upstream\n", dev);
		goto dealloc_ds_node;
	}

	priv = (struct nss_clmapmgr_priv_t *)netdev_priv(dev);
	priv->clmap_enabled = false;
	priv->nss_if_number_us = us_if;
	priv->nss_if_number_ds = ds_if;

	/*
	 * Register downstream clmap interface with NSS
	 */
	nss_ctx = nss_clmap_register(ds_if,
				NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS,
				nss_clmapmgr_ds_exception,
	 			nss_clmapmgr_event_receive,
				dev,
				features);
	if (!nss_ctx) {
		nss_clmapmgr_info("%px: nss_clmap_register failed for downstream interface\n", dev);
		goto dealloc_us_node;
	}

	/*
	 * Register upstream clmap interface with NSS
	 */
	nss_ctx = nss_clmap_register(us_if,
				NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US,
				nss_clmapmgr_us_exception,
	 			nss_clmapmgr_event_receive,
				dev,
				features);
	if (!nss_ctx) {
		nss_clmapmgr_info("%px: nss_clmap_register failed for upstream interface\n", dev);
		goto unregister_ds;
	}

	/*
	 * Register decongestion callback
	 */
	if (nss_cmn_register_queue_decongestion(nss_clmap_get_ctx(), nss_clmapmgr_decongestion_callback, dev) != NSS_CB_REGISTER_SUCCESS) {
		nss_clmapmgr_warning("%px: failed to register decongestion callback\n", dev);
		goto unregister_us;
	}

	/*
	 * Success
	 */
	nss_clmapmgr_info("%px: nss_clmap_register() successful. nss_ctx = %px\n", dev, nss_ctx);
	return dev;

unregister_us:
	nss_clmap_unregister(us_if);

unregister_ds:
	nss_clmap_unregister(ds_if);

dealloc_us_node:
	status = nss_dynamic_interface_dealloc_node(us_if, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_US);
	if (status != NSS_TX_SUCCESS) {
		if (++retry <= NSS_CLMAPMGR_CMD_MAX_RETRY_COUNT) {
			goto dealloc_us_node;
		}
		nss_clmapmgr_error("%px: fatal Error, Unable to dealloc the node[%d] in the NSS FW!\n", dev, us_if);
	}

	retry = 0;
dealloc_ds_node:
	status = nss_dynamic_interface_dealloc_node(ds_if, NSS_DYNAMIC_INTERFACE_TYPE_CLMAP_DS);
	if (status != NSS_TX_SUCCESS) {
		if (++retry <= NSS_CLMAPMGR_CMD_MAX_RETRY_COUNT) {
			goto dealloc_ds_node;
		}
		nss_clmapmgr_error("%px: fatal Error, Unable to dealloc the node[%d] in the NSS FW!\n", dev, ds_if);
	}

deregister_netdev:
	unregister_netdev(dev);
	free_netdev(dev);

	return NULL;
}
EXPORT_SYMBOL(nss_clmapmgr_netdev_create);

/*
 * Linux Net device Notifier
 */
static struct notifier_block nss_clmapmgr_notifier = {
	.notifier_call = nss_clmapmgr_dev_event,
};

/*
 * nss_clmapmgr_dev_init_module()
 *	Client map module init function
 */
static int __init nss_clmapmgr_dev_init_module(void)
{
#ifdef CONFIG_OF
	/*
	 * If the node is not compatible, don't do anything.
	 */
	if (!of_find_node_by_name(NULL, "nss-common")) {
		return 0;
	}
#endif
	register_netdevice_notifier(&nss_clmapmgr_notifier);

	return 0;
}

/*
 * nss_clmapmgr_exit_module
 *	Client map module exit function
 */
static void __exit nss_clmapmgr_exit_module(void)
{
#ifdef CONFIG_OF
	/*
	 * If the node is not compatible, don't do anything.
	 */
	if (!of_find_node_by_name(NULL, "nss-common")) {
		return;
	}
#endif
	/*
	 * Unregister clmap interfaces created
	 */
	unregister_netdevice_notifier(&nss_clmapmgr_notifier);
}

module_init(nss_clmapmgr_dev_init_module);
module_exit(nss_clmapmgr_exit_module);

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