/*
 * Copyright (C) 2012-2017 ARM Limited or its affiliates.
 * 
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 * 
 * 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, see <http://www.gnu.org/licenses/>.
 */

#include <linux/kernel.h>
#include "ssi_config.h"
#include "ssi_driver.h"
#include "cc_crypto_ctx.h"
#include "ssi_sysfs.h"

#ifdef ENABLE_CC_SYSFS

static struct ssi_drvdata *sys_get_drvdata(void);

#ifdef CC_CYCLE_COUNT

#include <asm/timex.h>

struct stat_item {
	unsigned int min;
	unsigned int max;
	cycles_t sum;
	unsigned int count;
};

struct stat_name {
	const char *op_type_name;
	const char *stat_phase_name[MAX_STAT_PHASES];
};

static struct stat_name stat_name_db[MAX_STAT_OP_TYPES] = 
{
	{
		/* STAT_OP_TYPE_NULL */
		.op_type_name = "NULL",
		.stat_phase_name = {NULL},
	},
	{
		.op_type_name = "Encode",
		.stat_phase_name[STAT_PHASE_0] = "Init and sanity checks",
		.stat_phase_name[STAT_PHASE_1] = "Map buffers", 
		.stat_phase_name[STAT_PHASE_2] = "Create sequence", 
		.stat_phase_name[STAT_PHASE_3] = "Send Request",
		.stat_phase_name[STAT_PHASE_4] = "HW-Q push",
		.stat_phase_name[STAT_PHASE_5] = "Sequence completion",
		.stat_phase_name[STAT_PHASE_6] = "HW cycles",
	},
	{	.op_type_name = "Decode",
		.stat_phase_name[STAT_PHASE_0] = "Init and sanity checks",
		.stat_phase_name[STAT_PHASE_1] = "Map buffers", 
		.stat_phase_name[STAT_PHASE_2] = "Create sequence", 
		.stat_phase_name[STAT_PHASE_3] = "Send Request",
		.stat_phase_name[STAT_PHASE_4] = "HW-Q push",
		.stat_phase_name[STAT_PHASE_5] = "Sequence completion",
		.stat_phase_name[STAT_PHASE_6] = "HW cycles",
	},
	{ 	.op_type_name = "Setkey",
		.stat_phase_name[STAT_PHASE_0] = "Init and sanity checks",
		.stat_phase_name[STAT_PHASE_1] = "Copy key to ctx",
		.stat_phase_name[STAT_PHASE_2] = "Create sequence",
		.stat_phase_name[STAT_PHASE_3] = "Send Request",
		.stat_phase_name[STAT_PHASE_4] = "HW-Q push",
		.stat_phase_name[STAT_PHASE_5] = "Sequence completion",
		.stat_phase_name[STAT_PHASE_6] = "HW cycles",
	},
	{
		.op_type_name = "Generic",
		.stat_phase_name[STAT_PHASE_0] = "Interrupt",
		.stat_phase_name[STAT_PHASE_1] = "ISR-to-Tasklet",
		.stat_phase_name[STAT_PHASE_2] = "Tasklet start-to-end",
		.stat_phase_name[STAT_PHASE_3] = "Tasklet:user_cb()",
		.stat_phase_name[STAT_PHASE_4] = "Tasklet:dx_X_complete() - w/o X_complete()",
		.stat_phase_name[STAT_PHASE_5] = "",
		.stat_phase_name[STAT_PHASE_6] = "HW cycles",
	}
};

/*
 * Structure used to create a directory 
 * and its attributes in sysfs.
 */
struct sys_dir {
	struct kobject *sys_dir_kobj;
	struct attribute_group sys_dir_attr_group;
	struct attribute **sys_dir_attr_list;
	uint32_t num_of_attrs;
	struct ssi_drvdata *drvdata; /* Associated driver context */
};

/* top level directory structures */
struct sys_dir sys_top_dir;

static DEFINE_SPINLOCK(stat_lock);

/* List of DBs */
static struct stat_item stat_host_db[MAX_STAT_OP_TYPES][MAX_STAT_PHASES];
static struct stat_item stat_cc_db[MAX_STAT_OP_TYPES][MAX_STAT_PHASES];


