/*
 **************************************************************************
 * Copyright (c) 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 "nss_core.h"
#include "nss_tx_rx_common.h"
#include "nss_wifi_mesh.h"
#include "nss_wifi_mesh_stats.h"
#include "nss_wifi_mesh_strings.h"

#define NSS_WIFI_MESH_OUTER_STATS 0
#define NSS_WIFI_MESH_INNER_STATS 1
#define NSS_WIFI_MESH_PATH_STATS 2
#define NSS_WIFI_MESH_PROXY_PATH_STATS 3
#define NSS_WIFI_MESH_EXCEPTION_STATS 4

/*
 * Wi-Fi mesh stats dentry file size.
 */
#define NSS_WIFI_MESH_DENTRY_FILE_SIZE 19

/*
 * Spinlock for protecting tunnel operations colliding with a tunnel destroy
 */
static DEFINE_SPINLOCK(nss_wifi_mesh_stats_lock);

/*
 * Declare atomic notifier data structure for statistics.
 */
static ATOMIC_NOTIFIER_HEAD(nss_wifi_mesh_stats_notifier);

/*
 * Declare an array of Wi-Fi mesh stats handle.
 */
struct nss_wifi_mesh_stats_handle *nss_wifi_mesh_stats_hdl[NSS_WIFI_MESH_MAX_DYNAMIC_INTERFACE];

/*
 * nss_wifi_mesh_max_statistics()
 * 	Wi-Fi mesh maximum statistics.
 */
static uint32_t nss_wifi_mesh_max_statistics(void)
{
	uint32_t max1;
	uint32_t exception_stats_max = NSS_WIFI_MESH_EXCEPTION_STATS_TYPE_MAX;
	uint32_t encap_stats_max = NSS_WIFI_MESH_ENCAP_STATS_TYPE_MAX;
	uint32_t decap_stats_max = NSS_WIFI_MESH_DECAP_STATS_TYPE_MAX;
	uint32_t path_stats_max = NSS_WIFI_MESH_PATH_STATS_TYPE_MAX;
	uint32_t proxy_path_stats_max = NSS_WIFI_MESH_PROXY_PATH_STATS_TYPE_MAX;

	max1 = max(max(encap_stats_max, decap_stats_max), max(path_stats_max, proxy_path_stats_max));

	return (max(max1, exception_stats_max));
}

/*
 * nss_wifi_mesh_stats_handle_alloc()
 *	Allocate Wi-Fi mesh tunnel instance
 */
bool nss_wifi_mesh_stats_handle_alloc(nss_if_num_t if_num, int32_t ifindex)
{
	struct nss_wifi_mesh_stats_handle *h;
	uint32_t idx;

	/*
	 * Allocate a handle
	 */
	h = kzalloc(sizeof(struct nss_wifi_mesh_stats_handle), GFP_ATOMIC);
	if (!h) {
		nss_warning("Failed to allocate memory for Wi-Fi mesh instance for interface : 0x%x\n", if_num);
		return false;
	}

	spin_lock(&nss_wifi_mesh_stats_lock);
	for (idx = 0; idx < NSS_WIFI_MESH_MAX_DYNAMIC_INTERFACE; idx++) {
		if (nss_wifi_mesh_stats_hdl[idx] && nss_wifi_mesh_stats_hdl[idx]->if_num == if_num) {
			spin_unlock(&nss_wifi_mesh_stats_lock);
			nss_warning("Already a handle present for this interface number: 0x%x\n", if_num);
			kfree(h);
			return false;
		}
	}

	for (idx = 0; idx < NSS_WIFI_MESH_MAX_DYNAMIC_INTERFACE; idx++) {
		if (nss_wifi_mesh_stats_hdl[idx]) {
			continue;
		}

		h->if_num = if_num;
		h->mesh_idx = idx;
		h->ifindex = ifindex;
		nss_wifi_mesh_stats_hdl[idx] = h;
		spin_unlock(&nss_wifi_mesh_stats_lock);
		return true;
	}
	spin_unlock(&nss_wifi_mesh_stats_lock);
	nss_warning("No free index available for handle with ifnum: 0x%x\n", if_num);
	kfree(h);
	return false;
}

