/*
 * Atheros CARL9170 driver
 *
 * firmware parser
 *
 * Copyright 2009, 2010, Christian Lamparter <chunkeey@googlemail.com>
 *
 * 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.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; see the file COPYING.  If not, see
 * http://www.gnu.org/licenses/.
 */

#include <linux/kernel.h>
#include <linux/firmware.h>
#include <linux/crc32.h>
#include <linux/module.h>
#include "carl9170.h"
#include "fwcmd.h"
#include "version.h"

#define MAKE_STR(symbol) #symbol
#define TO_STR(symbol) MAKE_STR(symbol)
#define CARL9170FW_API_VER_STR TO_STR(CARL9170FW_API_MAX_VER)
MODULE_VERSION(CARL9170FW_API_VER_STR ":" CARL9170FW_VERSION_GIT);

static const u8 otus_magic[4] = { OTUS_MAGIC };

static const void *carl9170_fw_find_desc(struct ar9170 *ar, const u8 descid[4],
	const unsigned int len, const u8 compatible_revision)
{
	const struct carl9170fw_desc_head *iter;

	carl9170fw_for_each_hdr(iter, ar->fw.desc) {
		if (carl9170fw_desc_cmp(iter, descid, len,
					compatible_revision))
			return (void *)iter;
	}

	/* needed to find the LAST desc */
	if (carl9170fw_desc_cmp(iter, descid, len,
				compatible_revision))
		return (void *)iter;

	return NULL;
}

static int carl9170_fw_verify_descs(struct ar9170 *ar,
	const struct carl9170fw_desc_head *head, unsigned int max_len)
{
	const struct carl9170fw_desc_head *pos;
	unsigned long pos_addr, end_addr;
	unsigned int pos_length;

	if (max_len < sizeof(*pos))
		return -ENODATA;

	max_len = min_t(unsigned int, CARL9170FW_DESC_MAX_LENGTH, max_len);

	pos = head;
	pos_addr = (unsigned long) pos;
	end_addr = pos_addr + max_len;

	while (pos_addr < end_addr) {
		if (pos_addr + sizeof(*head) > end_addr)
			return -E2BIG;

		pos_length = le16_to_cpu(pos->length);

		if (pos_length < sizeof(*head))
			return -EBADMSG;

		if (pos_length > max_len)
			return -EOVERFLOW;

		if (pos_addr + pos_length > end_addr)
			return -EMSGSIZE;

		if (carl9170fw_desc_cmp(pos, LAST_MAGIC,
					CARL9170FW_LAST_DESC_SIZE,
					CARL9170FW_LAST_DESC_CUR_VER))
			return 0;

		pos_addr += pos_length;
		pos = (void *)pos_addr;
		max_len -= pos_length;
	}
	return -EINVAL;
}

static void carl9170_fw_info(struct ar9170 *ar)
{
	const struct carl9170fw_motd_desc *motd_desc;
	unsigned int str_ver_len;
	u32 fw_date;

	dev_info(&ar->udev->dev, "driver   API: %s 2%03d-%02d-%02d [%d-%d]\n",
		CARL9170FW_VERSION_GIT, CARL9170FW_VERSION_YEAR,
		CARL9170FW_VERSION_MONTH, CARL9170FW_VERSION_DAY,
		CARL9170FW_API_MIN_VER, CARL9170FW_API_MAX_VER);

	motd_desc = carl9170_fw_find_desc(ar, MOTD_MAGIC,
		sizeof(*motd_desc), CARL9170FW_MOTD_DESC_CUR_VER);

	if (motd_desc) {
		str_ver_len = strnlen(motd_desc->release,
			CARL9170FW_MOTD_RELEASE_LEN);

		fw_date = le32_to_cpu(motd_desc->fw_year_month_day);

		dev_info(&ar->udev->dev, "firmware API: %.*s 2%03d-%02d-%02d\n",
			 str_ver_len, motd_desc->release,
			 CARL9170FW_GET_YEAR(fw_date),
			 CARL9170FW_GET_MONTH(fw_date),
			 CARL9170FW_GET_DAY(fw_date));

		strlcpy(ar->hw->wiphy->fw_version, motd_desc->release,
			sizeof(ar->hw->wiphy->fw_version));
	}
}

