/*
 * iwmc3200top - Intel Wireless MultiCom 3200 Top Driver
 * drivers/misc/iwmc3200top/fw-download.c
 *
 * Copyright (C) 2009 Intel Corporation. All rights reserved.
 *
 * 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, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 * 02110-1301, USA.
 *
 *
 * Author Name: Maxim Grabarnik <maxim.grabarnink@intel.com>
 *  -
 *
 */

#include <linux/firmware.h>
#include <linux/mmc/sdio_func.h>
#include <linux/slab.h>
#include <asm/unaligned.h>

#include "iwmc3200top.h"
#include "log.h"
#include "fw-msg.h"

#define CHECKSUM_BYTES_NUM sizeof(u32)

/**
  init parser struct with file
 */
static int iwmct_fw_parser_init(struct iwmct_priv *priv, const u8 *file,
			      size_t file_size, size_t block_size)
{
	struct iwmct_parser *parser = &priv->parser;
	struct iwmct_fw_hdr *fw_hdr = &parser->versions;

	LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");

	LOG_INFO(priv, FW_DOWNLOAD, "file_size=%zd\n", file_size);

	parser->file = file;
	parser->file_size = file_size;
	parser->cur_pos = 0;
	parser->entry_point = 0;
	parser->buf = kzalloc(block_size, GFP_KERNEL);
	if (!parser->buf) {
		LOG_ERROR(priv, FW_DOWNLOAD, "kzalloc error\n");
		return -ENOMEM;
	}
	parser->buf_size = block_size;

	/* extract fw versions */
	memcpy(fw_hdr, parser->file, sizeof(struct iwmct_fw_hdr));
	LOG_INFO(priv, FW_DOWNLOAD, "fw versions are:\n"
		"top %u.%u.%u gps %u.%u.%u bt %u.%u.%u tic %s\n",
		fw_hdr->top_major, fw_hdr->top_minor, fw_hdr->top_revision,
		fw_hdr->gps_major, fw_hdr->gps_minor, fw_hdr->gps_revision,
		fw_hdr->bt_major, fw_hdr->bt_minor, fw_hdr->bt_revision,
		fw_hdr->tic_name);

	parser->cur_pos += sizeof(struct iwmct_fw_hdr);

	LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
	return 0;
}

static bool iwmct_checksum(struct iwmct_priv *priv)
{
	struct iwmct_parser *parser = &priv->parser;
	__le32 *file = (__le32 *)parser->file;
	int i, pad, steps;
	u32 accum = 0;
	u32 checksum;
	u32 mask = 0xffffffff;

	pad = (parser->file_size - CHECKSUM_BYTES_NUM) % 4;
	steps =  (parser->file_size - CHECKSUM_BYTES_NUM) / 4;

	LOG_INFO(priv, FW_DOWNLOAD, "pad=%d steps=%d\n", pad, steps);

	for (i = 0; i < steps; i++)
		accum += le32_to_cpu(file[i]);

	if (pad) {
		mask <<= 8 * (4 - pad);
		accum += le32_to_cpu(file[steps]) & mask;
	}

	checksum = get_unaligned_le32((__le32 *)(parser->file +
			parser->file_size - CHECKSUM_BYTES_NUM));

	LOG_INFO(priv, FW_DOWNLOAD,
		"compare checksum accum=0x%x to checksum=0x%x\n",
		accum, checksum);

	return checksum == accum;
}

