/*
 * Intel Wireless Multicomm 3200 WiFi driver
 *
 * Copyright (C) 2009 Intel Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   * Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *   * Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in
 *     the documentation and/or other materials provided with the
 *     distribution.
 *   * Neither the name of Intel Corporation nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 *
 * Intel Corporation <ilw@linux.intel.com>
 * Samuel Ortiz <samuel.ortiz@intel.com>
 * Zhu Yi <yi.zhu@intel.com>
 *
 */

#include <linux/kernel.h>
#include <linux/firmware.h>

#include "iwm.h"
#include "bus.h"
#include "hal.h"
#include "umac.h"
#include "debug.h"
#include "fw.h"
#include "commands.h"

static const char fw_barker[] = "*WESTOPFORNOONE*";

/*
 * @op_code: Op code we're looking for.
 * @index: There can be several instances of the same opcode within
 *         the firmware. Index specifies which one we're looking for.
 */
static int iwm_fw_op_offset(struct iwm_priv *iwm, const struct firmware *fw,
			    u16 op_code, u32 index)
{
	int offset = -EINVAL, fw_offset;
	u32 op_index = 0;
	const u8 *fw_ptr;
	struct iwm_fw_hdr_rec *rec;

	fw_offset = 0;
	fw_ptr = fw->data;

	/* We first need to look for the firmware barker */
	if (memcmp(fw_ptr, fw_barker, IWM_HDR_BARKER_LEN)) {
		IWM_ERR(iwm, "No barker string in this FW\n");
		return -EINVAL;
	}

	if (fw->size < IWM_HDR_LEN) {
		IWM_ERR(iwm, "FW is too small (%zu)\n", fw->size);
		return -EINVAL;
	}

	fw_offset += IWM_HDR_BARKER_LEN;

	while (fw_offset < fw->size) {
		rec = (struct iwm_fw_hdr_rec *)(fw_ptr + fw_offset);

		IWM_DBG_FW(iwm, DBG, "FW: op_code: 0x%x, len: %d @ 0x%x\n",
			   rec->op_code, rec->len, fw_offset);

		if (rec->op_code == IWM_HDR_REC_OP_INVALID) {
			IWM_DBG_FW(iwm, DBG, "Reached INVALID op code\n");
			break;
		}

		if (rec->op_code == op_code) {
			if (op_index == index) {
				fw_offset += sizeof(struct iwm_fw_hdr_rec);
				offset = fw_offset;
				goto out;
			}
			op_index++;
		}

		fw_offset += sizeof(struct iwm_fw_hdr_rec) + rec->len;
	}

 out:
	return offset;
}

static int iwm_load_firmware_chunk(struct iwm_priv *iwm,
				   const struct firmware *fw,
				   struct iwm_fw_img_desc *img_desc)
{
	struct iwm_udma_nonwifi_cmd target_cmd;
	u32 chunk_size;
	const u8 *chunk_ptr;
	int ret = 0;

	IWM_DBG_FW(iwm, INFO, "Loading FW chunk: %d bytes @ 0x%x\n",
		   img_desc->length, img_desc->address);

	target_cmd.opcode = UMAC_HDI_OUT_OPCODE_WRITE;
	target_cmd.handle_by_hw = 1;
	target_cmd.op2 = 0;
	target_cmd.resp = 0;
	target_cmd.eop = 1;

	chunk_size = img_desc->length;
	chunk_ptr = fw->data + img_desc->offset;

	while (chunk_size > 0) {
		u32 tmp_chunk_size;

		tmp_chunk_size = min_t(u32, chunk_size,
				       IWM_MAX_NONWIFI_CMD_BUFF_SIZE);

		target_cmd.addr = cpu_to_le32(img_desc->address +
				    (chunk_ptr - fw->data - img_desc->offset));
		target_cmd.op1_sz = cpu_to_le32(tmp_chunk_size);

		IWM_DBG_FW(iwm, DBG, "\t%d bytes @ 0x%x\n",
			   tmp_chunk_size, target_cmd.addr);

		ret = iwm_hal_send_target_cmd(iwm, &target_cmd, chunk_ptr);
		if (ret < 0) {
			IWM_ERR(iwm, "Couldn't load FW chunk\n");
			break;
		}

		chunk_size -= tmp_chunk_size;
		chunk_ptr += tmp_chunk_size;
	}

	return ret;
}
/*
 * To load a fw image to the target, we basically go through the
 * fw, looking for OP_MEM_DESC records. Once we found one, we
 * pass it to iwm_load_firmware_chunk().
 * The OP_MEM_DESC records contain the actuall memory chunk to be
 * sent, but also the destination address.
 */
