/*
 * (C) Copyright 2012 Quantenna Communications Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * Quantenna HBM skb payload pool
 */
#include <linux/kernel.h>
#include <linux/cache.h>
#include <linux/module.h>
#include <linux/mm.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/skbuff.h>
#include <qtn/dmautil.h>
#include <asm/io.h>

#include <common/queue.h>

#include <qtn/topaz_hbm.h>
#include <qtn/dmautil.h>

#include <net80211/if_ethersubr.h>

#define isspace(c) ((((c) == ' ') || (((unsigned int)((c) - 9)) <= (13 - 9))))

#define TOPAZ_HBM_PROC_FILENAME "topaz_hbm"
#define TOPAZ_HBM_IF_PROC_NAME "topaz_hbm_if"

#define HBM_BUF_DEPLETION_TH		(20)
#define HBM_BUF_POLL_S_INTRVAL		(10 * HZ)
#define HBM_BUF_POLL_L_INTRVAL		(60 * HZ)
#define HBM_BUF_MINIMUM_AVAIL_NUM	(3)
#define HBM_BUF_MINIMUM_REL_NUM		(10 * HBM_BUF_POLL_S_INTRVAL)

typedef enum hbm_if_usr_cmd {
	HBM_IF_CMD_DUMPCTL = 0,
	HBM_IF_CMD_STATS = 1,
	HBM_IF_MAX_CMD,
} hbm_if_usr_cmd;

#define HBM_IF_KEY_DUMPCTL	"dumpctl"
#define HBM_IF_KEY_STATS	"stats"
static char* str_cmd[HBM_IF_MAX_CMD] = {
	HBM_IF_KEY_DUMPCTL,
	HBM_IF_KEY_STATS,
};

typedef enum hbm_stats {
	HBM_CNT_INVALID_POOL = 0,
	HBM_CNT_MISALIGNED = 1,
	HBM_CNT_MAGIC_CORRUPTED = 2,
	HBM_CNT_QUARANTINE_CORRUPTED = 3,
	HBM_CNT_QUARANTINE_ALLOC_FAIL = 4,
	HBM_CNT_QUARANTINE_OK = 5,
	HBM_CNT_NUM,
} hbm_stats;

struct hbm_pool_cnt {
	uint32_t prev_release_cnt;
	uint32_t pool_depleted_cnt;
};
struct topaz_hbm_mnt {
	uint32_t prev_unflow_cnt;
	uint32_t unflow_flag;
	struct hbm_pool_cnt wmac_pl;
	struct hbm_pool_cnt emac_pl;
};

static DEFINE_TIMER(hbm_timer, NULL, 0, 0);
static uint32_t topaz_hbm_stats[HBM_CNT_NUM] = {0};
static const char *topaz_hbm_stats_names[HBM_CNT_NUM] = {
	"Invalid pool",
	"Misaligned pointer",
	"Magic corrupted",
	"Quarantine corrupted buffer",
	"Quarantine allocation fail",
	"Quarantine ok",
};
#define HBM_STATS(_idx, _num)	(topaz_hbm_stats[(_idx)] += (_num))

#ifdef TOPAZ_EMAC_NULL_BUF_WR
#define HBM_UFLOW_RECOVER_TH	32
void __attribute__((section(".sram.data")))(*topaz_emac_null_buf_del_cb)(void) = NULL;
EXPORT_SYMBOL(topaz_emac_null_buf_del_cb);
#endif

static const char *topaz_hbm_requestor_names[TOPAZ_HBM_MASTER_COUNT] = TOPAZ_HBM_REQUESTOR_NAMES;

unsigned int topaz_hbm_pool_available(int8_t pool)
{
	uint32_t wr_ptr;
	uint32_t rd_ptr;
	static const unsigned int TOPAZ_HBM_MAX_POOL_COUNT = (1 << 16);

	if (!topaz_hbm_pool_valid(pool)) {
		printk(KERN_ERR"%s: Invalid pool %d\n", __func__, pool);
		return TOPAZ_HBM_MAX_POOL_COUNT;
	}

	wr_ptr = readl(TOPAZ_HBM_WR_PTR(pool));
	rd_ptr = readl(TOPAZ_HBM_RD_PTR(pool));

	if (wr_ptr >= rd_ptr)
		return (wr_ptr - rd_ptr);
	else
		return (TOPAZ_HBM_MAX_POOL_COUNT - rd_ptr + wr_ptr);
}
EXPORT_SYMBOL(topaz_hbm_pool_available);

#define HBM_DUMP_SORT_ORDER_INV_BASE	100
typedef enum hbm_dump_sort_type {
	HBM_DUMP_SORT_ADDR = 0,					/* lower addr first */
	HBM_DUMP_SORT_JIFF,					/* newest freed first */
	HBM_DUMP_SORT_BAD_MAGIC,				/* bad magic first */
	HBM_DUMP_SORT_ADDR_MAX = HBM_DUMP_SORT_ORDER_INV_BASE - 1,
} hbm_dump_sort_type;

static hbm_dump_sort_type topaz_hbm_dump_sort_type = HBM_DUMP_SORT_ADDR;
static int topaz_hbm_dump_sort_range_min = 0;			/* meaning dependent on sort type */
static int topaz_hbm_dump_sort_range_max = 0xFFFFFFFF;		/* meaning dependent on sort type */
static int topaz_hbm_dump_num = 5;				/* max dump number */
static int topaz_hbm_dump_len = 128;				/* bytes dump at head */
static int topaz_hbm_dump_taillen = 32;				/* bytes dump at tail */
static int topaz_hbm_dumped_num = 0;				/* currently dumpped number */

#define TOPAZ_HBM_POOL_SIZE_MAX		(TOPAZ_HBM_BUF_EMAC_RX_COUNT + 1)
uint32_t* topaz_hbm_dump_bufs_sorted[TOPAZ_HBM_POOL_SIZE_MAX] = {0};

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
static int topaz_hbm_stat_rd(struct seq_file *sfile, void *data)
#else

static int topaz_hbm_stat_rd(char *page, char **start, off_t offset,
		int count, int *eof, void *data)