static int iwmct_parse_next_section(struct iwmct_priv *priv, const u8 **p_sec,
				  size_t *sec_size, __le32 *sec_addr)
{
	struct iwmct_parser *parser = &priv->parser;
	struct iwmct_dbg *dbg = &priv->dbg;
	struct iwmct_fw_sec_hdr *sec_hdr;

	LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");

	while (parser->cur_pos + sizeof(struct iwmct_fw_sec_hdr)
		<= parser->file_size) {

		sec_hdr = (struct iwmct_fw_sec_hdr *)
				(parser->file + parser->cur_pos);
		parser->cur_pos += sizeof(struct iwmct_fw_sec_hdr);

		LOG_INFO(priv, FW_DOWNLOAD,
			"sec hdr: type=%s addr=0x%x size=%d\n",
			sec_hdr->type, sec_hdr->target_addr,
			sec_hdr->data_size);

		if (strcmp(sec_hdr->type, "ENT") == 0)
			parser->entry_point = le32_to_cpu(sec_hdr->target_addr);
		else if (strcmp(sec_hdr->type, "LBL") == 0)
			strcpy(dbg->label_fw, parser->file + parser->cur_pos);
		else if (((strcmp(sec_hdr->type, "TOP") == 0) &&
			  (priv->barker & BARKER_DNLOAD_TOP_MSK)) ||
			 ((strcmp(sec_hdr->type, "GPS") == 0) &&
			  (priv->barker & BARKER_DNLOAD_GPS_MSK)) ||
			 ((strcmp(sec_hdr->type, "BTH") == 0) &&
			  (priv->barker & BARKER_DNLOAD_BT_MSK))) {
			*sec_addr = sec_hdr->target_addr;
			*sec_size = le32_to_cpu(sec_hdr->data_size);
			*p_sec = parser->file + parser->cur_pos;
			parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
			return 1;
		} else if (strcmp(sec_hdr->type, "LOG") != 0)
			LOG_WARNING(priv, FW_DOWNLOAD,
				    "skipping section type %s\n",
				    sec_hdr->type);

		parser->cur_pos += le32_to_cpu(sec_hdr->data_size);
		LOG_INFO(priv, FW_DOWNLOAD,
			"finished with section cur_pos=%zd\n", parser->cur_pos);
	}

	LOG_TRACE(priv, INIT, "<--\n");
	return 0;
}

static int iwmct_download_section(struct iwmct_priv *priv, const u8 *p_sec,
				size_t sec_size, __le32 addr)
{
	struct iwmct_parser *parser = &priv->parser;
	struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
	const u8 *cur_block = p_sec;
	size_t sent = 0;
	int cnt = 0;
	int ret = 0;
	u32 cmd = 0;

	LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");
	LOG_INFO(priv, FW_DOWNLOAD, "Download address 0x%x size 0x%zx\n",
				addr, sec_size);

	while (sent < sec_size) {
		int i;
		u32 chksm = 0;
		u32 reset = atomic_read(&priv->reset);
		/* actual FW data */
		u32 data_size = min(parser->buf_size - sizeof(*hdr),
				    sec_size - sent);
		/* Pad to block size */
		u32 trans_size = (data_size + sizeof(*hdr) +
				  IWMC_SDIO_BLK_SIZE - 1) &
				  ~(IWMC_SDIO_BLK_SIZE - 1);
		++cnt;

		/* in case of reset, interrupt FW DOWNLAOD */
		if (reset) {
			LOG_INFO(priv, FW_DOWNLOAD,
				 "Reset detected. Abort FW download!!!");
			ret = -ECANCELED;
			goto exit;
		}

		memset(parser->buf, 0, parser->buf_size);
		cmd |= IWMC_OPCODE_WRITE << CMD_HDR_OPCODE_POS;
		cmd |= IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
		cmd |= (priv->dbg.direct ? 1 : 0) << CMD_HDR_DIRECT_ACCESS_POS;
		cmd |= (priv->dbg.checksum ? 1 : 0) << CMD_HDR_USE_CHECKSUM_POS;
		hdr->data_size = cpu_to_le32(data_size);
		hdr->target_addr = addr;

		/* checksum is allowed for sizes divisible by 4 */
		if (data_size & 0x3)
			cmd &= ~CMD_HDR_USE_CHECKSUM_MSK;

		memcpy(hdr->data, cur_block, data_size);


		if (cmd & CMD_HDR_USE_CHECKSUM_MSK) {

			chksm = data_size + le32_to_cpu(addr) + cmd;
			for (i = 0; i < data_size >> 2; i++)
				chksm += ((u32 *)cur_block)[i];

			hdr->block_chksm = cpu_to_le32(chksm);
			LOG_INFO(priv, FW_DOWNLOAD, "Checksum = 0x%X\n",
				 hdr->block_chksm);
		}

		LOG_INFO(priv, FW_DOWNLOAD, "trans#%d, len=%d, sent=%zd, "
				"sec_size=%zd, startAddress 0x%X\n",
				cnt, trans_size, sent, sec_size, addr);

		if (priv->dbg.dump)
			LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, trans_size);


		hdr->cmd = cpu_to_le32(cmd);
		/* send it down */
		/* TODO: add more proper sending and error checking */
		ret = iwmct_tx(priv, parser->buf, trans_size);
		if (ret != 0) {
			LOG_INFO(priv, FW_DOWNLOAD,
				"iwmct_tx returned %d\n", ret);
			goto exit;
		}

		addr = cpu_to_le32(le32_to_cpu(addr) + data_size);
		sent += data_size;
		cur_block = p_sec + sent;

		if (priv->dbg.blocks && (cnt + 1) >= priv->dbg.blocks) {
			LOG_INFO(priv, FW_DOWNLOAD,
				"Block number limit is reached [%d]\n",
				priv->dbg.blocks);
			break;
		}
	}

	if (sent < sec_size)
		ret = -EINVAL;
