/*
 * Copyright (c) 1996, 2003 VIA Networking Technologies, Inc.
 * 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 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.
 *
 *
 * File: baseband.c
 *
 * Purpose: Implement functions to access baseband
 *
 * Author: Yiching Chen
 *
 * Date: May 20, 2004
 *
 * Functions:
 *
 * Revision History:
 *
 */

#include <linux/compiler.h>
#include "firmware.h"
#include "usbpipe.h"

#define FIRMWARE_VERSION	0x133		/* version 1.51 */
#define FIRMWARE_NAME		"vntwusb.fw"

#define FIRMWARE_CHUNK_SIZE	0x400

int vnt_download_firmware(struct vnt_private *priv)
{
	struct device *dev = &priv->usb->dev;
	const struct firmware *fw;
	int status;
	void *buffer = NULL;
	bool result = false;
	u16 length;
	int ii, rc;

	dev_dbg(dev, "---->Download firmware\n");

	rc = request_firmware(&fw, FIRMWARE_NAME, dev);
	if (rc) {
		dev_err(dev, "firmware file %s request failed (%d)\n",
			FIRMWARE_NAME, rc);
			goto out;
	}

	buffer = kmalloc(FIRMWARE_CHUNK_SIZE, GFP_KERNEL);
	if (!buffer)
		goto free_fw;

	for (ii = 0; ii < fw->size; ii += FIRMWARE_CHUNK_SIZE) {
		length = min_t(int, fw->size - ii, FIRMWARE_CHUNK_SIZE);
		memcpy(buffer, fw->data + ii, length);

		status = vnt_control_out(priv,
					 0,
					 0x1200 + ii,
					 0x0000,
					 length,
					 buffer);

		dev_dbg(dev, "Download firmware...%d %zu\n", ii, fw->size);

		if (status != STATUS_SUCCESS)
			goto free_fw;
	}

	result = true;
free_fw:
	release_firmware(fw);

out:
	kfree(buffer);

	return result;
}
MODULE_FIRMWARE(FIRMWARE_NAME);

int vnt_firmware_branch_to_sram(struct vnt_private *priv)
{
	int status;

	dev_dbg(&priv->usb->dev, "---->Branch to Sram\n");

	status = vnt_control_out(priv,
				 1,
				 0x1200,
				 0x0000,
				 0,
				 NULL);
	return status == STATUS_SUCCESS;
}

int vnt_check_firmware_version(struct vnt_private *priv)
{
	int status;

	status = vnt_control_in(priv,
				MESSAGE_TYPE_READ,
				0,
				MESSAGE_REQUEST_VERSION,
				2,
				(u8 *)&priv->firmware_version);

	dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
		priv->firmware_version);

	if (status != STATUS_SUCCESS) {
		dev_dbg(&priv->usb->dev, "Firmware Invalid.\n");
		return false;
	}
	if (priv->firmware_version == 0xFFFF) {
		dev_dbg(&priv->usb->dev, "In Loader.\n");
		return false;
	}

	dev_dbg(&priv->usb->dev, "Firmware Version [%04x]\n",
		priv->firmware_version);

	if (priv->firmware_version < FIRMWARE_VERSION) {
		/* branch to loader for download new firmware */
		vnt_firmware_branch_to_sram(priv);
		return false;
	}
	return true;
}