#endif
{

	uint32_t wr_ptr;
	uint32_t rd_ptr;
	int ret = 0;
	unsigned long flags;
	int req_rel_diff = 0;
	int req_rel_perpool_diff[TOPAZ_HBM_POOL_COUNT];
	int master, pool;
	uint32_t overflow;
	uint32_t underflow;
	int allocated;

#if LINUX_VERSION_CODE < KERNEL_VERSION(4,7,0)
	char *p = page;
#endif

	local_irq_save(flags);
	/* offsets for initial pool loading */
	req_rel_perpool_diff[TOPAZ_HBM_BUF_EMAC_RX_POOL] = TOPAZ_HBM_BUF_EMAC_RX_COUNT;
	req_rel_perpool_diff[TOPAZ_HBM_BUF_WMAC_RX_POOL] = TOPAZ_HBM_BUF_WMAC_RX_COUNT;
	req_rel_perpool_diff[TOPAZ_HBM_AUC_FEEDBACK_POOL] = 0;
	req_rel_perpool_diff[TOPAZ_HBM_EMAC_TX_DONE_POOL] = 0;

	for (pool = 0; pool < TOPAZ_HBM_POOL_COUNT; ++pool) {
		for (master = 0; master < TOPAZ_HBM_MASTER_COUNT; ++master) {
			uint32_t req = readl(TOPAZ_HBM_POOL_REQUEST_CNT(master, pool));
			uint32_t rel = readl(TOPAZ_HBM_POOL_RELEASE_CNT(master, pool));

			req_rel_perpool_diff[pool] += req;
			req_rel_perpool_diff[pool] -= rel;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
			seq_printf(sfile, "master %5s pool %d req %u rel %u\n",
					topaz_hbm_requestor_names[master], pool, req, rel);
#else
			p += sprintf(p, "master %5s pool %d req %u rel %u\n",
					topaz_hbm_requestor_names[master], pool, req, rel);
#endif
		}
	}

	for (pool = 0; pool < TOPAZ_HBM_POOL_COUNT; ++pool) {
		req_rel_diff += req_rel_perpool_diff[pool];
		wr_ptr = readl(TOPAZ_HBM_WR_PTR(pool));
		rd_ptr = readl(TOPAZ_HBM_RD_PTR(pool));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
		seq_printf(sfile, "pool %u rd_ptr %u wr_ptr %u\n", pool, rd_ptr, wr_ptr);
#else
		p += sprintf(p, "pool %u rd_ptr %u wr_ptr %u\n", pool, rd_ptr, wr_ptr);
#endif
	}

	overflow = readl(TOPAZ_HBM_OVERFLOW_CNT);
	underflow = readl(TOPAZ_HBM_UNDERFLOW_CNT);
	allocated = req_rel_diff - underflow;
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	seq_printf(sfile, "underflow %u overflow %u req rel diff %d allocated %d\n",
		underflow, overflow, req_rel_diff, allocated);
#else
	p += sprintf(p, "underflow %u overflow %u req rel diff %d allocated %d\n",
		underflow, overflow, req_rel_diff, allocated);
#endif
	if (overflow) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
		seq_printf(sfile, "ERROR: overflow counter must be zero\n");
#else
		p += sprintf(p, "ERROR: overflow counter must be zero\n");
#endif
	}

	if (underflow) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
		seq_printf(sfile, "WARNING: underflow counter is non zero, may need to increase pool\n");
#else
		p += sprintf(p, "WARNING: underflow counter is non zero, may need to increase pool\n");
#endif
	}

	for (pool = 0; pool < TOPAZ_HBM_POOL_COUNT; ++pool) {
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
		seq_printf(sfile, "pool %d req rel diff %d, available %u\n", pool, req_rel_perpool_diff[pool],
				topaz_hbm_pool_available(pool));
#else
		p += sprintf(p, "pool %d req rel diff %d, available %u\n", pool, req_rel_perpool_diff[pool],
				topaz_hbm_pool_available(pool));
#endif
	}

	local_irq_restore(flags);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	return ret;
#else
	*eof = 1;
	return p - page;
#endif
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
static int topaz_hbm_stat_open(struct inode *inode, struct file *file)
{
        return single_open(file, topaz_hbm_stat_rd, NULL);
}

static const struct file_operations topaz_hbm_stat_fops = {
        .owner          = THIS_MODULE,
        .open           = topaz_hbm_stat_open,
        .read           = seq_read,
        .llseek         = seq_lseek,
        .release        = single_release,
};
#endif

static int __init topaz_hbm_stat_init(void)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	if (!proc_create(TOPAZ_HBM_PROC_FILENAME, 0x400, NULL, &topaz_hbm_stat_fops))
		return -ENOMEM;
#else	
	if (!create_proc_read_entry(TOPAZ_HBM_PROC_FILENAME, 0,
			NULL, topaz_hbm_stat_rd, NULL)) {
		return -EEXIST;
	}
#endif
	return 0;
}

static void __exit topaz_hbm_stat_exit(void)
{
	remove_proc_entry(TOPAZ_HBM_PROC_FILENAME, 0);
}

void topaz_hbm_init_pool_list(unsigned long *const pool_list, const uint16_t payload_count_s,
		const uintptr_t payloads_bus, const uint32_t payload_size,
		const uint32_t payload_headroom, const int8_t pool)
{
	uint32_t i;
	const uint16_t payload_count = (1 << payload_count_s);

	topaz_hbm_init((void *) virt_to_bus(pool_list), payload_count_s, pool, 0);

	if (payloads_bus) {
		for (i = 0; i < payload_count; i++) {
			uintptr_t buf_bus = payloads_bus + (i * payload_size) + payload_headroom;
			uint32_t *_p = bus_to_virt(buf_bus);
			uint32_t *_m = topaz_hbm_buf_get_meta(_p);
			uint32_t *enqueuep = _m - HBM_HR_OFFSET_ENQ_CNT;
			uint32_t *freep = _m - HBM_HR_OFFSET_FREE_CNT;
			uint32_t *statep = _m - HBM_HR_OFFSET_STATE;
			uint32_t *magicp = _p - HBM_HR_OFFSET_MAGIC;
			uint32_t *guardp =(uint32_t*)((uint32_t)_p + payload_size - payload_headroom -
							TOPAZ_HBM_PAYLOAD_END_GUARD_SIZE);
#if TOPAZ_HBM_BUF_EXTERNAL_META
			uint32_t *meta_ptr_p = _p - HBM_HR_OFFSET_META_PTR;
			uint32_t *meta_backptr_p = _m - HBM_HR_OFFSET_META_PTR;
#endif
			int j;
#if TOPAZ_HBM_DEBUG_STAMPS
			uint32_t *jiffp = _m - HBM_HR_OFFSET_FREE_JIFF;
			uint32_t *ownerp = _m - HBM_HR_OFFSET_OWNER;
			arc_write_uncached_32(jiffp, jiffies);
			arc_write_uncached_32(ownerp, TOPAZ_HBM_OWNER_INIT);
#endif
			/* always setup magic and guard area to provide minimum detection */
			arc_write_uncached_32(magicp, TOPAZ_HBM_BUF_GUARD_MAGIC);
			arc_write_uncached_32(statep, 0);
			for (j = 0; j < (TOPAZ_HBM_PAYLOAD_END_GUARD_SIZE >> 2); j++) {
				arc_write_uncached_32((guardp + j), TOPAZ_HBM_BUF_GUARD_MAGIC);
			}
			arc_write_uncached_32(enqueuep, 1);
			arc_write_uncached_32(freep, 0);

#if TOPAZ_HBM_BUF_EXTERNAL_META
			arc_write_uncached_32(meta_ptr_p, virt_to_bus(_m));
			arc_write_uncached_32(meta_backptr_p, buf_bus);
#endif

			topaz_hbm_put_buf((void *) buf_bus, pool);
		}
	}

	printk(KERN_INFO "%s pool %u pool_list 0x%p bus_range 0x%lx to 0x%lx sz %u count %u\n",
			__FUNCTION__, pool, pool_list,
			payloads_bus, payloads_bus + payload_size * payload_count,
			payload_size, payload_count);
}