static bool valid_dma_addr(const u32 address)
{
	if (address >= AR9170_SRAM_OFFSET &&
	    address < (AR9170_SRAM_OFFSET + AR9170_SRAM_SIZE))
		return true;

	return false;
}

static bool valid_cpu_addr(const u32 address)
{
	if (valid_dma_addr(address) || (address >= AR9170_PRAM_OFFSET &&
	    address < (AR9170_PRAM_OFFSET + AR9170_PRAM_SIZE)))
		return true;

	return false;
}

static int carl9170_fw_checksum(struct ar9170 *ar, const __u8 *data,
				size_t len)
{
	const struct carl9170fw_otus_desc *otus_desc;
	const struct carl9170fw_last_desc *last_desc;
	const struct carl9170fw_chk_desc *chk_desc;
	unsigned long fin, diff;
	unsigned int dsc_len;
	u32 crc32;

	last_desc = carl9170_fw_find_desc(ar, LAST_MAGIC,
		sizeof(*last_desc), CARL9170FW_LAST_DESC_CUR_VER);
	if (!last_desc)
		return -EINVAL;

	otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC,
		sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER);
	if (!otus_desc) {
		dev_err(&ar->udev->dev, "failed to find compatible firmware "
			"descriptor.\n");
		return -ENODATA;
	}

	chk_desc = carl9170_fw_find_desc(ar, CHK_MAGIC,
		sizeof(*chk_desc), CARL9170FW_CHK_DESC_CUR_VER);

	if (!chk_desc) {
		dev_warn(&ar->udev->dev, "Unprotected firmware image.\n");
		return 0;
	}

	dsc_len = min_t(unsigned int, len,
			(unsigned long)chk_desc - (unsigned long)otus_desc);

	fin = (unsigned long) last_desc + sizeof(*last_desc);
	diff = fin - (unsigned long) otus_desc;

	if (diff < len)
		len -= diff;

	if (len < 256)
		return -EIO;

	crc32 = crc32_le(~0, data, len);
	if (cpu_to_le32(crc32) != chk_desc->fw_crc32) {
		dev_err(&ar->udev->dev, "fw checksum test failed.\n");
		return -ENOEXEC;
	}

	crc32 = crc32_le(crc32, (void *)otus_desc, dsc_len);
	if (cpu_to_le32(crc32) != chk_desc->hdr_crc32) {
		dev_err(&ar->udev->dev, "descriptor check failed.\n");
		return -EINVAL;
	}
	return 0;
}

static int carl9170_fw_tx_sequence(struct ar9170 *ar)
{
	const struct carl9170fw_txsq_desc *txsq_desc;

	txsq_desc = carl9170_fw_find_desc(ar, TXSQ_MAGIC, sizeof(*txsq_desc),
					  CARL9170FW_TXSQ_DESC_CUR_VER);
	if (txsq_desc) {
		ar->fw.tx_seq_table = le32_to_cpu(txsq_desc->seq_table_addr);
		if (!valid_cpu_addr(ar->fw.tx_seq_table))
			return -EINVAL;
	} else {
		ar->fw.tx_seq_table = 0;
	}

	return 0;
}