/*
 * nss_wifi_mesh_stats_handle_free()
 *	Free Wi-Fi mesh tunnel handle instance.
 */
bool nss_wifi_mesh_stats_handle_free(nss_if_num_t if_num)
{
	struct nss_wifi_mesh_stats_handle *h;

	spin_lock(&nss_wifi_mesh_stats_lock);
	h = nss_wifi_mesh_get_stats_handle(if_num);
	if (!h) {
		spin_unlock(&nss_wifi_mesh_stats_lock);
		nss_warning("Unable to free Wi-Fi mesh stats handle instance for interface number: 0x%x\n", if_num);
		return false;
	}

	nss_wifi_mesh_stats_hdl[h->mesh_idx] = NULL;
	spin_unlock(&nss_wifi_mesh_stats_lock);
	kfree(h);
	return true;
}

/**
 * nss_wifi_mesh_get_stats_handle()
 * 	Get Wi-Fi mesh stats handle from interface number.
 */
struct nss_wifi_mesh_stats_handle *nss_wifi_mesh_get_stats_handle(nss_if_num_t if_num)
{
	uint32_t idx;

	assert_spin_locked(&nss_wifi_mesh_stats_lock);

	for (idx = 0; idx < NSS_WIFI_MESH_MAX_DYNAMIC_INTERFACE; idx++) {
		if (nss_wifi_mesh_stats_hdl[idx]) {
			if (nss_wifi_mesh_stats_hdl[idx]->if_num == if_num) {
				struct nss_wifi_mesh_stats_handle *h = nss_wifi_mesh_stats_hdl[idx];
				return h;
			}
		}
	}
	return NULL;
}

/*
 * nss_wifi_mesh_get_stats()
 *	API for getting stats from a Wi-Fi mesh interface stats
 */
static bool nss_wifi_mesh_get_stats(nss_if_num_t if_num, struct nss_wifi_mesh_hdl_stats_sync_msg *stats)
{
	struct nss_wifi_mesh_stats_handle *h;

	if (!nss_wifi_mesh_verify_if_num(if_num)) {
		return false;
	}

	spin_lock(&nss_wifi_mesh_stats_lock);
	h = nss_wifi_mesh_get_stats_handle(if_num);
	if (!h) {
		spin_unlock(&nss_wifi_mesh_stats_lock);
		nss_warning("Invalid Wi-Fi mesh stats handle for interface number: %d\n", if_num);
		return false;
	}

	memcpy(stats, &h->stats, sizeof(*stats));
	spin_unlock(&nss_wifi_mesh_stats_lock);
	return true;
}

/*
 * nss_wifi_mesh_get_valid_interface_count()
 * 	Get count of valid Wi-Fi mesh interfaces up.
 */
static uint32_t nss_wifi_mesh_get_valid_interface_count(uint16_t type, uint32_t if_num, uint32_t max_if_num)
{
	uint32_t interface_count = 0;
	enum nss_dynamic_interface_type dtype;

	for (; if_num <= max_if_num; if_num++) {
		if (!nss_is_dynamic_interface(if_num)) {
			continue;
		}

		dtype = nss_dynamic_interface_get_type(nss_wifi_mesh_get_context(), if_num);

		if ((type == NSS_WIFI_MESH_OUTER_STATS) && (dtype != NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER)) {
			continue;
		}

		if ((type == NSS_WIFI_MESH_INNER_STATS) && (dtype != NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER)) {
			continue;
		}

		if ((type == NSS_WIFI_MESH_PATH_STATS) && (dtype != NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER)) {
			continue;
		}

		if ((type == NSS_WIFI_MESH_PROXY_PATH_STATS) && (dtype != NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER)) {
			continue;
		}
		interface_count++;
	}
	return interface_count;
}