static int g_pools_inited = 0;

static void topaz_hbm_init_payload_pools(void)
{
	unsigned long flags;
	uintptr_t *topaz_hbm_emac_rx_ptrs = (void *) (RUBY_SRAM_BEGIN + TOPAZ_HBM_POOL_EMAC_RX_START);
	uintptr_t *topaz_hbm_wmac_rx_ptrs = (void *) (RUBY_SRAM_BEGIN + TOPAZ_HBM_POOL_WMAC_RX_START);
	uintptr_t *topaz_hbm_emac_free_ptrs = (void *) (RUBY_SRAM_BEGIN + TOPAZ_HBM_POOL_EMAC_TX_DONE_START);

	printk("HBM pool: emac rx 0x%x to 0x%x, wmac rx 0x%x to 0x%x\n",
		TOPAZ_HBM_POOL_EMAC_RX_START,
		TOPAZ_HBM_POOL_EMAC_RX_END,
		TOPAZ_HBM_POOL_WMAC_RX_START,
		TOPAZ_HBM_POOL_WMAC_RX_END);

	memset((void *) (RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_EMAC_RX_BASE), TOPAZ_HBM_BUF_PAYLOAD_POISON,
			TOPAZ_HBM_BUF_EMAC_RX_TOTAL);
	memset((void *) (RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_WMAC_RX_BASE), TOPAZ_HBM_BUF_PAYLOAD_POISON,
			TOPAZ_HBM_BUF_WMAC_RX_TOTAL);
	flush_and_inv_dcache_sizerange_safe((void *) (RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_EMAC_RX_BASE), TOPAZ_HBM_BUF_EMAC_RX_TOTAL);
	flush_and_inv_dcache_sizerange_safe((void *) (RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_WMAC_RX_BASE), TOPAZ_HBM_BUF_WMAC_RX_TOTAL);

	memset((void *) (RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_META_BASE), TOPAZ_HBM_BUF_PAYLOAD_POISON,
			TOPAZ_HBM_BUF_META_TOTAL);
	flush_and_inv_dcache_sizerange_safe((void *)(RUBY_DRAM_BEGIN + TOPAZ_HBM_BUF_META_BASE),
			TOPAZ_HBM_BUF_META_TOTAL);
#if TOPAZ_HBM_BUF_EXTERNAL_META
	printk("HBM meta: emac rx 0x%x to 0x%x, wmac rx 0x%x to 0x%x\n",
			TOPAZ_HBM_BUF_META_EMAC_RX_BASE,
			TOPAZ_HBM_BUF_META_EMAC_RX_END,
			TOPAZ_HBM_BUF_META_WMAC_RX_BASE,
			TOPAZ_HBM_BUF_META_WMAC_RX_END);
#else
	printk("HBM used internal meta\n");
#endif

	local_irq_save(flags);

	topaz_hbm_init_pool_list(topaz_hbm_emac_rx_ptrs, TOPAZ_HBM_BUF_EMAC_RX_COUNT_S,
			RUBY_DRAM_BUS_BEGIN + TOPAZ_HBM_BUF_EMAC_RX_BASE,
			TOPAZ_HBM_BUF_EMAC_RX_SIZE, TOPAZ_HBM_PAYLOAD_HEADROOM,
			TOPAZ_HBM_BUF_EMAC_RX_POOL);
	topaz_hbm_init_pool_list(topaz_hbm_wmac_rx_ptrs, TOPAZ_HBM_BUF_WMAC_RX_COUNT_S,
			RUBY_DRAM_BUS_BEGIN + TOPAZ_HBM_BUF_WMAC_RX_BASE,
			TOPAZ_HBM_BUF_WMAC_RX_SIZE, TOPAZ_HBM_PAYLOAD_HEADROOM,
			TOPAZ_HBM_BUF_WMAC_RX_POOL);
	topaz_hbm_init_pool_list(topaz_hbm_emac_free_ptrs, TOPAZ_HBM_EMAC_TX_DONE_COUNT_S,
			0, 0, 0, TOPAZ_HBM_EMAC_TX_DONE_POOL);

	local_irq_restore(flags);

	g_pools_inited = 1;
}

int topaz_hbm_handle_buf_err(void *const buf_virt, int8_t dest_pool)
{
	if (!topaz_hbm_buf_ptr_valid(buf_virt)) {
		HBM_STATS(HBM_CNT_MISALIGNED, 1);
		printk(KERN_CRIT "%s: buf 0x%x misaligned: pool %u\n",
				__FUNCTION__,
				(unsigned int)buf_virt, dest_pool);
		return 0;
	}

	HBM_STATS(HBM_CNT_MAGIC_CORRUPTED, 1);
	hbm_buf_fix_buf_magic(buf_virt);

	return 1;
}