static int carl9170_fw(struct ar9170 *ar, const __u8 *data, size_t len)
{
	const struct carl9170fw_otus_desc *otus_desc;
	int err;
	u16 if_comb_types;

	err = carl9170_fw_checksum(ar, data, len);
	if (err)
		return err;

	otus_desc = carl9170_fw_find_desc(ar, OTUS_MAGIC,
		sizeof(*otus_desc), CARL9170FW_OTUS_DESC_CUR_VER);
	if (!otus_desc) {
		return -ENODATA;
	}

#define SUPP(feat)						\
	(carl9170fw_supports(otus_desc->feature_set, feat))

	if (!SUPP(CARL9170FW_DUMMY_FEATURE)) {
		dev_err(&ar->udev->dev, "invalid firmware descriptor "
			"format detected.\n");
		return -EINVAL;
	}

	ar->fw.api_version = otus_desc->api_ver;

	if (ar->fw.api_version < CARL9170FW_API_MIN_VER ||
	    ar->fw.api_version > CARL9170FW_API_MAX_VER) {
		dev_err(&ar->udev->dev, "unsupported firmware api version.\n");
		return -EINVAL;
	}

	if (!SUPP(CARL9170FW_COMMAND_PHY) || SUPP(CARL9170FW_UNUSABLE) ||
	    !SUPP(CARL9170FW_HANDLE_BACK_REQ)) {
		dev_err(&ar->udev->dev, "firmware does support "
			"mandatory features.\n");
		return -ECANCELED;
	}

	if (ilog2(le32_to_cpu(otus_desc->feature_set)) >=
		__CARL9170FW_FEATURE_NUM) {
		dev_warn(&ar->udev->dev, "driver does not support all "
			 "firmware features.\n");
	}

	if (!SUPP(CARL9170FW_COMMAND_CAM)) {
		dev_info(&ar->udev->dev, "crypto offloading is disabled "
			 "by firmware.\n");
		ar->disable_offload = true;
	}

	if (SUPP(CARL9170FW_PSM) && SUPP(CARL9170FW_FIXED_5GHZ_PSM))
		ar->hw->flags |= IEEE80211_HW_SUPPORTS_PS;

	if (!SUPP(CARL9170FW_USB_INIT_FIRMWARE)) {
		dev_err(&ar->udev->dev, "firmware does not provide "
			"mandatory interfaces.\n");
		return -EINVAL;
	}

	if (SUPP(CARL9170FW_MINIBOOT))
		ar->fw.offset = le16_to_cpu(otus_desc->miniboot_size);
	else
		ar->fw.offset = 0;

	if (SUPP(CARL9170FW_USB_DOWN_STREAM)) {
		ar->hw->extra_tx_headroom += sizeof(struct ar9170_stream);
		ar->fw.tx_stream = true;
	}

	if (SUPP(CARL9170FW_USB_UP_STREAM))
		ar->fw.rx_stream = true;

	if (SUPP(CARL9170FW_RX_FILTER)) {
		ar->fw.rx_filter = true;
		ar->rx_filter_caps = FIF_FCSFAIL | FIF_PLCPFAIL |
			FIF_CONTROL | FIF_PSPOLL | FIF_OTHER_BSS |
			FIF_PROMISC_IN_BSS;
	}

	if (SUPP(CARL9170FW_HW_COUNTERS))
		ar->fw.hw_counters = true;

	if (SUPP(CARL9170FW_WOL))
		device_set_wakeup_enable(&ar->udev->dev, true);

	if_comb_types = BIT(NL80211_IFTYPE_STATION) |
			BIT(NL80211_IFTYPE_P2P_CLIENT);

	ar->fw.vif_num = otus_desc->vif_num;
	ar->fw.cmd_bufs = otus_desc->cmd_bufs;
	ar->fw.address = le32_to_cpu(otus_desc->fw_address);
	ar->fw.rx_size = le16_to_cpu(otus_desc->rx_max_frame_len);
	ar->fw.mem_blocks = min_t(unsigned int, otus_desc->tx_descs, 0xfe);
	atomic_set(&ar->mem_free_blocks, ar->fw.mem_blocks);
	ar->fw.mem_block_size = le16_to_cpu(otus_desc->tx_frag_len);

	if (ar->fw.vif_num >= AR9170_MAX_VIRTUAL_MAC || !ar->fw.vif_num ||
	    ar->fw.mem_blocks < 16 || !ar->fw.cmd_bufs ||
	    ar->fw.mem_block_size < 64 || ar->fw.mem_block_size > 512 ||
	    ar->fw.rx_size > 32768 || ar->fw.rx_size < 4096 ||
	    !valid_cpu_addr(ar->fw.address)) {
		dev_err(&ar->udev->dev, "firmware shows obvious signs of "
			"malicious tampering.\n");
		return -EINVAL;
	}

	ar->fw.beacon_addr = le32_to_cpu(otus_desc->bcn_addr);
	ar->fw.beacon_max_len = le16_to_cpu(otus_desc->bcn_len);

	if (valid_dma_addr(ar->fw.beacon_addr) && ar->fw.beacon_max_len >=
	    AR9170_MAC_BCN_LENGTH_MAX) {
		ar->hw->wiphy->interface_modes |= BIT(NL80211_IFTYPE_ADHOC);

		if (SUPP(CARL9170FW_WLANTX_CAB)) {
			if_comb_types |=
				BIT(NL80211_IFTYPE_AP) |
				BIT(NL80211_IFTYPE_P2P_GO);
		}
	}

	ar->if_comb_limits[0].max = ar->fw.vif_num;
	ar->if_comb_limits[0].types = if_comb_types;

	ar->if_combs[0].num_different_channels = 1;
	ar->if_combs[0].max_interfaces = ar->fw.vif_num;
	ar->if_combs[0].limits = ar->if_comb_limits;
	ar->if_combs[0].n_limits = ARRAY_SIZE(ar->if_comb_limits);

	ar->hw->wiphy->iface_combinations = ar->if_combs;
	ar->hw->wiphy->n_iface_combinations = ARRAY_SIZE(ar->if_combs);

	ar->hw->wiphy->interface_modes |= if_comb_types;

#undef SUPPORTED
	return carl9170_fw_tx_sequence(ar);
}