static int iwm_load_img(struct iwm_priv *iwm, const char *img_name)
{
	const struct firmware *fw;
	struct iwm_fw_img_desc *img_desc;
	struct iwm_fw_img_ver *ver;
	int ret = 0, fw_offset;
	u32 opcode_idx = 0, build_date;
	char *build_tag;

	ret = request_firmware(&fw, img_name, iwm_to_dev(iwm));
	if (ret) {
		IWM_ERR(iwm, "Request firmware failed");
		return ret;
	}

	IWM_DBG_FW(iwm, INFO, "Start to load FW %s\n", img_name);

	while (1) {
		fw_offset = iwm_fw_op_offset(iwm, fw,
					     IWM_HDR_REC_OP_MEM_DESC,
					     opcode_idx);
		if (fw_offset < 0)
			break;

		img_desc = (struct iwm_fw_img_desc *)(fw->data + fw_offset);
		ret = iwm_load_firmware_chunk(iwm, fw, img_desc);
		if (ret < 0)
			goto err_release_fw;
		opcode_idx++;
	}

	/* Read firmware version */
	fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_SW_VER, 0);
	if (fw_offset < 0)
		goto err_release_fw;

	ver = (struct iwm_fw_img_ver *)(fw->data + fw_offset);

	/* Read build tag */
	fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_BUILD_TAG, 0);
	if (fw_offset < 0)
		goto err_release_fw;

	build_tag = (char *)(fw->data + fw_offset);

	/* Read build date */
	fw_offset = iwm_fw_op_offset(iwm, fw, IWM_HDR_REC_OP_BUILD_DATE, 0);
	if (fw_offset < 0)
		goto err_release_fw;

	build_date = *(u32 *)(fw->data + fw_offset);

	IWM_INFO(iwm, "%s:\n", img_name);
	IWM_INFO(iwm, "\tVersion:    %02X.%02X\n", ver->major, ver->minor);
	IWM_INFO(iwm, "\tBuild tag:  %s\n", build_tag);
	IWM_INFO(iwm, "\tBuild date: %x-%x-%x\n",
		 IWM_BUILD_YEAR(build_date), IWM_BUILD_MONTH(build_date),
		 IWM_BUILD_DAY(build_date));

	if (!strcmp(img_name, iwm->bus_ops->umac_name))
		sprintf(iwm->umac_version, "%02X.%02X",
			ver->major, ver->minor);

	if (!strcmp(img_name, iwm->bus_ops->lmac_name))
		sprintf(iwm->lmac_version, "%02X.%02X",
			ver->major, ver->minor);

 err_release_fw:
	release_firmware(fw);

	return ret;
}

static int iwm_load_umac(struct iwm_priv *iwm)
{
	struct iwm_udma_nonwifi_cmd target_cmd;
	int ret;

	ret = iwm_load_img(iwm, iwm->bus_ops->umac_name);
	if (ret < 0)
		return ret;

	/* We've loaded the UMAC, we can tell the target to jump there */
	target_cmd.opcode = UMAC_HDI_OUT_OPCODE_JUMP;
	target_cmd.addr = cpu_to_le32(UMAC_MU_FW_INST_DATA_12_ADDR);
	target_cmd.op1_sz = 0;
	target_cmd.op2 = 0;
	target_cmd.handle_by_hw = 0;
	target_cmd.resp = 1 ;
	target_cmd.eop = 1;

	ret = iwm_hal_send_target_cmd(iwm, &target_cmd, NULL);
	if (ret < 0)
		IWM_ERR(iwm, "Couldn't send JMP command\n");

	return ret;
}

static int iwm_load_lmac(struct iwm_priv *iwm, const char *img_name)
{
	int ret;

	ret = iwm_load_img(iwm, img_name);
	if (ret < 0)
		return ret;

	return iwm_send_umac_reset(iwm,
			cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_CLK_EN), 0);
}

static int iwm_init_calib(struct iwm_priv *iwm, unsigned long cfg_bitmap,
			  unsigned long expected_bitmap, u8 rx_iq_cmd)
{
	/* Read RX IQ calibration result from EEPROM */
	if (test_bit(rx_iq_cmd, &cfg_bitmap)) {
		iwm_store_rxiq_calib_result(iwm);
		set_bit(PHY_CALIBRATE_RX_IQ_CMD, &iwm->calib_done_map);
	}

	iwm_send_prio_table(iwm);
	iwm_send_init_calib_cfg(iwm, cfg_bitmap);

	while (iwm->calib_done_map != expected_bitmap) {
		if (iwm_notif_handle(iwm, CALIBRATION_RES_NOTIFICATION,
				     IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT)) {
			IWM_DBG_FW(iwm, DBG, "Initial calibration timeout\n");
			return -ETIMEDOUT;
		}

		IWM_DBG_FW(iwm, DBG, "Got calibration result. calib_done_map: "
			   "0x%lx, expected calibrations: 0x%lx\n",
			   iwm->calib_done_map, expected_bitmap);
	}

	return 0;
}