void  __attribute__((section(".sram.text"))) topaz_hbm_filter_txdone_buf(void *const buf_bus)
{
	const int8_t dest_pool = topaz_hbm_payload_get_pool_bus(buf_bus);

	if (dest_pool == TOPAZ_HBM_BUF_WMAC_RX_POOL ||
			dest_pool == TOPAZ_HBM_BUF_EMAC_RX_POOL) {
		uint32_t *const _p = bus_to_virt((uintptr_t) buf_bus);
		uint32_t *_m = topaz_hbm_buf_get_meta(_p);
		uint32_t *const enqueuep = _m - HBM_HR_OFFSET_ENQ_CNT;
		uint32_t *const freep = _m - HBM_HR_OFFSET_FREE_CNT;
		const uint32_t ec = arc_read_uncached_32(enqueuep);
		const uint32_t fc = arc_read_uncached_32(freep) + 1;
		const bool release = (ec && (fc == ec));

		if (release) {
			/* only fix magic corruption when we are sure no one else is using it right now */
			if (TOPAZ_HBM_BUF_MAGIC_CHK_ALLPOOL || (dest_pool == TOPAZ_HBM_BUF_WMAC_RX_POOL)) {
				int state = hbm_buf_check_buf_magic(_p);
				if (unlikely(state)) {
					if (!topaz_hbm_handle_buf_err(_p, dest_pool)) {
						/* shouldn't put it back to pool */
						return;
					}
				}
			}
#if TOPAZ_HBM_DEBUG_STAMPS
			uint32_t *jiffp = _m - HBM_HR_OFFSET_FREE_JIFF;
			uint32_t *ownerp = _m - HBM_HR_OFFSET_OWNER;
			const uint32_t owner = arc_read_uncached_32(ownerp);
			const uint8_t owner1 = (owner & 0xF) >> 0;

			if (owner1 == TOPAZ_HBM_OWNER_FREE) {
				/*
				 * Double free check is already broken because a lot of free places
				 * doesn't update the owner, both VB and PCIe platform.
				 */
				/*
				uint32_t *sizep = _m - HBM_HR_OFFSET_SIZE;
				const uint32_t size = arc_read_uncached_32(sizep);
				printk(KERN_ERR "%s: double free of buf_bus %p size %u owner %08x\n",
						__FUNCTION__, buf_bus, size, owner);
				topaz_hbm_buf_show(_p, TOPAZ_HBM_BUF_DUMP_DFT, 0);
				*/
			}
			arc_write_uncached_32(jiffp, jiffies);
			arc_write_uncached_32(ownerp, (owner << 4) | TOPAZ_HBM_OWNER_FREE);
#endif

			if (ec != 1) {
				arc_write_uncached_32(enqueuep, 1);
				arc_write_uncached_32(freep, 0);
			}
			topaz_hbm_put_payload_aligned_bus(buf_bus, dest_pool);
		} else {
			arc_write_uncached_32(freep, fc);
		}
	} else {
		HBM_STATS(HBM_CNT_INVALID_POOL, 1);
		printk(KERN_CRIT "%s: unknown pool %hhd for buf_bus 0x%p\n",
				__FUNCTION__, dest_pool, buf_bus);
	}
}
EXPORT_SYMBOL(topaz_hbm_filter_txdone_buf);

/*
 * Safely return the buf.
 * @pkt_bus needn't to be the pointer from the pool. It can be any location in the buffer.
 */
void topaz_hbm_release_buf_safe(void *const pkt_bus)
{
	const int8_t dest_pool = topaz_hbm_payload_get_pool_bus(pkt_bus);
	void *buf_bus = topaz_hbm_payload_store_align_bus(pkt_bus, dest_pool, 0);
	unsigned long flags;

	local_irq_save(flags);
	topaz_hbm_filter_txdone_buf(buf_bus);
	local_irq_restore(flags);
}
EXPORT_SYMBOL(topaz_hbm_release_buf_safe);

void topaz_hbm_filter_txdone_pool(void)
{
	unsigned long flags;
	void *buf_bus;
	const int8_t src_pool = TOPAZ_HBM_EMAC_TX_DONE_POOL;

	const uint32_t mask = TOPAZ_HBM_EMAC_TX_DONE_COUNT - 1;
	uint32_t wr_ptr;
	uint32_t rd_ptr;
	uint32_t wr_raw;
	uint32_t rd_raw;
	uint32_t i;
	uint32_t count;
	uint32_t full;

	if (unlikely(!g_pools_inited)) {
		return;
	}

	local_irq_save(flags);

	wr_raw = readl(TOPAZ_HBM_WR_PTR(src_pool));
	rd_raw = readl(TOPAZ_HBM_RD_PTR(src_pool));
	wr_ptr = wr_raw & mask;
	rd_ptr = rd_raw & mask;
	full = ((wr_raw != rd_raw) && (wr_ptr == rd_ptr));

	for (count = 0, i = rd_ptr; ((i != wr_ptr) || full); i = (i + 1) & mask, count++) {
		buf_bus = topaz_hbm_get_payload_bus(src_pool);
		if (buf_bus != NULL) {
			topaz_hbm_filter_txdone_buf(buf_bus);
		} else if (printk_ratelimit()) {
			printk(KERN_CRIT "%s: read NULL from pool %d\n",
					__FUNCTION__, src_pool);
			break;
		}
		full = 0;
	}
#ifdef TOPAZ_EMAC_NULL_BUF_WR
	if (topaz_emac_null_buf_del_cb) {
		uint32_t n;
		wr_ptr = readl(TOPAZ_HBM_WR_PTR(TOPAZ_HBM_BUF_EMAC_RX_POOL));
		rd_ptr = readl(TOPAZ_HBM_RD_PTR(TOPAZ_HBM_BUF_EMAC_RX_POOL));
		n = (wr_ptr - rd_ptr) % TOPAZ_HBM_BUF_EMAC_RX_COUNT;
		if (n > HBM_UFLOW_RECOVER_TH)
			topaz_emac_null_buf_del_cb();
	}
#endif
	local_irq_restore(flags);

	if (unlikely(count > (TOPAZ_HBM_EMAC_TX_DONE_COUNT * 3 / 4))) {
		if (printk_ratelimit())
			printk("Warning! %s count: %u\n", __FUNCTION__, count);
	}
}
EXPORT_SYMBOL(topaz_hbm_filter_txdone_pool);

static struct kmem_cache *shinfo_cache;

static uint8_t *topaz_hbm_skb_allocator_payload_alloc(struct skb_shared_info **shinfo,
		size_t size, gfp_t gfp_mask, int node)
{
	uint8_t *data;

	size = SKB_DATA_ALIGN(size);

	*shinfo = kmem_cache_alloc(shinfo_cache, gfp_mask);
	if (*shinfo == NULL) {
		return NULL;
	}

	if (size < topaz_hbm_pool_buf_max_size(TOPAZ_HBM_BUF_EMAC_RX_POOL)) {
		data = topaz_hbm_get_payload_virt(TOPAZ_HBM_BUF_EMAC_RX_POOL);
	} else {
		data = kmalloc(size, gfp_mask);
	}

	if (data == NULL) {
		kmem_cache_free(shinfo_cache, *shinfo);
		*shinfo = NULL;
	}

	return data;
}