static void init_db(struct stat_item item[MAX_STAT_OP_TYPES][MAX_STAT_PHASES])
{
	unsigned int i, j;

	/* Clear db */
	for (i=0; i<MAX_STAT_OP_TYPES; i++) {
		for (j=0; j<MAX_STAT_PHASES; j++) {
			item[i][j].min = 0xFFFFFFFF;
			item[i][j].max = 0;
			item[i][j].sum = 0;
			item[i][j].count = 0;
		}
	}
}

static void update_db(struct stat_item *item, unsigned int result)
{
	item->count++;
	item->sum += result;
	if (result < item->min)
		item->min = result;
	if (result > item->max )
		item->max = result;
}

static void display_db(struct stat_item item[MAX_STAT_OP_TYPES][MAX_STAT_PHASES])
{
	unsigned int i, j;
	uint64_t avg;

	for (i=STAT_OP_TYPE_ENCODE; i<MAX_STAT_OP_TYPES; i++) {
		for (j=0; j<MAX_STAT_PHASES; j++) {	
			if (item[i][j].count > 0) {
				avg = (uint64_t)item[i][j].sum;
				do_div(avg, item[i][j].count);
				SSI_LOG_ERR("%s, %s: min=%d avg=%d max=%d sum=%lld count=%d\n", 
					stat_name_db[i].op_type_name, stat_name_db[i].stat_phase_name[j], 
					item[i][j].min, (int)avg, item[i][j].max, (long long)item[i][j].sum, item[i][j].count);
			}
		}
	}
}


/**************************************
 * Attributes show functions section  *
 **************************************/

static ssize_t ssi_sys_stats_host_db_clear(struct kobject *kobj,
	struct kobj_attribute *attr, const char *buf, size_t count)
{
	init_db(stat_host_db);
	return count;
}

static ssize_t ssi_sys_stats_cc_db_clear(struct kobject *kobj,
	struct kobj_attribute *attr, const char *buf, size_t count)
{
	init_db(stat_cc_db);
	return count;
}

static ssize_t ssi_sys_stat_host_db_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	int i, j ;
	char line[512];
	uint32_t min_cyc, max_cyc;
	uint64_t avg;
	ssize_t buf_len, tmp_len=0;

	buf_len = scnprintf(buf,PAGE_SIZE,
		"phase\t\t\t\t\t\t\tmin[cy]\tavg[cy]\tmax[cy]\t#samples\n");
	if ( buf_len <0 )/* scnprintf shouldn't return negative value according to its implementation*/
		return buf_len;
	for (i=STAT_OP_TYPE_ENCODE; i<MAX_STAT_OP_TYPES; i++) {
		for (j=0; j<MAX_STAT_PHASES-1; j++) {
			if (stat_host_db[i][j].count > 0) {
				avg = (uint64_t)stat_host_db[i][j].sum;
				do_div(avg, stat_host_db[i][j].count);
				min_cyc = stat_host_db[i][j].min;
				max_cyc = stat_host_db[i][j].max;
			} else {
				avg = min_cyc = max_cyc = 0;
			}
			tmp_len = scnprintf(line,512,
				"%s::%s\t\t\t\t\t%6u\t%6u\t%6u\t%7u\n",
				stat_name_db[i].op_type_name,
				stat_name_db[i].stat_phase_name[j],
				min_cyc, (unsigned int)avg, max_cyc,
				stat_host_db[i][j].count);
			if ( tmp_len <0 )/* scnprintf shouldn't return negative value according to its implementation*/
				return buf_len;
			if ( buf_len + tmp_len >= PAGE_SIZE)
				return buf_len;
			buf_len += tmp_len;
			strncat(buf, line,512);
		}
	}
	return buf_len;
}