/**
 * nss_wifi_mesh_stats_read()
 * 	Read Wi-Fi Mesh stats.
 */
static ssize_t nss_wifi_mesh_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos, uint16_t type)
{
	uint32_t max_output_lines, max_stats;
	size_t size_al, size_wr = 0;
	ssize_t bytes_read = 0;
	struct nss_stats_data *data = fp->private_data;
	int ifindex;
	uint32_t if_num = NSS_DYNAMIC_IF_START;
	uint32_t interface_count = 0;
	uint32_t max_if_num = NSS_DYNAMIC_IF_START + NSS_MAX_DYNAMIC_INTERFACES;
	struct nss_wifi_mesh_hdl_stats_sync_msg *stats;
	struct net_device *ndev;
	struct nss_wifi_mesh_stats_handle *handle;
	char *lbuf;
	enum nss_dynamic_interface_type dtype;

	if (data) {
		if_num = data->if_num;
	}

	/*
	 * If we are done accomodating all the Wi-Fi mesh interfaces.
	 */
	if (if_num > max_if_num) {
		return 0;
	}

	/*
	 * Get number of Wi-Fi mesh interfaces up.
	 */
	interface_count = nss_wifi_mesh_get_valid_interface_count(type, if_num, max_if_num);
	if (!interface_count) {
		nss_warning("%px: Invalid number of valid interface for if_num: 0x%x\n", data, if_num);
		return 0;
	}

	/*
	 * max output lines = #stats + Number of Extra outputlines for future reference to add new stats +
	 * Maximum node stats + Maximum of all the stats + three blank lines.
	 */
	max_stats = nss_wifi_mesh_max_statistics();
	max_output_lines = max_stats + NSS_STATS_NODE_MAX + NSS_STATS_EXTRA_OUTPUT_LINES;
	size_al = NSS_STATS_MAX_STR_LENGTH * max_output_lines * interface_count;

	lbuf = kzalloc(size_al, GFP_KERNEL);
	if (unlikely(lbuf == NULL)) {
		nss_warning("Could not allocate memory for local statistics buffer\n");
		return 0;
	}

	size_wr += nss_stats_banner(lbuf, size_wr, size_al, "wifi_mesh", NSS_STATS_SINGLE_CORE);

	stats = kzalloc(sizeof(struct nss_wifi_mesh_hdl_stats_sync_msg), GFP_KERNEL);
	if (!stats) {
		nss_warning("%px: Failed to allocate stats memory for if_num: 0x%x\n", data, if_num);
		kfree(lbuf);
		return 0;
	}

	for (; if_num <= max_if_num; if_num++) {
		bool ret;

		if (!nss_is_dynamic_interface(if_num)) {
			continue;
		}

		dtype = nss_dynamic_interface_get_type(nss_wifi_mesh_get_context(), if_num);

		if ((type == NSS_WIFI_MESH_OUTER_STATS) && (dtype != NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER)) {
			continue;
		}

		if ((type == NSS_WIFI_MESH_INNER_STATS) && (dtype != NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER)) {
			continue;
		}

		if ((type == NSS_WIFI_MESH_PATH_STATS) && (dtype != NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER)) {
			continue;
		}

		if ((type == NSS_WIFI_MESH_PROXY_PATH_STATS) && (dtype != NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER)) {
			continue;
		}

		/*
		 * If Wi-Fi mesh stats handle does not exists, then ret will be false.
		 */
		ret = nss_wifi_mesh_get_stats(if_num, stats);
		if (!ret) {
			continue;
		}

		spin_lock(&nss_wifi_mesh_stats_lock);
		handle = nss_wifi_mesh_get_stats_handle(if_num);
		if (!handle) {
			spin_unlock(&nss_wifi_mesh_stats_lock);
			nss_warning("Invalid Wi-Fi mesh stats handle, if_num: %d\n", if_num);
			continue;
		}
		ifindex = handle->ifindex;
		spin_unlock(&nss_wifi_mesh_stats_lock);

		ndev = dev_get_by_index(&init_net, ifindex);
		if (!ndev) {
			continue;
		}

		size_wr += scnprintf(lbuf + size_wr, size_al - size_wr, "\n%s if_num:%03u\n",
				     ndev->name, if_num);
		dev_put(ndev);

		/*
		 * Read encap stats, path stats, proxy path stats from inner node and decap stats from outer node.
		 */
		switch (type) {
		case NSS_WIFI_MESH_INNER_STATS:
			size_wr += nss_stats_print("wifi_mesh", "encap stats", NSS_STATS_SINGLE_INSTANCE
					, nss_wifi_mesh_strings_encap_stats
					, stats->encap_stats
					, NSS_WIFI_MESH_ENCAP_STATS_TYPE_MAX
					, lbuf, size_wr, size_al);
			break;

		case NSS_WIFI_MESH_PATH_STATS:
			size_wr += nss_stats_print("wifi_mesh", "path stats", NSS_STATS_SINGLE_INSTANCE
					, nss_wifi_mesh_strings_path_stats
					, stats->path_stats
					, NSS_WIFI_MESH_PATH_STATS_TYPE_MAX
					, lbuf, size_wr, size_al);
			break;

		case NSS_WIFI_MESH_PROXY_PATH_STATS:
			size_wr += nss_stats_print("wifi_mesh", "proxy path stats", NSS_STATS_SINGLE_INSTANCE
					, nss_wifi_mesh_strings_proxy_path_stats
					, stats->proxy_path_stats
					, NSS_WIFI_MESH_PROXY_PATH_STATS_TYPE_MAX
					, lbuf, size_wr, size_al);
			break;

		case NSS_WIFI_MESH_OUTER_STATS:
			size_wr += nss_stats_print("wifi_mesh", "decap stats", NSS_STATS_SINGLE_INSTANCE
					, nss_wifi_mesh_strings_decap_stats
					, stats->decap_stats
					, NSS_WIFI_MESH_DECAP_STATS_TYPE_MAX
					, lbuf, size_wr, size_al);
			break;

		case NSS_WIFI_MESH_EXCEPTION_STATS:
			size_wr += nss_stats_print("wifi_mesh", "exception stats", NSS_STATS_SINGLE_INSTANCE
					, nss_wifi_mesh_strings_exception_stats
					, stats->except_stats
					, NSS_WIFI_MESH_EXCEPTION_STATS_TYPE_MAX
					, lbuf, size_wr, size_al);
			break;

		default:
			nss_warning("%px: Invalid stats type: %d\n", stats, type);
			nss_assert(0);
			kfree(stats);
			kfree(lbuf);
			return 0;
		}
	}

	bytes_read = simple_read_from_buffer(ubuf, sz, ppos, lbuf, size_wr);
	kfree(stats);
	kfree(lbuf);
	return bytes_read;
}