static void topaz_hbm_skb_allocator_payload_free(struct sk_buff *skb)
{
	void *buf_bus = (void *) virt_to_bus(skb->head);
	const int8_t pool = topaz_hbm_payload_get_free_pool_bus(buf_bus);

	buf_bus = topaz_hbm_payload_store_align_bus(buf_bus,
		topaz_hbm_payload_get_pool_bus(buf_bus), 0);
	kmem_cache_free(shinfo_cache, skb_shinfo(skb));

	if (topaz_hbm_pool_valid(pool)) {
		if (!skb->hbm_no_free) {
			unsigned long flags;

			local_irq_save(flags);

			topaz_hbm_flush_skb_cache(skb);
			topaz_hbm_filter_txdone_buf(buf_bus);

			local_irq_restore(flags);
		}
	} else {
		kfree(skb->head);
	}

	topaz_hbm_filter_txdone_pool();
}

const struct skb_allocator topaz_hbm_skb_allocator = {
	.name = "topaz_hbm",
	.skb_alloc = &skb_allocator_kmem_caches_skb_alloc,
	.skb_free = &skb_allocator_kmem_caches_skb_free,
	.payload_alloc = &topaz_hbm_skb_allocator_payload_alloc,
	.payload_free = &topaz_hbm_skb_allocator_payload_free,
	.max_size = 0,
};

#define QTN_HBM_MAX_FRAME_LEN	12000	/* 12000 is over maximum vht frame size,
					and there is no rx frame whose size is over 12000 */
struct sk_buff *_topaz_hbm_attach_skb(void *buf_virt, int8_t pool, int inv, uint8_t headroom
		QTN_SKB_ALLOC_TRACE_ARGS)
{
	struct sk_buff *skb;
	struct skb_shared_info *shinfo;
	uint32_t buf_size;
	uint8_t *buf_head;
	uint8_t *buf_head2;
	uintptr_t inv_start;
	uintptr_t inv_end;

	if (unlikely(headroom > TOPAZ_HBM_PAYLOAD_HEADROOM)) {
		printk(KERN_WARNING "specified headroom(%u) should be smaller than %u\n",
			headroom, TOPAZ_HBM_PAYLOAD_HEADROOM);
		return NULL;
	}

	shinfo = kmem_cache_alloc(shinfo_cache, GFP_ATOMIC);
	if (!shinfo) {
		return NULL;
	}

	skb = skb_allocator_kmem_caches_skb_alloc(GFP_ATOMIC, 0, -1);
	if (!skb) {
		kmem_cache_free(shinfo_cache, shinfo);
		return NULL;
	}

	/*
	 * TODO FIXME: Restrict the buffer size less than 12k, because we saw ping failed
	 * if we set skb buffer size as 17K
	 */
	buf_size = min((int)topaz_hbm_pool_buf_max_size(pool), QTN_HBM_MAX_FRAME_LEN);
	buf_head = topaz_hbm_payload_store_align_virt(buf_virt, pool, 0);
	buf_head2 = buf_head - headroom;

	/* invalidate all packet dcache before passing to the kernel */
	if (inv)
		inv_dcache_sizerange_safe(buf_head, buf_size);

	inv_start = (uintptr_t) align_buf_cache(buf_head);
	inv_end = align_val_up((uintptr_t) buf_head + buf_size,
			dma_get_cache_alignment());
	inv_dcache_range(inv_start, inv_end);

	__alloc_skb_init(skb, shinfo, buf_head2,
			buf_size, 0, &topaz_hbm_skb_allocator
			QTN_SKB_ALLOC_TRACE_ARGVARS);
	skb_reserve(skb, ((uint8_t *) buf_virt) - buf_head2);

	return skb;
}
EXPORT_SYMBOL(_topaz_hbm_attach_skb);

/*
 * Allocate a new buffer to hold the pkt. The new buffer is guranteed to be safe from wmac rx dma overrun.
 * The original buffer is not used anymore. Caller should be responsible for freeing the buffer.
 */
struct sk_buff *topaz_hbm_attach_skb_quarantine(void *buf_virt, int pool, int len, uint8_t **whole_frm_hdr_p)
{
	uint8_t *buf_head;
	struct sk_buff *skb = NULL;
	uint32_t prev_len;
	uint32_t buf_size;

	KASSERT((pool == TOPAZ_HBM_BUF_WMAC_RX_POOL), ("buf quarantine is only for wmac rx pool, %d", pool));

	buf_head = topaz_hbm_payload_store_align_virt(buf_virt, pool, 0);
	if (hbm_buf_check_buf_magic(buf_head)) {
		/* don't copy to new skb if it is aleady corrupted */
		HBM_STATS(HBM_CNT_QUARANTINE_CORRUPTED, 1);
		return NULL;
	}

	/* copy from buffer head in case mac header is needed */
	prev_len = (uint32_t)buf_virt - (uint32_t)buf_head;
	buf_size = prev_len + len;

	skb = dev_alloc_skb(buf_size);
	if (!skb) {
		HBM_STATS(HBM_CNT_QUARANTINE_ALLOC_FAIL, 1);
		return NULL;
	}

	/* caller only invalidate this pkt, not entire buffer */
	inv_dcache_sizerange_safe(buf_head, prev_len);
	if (whole_frm_hdr_p)
		*whole_frm_hdr_p = skb->data;
	memcpy(skb->data, buf_head, buf_size);
	if (hbm_buf_check_buf_magic(buf_head)) {
		/* if corruption happens during data copying */
		HBM_STATS(HBM_CNT_QUARANTINE_CORRUPTED, 1);
		goto post_check_fail;
	}

	/* reserve head space so that later caller's skb_put() covers the packet */
	skb_reserve(skb, prev_len);
	HBM_STATS(HBM_CNT_QUARANTINE_OK, 1);

	/*
	 * Quarantine is done. now we are sure the data copy in skb is not corrupted and won't
	 */
	return skb;

post_check_fail:
	if (skb)
		dev_kfree_skb(skb);
	return NULL;
}
EXPORT_SYMBOL(topaz_hbm_attach_skb_quarantine);

static int topaz_hbm_bufs_sort_need_swap(const uint32_t *buf0, const uint32_t *buf1)
{
	int type;
	int inv;
	uint32_t v0;
	uint32_t v1;

	type = topaz_hbm_dump_sort_type;
	inv = 0;
	if (topaz_hbm_dump_sort_type >= HBM_DUMP_SORT_ORDER_INV_BASE) {
		type -= HBM_DUMP_SORT_ORDER_INV_BASE;
		inv = 1;
	}

	switch(type) {
	case HBM_DUMP_SORT_ADDR:
		v0 = (uint32_t)buf0;
		v1 = (uint32_t)buf1;
		break;
	case HBM_DUMP_SORT_JIFF:
		v0 = jiffies - arc_read_uncached_32(topaz_hbm_buf_get_meta(buf0) - HBM_HR_OFFSET_FREE_JIFF);
		v1 = jiffies - arc_read_uncached_32(topaz_hbm_buf_get_meta(buf1) - HBM_HR_OFFSET_FREE_JIFF);
		break;
	case HBM_DUMP_SORT_BAD_MAGIC:
		v0 = (arc_read_uncached_32(buf0 - HBM_HR_OFFSET_MAGIC) == TOPAZ_HBM_BUF_GUARD_MAGIC);
		v1 = (arc_read_uncached_32(buf1 - HBM_HR_OFFSET_MAGIC) == TOPAZ_HBM_BUF_GUARD_MAGIC);
		break;
	default:
		return 0;
		break;
	}

	return (inv ? (v1 > v0) : (v0 > v1));
}