static ssize_t ssi_sys_stat_cc_db_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	int i;
	char line[256];
	uint32_t min_cyc, max_cyc;
	uint64_t avg;
	ssize_t buf_len,tmp_len=0;

	buf_len = scnprintf(buf,PAGE_SIZE,
		"phase\tmin[cy]\tavg[cy]\tmax[cy]\t#samples\n");
	if ( buf_len <0 )/* scnprintf shouldn't return negative value according to its implementation*/
		return buf_len;
	for (i=STAT_OP_TYPE_ENCODE; i<MAX_STAT_OP_TYPES; i++) {
		if (stat_cc_db[i][STAT_PHASE_6].count > 0) {
			avg = (uint64_t)stat_cc_db[i][STAT_PHASE_6].sum;
			do_div(avg, stat_cc_db[i][STAT_PHASE_6].count);
			min_cyc = stat_cc_db[i][STAT_PHASE_6].min;
			max_cyc = stat_cc_db[i][STAT_PHASE_6].max;
		} else {
			avg = min_cyc = max_cyc = 0;
		}
		tmp_len = scnprintf(line,256,
			"%s\t%6u\t%6u\t%6u\t%7u\n",
			stat_name_db[i].op_type_name,
			min_cyc,
			(unsigned int)avg,
			max_cyc,
			stat_cc_db[i][STAT_PHASE_6].count);

		if ( tmp_len < 0 )/* scnprintf shouldn't return negative value according to its implementation*/
			return buf_len;

		if ( buf_len + tmp_len >= PAGE_SIZE)
			return buf_len;
		buf_len += tmp_len;
		strncat(buf, line,256);
	}
	return buf_len;
}

void update_host_stat(unsigned int op_type, unsigned int phase, cycles_t result)
{
	unsigned long flags;

	spin_lock_irqsave(&stat_lock, flags);
	update_db(&(stat_host_db[op_type][phase]), (unsigned int)result);
	spin_unlock_irqrestore(&stat_lock, flags);
}

void update_cc_stat(
	unsigned int op_type,
	unsigned int phase,
	unsigned int elapsed_cycles)
{
	update_db(&(stat_cc_db[op_type][phase]), elapsed_cycles);
}

void display_all_stat_db(void)
{
	SSI_LOG_ERR("\n=======    CYCLE COUNT STATS    =======\n"); 
	display_db(stat_host_db);
	SSI_LOG_ERR("\n======= CC HW CYCLE COUNT STATS =======\n"); 
	display_db(stat_cc_db);
}
#endif /*CC_CYCLE_COUNT*/



static ssize_t ssi_sys_regdump_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	struct ssi_drvdata *drvdata = sys_get_drvdata();
	uint32_t register_value;
	void __iomem* cc_base = drvdata->cc_base;
	int offset = 0;

	register_value = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_SIGNATURE));
	offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X  \n", "HOST_SIGNATURE       ", DX_HOST_SIGNATURE_REG_OFFSET, register_value);
	register_value = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_IRR));
	offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X  \n", "HOST_IRR             ", DX_HOST_IRR_REG_OFFSET, register_value);
	register_value = CC_HAL_READ_REGISTER(CC_REG_OFFSET(HOST_RGF, HOST_POWER_DOWN_EN));
	offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X  \n", "HOST_POWER_DOWN_EN   ", DX_HOST_POWER_DOWN_EN_REG_OFFSET, register_value);
	register_value =  CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, AXIM_MON_ERR));
	offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X  \n", "AXIM_MON_ERR         ", DX_AXIM_MON_ERR_REG_OFFSET, register_value);
	register_value = CC_HAL_READ_REGISTER(CC_REG_OFFSET(CRY_KERNEL, DSCRPTR_QUEUE_CONTENT));
	offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s \t(0x%lX)\t 0x%08X  \n", "DSCRPTR_QUEUE_CONTENT", DX_DSCRPTR_QUEUE_CONTENT_REG_OFFSET, register_value);
	return offset;
}

static ssize_t ssi_sys_help_show(struct kobject *kobj,
		struct kobj_attribute *attr, char *buf)
{
	char* help_str[]={
				"cat reg_dump              ", "Print several of CC register values",
		#if defined CC_CYCLE_COUNT
				"cat stats_host            ", "Print host statistics",
				"echo <number> > stats_host", "Clear host statistics database",
				"cat stats_cc              ", "Print CC statistics",
				"echo <number> > stats_cc  ", "Clear CC statistics database",
		#endif
				};
	int i=0, offset = 0;

	offset += scnprintf(buf + offset, PAGE_SIZE - offset, "Usage:\n");
	for ( i = 0; i < ARRAY_SIZE(help_str); i+=2) {
	   offset += scnprintf(buf + offset, PAGE_SIZE - offset, "%s\t\t%s\n", help_str[i], help_str[i+1]);
	}
	return offset;
}