/**
 * nss_wifi_mesh_decap_stats_read()
 *	Read Wi-Fi Mesh decap stats.
 */
static ssize_t nss_wifi_mesh_decap_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
	return nss_wifi_mesh_stats_read(fp, ubuf, sz, ppos, NSS_WIFI_MESH_OUTER_STATS);
}

/**
 * nss_wifi_mesh_encap_stats_read()
 *	Read Wi-Fi Mesh encap stats
 */
static ssize_t nss_wifi_mesh_encap_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
	return nss_wifi_mesh_stats_read(fp, ubuf, sz, ppos, NSS_WIFI_MESH_INNER_STATS);
}

/**
 * nss_wifi_mesh_path_stats_read()
 *	Read Wi-Fi Mesh path stats
 */
static ssize_t nss_wifi_mesh_path_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
	return nss_wifi_mesh_stats_read(fp, ubuf, sz, ppos, NSS_WIFI_MESH_PATH_STATS);
}

/**
 * nss_wifi_mesh_proxy_path_stats_read()
 *	Read Wi-Fi Mesh proxy path stats
 */
static ssize_t nss_wifi_mesh_proxy_path_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
	return nss_wifi_mesh_stats_read(fp, ubuf, sz, ppos, NSS_WIFI_MESH_PROXY_PATH_STATS);
}