static void topaz_hbm_bufs_sort(int pool, int pool_size)
{
	int i;
	int j;
	uint32_t *buf0;
	uint32_t *buf1;
	uint32_t *buf;
	int swapped;

	memset(topaz_hbm_dump_bufs_sorted, 0, sizeof(topaz_hbm_dump_bufs_sorted));
	for (i = 0; i < pool_size; i++) {
		topaz_hbm_dump_bufs_sorted[i] = (uint32_t*)
			topaz_hbm_payload_store_align_from_index(pool, i);
	}

	/* bubble sort */
	for (i = 0; i < (pool_size - 1); i++) {
		swapped = 0;
		for (j = 0; j < (pool_size - i - 1); j++) {
			buf0 = topaz_hbm_dump_bufs_sorted[j];
			buf1 = topaz_hbm_dump_bufs_sorted[j + 1];
			if (topaz_hbm_bufs_sort_need_swap(buf0, buf1)) {
				buf = buf0;
				topaz_hbm_dump_bufs_sorted[i] = buf1;
				topaz_hbm_dump_bufs_sorted[j] = buf;
				swapped = 1;
			}
		}
		if (!swapped)
			break;
	}

	topaz_hbm_dumped_num = 0;
}

static int topaz_hbm_buf_in_range(const uint32_t *buf)
{
	int type;
	uint32_t v;

	type = topaz_hbm_dump_sort_type;
	if (topaz_hbm_dump_sort_type >= HBM_DUMP_SORT_ORDER_INV_BASE) {
		type -= HBM_DUMP_SORT_ORDER_INV_BASE;
	}

	switch(type) {
	case HBM_DUMP_SORT_ADDR:
		v = (uint32_t)buf;
		break;
	case HBM_DUMP_SORT_JIFF:
		v = jiffies - arc_read_uncached_32(topaz_hbm_buf_get_meta(buf) - HBM_HR_OFFSET_FREE_JIFF);
		break;
	case HBM_DUMP_SORT_BAD_MAGIC:
		v = (arc_read_uncached_32(buf - HBM_HR_OFFSET_MAGIC) == TOPAZ_HBM_BUF_GUARD_MAGIC);
		break;
	default:
		return 0;
		break;
	}

	return ((topaz_hbm_dump_sort_range_min <= v) && (v <= topaz_hbm_dump_sort_range_max));
}

static void *topaz_hbm_bufs_emac_seq_start(struct seq_file *sfile, loff_t *pos)
{
	if (*pos > (TOPAZ_HBM_POOL_SIZE_MAX - 1))
		return NULL;

	if (*pos == 0)
		topaz_hbm_bufs_sort(TOPAZ_HBM_BUF_EMAC_RX_POOL, TOPAZ_HBM_BUF_EMAC_RX_COUNT);

	return topaz_hbm_dump_bufs_sorted[*pos];
}

static void *topaz_hbm_bufs_wmac_seq_start(struct seq_file *sfile, loff_t *pos)
{
	if (*pos > (TOPAZ_HBM_POOL_SIZE_MAX - 1))
		return NULL;

	if (*pos == 0)
		topaz_hbm_bufs_sort(TOPAZ_HBM_BUF_WMAC_RX_POOL, TOPAZ_HBM_BUF_WMAC_RX_COUNT);

	return topaz_hbm_dump_bufs_sorted[*pos];
}

static void* topaz_hbm_bufs_seq_next(struct seq_file *sfile, void *v, loff_t *pos)
{
	if (*pos > (TOPAZ_HBM_POOL_SIZE_MAX - 1))
		return NULL;

	*pos += 1;

	return topaz_hbm_dump_bufs_sorted[*pos];
}

static void topaz_hbm_bufs_seq_stop(struct seq_file *sfile, void *v)
{
}

static int topaz_hbm_bufs_seq_show(struct seq_file *sfile, void *v)
{
	const uint32_t *_p = v;
	const uint32_t *_m = topaz_hbm_buf_get_meta(_p);
	const uint32_t *enqueuep = _m - HBM_HR_OFFSET_ENQ_CNT;
	const uint32_t *freep = _m - HBM_HR_OFFSET_FREE_CNT;
	const uint32_t *jiffp = _m - HBM_HR_OFFSET_FREE_JIFF;
	const uint32_t *ownerp = _m - HBM_HR_OFFSET_OWNER;
	const uint32_t *sizep = _m - HBM_HR_OFFSET_SIZE;
	const uint32_t *magicp = _p - HBM_HR_OFFSET_MAGIC;
	const uint32_t ec = arc_read_uncached_32(enqueuep);
	const uint32_t fc = arc_read_uncached_32(freep);
	const uint32_t jc = arc_read_uncached_32(jiffp);
	const uint32_t oc = arc_read_uncached_32(ownerp);
	const uint32_t sz = arc_read_uncached_32(sizep);
	const uint32_t magic = arc_read_uncached_32(magicp);
	const uint8_t *d;
	int dump_bytes;
	int i;
	uint8_t *tail;
	int tail_bytes;
	uint32_t whole_size;
	uint32_t payload_size;
	int pool;
	uint32_t idx;

	if (!topaz_hbm_buf_in_range(_p)) {
		return 0;
	}

	if (topaz_hbm_dumped_num++ >= topaz_hbm_dump_num) {
		return 0;
	}

	pool = topaz_hbm_buf_identify_buf_virt(v, &whole_size, &idx);
	if (pool < 0) {
		seq_printf(sfile, "invalid hbm buffer %x\n", (unsigned int)v);
		return 0;
	}
	payload_size = whole_size - TOPAZ_HBM_PAYLOAD_HEADROOM;

	dump_bytes = (topaz_hbm_dump_len == TOPAZ_HBM_BUF_DUMP_MAX) ? payload_size : topaz_hbm_dump_len;

	d = v;
	inv_dcache_sizerange_safe(v, dump_bytes);
	seq_printf(sfile, "%p ec %u fp %u own %08x size %u j %u (%u s ago) mg %x\n",
			v, ec, fc, oc, sz, jc, (((uint32_t) jiffies) - jc) / HZ, magic);
	for (i = 0; i < dump_bytes; ) {
		if (!(i % 32))
			seq_printf(sfile, "%08x ", (i - i % 32));
		++i;
		seq_printf(sfile, "%02x%s", *d++, (i % 32) == 0 ? "\n" : " ");
	}

	if (topaz_hbm_dump_taillen) {
		seq_printf(sfile, "\n");
		tail_bytes = topaz_hbm_dump_taillen;
		tail = (uint8_t*)((uint32_t)v + payload_size - tail_bytes);
		inv_dcache_sizerange_safe(tail, tail_bytes);
		seq_printf(sfile, "%p tail %p\n", v, tail);
		for (i = 0; i < tail_bytes; ) {
			if (!(i % 32))
				seq_printf(sfile, "%08x ", (i - i % 32));
			++i;
			seq_printf(sfile, "%02x%s", *tail++, (i % 32) == 0 ? "\n" : " ");
		}
	}
	seq_printf(sfile, "\n");

	return 0;
}