/*
 * We currently have to load 3 FWs:
 * 1) The UMAC (Upper MAC).
 * 2) The calibration LMAC (Lower MAC).
 *    We then send the calibration init command, so that the device can
 *    run a first calibration round.
 * 3) The operational LMAC, which replaces the calibration one when it's
 *    done with the first calibration round.
 *
 * Once those 3 FWs have been loaded, we send the periodic calibration
 * command, and then the device is available for regular 802.11 operations.
 */
int iwm_load_fw(struct iwm_priv *iwm)
{
	unsigned long init_calib_map, periodic_calib_map;
	unsigned long expected_calib_map;
	int ret;

	/* We first start downloading the UMAC */
	ret = iwm_load_umac(iwm);
	if (ret < 0) {
		IWM_ERR(iwm, "UMAC loading failed\n");
		return ret;
	}

	/* Handle UMAC_ALIVE notification */
	ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_ALIVE, IWM_SRC_UMAC,
			       WAIT_NOTIF_TIMEOUT);
	if (ret) {
		IWM_ERR(iwm, "Handle UMAC_ALIVE failed: %d\n", ret);
		return ret;
	}

	/* UMAC is alive, we can download the calibration LMAC */
	ret = iwm_load_lmac(iwm, iwm->bus_ops->calib_lmac_name);
	if (ret) {
		IWM_ERR(iwm, "Calibration LMAC loading failed\n");
		return ret;
	}

	/* Handle UMAC_INIT_COMPLETE notification */
	ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_INIT_COMPLETE,
			       IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
	if (ret) {
		IWM_ERR(iwm, "Handle INIT_COMPLETE failed for calibration "
			"LMAC: %d\n", ret);
		return ret;
	}

	/* Read EEPROM data */
	ret = iwm_eeprom_init(iwm);
	if (ret < 0) {
		IWM_ERR(iwm, "Couldn't init eeprom array\n");
		return ret;
	}

	init_calib_map = iwm->conf.calib_map & IWM_CALIB_MAP_INIT_MSK;
	expected_calib_map = iwm->conf.expected_calib_map &
		IWM_CALIB_MAP_INIT_MSK;
	periodic_calib_map = IWM_CALIB_MAP_PER_LMAC(iwm->conf.calib_map);

	ret = iwm_init_calib(iwm, init_calib_map, expected_calib_map,
			     CALIB_CFG_RX_IQ_IDX);
	if (ret < 0) {
		/* Let's try the old way */
		ret = iwm_init_calib(iwm, expected_calib_map,
				     expected_calib_map,
				     PHY_CALIBRATE_RX_IQ_CMD);
		if (ret < 0) {
			IWM_ERR(iwm, "Calibration result timeout\n");
			goto out;
		}
	}

	/* Handle LMAC CALIBRATION_COMPLETE notification */
	ret = iwm_notif_handle(iwm, CALIBRATION_COMPLETE_NOTIFICATION,
			       IWM_SRC_LMAC, WAIT_NOTIF_TIMEOUT);
	if (ret) {
		IWM_ERR(iwm, "Wait for CALIBRATION_COMPLETE timeout\n");
		goto out;
	}

	IWM_INFO(iwm, "LMAC calibration done: 0x%lx\n", iwm->calib_done_map);

	iwm_send_umac_reset(iwm, cpu_to_le32(UMAC_RST_CTRL_FLG_LARC_RESET), 1);

	ret = iwm_notif_handle(iwm, UMAC_CMD_OPCODE_RESET, IWM_SRC_UMAC,
			       WAIT_NOTIF_TIMEOUT);
	if (ret) {
		IWM_ERR(iwm, "Wait for UMAC RESET timeout\n");
		goto out;
	}

	/* Download the operational LMAC */
	ret = iwm_load_lmac(iwm, iwm->bus_ops->lmac_name);
	if (ret) {
		IWM_ERR(iwm, "LMAC loading failed\n");
		goto out;
	}

	ret = iwm_notif_handle(iwm, UMAC_NOTIFY_OPCODE_INIT_COMPLETE,
			       IWM_SRC_UMAC, WAIT_NOTIF_TIMEOUT);
	if (ret) {
		IWM_ERR(iwm, "Handle INIT_COMPLETE failed for LMAC: %d\n", ret);
		goto out;
	}

	iwm_send_prio_table(iwm);
	iwm_send_calib_results(iwm);
	iwm_send_periodic_calib_cfg(iwm, periodic_calib_map);
	iwm_send_ct_kill_cfg(iwm, iwm->conf.ct_kill_entry,
			     iwm->conf.ct_kill_exit);

	return 0;

 out:
	iwm_eeprom_exit(iwm);
	return ret;
}