/**
 * nss_wifi_mesh_exception_stats_read()
 *	Read Wi-Fi Mesh exception stats
 */
static ssize_t nss_wifi_mesh_exception_stats_read(struct file *fp, char __user *ubuf, size_t sz, loff_t *ppos)
{
	return nss_wifi_mesh_stats_read(fp, ubuf, sz, ppos, NSS_WIFI_MESH_EXCEPTION_STATS);
}

/*
 * nss_wifi_mesh_stats_ops
 */
NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_mesh_encap);
NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_mesh_decap);
NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_mesh_path);
NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_mesh_proxy_path);
NSS_STATS_DECLARE_FILE_OPERATIONS(wifi_mesh_exception);

/*
 * nss_wifi_mesh_get_interface_type()
 * 	Function to get the type of dynamic interface.
 */
static enum nss_dynamic_interface_type nss_wifi_mesh_get_interface_type(nss_if_num_t if_num)
{
	struct nss_ctx_instance *nss_ctx = &nss_top_main.nss[nss_top_main.wifi_handler_id];
	NSS_VERIFY_CTX_MAGIC(nss_ctx);
	return nss_dynamic_interface_get_type(nss_ctx, if_num);
}

/*
 * nss_wifi_mesh_update_stats()
 *	Update stats for Wi-Fi mesh interface.
 */