static struct seq_operations topaz_hbm_bufs_emac_seq_ops = {
	.start = topaz_hbm_bufs_emac_seq_start,
	.next  = topaz_hbm_bufs_seq_next,
	.stop  = topaz_hbm_bufs_seq_stop,
	.show  = topaz_hbm_bufs_seq_show
};

static struct seq_operations topaz_hbm_bufs_wmac_seq_ops = {
	.start = topaz_hbm_bufs_wmac_seq_start,
	.next  = topaz_hbm_bufs_seq_next,
	.stop  = topaz_hbm_bufs_seq_stop,
	.show  = topaz_hbm_bufs_seq_show
};

static int topaz_hbm_bufs_emac_proc_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &topaz_hbm_bufs_emac_seq_ops);
}

static int topaz_hbm_bufs_wmac_proc_open(struct inode *inode, struct file *file)
{
	return seq_open(file, &topaz_hbm_bufs_wmac_seq_ops);
}

static struct file_operations topaz_hbm_bufs_emac_proc_ops = {
	.owner   = THIS_MODULE,
	.open    = topaz_hbm_bufs_emac_proc_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = seq_release
};

static struct file_operations topaz_hbm_bufs_wmac_proc_ops = {
	.owner   = THIS_MODULE,
	.open    = topaz_hbm_bufs_wmac_proc_open,
	.read    = seq_read,
	.llseek  = seq_lseek,
	.release = seq_release
};

static inline int hbm_if_split_words(char **words, char *str)
{
	int word_count = 0;

	/* skip leading space */
	while (str && *str && isspace(*str)) {
		str++;
	}

	while (str && *str) {
		words[word_count++] = str;

		/* skip this word */
		while (str && *str && !isspace(*str)) {
			str++;
		}

		/* replace spaces with NULL */
		while (str && *str && isspace(*str)) {
			*str = 0;
			str++;
		}
	}

	return word_count;
}

static int hbm_if_cmd_dumpctl(char **words, uint8_t word_count)
{
	int idx = 1;

	if (word_count >= (idx + 1))
		sscanf(words[idx++], "%u", &topaz_hbm_dump_sort_type);
	if (word_count >= (idx + 1))
		sscanf(words[idx++], "0x%x", &topaz_hbm_dump_sort_range_min);
	if (word_count >= (idx + 1))
		sscanf(words[idx++], "0x%x", &topaz_hbm_dump_sort_range_max);
	if (word_count >= (idx + 1))
		sscanf(words[idx++], "%u", &topaz_hbm_dump_num);
	if (word_count >= (idx + 1))
		sscanf(words[idx++], "%u", &topaz_hbm_dump_len);
	if (word_count >= (idx + 1))
		sscanf(words[idx++], "%u", &topaz_hbm_dump_taillen);

	printk("hbm_if set dump ctl: sort_type %u sort_range [0x%x 0x%x] num %u len %u %u\n",
			topaz_hbm_dump_sort_type,
			topaz_hbm_dump_sort_range_min,
			topaz_hbm_dump_sort_range_max,
			topaz_hbm_dump_num,
			topaz_hbm_dump_len,
			topaz_hbm_dump_taillen
			);
	return 0;
}

static int hbm_if_cmd_show_stats(char **words, uint8_t word_count)
{
	int i;

	printk("HBM stats:\n");

	for (i = 0; i < HBM_CNT_NUM; i++) {
		printk("%s = %u\n", topaz_hbm_stats_names[i], topaz_hbm_stats[i]);
	}

	return 0;
}

/* Apply user command.
 * User command can control the HBM interface.
 * @param cmd_num: command number
 * @param words: the split words without spaces from the user space console interface
 * @param word_count: number of words after split
 * @return: status indication
 */
static int hbm_if_apply_user_command(hbm_if_usr_cmd cmd_num, char **words, uint8_t word_count)
{
	int rc = -EINVAL;

	if ((word_count == 0) || (!words)) {
		goto cmd_failure;
	}

	switch(cmd_num) {
		case HBM_IF_CMD_DUMPCTL:
			rc = hbm_if_cmd_dumpctl(words, word_count);
			break;
		case HBM_IF_CMD_STATS:
			rc = hbm_if_cmd_show_stats(words, word_count);
			break;
		default:
			goto cmd_failure;
			break;
	}

	if (rc < 0) {
		goto cmd_failure;
	}

	return 1;

cmd_failure:
	if (words)
		printk(KERN_INFO "Failed to parse command:%s, word count:%d\n", *words, word_count);
	else
		printk(KERN_INFO "Failed to parse command:(NULL)\n");

	return -EPERM;
}

static int hbm_if_write_proc(struct file *file, const char __user *buffer,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
		size_t count, loff_t *ppos)
#else
		unsigned long count, void *_unused)
#endif
{
	char *cmd;
	int rc, i;
	char **words;
	uint8_t word_count;
	hbm_if_usr_cmd cmd_num = 0;

	cmd = kmalloc(count, GFP_KERNEL);
	words = kmalloc(count * sizeof(char *) / 2, GFP_KERNEL);
	if (!cmd || !words) {
		rc = -ENOMEM;
		goto out;
	}

	if (copy_from_user(cmd, buffer, count)) {
		rc = -EFAULT;
		goto out;
	}

	/* Set null at last byte, note that count already gives +1 byte count*/
	cmd[count - 1] = '\0';

	word_count = hbm_if_split_words(words, cmd);
	for (i = 0; i < HBM_IF_MAX_CMD; i++, cmd_num++) {
		/* Extract command from first word */
		if (strcmp(words[0], str_cmd[i]) == 0) {
			printk(KERN_INFO"HBM user command:%s  \n", str_cmd[i]);
			break;
		}
	}

	/* Exclude softirqs whilst manipulating forwarding table */
	local_bh_disable();

	rc = hbm_if_apply_user_command(cmd_num, words, word_count);

	local_bh_enable();

	out:
	if (cmd) {
		kfree(cmd);
	}
	if (words) {
		kfree(words);
	}
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	*ppos += count;
#endif
	return count;
}

