/*
 * Copyright (c) 2011 Quantenna Communications, Inc.
 * All rights reserved.
 *
 * Bootcfg store through mtd driver (flash partitions)
 *
 * 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 **/

#include "bootcfg_drv.h"
#include "bootcfg_store_init.h"

#include <qtn/bootcfg.h>
#include <common/ruby_partitions.h>
#include <common/ruby_version.h>

#include <linux/mtd/mtd.h>
#include <linux/sched.h>

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
#include <linux/spinlock_types.h>
#endif

#define UBOOT_MTD_DEVICE	0
#define BOOTCFG_MTD_DEVICE	1

static struct cfg_data_t {
	spinlock_t	lock;
	struct mtd_info *mtd;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
} cfg_data = {  __SPIN_LOCK_UNLOCKED((worker).lock), NULL };
#else
} cfg_data = { SPIN_LOCK_UNLOCKED, NULL };
#endif

static void erase_callback(struct erase_info *done)
{
	wait_queue_head_t *wait_q = (wait_queue_head_t *) done->priv;
	wake_up(wait_q);
}

static int bootcfg_flash_write(struct bootcfg_store_ops *ops, const void *buf, const size_t bytes)
{
	size_t bytes_written;
	struct erase_info erase;
	DECLARE_WAITQUEUE(wait, current);
	wait_queue_head_t wait_q;
	size_t erase_size;
	int ret = 0;

	spin_lock(&cfg_data.lock);

	if (cfg_data.mtd == NULL) {
		ret = -ENODEV;
		goto out;
	}

	erase_size = bytes + (cfg_data.mtd->erasesize - 1);
	erase_size = erase_size - (erase_size % cfg_data.mtd->erasesize);

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	if (cfg_data.mtd->_unlock && cfg_data.mtd->_unlock(cfg_data.mtd, 0, erase_size)) {
#else
	if (cfg_data.mtd->unlock && cfg_data.mtd->unlock(cfg_data.mtd, 0, erase_size)) {
#endif
		printk("bootcfg: %s unlock failed\n", cfg_data.mtd->name);
		ret = -ENOLCK;
		goto out;
	}

	init_waitqueue_head(&wait_q);
	set_current_state(TASK_INTERRUPTIBLE);
	add_wait_queue(&wait_q, &wait);

	memset(&erase, 0, sizeof(struct erase_info));
	erase.mtd = cfg_data.mtd;
	erase.callback = erase_callback;
	erase.addr = 0;
	erase.len = erase_size;
	erase.priv = (u_long) & wait_q;

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	ret = cfg_data.mtd->_erase(cfg_data.mtd, &erase);
#else
	ret = cfg_data.mtd->erase(cfg_data.mtd, &erase);
#endif
	if (ret) {
		set_current_state(TASK_RUNNING);
		remove_wait_queue(&wait_q, &wait);
		printk(KERN_WARNING "bootcfg: erase of region [0x%x, 0x%x] "
		       "on \"%s\" failed\n",
		       (unsigned)erase.addr, (unsigned)erase.len, cfg_data.mtd->name);
		ret = -EIO;
		goto out;
	}

	schedule();		/* Wait for erase to finish. */
	remove_wait_queue(&wait_q, &wait);

	/* write to device */
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	if (cfg_data.mtd->_write(cfg_data.mtd, 0, bytes, &bytes_written, buf)) {
#else
	if (cfg_data.mtd->write(cfg_data.mtd, 0, bytes, &bytes_written, buf)) {
#endif
		printk("bootcfg: could not write device\n");
		ret = -EIO;
		goto out;
	}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	if (cfg_data.mtd->_lock && cfg_data.mtd->_lock(cfg_data.mtd, 0, erase_size)) {
#else
	if (cfg_data.mtd->lock && cfg_data.mtd->lock(cfg_data.mtd, 0, erase_size)) {
#endif
		printk("bootcfg: could not lock device\n");
		ret = -ENOLCK;
	}
out:
	spin_unlock(&cfg_data.lock);
	return ret;
}

#define VERSION_STR_SIZE 16

static int bootcfg_flash_read(struct bootcfg_store_ops *ops, void *buf, const size_t bytes)
{
	size_t bytes_read;
	int ret = 0;

	spin_lock(&cfg_data.lock);

	if (cfg_data.mtd == NULL) {
		ret = -ENODEV;
		goto out;
	}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	ret = cfg_data.mtd->_read(cfg_data.mtd, 0, bytes, &bytes_read, buf);
#else
	ret = cfg_data.mtd->read(cfg_data.mtd, 0, bytes, &bytes_read, buf);
#endif
	if (ret) {
		goto out;
	}

	if (bytes_read != bytes) {
		ret = -ENODATA;
	}
out:
	spin_unlock(&cfg_data.lock);
	return ret;

}

int __init bootcfg_flash_init(struct bootcfg_store_ops *ops, size_t *store_limit)
{
	struct mtd_info *mtd;
	uint8_t version[VERSION_STR_SIZE];
	size_t version_bytes;
	int ret = 0;

	spin_lock(&cfg_data.lock);

	mtd = get_mtd_device(NULL, UBOOT_MTD_DEVICE);
	if (mtd == NULL) {
		printk(KERN_ERR "%s: Could not get flash device mtd%d\n",
				__FUNCTION__, UBOOT_MTD_DEVICE);
		ret = -ENODEV;
		goto out;
	}

	cfg_data.mtd = get_mtd_device(NULL, BOOTCFG_MTD_DEVICE);
	if (cfg_data.mtd == NULL) {
		printk(KERN_ERR "Could not get flash device mtd%d\n", BOOTCFG_MTD_DEVICE);
		ret = -ENODEV;
		goto out;
	}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	if (mtd->_read(mtd, 4, VERSION_STR_SIZE, &version_bytes, version)) {
#else
	if (mtd->read(mtd, 4, VERSION_STR_SIZE, &version_bytes, version)) {
#endif
		ret = -EIO;
		put_mtd_device(cfg_data.mtd);
		cfg_data.mtd = NULL;
		goto out;
	}

	*store_limit = cfg_data.mtd->size;
	/* here we need to figure out version to be backward compatible */
	/* version previous to 1.1.2 do not have U_BOOT tag at fixed location */
	/* also note this will not work for umsdl uboot, must be set to boot from flash */
	/* we only check for presense of the string to make sure we are > U-boot 1.1.1 */
	/* Hardwired the string here since the global version string was modified */
	if (memcmp(version, "U-BOOT", 6) != 0) {
		printk(KERN_WARNING "%s: warning, detected old U-BOOT.  bootcfg data size limited to 4k\n",
				__FUNCTION__);
		/* size here is 4k env, 4k data */
		*store_limit = 8192;
	}

out:
	if (mtd)
		put_mtd_device(mtd);
	spin_unlock(&cfg_data.lock);
	return ret;
}

void __exit bootcfg_flash_exit(struct bootcfg_store_ops *ops)
{
	if (cfg_data.mtd)
		put_mtd_device(cfg_data.mtd);
}

static struct bootcfg_store_ops flash_store_ops = {
	.read	= bootcfg_flash_read,
	.write	= bootcfg_flash_write,
	.init	= bootcfg_flash_init,
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,7,0)
	.exit	= bootcfg_flash_exit,
#else
	.exit	= __devexit_p(bootcfg_flash_exit),
#endif
};

struct bootcfg_store_ops *__init bootcfg_flash_get_ops(void)
{
	return &flash_store_ops;
}