static struct carl9170fw_desc_head *
carl9170_find_fw_desc(struct ar9170 *ar, const __u8 *fw_data, const size_t len)

{
	int scan = 0, found = 0;

	if (!carl9170fw_size_check(len)) {
		dev_err(&ar->udev->dev, "firmware size is out of bound.\n");
		return NULL;
	}

	while (scan < len - sizeof(struct carl9170fw_desc_head)) {
		if (fw_data[scan++] == otus_magic[found])
			found++;
		else
			found = 0;

		if (scan >= len)
			break;

		if (found == sizeof(otus_magic))
			break;
	}

	if (found != sizeof(otus_magic))
		return NULL;

	return (void *)&fw_data[scan - found];
}

int carl9170_fw_fix_eeprom(struct ar9170 *ar)
{
	const struct carl9170fw_fix_desc *fix_desc = NULL;
	unsigned int i, n, off;
	u32 *data = (void *)&ar->eeprom;

	fix_desc = carl9170_fw_find_desc(ar, FIX_MAGIC,
		sizeof(*fix_desc), CARL9170FW_FIX_DESC_CUR_VER);

	if (!fix_desc)
		return 0;

	n = (le16_to_cpu(fix_desc->head.length) - sizeof(*fix_desc)) /
	    sizeof(struct carl9170fw_fix_entry);

	for (i = 0; i < n; i++) {
		off = le32_to_cpu(fix_desc->data[i].address) -
		      AR9170_EEPROM_START;

		if (off >= sizeof(struct ar9170_eeprom) || (off & 3)) {
			dev_err(&ar->udev->dev, "Skip invalid entry %d\n", i);
			continue;
		}

		data[off / sizeof(*data)] &=
			le32_to_cpu(fix_desc->data[i].mask);
		data[off / sizeof(*data)] |=
			le32_to_cpu(fix_desc->data[i].value);
	}

	return 0;
}

int carl9170_parse_firmware(struct ar9170 *ar)
{
	const struct carl9170fw_desc_head *fw_desc = NULL;
	const struct firmware *fw = ar->fw.fw;
	unsigned long header_offset = 0;
	int err;

	if (WARN_ON(!fw))
		return -EINVAL;

	fw_desc = carl9170_find_fw_desc(ar, fw->data, fw->size);

	if (!fw_desc) {
		dev_err(&ar->udev->dev, "unsupported firmware.\n");
		return -ENODATA;
	}

	header_offset = (unsigned long)fw_desc - (unsigned long)fw->data;

	err = carl9170_fw_verify_descs(ar, fw_desc, fw->size - header_offset);
	if (err) {
		dev_err(&ar->udev->dev, "damaged firmware (%d).\n", err);
		return err;
	}

	ar->fw.desc = fw_desc;

	carl9170_fw_info(ar);

	err = carl9170_fw(ar, fw->data, fw->size);
	if (err) {
		dev_err(&ar->udev->dev, "failed to parse firmware (%d).\n",
			err);
		return err;
	}

	return 0;
}