void nss_wifi_mesh_update_stats(nss_if_num_t if_num, struct nss_wifi_mesh_stats_sync_msg *mstats)
{
	struct nss_wifi_mesh_stats_handle *handle;
	struct nss_wifi_mesh_hdl_stats_sync_msg *stats;
	enum nss_dynamic_interface_type type;
	uint64_t *dst;
	uint32_t *src;
	int i;

	spin_lock(&nss_wifi_mesh_stats_lock);
	handle = nss_wifi_mesh_get_stats_handle(if_num);
	if (!handle) {
		spin_unlock(&nss_wifi_mesh_stats_lock);
		nss_warning("Invalid Wi-Fi mesh stats handle, if_num: %d\n", if_num);
		return;
	}

	type = nss_wifi_mesh_get_interface_type(handle->if_num);;
	stats = &handle->stats;

	switch (type) {
	case NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_INNER:
		/*
		 * Update pnode Rx stats.
		 */
		stats->encap_stats[NSS_WIFI_MESH_ENCAP_STATS_TYPE_PNODE_RX_PACKETS] += mstats->pnode_stats.rx_packets;
		stats->encap_stats[NSS_WIFI_MESH_ENCAP_STATS_TYPE_PNODE_RX_BYTES] += mstats->pnode_stats.rx_bytes;
		stats->encap_stats[NSS_WIFI_MESH_ENCAP_STATS_TYPE_PNODE_RX_DROPPED] += nss_cmn_rx_dropped_sum(&mstats->pnode_stats);

		/*
		 * Update pnode Tx stats.
		 */
		stats->encap_stats[NSS_WIFI_MESH_ENCAP_STATS_TYPE_PNODE_TX_PACKETS] += mstats->pnode_stats.tx_packets;
		stats->encap_stats[NSS_WIFI_MESH_ENCAP_STATS_TYPE_PNODE_TX_BYTES] += mstats->pnode_stats.tx_bytes;

		/*
		 * Update encap stats.
		 */
		dst = &stats->encap_stats[NSS_WIFI_MESH_ENCAP_STATS_TYPE_EXPIRY_NOTIFY_SENT];
		src = &mstats->mesh_encap_stats.expiry_notify_sent;
		for (i = NSS_WIFI_MESH_ENCAP_STATS_TYPE_EXPIRY_NOTIFY_SENT; i < NSS_WIFI_MESH_ENCAP_STATS_TYPE_MAX; i++) {
			*dst++ += *src++;
		}

		/*
		 * Update mesh path stats.
		 */
		dst = &stats->path_stats[NSS_WIFI_MESH_PATH_STATS_TYPE_ALLOC_FAILURES];
		src = &mstats->mesh_path_stats.alloc_failures;
		for (i = NSS_WIFI_MESH_PATH_STATS_TYPE_ALLOC_FAILURES; i < NSS_WIFI_MESH_PATH_STATS_TYPE_MAX; i++) {
			*dst++ += *src++;
		}

		/*
		 * Update mesh proxy path stats.
		 */
		dst = &stats->proxy_path_stats[NSS_WIFI_MESH_PROXY_PATH_STATS_TYPE_ALLOC_FAILURES];
		src = &mstats->mesh_proxy_path_stats.alloc_failures;
		for (i = NSS_WIFI_MESH_PROXY_PATH_STATS_TYPE_ALLOC_FAILURES; i < NSS_WIFI_MESH_PROXY_PATH_STATS_TYPE_MAX; i++) {
			*dst++ += *src++;
		}

		/*
		 * Update exception stats.
		 */
		dst = &stats->except_stats[NSS_WIFI_MESH_EXCEPTION_STATS_TYPE_PACKETS_SUCCESS];
		src = &mstats->mesh_except_stats.packets_success;
		for (i = NSS_WIFI_MESH_EXCEPTION_STATS_TYPE_PACKETS_SUCCESS; i < NSS_WIFI_MESH_EXCEPTION_STATS_TYPE_MAX; i++) {
			*dst++ += *src++;
		}
		spin_unlock(&nss_wifi_mesh_stats_lock);
		break;

	case NSS_DYNAMIC_INTERFACE_TYPE_WIFI_MESH_OUTER:
		/*
		 * Update pnode Rx stats.
		 */
		stats->decap_stats[NSS_WIFI_MESH_DECAP_STATS_TYPE_PNODE_RX_PACKETS] += mstats->pnode_stats.rx_packets;
		stats->decap_stats[NSS_WIFI_MESH_DECAP_STATS_TYPE_PNODE_RX_BYTES] += mstats->pnode_stats.rx_bytes;
		stats->decap_stats[NSS_WIFI_MESH_DECAP_STATS_TYPE_PNODE_RX_DROPPED] += nss_cmn_rx_dropped_sum(&mstats->pnode_stats);

		/*
		 * Update pnode Tx stats.
		 */
		stats->decap_stats[NSS_WIFI_MESH_DECAP_STATS_TYPE_PNODE_TX_PACKETS] += mstats->pnode_stats.tx_packets;
		stats->decap_stats[NSS_WIFI_MESH_DECAP_STATS_TYPE_PNODE_TX_BYTES] += mstats->pnode_stats.tx_bytes;

		/*
		 * Update decap stats.
		 */
		dst = &stats->decap_stats[NSS_WIFI_MESH_DECAP_STATS_TYPE_PATH_REFRESH_SENT];
		src = &mstats->mesh_decap_stats.path_refresh_sent;
		for (i = NSS_WIFI_MESH_DECAP_STATS_TYPE_PATH_REFRESH_SENT; i < NSS_WIFI_MESH_DECAP_STATS_TYPE_MAX; i++) {
			*dst++ += *src++;
		}
		spin_unlock(&nss_wifi_mesh_stats_lock);
		break;

	default:
		spin_unlock(&nss_wifi_mesh_stats_lock);
		nss_warning("%px: Received invalid dynamic interface type: %d\n", handle, type);
		nss_assert(0);
	}
}

/*
 * nss_wifi_mesh_stats_notify()
 *	Sends notifications to the registered modules.
 *
 * Leverage NSS-FW statistics timing to update Netlink.
 */