exit:
	LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
	return ret;
}

static int iwmct_kick_fw(struct iwmct_priv *priv, bool jump)
{
	struct iwmct_parser *parser = &priv->parser;
	struct iwmct_fw_load_hdr *hdr = (struct iwmct_fw_load_hdr *)parser->buf;
	int ret;
	u32 cmd;

	LOG_TRACE(priv, FW_DOWNLOAD, "-->\n");

	memset(parser->buf, 0, parser->buf_size);
	cmd = IWMC_CMD_SIGNATURE << CMD_HDR_SIGNATURE_POS;
	if (jump) {
		cmd |= IWMC_OPCODE_JUMP << CMD_HDR_OPCODE_POS;
		hdr->target_addr = cpu_to_le32(parser->entry_point);
		LOG_INFO(priv, FW_DOWNLOAD, "jump address 0x%x\n",
				parser->entry_point);
	} else {
		cmd |= IWMC_OPCODE_LAST_COMMAND << CMD_HDR_OPCODE_POS;
		LOG_INFO(priv, FW_DOWNLOAD, "last command\n");
	}

	hdr->cmd = cpu_to_le32(cmd);

	LOG_HEXDUMP(FW_DOWNLOAD, parser->buf, sizeof(*hdr));
	/* send it down */
	/* TODO: add more proper sending and error checking */
	ret = iwmct_tx(priv, parser->buf, IWMC_SDIO_BLK_SIZE);
	if (ret)
		LOG_INFO(priv, FW_DOWNLOAD, "iwmct_tx returned %d", ret);

	LOG_TRACE(priv, FW_DOWNLOAD, "<--\n");
	return 0;
}

int iwmct_fw_load(struct iwmct_priv *priv)
{
	const u8 *fw_name = FW_NAME(FW_API_VER);
	const struct firmware *raw;
	const u8 *pdata;
	size_t len;
	__le32 addr;
	int ret;


	LOG_INFO(priv, FW_DOWNLOAD, "barker download request 0x%x is:\n",
			priv->barker);
	LOG_INFO(priv, FW_DOWNLOAD, "*******  Top FW %s requested ********\n",
			(priv->barker & BARKER_DNLOAD_TOP_MSK) ? "was" : "not");
	LOG_INFO(priv, FW_DOWNLOAD, "*******  GPS FW %s requested ********\n",
			(priv->barker & BARKER_DNLOAD_GPS_MSK) ? "was" : "not");
	LOG_INFO(priv, FW_DOWNLOAD, "*******  BT FW %s requested ********\n",
			(priv->barker & BARKER_DNLOAD_BT_MSK) ? "was" : "not");


	/* get the firmware */
	ret = request_firmware(&raw, fw_name, &priv->func->dev);
	if (ret < 0) {
		LOG_ERROR(priv, FW_DOWNLOAD, "%s request_firmware failed %d\n",
			  fw_name, ret);
		goto exit;
	}

	if (raw->size < sizeof(struct iwmct_fw_sec_hdr)) {
		LOG_ERROR(priv, FW_DOWNLOAD, "%s smaller then (%zd) (%zd)\n",
			  fw_name, sizeof(struct iwmct_fw_sec_hdr), raw->size);
		goto exit;
	}

	LOG_INFO(priv, FW_DOWNLOAD, "Read firmware '%s'\n", fw_name);

	/* clear parser struct */
	ret = iwmct_fw_parser_init(priv, raw->data, raw->size, priv->trans_len);
	if (ret < 0) {
		LOG_ERROR(priv, FW_DOWNLOAD,
			  "iwmct_parser_init failed: Reason %d\n", ret);
		goto exit;
	}

	if (!iwmct_checksum(priv)) {
		LOG_ERROR(priv, FW_DOWNLOAD, "checksum error\n");
		ret = -EINVAL;
		goto exit;
	}

	/* download firmware to device */
	while (iwmct_parse_next_section(priv, &pdata, &len, &addr)) {
		ret = iwmct_download_section(priv, pdata, len, addr);
		if (ret) {
			LOG_ERROR(priv, FW_DOWNLOAD,
				  "%s download section failed\n", fw_name);
			goto exit;
		}
	}

	ret = iwmct_kick_fw(priv, !!(priv->barker & BARKER_DNLOAD_JUMP_MSK));

exit:
	kfree(priv->parser.buf);
	release_firmware(raw);
	return ret;
}
