/*
 * 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) {
		dev_err(&usbdev->dev, "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) {
		dev_err(&usbdev->dev,
			"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) {
		dev_err(&usbdev->dev,
			"requesting firmware %s failed with error %d\n",
			img_name, ret);
		return ret;
	}

	tx_buf = kmalloc(DOWNLOAD_SIZE, GFP_KERNEL);
	if (tx_buf == NULL) {
		dev_err(&usbdev->dev, "Error: kmalloc\n");
		return -ENOMEM;
	}

	if (firm->size < sizeof(hdr)) {
		dev_err(&usbdev->dev, "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) {
		dev_err(&usbdev->dev, "Invalid magic code 0x%08x\n",
			hdr.magic_code);
		ret = -EINVAL;
		goto out;
	}
#endif
	if (hdr.count > MAX_IMG_CNT) {
		dev_err(&usbdev->dev, "Too many images. %d\n", hdr.count);
		ret = -EINVAL;
		goto out;
	}

	for (i = 0; i < hdr.count; i++) {
		if (hdr.offset[i] > hdr.len) {
			dev_err(&usbdev->dev,
				"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) {
			dev_err(&usbdev->dev, "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) {
			dev_err(&usbdev->dev, "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) {
			dev_err(&usbdev->dev, "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;
		dev_info(&usbdev->dev, "GCT: Kernel download success.\n");

		pos = hdr.offset[i] + fw_info.rootfs_offset;
		if (firm->size < fw_info.rootfs_len + pos) {
			dev_err(&usbdev->dev, "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;
		dev_info(&usbdev->dev, "GCT: Filesystem download success.\n");

		break;
	}

	if (i == hdr.count) {
		dev_err(&usbdev->dev, "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) {
		dev_err(&usbdev->dev,
			"requesting firmware %s failed with error %d\n",
			img_name, ret);
		return ret;
	}

	buf = kmalloc(DOWNLOAD_CHUCK + pad_size, GFP_KERNEL);
	if (buf == NULL) {
		dev_err(&usbdev->dev, "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;
	dev_err(&usbdev->dev, "GCT Emergency: Kernel download success.\n");

	ret = em_download_image(usbdev, fs_name, FS_TYPE_STRING);
	if (ret < 0)
		return ret;
	dev_info(&usbdev->dev, "GCT Emergency: Filesystem download success.\n");

	ret = em_fw_reset(usbdev);

	return ret;
}