static const struct file_operations hbm_if_fops = {
        .write = hbm_if_write_proc,
};
static inline uint32_t hbm_get_rel_cnt(int pool)
{
	int master;
	uint32_t rel = 0;

	for (master = 0; master < TOPAZ_HBM_MASTER_COUNT; ++master)
		rel += readl(TOPAZ_HBM_POOL_RELEASE_CNT(master, pool));

	return rel;
}

static int topaz_hbm_pool_poll_stat(int pool, struct hbm_pool_cnt *ps)
{
	uint32_t free;
	uint32_t fdelt;
	int rc;

	free = hbm_get_rel_cnt(pool);
	fdelt = free - ps->prev_release_cnt;
	ps->prev_release_cnt = free;

	if ((topaz_hbm_pool_available(pool) < HBM_BUF_MINIMUM_AVAIL_NUM) &&
			(fdelt < HBM_BUF_MINIMUM_REL_NUM)) {
		ps->pool_depleted_cnt++;
		rc = -1;
	} else {
		ps->pool_depleted_cnt = 0;
		rc = 0;
	}

	return rc;
}

void topaz_hbm_monitor(unsigned long data)
{
	struct topaz_hbm_mnt *hm =  (struct topaz_hbm_mnt *)data;
	uint32_t uf;
	int rc;
	unsigned long intval;

	intval = HBM_BUF_POLL_L_INTRVAL;
	if (!hm->unflow_flag) {
		uf = readl(TOPAZ_HBM_UNDERFLOW_CNT);
		if (uf - hm->prev_unflow_cnt) {
			hm->unflow_flag = 1;
			hm->prev_unflow_cnt = uf;
		} else {
			goto exit;
		}
	}

	rc = topaz_hbm_pool_poll_stat(TOPAZ_HBM_BUF_WMAC_RX_POOL, &hm->wmac_pl);
	rc += topaz_hbm_pool_poll_stat(TOPAZ_HBM_BUF_EMAC_RX_POOL, &hm->emac_pl);

	if (rc == 0) {
		hm->unflow_flag = 0;
	} else {
		if ((hm->wmac_pl.pool_depleted_cnt > HBM_BUF_DEPLETION_TH) ||
			(hm->emac_pl.pool_depleted_cnt > HBM_BUF_DEPLETION_TH)) {
			panic("HBM pool is depleted, wmac pool:%u, emac rx pool:%u\n",
				topaz_hbm_pool_available(TOPAZ_HBM_BUF_WMAC_RX_POOL),
				topaz_hbm_pool_available(TOPAZ_HBM_BUF_EMAC_RX_POOL));
		}
		intval = HBM_BUF_POLL_S_INTRVAL;
	}
exit:
	mod_timer(&hbm_timer, jiffies + intval);
}

static int __init topaz_hbm_bufs_init(void)
{
	struct topaz_hbm_mnt *hm;
	struct proc_dir_entry *e;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	e = proc_create("hbm_bufs_emac", 0x444, NULL, &topaz_hbm_bufs_emac_proc_ops);
	if (!e)
		goto error4;

	e = proc_create("hbm_bufs_wmac", 0x444, NULL, &topaz_hbm_bufs_wmac_proc_ops);
	if (!e)
		goto error3;

	e = proc_create(TOPAZ_HBM_IF_PROC_NAME, 0x444, NULL, &hbm_if_fops);
	if (!e)
		goto error2;

	hm =  (struct topaz_hbm_mnt *)kzalloc(sizeof(*hm), GFP_KERNEL);
	if (!hm)
		goto error1;


#else
	if ((e = create_proc_entry("hbm_bufs_emac", 0, NULL)) != NULL) {
		e->proc_fops = &topaz_hbm_bufs_emac_proc_ops;
	}

	if ((e = create_proc_entry("hbm_bufs_wmac", 0, NULL)) != NULL) {
		e->proc_fops = &topaz_hbm_bufs_wmac_proc_ops;
	}

	struct proc_dir_entry *entry = create_proc_entry(TOPAZ_HBM_IF_PROC_NAME, 0600, NULL);
	if (entry) {
		entry->write_proc = hbm_if_write_proc;
		entry->read_proc = NULL;
	}

	hm =  (struct topaz_hbm_mnt *)kzalloc(sizeof(*hm), GFP_KERNEL);
	if (!hm) {
		printk(KERN_ERR"%s: fail to allocate hm", __func__);
		return -1;
	}
#endif

	init_timer(&hbm_timer);
	hbm_timer.data = (unsigned long)hm;
	hbm_timer.function = &topaz_hbm_monitor;
	mod_timer(&hbm_timer, jiffies + HBM_BUF_POLL_L_INTRVAL);

	return 0;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
error1:
	remove_proc_entry(TOPAZ_HBM_IF_PROC_NAME, 0);
error2:
	remove_proc_entry("hbm_bufs_wmac", 0);
error3:
	remove_proc_entry("hbm_bufs_emac", 0);
error4:
	return -1;
#endif
}

static void __exit topaz_hbm_bufs_exit(void)
{
	remove_proc_entry("hbm_bufs_wmac", 0);
	remove_proc_entry("hbm_bufs_emac", 0);
	remove_proc_entry(TOPAZ_HBM_IF_PROC_NAME, NULL);

	del_timer(&hbm_timer);
	if (hbm_timer.data)
		kfree((void *)hbm_timer.data);
}

static int __init topaz_hbm_module_init(void)
{
	COMPILE_TIME_ASSERT(TOPAZ_HBM_BUF_META_SIZE >= (HBM_HR_OFFSET_MAX * 4));

	topaz_hbm_init_payload_pools();

	shinfo_cache = kmem_cache_create("topaz_skb_shinfo_cache",
			sizeof(struct skb_shared_info),
			0,
			SLAB_HWCACHE_ALIGN | SLAB_PANIC,
			NULL);

	skb_allocator_register(TOPAZ_HBM_SKB_ALLOCATOR, &topaz_hbm_skb_allocator, 0);

	topaz_hbm_stat_init();
	topaz_hbm_bufs_init();

	return 0;
}
module_init(topaz_hbm_module_init)

static void __exit topaz_hbm_module_exit(void)
{
	topaz_hbm_stat_exit();
	topaz_hbm_bufs_exit();
}
module_exit(topaz_hbm_module_exit)


