/*
 * Copyright (c) 2012 GCT Semiconductor, Inc. All rights reserved.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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.
 */

#include <linux/uaccess.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/usb.h>
#include <linux/unistd.h>
#include <linux/slab.h>
#include <linux/firmware.h>

#include <asm/byteorder.h>
#include "gdm_usb.h"
#include "usb_boot.h"

#define DN_KERNEL_MAGIC_NUMBER	0x10760001
#define DN_ROOTFS_MAGIC_NUMBER	0x10760002

#define DOWNLOAD_SIZE		1024

#define MAX_IMG_CNT		16
#define FW_DIR			"gdm72xx/"
#define FW_UIMG			"gdmuimg.bin"
#define FW_KERN			"zImage"
#define FW_FS			"ramdisk.jffs2"

struct dn_header {
	u32	magic_num;
	u32	file_size;
};

struct img_header {
	u32	magic_code;
	u32	count;
	u32	len;
	u32	offset[MAX_IMG_CNT];
	char	hostname[32];
	char	date[32];
};

struct fw_info {
	u32	id;
	u32	len;
	u32	kernel_len;
	u32	rootfs_len;
	u32	kernel_offset;
	u32	rootfs_offset;
	u32	fw_ver;
	u32	mac_ver;
	char	hostname[32];
	char	userid[16];
	char	date[32];
	char	user_desc[128];
};

static void array_le32_to_cpu(u32 *arr, int num)
{
	int i;
	for (i = 0; i < num; i++, arr++)
		*arr = __le32_to_cpu(*arr);
}

static u8 *tx_buf;

static int gdm_wibro_send(struct usb_device *usbdev, void *data, int len)
{
	int ret;
	int actual;

	ret = usb_bulk_msg(usbdev, usb_sndbulkpipe(usbdev, 1), data, len,
			&actual, 1000);

	if (ret < 0) {
		printk(KERN_ERR "Error : usb_bulk_msg ( result = %d )\n", ret);
		return ret;
	}
	return 0;
}

static int gdm_wibro_recv(struct usb_device *usbdev, void *data, int len)
{
	int ret;
	int actual;

	ret = usb_bulk_msg(usbdev, usb_rcvbulkpipe(usbdev, 2), data, len,
			&actual, 5000);

	if (ret < 0) {
		printk(KERN_ERR "Error : usb_bulk_msg(recv) ( result = %d )\n",
			ret);
		return ret;
	}
	return 0;
}

static int download_image(struct usb_device *usbdev,
				const struct firmware *firm,
				loff_t pos, u32 img_len, u32 magic_num)
{
	struct dn_header h;
	int ret = 0;
	u32 size;

	size = ALIGN(img_len, DOWNLOAD_SIZE);
	h.magic_num = __cpu_to_be32(magic_num);
	h.file_size = __cpu_to_be32(size);

	ret = gdm_wibro_send(usbdev, &h, sizeof(h));
	if (ret < 0)
		return ret;

	while (img_len > 0) {
		if (img_len > DOWNLOAD_SIZE)
			size = DOWNLOAD_SIZE;
		else
			size = img_len;	/* the last chunk of data */

		memcpy(tx_buf, firm->data + pos, size);
		ret = gdm_wibro_send(usbdev, tx_buf, size);

		if (ret < 0)
			return ret;

		img_len -= size;
		pos += size;
	}

	return ret;
}

int usb_boot(struct usb_device *usbdev, u16 pid)
{
	int i, ret = 0;
	struct img_header hdr;
	struct fw_info fw_info;
	loff_t pos = 0;
	char *img_name = FW_DIR FW_UIMG;
	const struct firmware *firm;

	ret = request_firmware(&firm, img_name, &usbdev->dev);
	if (ret < 0) {
		printk(KERN_ERR
		       "requesting firmware %s failed with error %d\n",
			img_name, ret);
		return ret;
	}

	tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL);
	if (tx_buf == NULL) {
		printk(KERN_ERR "Error: kmalloc\n");
		return -ENOMEM;
	}

	if (firm->size < sizeof(hdr)) {
		printk(KERN_ERR "gdmwm: Cannot read the image info.\n");
		ret = -EIO;
		goto out;
	}
	memcpy(&hdr, firm->data, sizeof(hdr));

	array_le32_to_cpu((u32 *)&hdr, 19);
#if 0
	if (hdr.magic_code != 0x10767fff) {
		printk(KERN_ERR "gdmwm: Invalid magic code 0x%08x\n",
			hdr.magic_code);
		ret = -EINVAL;
		goto out;
	}