void nss_wifi_mesh_stats_notify(nss_if_num_t if_num, uint32_t core_id)
{
	struct nss_wifi_mesh_stats_notification wifi_mesh_stats;

	if (!nss_wifi_mesh_get_stats(if_num, &wifi_mesh_stats.stats)) {
		nss_warning("No handle is present with ifnum: 0x%x\n", if_num);
		return;
	}

	wifi_mesh_stats.core_id = core_id;
	wifi_mesh_stats.if_num = if_num;
	atomic_notifier_call_chain(&nss_wifi_mesh_stats_notifier, NSS_STATS_EVENT_NOTIFY, (void *)&wifi_mesh_stats);
}

/*
 * nss_wifi_mesh_stats_dentry_create()
 *	Create Wi-Fi Mesh statistics debug entry
 */
struct dentry *nss_wifi_mesh_stats_dentry_create(void)
{
	struct dentry *stats_dentry_dir;
	struct dentry *stats_file;
	char dir_name[NSS_WIFI_MESH_DENTRY_FILE_SIZE] = {0};

	if (!nss_top_main.stats_dentry) {
		nss_warning("qca-nss-drv/stats is not present\n");
		return NULL;
	}

	snprintf(dir_name, sizeof(dir_name), "wifi_mesh");

	stats_dentry_dir = debugfs_create_dir(dir_name,  nss_top_main.stats_dentry);
	if (!stats_dentry_dir) {
		nss_warning("Failed to create qca-nss-drv/stats/wifi_mesh directory\n");
		return NULL;
	}

	stats_file = debugfs_create_file("encap_stats", 0400, stats_dentry_dir, &nss_top_main, &nss_wifi_mesh_encap_stats_ops);
	if (!stats_file) {
		nss_warning("Failed to create qca-nss-drv/stats/wifi_mesh/encap_stats file\n");
		goto fail;
	}

	stats_file = debugfs_create_file("decap_stats", 0400, stats_dentry_dir, &nss_top_main, &nss_wifi_mesh_decap_stats_ops);
	if (!stats_file) {
		nss_warning("Failed to create qca-nss-drv/stats/wifi_mesh/decap_stats file\n");
		goto fail;
	}

	stats_file = debugfs_create_file("path_stats", 0400, stats_dentry_dir, &nss_top_main, &nss_wifi_mesh_path_stats_ops);
	if (!stats_file) {
		nss_warning("Failed to create qca-nss-drv/stats/wifi_mesh/path_stats file\n");
		goto fail;
	}

	stats_file = debugfs_create_file("proxy_path_stats", 0400, stats_dentry_dir, &nss_top_main, &nss_wifi_mesh_proxy_path_stats_ops);
	if (!stats_file) {
		nss_warning("Failed to create qca-nss-drv/stats/wifi_mesh/proxy_path_stats file\n");
		goto fail;
	}
	stats_file = debugfs_create_file("exception_stats", 0400, stats_dentry_dir, &nss_top_main, &nss_wifi_mesh_exception_stats_ops);
	if (!stats_file) {
		nss_warning("Failed to create qca-nss-drv/stats/wifi_mesh/exception_stats file\n");
		goto fail;
	}
	return stats_dentry_dir;
fail:
	debugfs_remove_recursive(stats_dentry_dir);
	return NULL;
}

/**
 * nss_wifi_mesh_stats_register_notifier()
 *	Registers statistics notifier.
 */
int nss_wifi_mesh_stats_register_notifier(struct notifier_block *nb)
{
	return atomic_notifier_chain_register(&nss_wifi_mesh_stats_notifier, nb);
}
EXPORT_SYMBOL(nss_wifi_mesh_stats_register_notifier);

/**
 * nss_wifi_mesh_stats_unregister_notifier()
 *	Deregisters statistics notifier.
 */
int nss_wifi_mesh_stats_unregister_notifier(struct notifier_block *nb)
{
	return atomic_notifier_chain_unregister(&nss_wifi_mesh_stats_notifier, nb);
}
EXPORT_SYMBOL(nss_wifi_mesh_stats_unregister_notifier);
