#include "../include/phynand.h"
#ifndef AML_NAND_UBOOT
#include <linux/module.h>
#include <linux/types.h>
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/bitops.h>
#include <linux/crc32.h>
#include <linux/fs.h>
#include <asm/uaccess.h>
#include <linux/amlogic/securitykey.h>
#endif

extern int amlnand_read_info_by_name(struct amlnand_chip *aml_chip,u8 * info,u8 * buf, u8 * name,unsigned size);
extern int amlnand_save_info_by_name(struct amlnand_chip *aml_chip,u8 * info,u8 * buf, u8 * name,unsigned size);
extern int amlnand_info_init(struct amlnand_chip *aml_chip, u8 * info,u8 * buf, u8 *name,unsigned size);

//#define KEYSIZE (CONFIG_KEYSIZE - (sizeof(uint32_t)))

static struct amlnand_chip *aml_chip_key = NULL;

 int aml_nand_update_key(struct amlnand_chip * aml_chip, char *key_ptr)
{
	int ret = 0;
	int malloc_flag = 0;
	char *key_buf = NULL;
	struct nand_flash *flash = &aml_chip->flash;

	if (key_buf == NULL) {

		key_buf = kzalloc(CONFIG_KEYSIZE + flash->pagesize, GFP_KERNEL);
		malloc_flag = 1;
		if (key_buf == NULL)
			return -ENOMEM;
		memset(key_buf,0,CONFIG_KEYSIZE);
		ret = amlnand_read_info_by_name(aml_chip, (u8 *)&(aml_chip->nand_key),(u8 *)key_buf,(u8 *)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE);
		if (ret) {
			aml_nand_msg("read key error,%s\n",__func__);
			ret = -EFAULT;
			goto exit;
		}
	}else{
		key_buf = key_ptr;
	}

	aml_nand_msg("aml_chip->nand_key : arg_type%d valid %d,update_flag %d,valid_blk_addr %d,valid_page_addr %d",aml_chip->nand_key.arg_type,aml_chip->nand_key.arg_valid,\
		aml_chip->nand_key.update_flag,aml_chip->nand_key.valid_blk_addr,aml_chip->nand_key.valid_page_addr);

	ret = amlnand_save_info_by_name( aml_chip,(u8 *)&(aml_chip->nand_key),(u8 *)key_buf, (u8 *)KEY_INFO_HEAD_MAGIC,CONFIG_KEYSIZE);
	if (ret < 0) {
		aml_nand_msg("aml_nand_update_key : save key info failed");
	}

exit:
	if (malloc_flag &&(key_buf)) {
		kfree(key_buf);
		key_buf = NULL;
	}
	return 0;
}

/*
 * This funcion reads the u-boot keyionment variables.
 * The f_pos points directly to the key location.
 */
static int nand_key_read(struct aml_keybox_provider_s * provider, u8 * buf, int len, int flags)
{
	struct amlnand_chip * aml_chip = provider->priv;
	struct nand_menson_key *key_ptr = NULL;
	//int error = 0,i=0;
	int error = 0;
	if (len > CONFIG_KEYSIZE)
	{
		printk("key data len too much,%s\n",__func__);
		return -EFAULT;
	}
	key_ptr = kzalloc(CONFIG_KEYSIZE, GFP_KERNEL);
	if (key_ptr == NULL)
		return -ENOMEM;
	memset(key_ptr, 0, CONFIG_KEYSIZE);

	error = amlnand_read_info_by_name(aml_chip, (u8 *)&(aml_chip->nand_key), (u8 *)key_ptr, (u8*)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE);
	//error = aml_nand_read_key(aml_chip, (u_char *)key_ptr);
	if (error)
	{
		printk("read key error,%s\n",__func__);
		error = -EFAULT;
		goto exit;
	}
	memcpy(buf, key_ptr->data, len);

exit:
	kfree(key_ptr);
	return 0;
}

static int nand_key_write(struct aml_keybox_provider_s * provider, u8 *buf,int len)
{
	struct amlnand_chip * aml_chip = provider->priv;
	struct nand_menson_key *key_ptr = NULL;
	//int error = 0,i=0;
	int error = 0;
	struct nand_flash *flash = &aml_chip_key->flash;

	if (len > CONFIG_KEYSIZE)
	{
		printk("key data len too much,%s\n",__func__);
		return -EFAULT;
	}
	key_ptr = kzalloc(CONFIG_KEYSIZE + flash->pagesize, GFP_KERNEL);
	if (key_ptr == NULL)
		return -ENOMEM;
	memset(key_ptr,0,CONFIG_KEYSIZE);
	memcpy(key_ptr->data + 0, buf, len);

	error = amlnand_save_info_by_name(aml_chip, (u8 *)&(aml_chip->nand_key),(u8 *)key_ptr,(u8 *)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE);
	if (error)
	{
		printk("save key error,%s\n",__func__);
		error = -EFAULT;
		goto exit;
	}
exit:
	kfree(key_ptr);
	return error;
}

static struct aml_keybox_provider_s nand_provider={
	.name="nand_key",
	.read=nand_key_read,
	.write=nand_key_write,
};

int aml_key_init(struct amlnand_chip *aml_chip)
{
	int ret = 0;
	struct nand_menson_key *key_ptr = NULL;
	struct aml_keybox_provider_s * provider;

	key_ptr = aml_nand_malloc(CONFIG_KEYSIZE);
	if (key_ptr == NULL) {
		aml_nand_msg("nand malloc for key_ptr failed");
		ret = -1;
		goto exit_error0;
	}
	memset(key_ptr,0x0,CONFIG_KEYSIZE);
	aml_nand_msg("nand key: nand_key_probe. ");

	ret = amlnand_info_init(aml_chip, (u8 *)&(aml_chip->nand_key),(u8 *)key_ptr,(u8 *)KEY_INFO_HEAD_MAGIC, CONFIG_KEYSIZE);
	if (ret < 0) {
		aml_nand_msg("invalid nand key\n");
	}

	aml_chip_key = aml_chip;
	nand_provider.priv=aml_chip_key;

	provider = aml_keybox_provider_get(nand_provider.name);
	if (provider) {
		return ret;
	}

	ret = aml_keybox_provider_register(&nand_provider);
	if (ret) {
		BUG();
	}

exit_error0:
	if (key_ptr) {
		aml_nand_free(key_ptr);
		key_ptr =NULL;
	}
	return ret;
}
#ifdef AML_NAND_UBOOT
int nandkey_provider_register(void)
{
	int ret = 0;
#if 0
	ret = aml_keybox_provider_register(&nand_provider);
	if (ret) {
		BUG();
	}
#endif
	return ret;
}
#endif