#endif
	if (hdr.count > MAX_IMG_CNT) {
		printk(KERN_ERR "gdmwm: Too many images. %d\n", hdr.count);
		ret = -EINVAL;
		goto out;
	}

	for (i = 0; i < hdr.count; i++) {
		if (hdr.offset[i] > hdr.len) {
			printk(KERN_ERR "gdmwm: Invalid offset. "
				"Entry = %d Offset = 0x%08x "
				"Image length = 0x%08x\n",
				i, hdr.offset[i], hdr.len);
			ret = -EINVAL;
			goto out;
		}

		pos = hdr.offset[i];
		if (firm->size < sizeof(fw_info) + pos) {
			printk(KERN_ERR "gdmwm: Cannot read the FW info.\n");
			ret = -EIO;
			goto out;
		}
		memcpy(&fw_info, firm->data + pos, sizeof(fw_info));

		array_le32_to_cpu((u32 *)&fw_info, 8);
#if 0
		if ((fw_info.id & 0xfffff000) != 0x10767000) {
			printk(KERN_ERR "gdmwm: Invalid FW id. 0x%08x\n",
				fw_info.id);
			ret = -EIO;
			goto out;
		}
#endif

		if ((fw_info.id & 0xffff) != pid)
			continue;

		pos = hdr.offset[i] + fw_info.kernel_offset;
		if (firm->size < fw_info.kernel_len + pos) {
			printk(KERN_ERR "gdmwm: Kernel FW is too small.\n");
			goto out;
		}

		ret = download_image(usbdev, firm, pos,
				fw_info.kernel_len, DN_KERNEL_MAGIC_NUMBER);
		if (ret < 0)
			goto out;
		printk(KERN_INFO "GCT: Kernel download success.\n");

		pos = hdr.offset[i] + fw_info.rootfs_offset;
		if (firm->size < fw_info.rootfs_len + pos) {
			printk(KERN_ERR "gdmwm: Filesystem FW is too small.\n");
			goto out;
		}
		ret = download_image(usbdev, firm, pos, fw_info.rootfs_len,
				DN_ROOTFS_MAGIC_NUMBER);
		if (ret < 0)
			goto out;
		printk(KERN_INFO "GCT: Filesystem download success.\n");

		break;
	}

	if (i == hdr.count) {
		printk(KERN_ERR "Firmware for gsk%x is not installed.\n", pid);
		ret = -EINVAL;
	}
out:
	release_firmware(firm);
	kfree(tx_buf);
	return ret;
}

/*#define GDM7205_PADDING		256 */
#define DOWNLOAD_CHUCK			2048
#define KERNEL_TYPE_STRING		"linux"
#define FS_TYPE_STRING			"rootfs"

static int em_wait_ack(struct usb_device *usbdev, int send_zlp)
{
	int ack;
	int ret = -1;

	if (send_zlp) {
		/*Send ZLP*/
		ret = gdm_wibro_send(usbdev, NULL, 0);
		if (ret < 0)
			goto out;
	}

	/*Wait for ACK*/
	ret = gdm_wibro_recv(usbdev, &ack, sizeof(ack));
	if (ret < 0)
		goto out;
out:
	return ret;
}

static int em_download_image(struct usb_device *usbdev, const char *img_name,
				char *type_string)
{
	char *buf = NULL;
	loff_t pos = 0;
	int ret = 0;
	int len;
	int img_len;
	const struct firmware *firm;
	#if defined(GDM7205_PADDING)
	const int pad_size = GDM7205_PADDING;
	#else
	const int pad_size = 0;
	#endif

	ret = request_firmware(&firm, img_name, &usbdev->dev);
	if (ret < 0) {
		printk(KERN_ERR
		       "requesting firmware %s failed with error %d\n",
			img_name, ret);
		return ret;
	}

	buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL);
	if (buf == NULL) {
		printk(KERN_ERR "Error: kmalloc\n");
		return -ENOMEM;
	}

	strcpy(buf+pad_size, type_string);
	ret = gdm_wibro_send(usbdev, buf, strlen(type_string)+pad_size);
	if (ret < 0)
		goto out;

	img_len = firm->size;

	if (img_len <= 0) {
		ret = -1;
		goto out;
	}

	while (img_len > 0) {
		if (img_len > DOWNLOAD_CHUCK)
			len = DOWNLOAD_CHUCK;
		else
			len = img_len; /* the last chunk of data */

		memcpy(buf+pad_size, firm->data + pos, len);
		ret = gdm_wibro_send(usbdev, buf, len+pad_size);

		if (ret < 0)
			goto out;

		img_len -= DOWNLOAD_CHUCK;
		pos += DOWNLOAD_CHUCK;

		ret = em_wait_ack(usbdev, ((len+pad_size) % 512 == 0));
		if (ret < 0)
			goto out;
	}

	ret = em_wait_ack(usbdev, 1);
	if (ret < 0)
		goto out;

out:
	release_firmware(firm);
	kfree(buf);

	return ret;
}

static int em_fw_reset(struct usb_device *usbdev)
{
	int ret;

	/*Send ZLP*/
	ret = gdm_wibro_send(usbdev, NULL, 0);
	return ret;
}

int usb_emergency(struct usb_device *usbdev)
{
	int ret;
	const char *kern_name = FW_DIR FW_KERN;
	const char *fs_name = FW_DIR FW_FS;

	ret = em_download_image(usbdev, kern_name, KERNEL_TYPE_STRING);
	if (ret < 0)
		return ret;
	printk(KERN_INFO "GCT Emergency: Kernel download success.\n");

	ret = em_download_image(usbdev, fs_name, FS_TYPE_STRING);
	if (ret < 0)
		return ret;
	printk(KERN_INFO "GCT Emergency: Filesystem download success.\n");

	ret = em_fw_reset(usbdev);

	return ret;
}