/********************************************************
 *		SYSFS objects				*
 ********************************************************/
/*
 * Structure used to create a directory
 * and its attributes in sysfs.
 */
struct sys_dir {
	struct kobject *sys_dir_kobj;
	struct attribute_group sys_dir_attr_group;
	struct attribute **sys_dir_attr_list;
	uint32_t num_of_attrs;
	struct ssi_drvdata *drvdata; /* Associated driver context */
};

/* top level directory structures */
static struct sys_dir sys_top_dir;

/* TOP LEVEL ATTRIBUTES */
static struct kobj_attribute ssi_sys_top_level_attrs[] = {
	__ATTR(dump_regs, 0444, ssi_sys_regdump_show, NULL),
	__ATTR(help, 0444, ssi_sys_help_show, NULL),
#if defined CC_CYCLE_COUNT
	__ATTR(stats_host, 0664, ssi_sys_stat_host_db_show, ssi_sys_stats_host_db_clear),
	__ATTR(stats_cc, 0664, ssi_sys_stat_cc_db_show, ssi_sys_stats_cc_db_clear),
#endif

};

static struct ssi_drvdata *sys_get_drvdata(void)
{
	/* TODO: supporting multiple SeP devices would require avoiding
	 * global "top_dir" and finding associated "top_dir" by traversing
	 * up the tree to the kobject which matches one of the top_dir's */
	return sys_top_dir.drvdata;
}

static int sys_init_dir(struct sys_dir *sys_dir, struct ssi_drvdata *drvdata,
		 struct kobject *parent_dir_kobj, const char *dir_name,
		 struct kobj_attribute *attrs, uint32_t num_of_attrs)
{
	int i;

	memset(sys_dir, 0, sizeof(struct sys_dir));

	sys_dir->drvdata = drvdata;

	/* initialize directory kobject */
	sys_dir->sys_dir_kobj =
		kobject_create_and_add(dir_name, parent_dir_kobj);

	if (!(sys_dir->sys_dir_kobj))
		return -ENOMEM;
	/* allocate memory for directory's attributes list */
	sys_dir->sys_dir_attr_list =
		kzalloc(sizeof(struct attribute *) * (num_of_attrs + 1),
				GFP_KERNEL);

	if (!(sys_dir->sys_dir_attr_list)) {
		kobject_put(sys_dir->sys_dir_kobj);
		return -ENOMEM;
	}

	sys_dir->num_of_attrs = num_of_attrs;

	/* initialize attributes list */
	for (i = 0; i < num_of_attrs; ++i)
		sys_dir->sys_dir_attr_list[i] = &(attrs[i].attr);

	/* last list entry should be NULL */
	sys_dir->sys_dir_attr_list[num_of_attrs] = NULL;

	sys_dir->sys_dir_attr_group.attrs = sys_dir->sys_dir_attr_list;

	return sysfs_create_group(sys_dir->sys_dir_kobj,
			&(sys_dir->sys_dir_attr_group));
}

static void sys_free_dir(struct sys_dir *sys_dir)
{
	if (!sys_dir)
		return;

	kfree(sys_dir->sys_dir_attr_list);

	if (sys_dir->sys_dir_kobj != NULL)
		kobject_put(sys_dir->sys_dir_kobj);
}

int ssi_sysfs_init(struct kobject *sys_dev_obj, struct ssi_drvdata *drvdata)
{
	int retval;

#if defined CC_CYCLE_COUNT
	/* Init. statistics */
	init_db(stat_host_db);
	init_db(stat_cc_db);
#endif

	SSI_LOG_ERR("setup sysfs under %s\n", sys_dev_obj->name);

	/* Initialize top directory */
	retval = sys_init_dir(&sys_top_dir, drvdata, sys_dev_obj,
				"cc_info", ssi_sys_top_level_attrs,
				ARRAY_SIZE(ssi_sys_top_level_attrs));
	return retval;
}

void ssi_sysfs_fini(void)
{
	sys_free_dir(&sys_top_dir);
}

#endif /*ENABLE_CC_SYSFS*/

