/*
 * Intel Wireless WiMAX Connection 2400m
 * Firmware uploader
 *
 *
 * Copyright (C) 2007-2008 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 <linux-wimax@intel.com>
 * Yanir Lubetkin <yanirx.lubetkin@intel.com>
 * Inaky Perez-Gonzalez <inaky.perez-gonzalez@intel.com>
 *  - Initial implementation
 *
 *
 * THE PROCEDURE
 *
 * The 2400m and derived devices work in two modes: boot-mode or
 * normal mode. In boot mode we can execute only a handful of commands
 * targeted at uploading the firmware and launching it.
 *
 * The 2400m enters boot mode when it is first connected to the
 * system, when it crashes and when you ask it to reboot. There are
 * two submodes of the boot mode: signed and non-signed. Signed takes
 * firmwares signed with a certain private key, non-signed takes any
 * firmware. Normal hardware takes only signed firmware.
 *
 * On boot mode, in USB, we write to the device using the bulk out
 * endpoint and read from it in the notification endpoint. In SDIO we
 * talk to it via the write address and read from the read address.
 *
 * Upon entrance to boot mode, the device sends (preceeded with a few
 * zero length packets (ZLPs) on the notification endpoint in USB) a
 * reboot barker (4 le32 words with the same value). We ack it by
 * sending the same barker to the device. The device acks with a
 * reboot ack barker (4 le32 words with value I2400M_ACK_BARKER) and
 * then is fully booted. At this point we can upload the firmware.
 *
 * Note that different iterations of the device and EEPROM
 * configurations will send different [re]boot barkers; these are
 * collected in i2400m_barker_db along with the firmware
 * characteristics they require.
 *
 * This process is accomplished by the i2400m_bootrom_init()
 * function. All the device interaction happens through the
 * i2400m_bm_cmd() [boot mode command]. Special return values will
 * indicate if the device did reset during the process.
 *
 * After this, we read the MAC address and then (if needed)
 * reinitialize the device. We need to read it ahead of time because
 * in the future, we might not upload the firmware until userspace
 * 'ifconfig up's the device.
 *
 * We can then upload the firmware file. The file is composed of a BCF
 * header (basic data, keys and signatures) and a list of write
 * commands and payloads. Optionally more BCF headers might follow the
 * main payload. We first upload the header [i2400m_dnload_init()] and
 * then pass the commands and payloads verbatim to the i2400m_bm_cmd()
 * function [i2400m_dnload_bcf()]. Then we tell the device to jump to
 * the new firmware [i2400m_dnload_finalize()].
 *
 * Once firmware is uploaded, we are good to go :)
 *
 * When we don't know in which mode we are, we first try by sending a
 * warm reset request that will take us to boot-mode. If we time out
 * waiting for a reboot barker, that means maybe we are already in
 * boot mode, so we send a reboot barker.
 *
 * COMMAND EXECUTION
 *
 * This code (and process) is single threaded; for executing commands,
 * we post a URB to the notification endpoint, post the command, wait
 * for data on the notification buffer. We don't need to worry about
 * others as we know we are the only ones in there.
 *
 * BACKEND IMPLEMENTATION
 *
 * This code is bus-generic; the bus-specific driver provides back end
 * implementations to send a boot mode command to the device and to
 * read an acknolwedgement from it (or an asynchronous notification)
 * from it.
 *
 * FIRMWARE LOADING
 *
 * Note that in some cases, we can't just load a firmware file (for
 * example, when resuming). For that, we might cache the firmware
 * file. Thus, when doing the bootstrap, if there is a cache firmware
 * file, it is used; if not, loading from disk is attempted.
 *
 * ROADMAP
 *
 * i2400m_barker_db_init              Called by i2400m_driver_init()
 *   i2400m_barker_db_add
 *
 * i2400m_barker_db_exit              Called by i2400m_driver_exit()
 *
 * i2400m_dev_bootstrap               Called by __i2400m_dev_start()
 *   request_firmware
 *   i2400m_fw_bootstrap
 *     i2400m_fw_check
 *       i2400m_fw_hdr_check
 *     i2400m_fw_dnload
 *   release_firmware
 *
 * i2400m_fw_dnload
 *   i2400m_bootrom_init
 *     i2400m_bm_cmd
 *     i2400m_reset
 *   i2400m_dnload_init
 *     i2400m_dnload_init_signed
 *     i2400m_dnload_init_nonsigned
 *       i2400m_download_chunk
 *         i2400m_bm_cmd
 *   i2400m_dnload_bcf
 *     i2400m_bm_cmd
 *   i2400m_dnload_finalize
 *     i2400m_bm_cmd
 *
 * i2400m_bm_cmd
 *   i2400m->bus_bm_cmd_send()
 *   i2400m->bus_bm_wait_for_ack
 *   __i2400m_bm_ack_verify
 *     i2400m_is_boot_barker
 *
 * i2400m_bm_cmd_prepare              Used by bus-drivers to prep
 *                                    commands before sending
 *
 * i2400m_pm_notifier                 Called on Power Management events
 *   i2400m_fw_cache
 *   i2400m_fw_uncache
 */
#include <linux/firmware.h>
#include <linux/sched.h>
#include <linux/usb.h>
#include "i2400m.h"


#define D_SUBMODULE fw
#include "debug-levels.h"


static const __le32 i2400m_ACK_BARKER[4] = {
	cpu_to_le32(I2400M_ACK_BARKER),
	cpu_to_le32(I2400M_ACK_BARKER),
	cpu_to_le32(I2400M_ACK_BARKER),
	cpu_to_le32(I2400M_ACK_BARKER)
};


/**
 * Prepare a boot-mode command for delivery
 *
 * @cmd: pointer to bootrom header to prepare
 *
 * Computes checksum if so needed. After calling this function, DO NOT
 * modify the command or header as the checksum won't work anymore.
 *
 * We do it from here because some times we cannot do it in the
 * original context the command was sent (it is a const), so when we
 * copy it to our staging buffer, we add the checksum there.
 */
void i2400m_bm_cmd_prepare(struct i2400m_bootrom_header *cmd)
{
	if (i2400m_brh_get_use_checksum(cmd)) {
		int i;
		u32 checksum = 0;
		const u32 *checksum_ptr = (void *) cmd->payload;
		for (i = 0; i < cmd->data_size / 4; i++)
			checksum += cpu_to_le32(*checksum_ptr++);
		checksum += cmd->command + cmd->target_addr + cmd->data_size;
		cmd->block_checksum = cpu_to_le32(checksum);
	}
}
EXPORT_SYMBOL_GPL(i2400m_bm_cmd_prepare);


/*
 * Database of known barkers.
 *
 * A barker is what the device sends indicating he is ready to be
 * bootloaded. Different versions of the device will send different
 * barkers. Depending on the barker, it might mean the device wants
 * some kind of firmware or the other.
 */
static struct i2400m_barker_db {
	__le32 data[4];
} *i2400m_barker_db;
static size_t i2400m_barker_db_used, i2400m_barker_db_size;


static
int i2400m_zrealloc_2x(void **ptr, size_t *_count, size_t el_size,
		       gfp_t gfp_flags)
{
	size_t old_count = *_count,
		new_count = old_count ? 2 * old_count : 2,
		old_size = el_size * old_count,
		new_size = el_size * new_count;
	void *nptr = krealloc(*ptr, new_size, gfp_flags);
	if (nptr) {
		/* zero the other half or the whole thing if old_count
		 * was zero */
		if (old_size == 0)
			memset(nptr, 0, new_size);
		else
			memset(nptr + old_size, 0, old_size);
		*_count = new_count;
		*ptr = nptr;
		return 0;
	} else
		return -ENOMEM;
}


/*
 * Add a barker to the database
 *
 * This cannot used outside of this module and only at at module_init
 * time. This is to avoid the need to do locking.
 */
static
int i2400m_barker_db_add(u32 barker_id)
{
	int result;

	struct i2400m_barker_db *barker;
	if (i2400m_barker_db_used >= i2400m_barker_db_size) {
		result = i2400m_zrealloc_2x(
			(void **) &i2400m_barker_db, &i2400m_barker_db_size,
			sizeof(i2400m_barker_db[0]), GFP_KERNEL);
		if (result < 0)
			return result;
	}
	barker = i2400m_barker_db + i2400m_barker_db_used++;
	barker->data[0] = le32_to_cpu(barker_id);
	barker->data[1] = le32_to_cpu(barker_id);
	barker->data[2] = le32_to_cpu(barker_id);
	barker->data[3] = le32_to_cpu(barker_id);
	return 0;
}


void i2400m_barker_db_exit(void)
{
	kfree(i2400m_barker_db);
	i2400m_barker_db = NULL;
	i2400m_barker_db_size = 0;
	i2400m_barker_db_used = 0;
}


/*
 * Helper function to add all the known stable barkers to the barker
 * database.
 */
static
int i2400m_barker_db_known_barkers(void)
{
	int result;

	result = i2400m_barker_db_add(I2400M_NBOOT_BARKER);
	if (result < 0)
		goto error_add;
	result = i2400m_barker_db_add(I2400M_SBOOT_BARKER);
	if (result < 0)
		goto error_add;
	result = i2400m_barker_db_add(I2400M_SBOOT_BARKER_6050);
	if (result < 0)
		goto error_add;
error_add:
       return result;
}


/*
 * Initialize the barker database
 *
 * This can only be used from the module_init function for this
 * module; this is to avoid the need to do locking.
 *
 * @options: command line argument with extra barkers to
 *     recognize. This is a comma-separated list of 32-bit hex
 *     numbers. They are appended to the existing list. Setting 0
 *     cleans the existing list and starts a new one.
 */
int i2400m_barker_db_init(const char *_options)
{
	int result;
	char *options = NULL, *options_orig, *token;

	i2400m_barker_db = NULL;
	i2400m_barker_db_size = 0;
	i2400m_barker_db_used = 0;

	result = i2400m_barker_db_known_barkers();
	if (result < 0)
		goto error_add;
	/* parse command line options from i2400m.barkers */
	if (_options != NULL) {
		unsigned barker;

		options_orig = kstrdup(_options, GFP_KERNEL);
		if (options_orig == NULL)
			goto error_parse;
		options = options_orig;

		while ((token = strsep(&options, ",")) != NULL) {
			if (*token == '\0')	/* eat joint commas */
				continue;
			if (sscanf(token, "%x", &barker) != 1
			    || barker > 0xffffffff) {
				printk(KERN_ERR "%s: can't recognize "
				       "i2400m.barkers value '%s' as "
				       "a 32-bit number\n",
				       __func__, token);
				result = -EINVAL;
				goto error_parse;
			}
			if (barker == 0) {
				/* clean list and start new */
				i2400m_barker_db_exit();
				continue;
			}
			result = i2400m_barker_db_add(barker);
			if (result < 0)
				goto error_add;
		}
		kfree(options_orig);
	}
	return 0;

error_parse:
error_add:
	kfree(i2400m_barker_db);
	return result;
}


/*
 * Recognize a boot barker
 *
 * @buf: buffer where the boot barker.
 * @buf_size: size of the buffer (has to be 16 bytes). It is passed
 *     here so the function can check it for the caller.
 *
 * Note that as a side effect, upon identifying the obtained boot
 * barker, this function will set i2400m->barker to point to the right
 * barker database entry. Subsequent calls to the function will result
 * in verifying that the same type of boot barker is returned when the
 * device [re]boots (as long as the same device instance is used).
 *
 * Return: 0 if @buf matches a known boot barker. -ENOENT if the
 *     buffer in @buf doesn't match any boot barker in the database or
 *     -EILSEQ if the buffer doesn't have the right size.
 */
int i2400m_is_boot_barker(struct i2400m *i2400m,
			  const void *buf, size_t buf_size)
{
	int result;
	struct device *dev = i2400m_dev(i2400m);
	struct i2400m_barker_db *barker;
	int i;

	result = -ENOENT;
	if (buf_size != sizeof(i2400m_barker_db[i].data))
		return result;

	/* Short circuit if we have already discovered the barker
	 * associated with the device. */
	if (i2400m->barker
	    && !memcmp(buf, i2400m->barker, sizeof(i2400m->barker->data))) {
		unsigned index = (i2400m->barker - i2400m_barker_db)
			/ sizeof(*i2400m->barker);
		d_printf(2, dev, "boot barker cache-confirmed #%u/%08x\n",
			 index, le32_to_cpu(i2400m->barker->data[0]));
		return 0;
	}

	for (i = 0; i < i2400m_barker_db_used; i++) {
		barker = &i2400m_barker_db[i];
		BUILD_BUG_ON(sizeof(barker->data) != 16);
		if (memcmp(buf, barker->data, sizeof(barker->data)))
			continue;

		if (i2400m->barker == NULL) {
			i2400m->barker = barker;
			d_printf(1, dev, "boot barker set to #%u/%08x\n",
				 i, le32_to_cpu(barker->data[0]));
			if (barker->data[0] == le32_to_cpu(I2400M_NBOOT_BARKER))
				i2400m->sboot = 0;
			else
				i2400m->sboot = 1;
		} else if (i2400m->barker != barker) {
			dev_err(dev, "HW inconsistency: device "
				"reports a different boot barker "
				"than set (from %08x to %08x)\n",
				le32_to_cpu(i2400m->barker->data[0]),
				le32_to_cpu(barker->data[0]));
			result = -EIO;
		} else
			d_printf(2, dev, "boot barker confirmed #%u/%08x\n",
				 i, le32_to_cpu(barker->data[0]));
		result = 0;
		break;
	}
	return result;
}
EXPORT_SYMBOL_GPL(i2400m_is_boot_barker);


/*
 * Verify the ack data received
 *
 * Given a reply to a boot mode command, chew it and verify everything
 * is ok.
 *
 * @opcode: opcode which generated this ack. For error messages.
 * @ack: pointer to ack data we received
 * @ack_size: size of that data buffer
 * @flags: I2400M_BM_CMD_* flags we called the command with.
 *
 * Way too long function -- maybe it should be further split
 */
static
ssize_t __i2400m_bm_ack_verify(struct i2400m *i2400m, int opcode,
			       struct i2400m_bootrom_header *ack,
			       size_t ack_size, int flags)
{
	ssize_t result = -ENOMEM;
	struct device *dev = i2400m_dev(i2400m);

	d_fnstart(8, dev, "(i2400m %p opcode %d ack %p size %zu)\n",
		  i2400m, opcode, ack, ack_size);
	if (ack_size < sizeof(*ack)) {
		result = -EIO;
		dev_err(dev, "boot-mode cmd %d: HW BUG? notification didn't "
			"return enough data (%zu bytes vs %zu expected)\n",
			opcode, ack_size, sizeof(*ack));
		goto error_ack_short;
	}
	result = i2400m_is_boot_barker(i2400m, ack, ack_size);
	if (result >= 0) {
		result = -ERESTARTSYS;
		d_printf(6, dev, "boot-mode cmd %d: HW boot barker\n", opcode);
		goto error_reboot;
	}
	if (ack_size == sizeof(i2400m_ACK_BARKER)
		 && memcmp(ack, i2400m_ACK_BARKER, sizeof(*ack)) == 0) {
		result = -EISCONN;
		d_printf(3, dev, "boot-mode cmd %d: HW reboot ack barker\n",
			 opcode);
		goto error_reboot_ack;
	}
	result = 0;
	if (flags & I2400M_BM_CMD_RAW)
		goto out_raw;
	ack->data_size = le32_to_cpu(ack->data_size);
	ack->target_addr = le32_to_cpu(ack->target_addr);
	ack->block_checksum = le32_to_cpu(ack->block_checksum);
	d_printf(5, dev, "boot-mode cmd %d: notification for opcode %u "
		 "response %u csum %u rr %u da %u\n",
		 opcode, i2400m_brh_get_opcode(ack),
		 i2400m_brh_get_response(ack),
		 i2400m_brh_get_use_checksum(ack),
		 i2400m_brh_get_response_required(ack),
		 i2400m_brh_get_direct_access(ack));
	result = -EIO;
	if (i2400m_brh_get_signature(ack) != 0xcbbc) {
		dev_err(dev, "boot-mode cmd %d: HW BUG? wrong signature "
			"0x%04x\n", opcode, i2400m_brh_get_signature(ack));
		goto error_ack_signature;
	}
	if (opcode != -1 && opcode != i2400m_brh_get_opcode(ack)) {
		dev_err(dev, "boot-mode cmd %d: HW BUG? "
			"received response for opcode %u, expected %u\n",
			opcode, i2400m_brh_get_opcode(ack), opcode);
		goto error_ack_opcode;
	}
	if (i2400m_brh_get_response(ack) != 0) {	/* failed? */
		dev_err(dev, "boot-mode cmd %d: error; hw response %u\n",
			opcode, i2400m_brh_get_response(ack));
		goto error_ack_failed;
	}
	if (ack_size < ack->data_size + sizeof(*ack)) {
		dev_err(dev, "boot-mode cmd %d: SW BUG "
			"driver provided only %zu bytes for %zu bytes "
			"of data\n", opcode, ack_size,
			(size_t) le32_to_cpu(ack->data_size) + sizeof(*ack));
		goto error_ack_short_buffer;
	}
	result = ack_size;
	/* Don't you love this stack of empty targets? Well, I don't
	 * either, but it helps track exactly who comes in here and
	 * why :) */
error_ack_short_buffer:
error_ack_failed:
error_ack_opcode:
error_ack_signature:
out_raw:
error_reboot_ack:
error_reboot:
error_ack_short:
	d_fnend(8, dev, "(i2400m %p opcode %d ack %p size %zu) = %d\n",
		i2400m, opcode, ack, ack_size, (int) result);
	return result;
}


/**
 * i2400m_bm_cmd - Execute a boot mode command
 *
 * @cmd: buffer containing the command data (pointing at the header).
 *     This data can be ANYWHERE (for USB, we will copy it to an
 *     specific buffer). Make sure everything is in proper little
 *     endian.
 *
 *     A raw buffer can be also sent, just cast it and set flags to
 *     I2400M_BM_CMD_RAW.
 *
 *     This function will generate a checksum for you if the
 *     checksum bit in the command is set (unless I2400M_BM_CMD_RAW
 *     is set).
 *
 *     You can use the i2400m->bm_cmd_buf to stage your commands and
 *     send them.
 *
 *     If NULL, no command is sent (we just wait for an ack).
 *
 * @cmd_size: size of the command. Will be auto padded to the
 *     bus-specific drivers padding requirements.
 *
 * @ack: buffer where to place the acknowledgement. If it is a regular
 *     command response, all fields will be returned with the right,
 *     native endianess.
 *
 *     You *cannot* use i2400m->bm_ack_buf for this buffer.
 *
 * @ack_size: size of @ack, 16 aligned; you need to provide at least
 *     sizeof(*ack) bytes and then enough to contain the return data
 *     from the command
 *
 * @flags: see I2400M_BM_CMD_* above.
 *
 * @returns: bytes received by the notification; if < 0, an errno code
 *     denoting an error or:
 *
 *     -ERESTARTSYS  The device has rebooted
 *
 * Executes a boot-mode command and waits for a response, doing basic
 * validation on it; if a zero length response is received, it retries
 * waiting for a response until a non-zero one is received (timing out
 * after %I2400M_BOOT_RETRIES retries).
 */
static
ssize_t i2400m_bm_cmd(struct i2400m *i2400m,
		      const struct i2400m_bootrom_header *cmd, size_t cmd_size,
		      struct i2400m_bootrom_header *ack, size_t ack_size,
		      int flags)
{
	ssize_t result = -ENOMEM, rx_bytes;
	struct device *dev = i2400m_dev(i2400m);
	int opcode = cmd == NULL ? -1 : i2400m_brh_get_opcode(cmd);

	d_fnstart(6, dev, "(i2400m %p cmd %p size %zu ack %p size %zu)\n",
		  i2400m, cmd, cmd_size, ack, ack_size);
	BUG_ON(ack_size < sizeof(*ack));
	BUG_ON(i2400m->boot_mode == 0);

	if (cmd != NULL) {		/* send the command */
		result = i2400m->bus_bm_cmd_send(i2400m, cmd, cmd_size, flags);
		if (result < 0)
			goto error_cmd_send;
		if ((flags & I2400M_BM_CMD_RAW) == 0)
			d_printf(5, dev,
				 "boot-mode cmd %d csum %u rr %u da %u: "
				 "addr 0x%04x size %u block csum 0x%04x\n",
				 opcode, i2400m_brh_get_use_checksum(cmd),
				 i2400m_brh_get_response_required(cmd),
				 i2400m_brh_get_direct_access(cmd),
				 cmd->target_addr, cmd->data_size,
				 cmd->block_checksum);
	}
	result = i2400m->bus_bm_wait_for_ack(i2400m, ack, ack_size);
	if (result < 0) {
		dev_err(dev, "boot-mode cmd %d: error waiting for an ack: %d\n",
			opcode, (int) result);	/* bah, %zd doesn't work */
		goto error_wait_for_ack;
	}
	rx_bytes = result;
	/* verify the ack and read more if necessary [result is the
	 * final amount of bytes we get in the ack]  */
	result = __i2400m_bm_ack_verify(i2400m, opcode, ack, ack_size, flags);
	if (result < 0)
		goto error_bad_ack;
	/* Don't you love this stack of empty targets? Well, I don't
	 * either, but it helps track exactly who comes in here and
	 * why :) */
	result = rx_bytes;
error_bad_ack:
error_wait_for_ack:
error_cmd_send:
	d_fnend(6, dev, "(i2400m %p cmd %p size %zu ack %p size %zu) = %d\n",
		i2400m, cmd, cmd_size, ack, ack_size, (int) result);
	return result;
}


/**
 * i2400m_download_chunk - write a single chunk of data to the device's memory
 *
 * @i2400m: device descriptor
 * @buf: the buffer to write
 * @buf_len: length of the buffer to write
 * @addr: address in the device memory space
 * @direct: bootrom write mode
 * @do_csum: should a checksum validation be performed
 */
static int i2400m_download_chunk(struct i2400m *i2400m, const void *chunk,
				 size_t __chunk_len, unsigned long addr,
				 unsigned int direct, unsigned int do_csum)
{
	int ret;
	size_t chunk_len = ALIGN(__chunk_len, I2400M_PL_ALIGN);
	struct device *dev = i2400m_dev(i2400m);
	struct {
		struct i2400m_bootrom_header cmd;
		u8 cmd_payload[chunk_len];
	} __attribute__((packed)) *buf;
	struct i2400m_bootrom_header ack;

	d_fnstart(5, dev, "(i2400m %p chunk %p __chunk_len %zu addr 0x%08lx "
		  "direct %u do_csum %u)\n", i2400m, chunk, __chunk_len,
		  addr, direct, do_csum);
	buf = i2400m->bm_cmd_buf;
	memcpy(buf->cmd_payload, chunk, __chunk_len);
	memset(buf->cmd_payload + __chunk_len, 0xad, chunk_len - __chunk_len);

	buf->cmd.command = i2400m_brh_command(I2400M_BRH_WRITE,
					      __chunk_len & 0x3 ? 0 : do_csum,
					      __chunk_len & 0xf ? 0 : direct);
	buf->cmd.target_addr = cpu_to_le32(addr);
	buf->cmd.data_size = cpu_to_le32(__chunk_len);
	ret = i2400m_bm_cmd(i2400m, &buf->cmd, sizeof(buf->cmd) + chunk_len,
			    &ack, sizeof(ack), 0);
	if (ret >= 0)
		ret = 0;
	d_fnend(5, dev, "(i2400m %p chunk %p __chunk_len %zu addr 0x%08lx "
		"direct %u do_csum %u) = %d\n", i2400m, chunk, __chunk_len,
		addr, direct, do_csum, ret);
	return ret;
}


/*
 * Download a BCF file's sections to the device
 *
 * @i2400m: device descriptor
 * @bcf: pointer to firmware data (first header followed by the
 *     payloads). Assumed verified and consistent.
 * @bcf_len: length (in bytes) of the @bcf buffer.
 *
 * Returns: < 0 errno code on error or the offset to the jump instruction.
 *
 * Given a BCF file, downloads each section (a command and a payload)
 * to the device's address space. Actually, it just executes each
 * command i the BCF file.
 *
 * The section size has to be aligned to 4 bytes AND the padding has
 * to be taken from the firmware file, as the signature takes it into
 * account.
 */
static
ssize_t i2400m_dnload_bcf(struct i2400m *i2400m,
			  const struct i2400m_bcf_hdr *bcf, size_t bcf_len)
{
	ssize_t ret;
	struct device *dev = i2400m_dev(i2400m);
	size_t offset,		/* iterator offset */
		data_size,	/* Size of the data payload */
		section_size,	/* Size of the whole section (cmd + payload) */
		section = 1;
	const struct i2400m_bootrom_header *bh;
	struct i2400m_bootrom_header ack;

	d_fnstart(3, dev, "(i2400m %p bcf %p bcf_len %zu)\n",
		  i2400m, bcf, bcf_len);
	/* Iterate over the command blocks in the BCF file that start
	 * after the header */
	offset = le32_to_cpu(bcf->header_len) * sizeof(u32);
	while (1) {	/* start sending the file */
		bh = (void *) bcf + offset;
		data_size = le32_to_cpu(bh->data_size);
		section_size = ALIGN(sizeof(*bh) + data_size, 4);
		d_printf(7, dev,
			 "downloading section #%zu (@%zu %zu B) to 0x%08x\n",
			 section, offset, sizeof(*bh) + data_size,
			 le32_to_cpu(bh->target_addr));
		/*
		 * We look for JUMP cmd from the bootmode header,
		 * either I2400M_BRH_SIGNED_JUMP for secure boot
		 * or I2400M_BRH_JUMP for unsecure boot, the last chunk
		 * should be the bootmode header with JUMP cmd.
		 */
		if (i2400m_brh_get_opcode(bh) == I2400M_BRH_SIGNED_JUMP ||
			i2400m_brh_get_opcode(bh) == I2400M_BRH_JUMP) {
			d_printf(5, dev,  "jump found @%zu\n", offset);
			break;
		}
		if (offset + section_size > bcf_len) {
			dev_err(dev, "fw %s: bad section #%zu, "
				"end (@%zu) beyond EOF (@%zu)\n",
				i2400m->fw_name, section,
				offset + section_size,  bcf_len);
			ret = -EINVAL;
			goto error_section_beyond_eof;
		}
		__i2400m_msleep(20);
		ret = i2400m_bm_cmd(i2400m, bh, section_size,
				    &ack, sizeof(ack), I2400M_BM_CMD_RAW);
		if (ret < 0) {
			dev_err(dev, "fw %s: section #%zu (@%zu %zu B) "
				"failed %d\n", i2400m->fw_name, section,
				offset, sizeof(*bh) + data_size, (int) ret);
			goto error_send;
		}
		offset += section_size;
		section++;
	}
	ret = offset;
error_section_beyond_eof:
error_send:
	d_fnend(3, dev, "(i2400m %p bcf %p bcf_len %zu) = %d\n",
		i2400m, bcf, bcf_len, (int) ret);
	return ret;
}


/*
 * Indicate if the device emitted a reboot barker that indicates
 * "signed boot"
 */
static
unsigned i2400m_boot_is_signed(struct i2400m *i2400m)
{
	return likely(i2400m->sboot);
}


/*
 * Do the final steps of uploading firmware
 *
 * @bcf_hdr: BCF header we are actually using
 * @bcf: pointer to the firmware image (which matches the first header
 *     that is followed by the actual payloads).
 * @offset: [byte] offset into @bcf for the command we need to send.
 *
 * Depending on the boot mode (signed vs non-signed), different
 * actions need to be taken.
 */
static
int i2400m_dnload_finalize(struct i2400m *i2400m,
			   const struct i2400m_bcf_hdr *bcf_hdr,
			   const struct i2400m_bcf_hdr *bcf, size_t offset)
{
	int ret = 0;
	struct device *dev = i2400m_dev(i2400m);
	struct i2400m_bootrom_header *cmd, ack;
	struct {
		struct i2400m_bootrom_header cmd;
		u8 cmd_pl[0];
	} __attribute__((packed)) *cmd_buf;
	size_t signature_block_offset, signature_block_size;

	d_fnstart(3, dev, "offset %zu\n", offset);
	cmd = (void *) bcf + offset;
	if (i2400m_boot_is_signed(i2400m) == 0) {
		struct i2400m_bootrom_header jump_ack;
		d_printf(1, dev, "unsecure boot, jumping to 0x%08x\n",
			le32_to_cpu(cmd->target_addr));
		cmd_buf = i2400m->bm_cmd_buf;
		memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd));
		cmd = &cmd_buf->cmd;
		/* now cmd points to the actual bootrom_header in cmd_buf */
		i2400m_brh_set_opcode(cmd, I2400M_BRH_JUMP);
		cmd->data_size = 0;
		ret = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
				    &jump_ack, sizeof(jump_ack), 0);
	} else {
		d_printf(1, dev, "secure boot, jumping to 0x%08x\n",
			 le32_to_cpu(cmd->target_addr));
		cmd_buf = i2400m->bm_cmd_buf;
		memcpy(&cmd_buf->cmd, cmd, sizeof(*cmd));
		signature_block_offset =
			sizeof(*bcf_hdr)
			+ le32_to_cpu(bcf_hdr->key_size) * sizeof(u32)
			+ le32_to_cpu(bcf_hdr->exponent_size) * sizeof(u32);
		signature_block_size =
			le32_to_cpu(bcf_hdr->modulus_size) * sizeof(u32);
		memcpy(cmd_buf->cmd_pl,
		       (void *) bcf_hdr + signature_block_offset,
		       signature_block_size);
		ret = i2400m_bm_cmd(i2400m, &cmd_buf->cmd,
				    sizeof(cmd_buf->cmd) + signature_block_size,
				    &ack, sizeof(ack), I2400M_BM_CMD_RAW);
	}
	d_fnend(3, dev, "returning %d\n", ret);
	return ret;
}


/**
 * i2400m_bootrom_init - Reboots a powered device into boot mode
 *
 * @i2400m: device descriptor
 * @flags:
 *      I2400M_BRI_SOFT: a reboot barker has been seen
 *          already, so don't wait for it.
 *
 *      I2400M_BRI_NO_REBOOT: Don't send a reboot command, but wait
 *          for a reboot barker notification. This is a one shot; if
 *          the state machine needs to send a reboot command it will.
 *
 * Returns:
 *
 *     < 0 errno code on error, 0 if ok.
 *
 * Description:
 *
 * Tries hard enough to put the device in boot-mode. There are two
 * main phases to this:
 *
 * a. (1) send a reboot command and (2) get a reboot barker
 *
 * b. (1) echo/ack the reboot sending the reboot barker back and (2)
 *        getting an ack barker in return
 *
 * We want to skip (a) in some cases [soft]. The state machine is
 * horrible, but it is basically: on each phase, send what has to be
 * sent (if any), wait for the answer and act on the answer. We might
 * have to backtrack and retry, so we keep a max tries counter for
 * that.
 *
 * It sucks because we don't know ahead of time which is going to be
 * the reboot barker (the device might send different ones depending
 * on its EEPROM config) and once the device reboots and waits for the
 * echo/ack reboot barker being sent back, it doesn't understand
 * anything else. So we can be left at the point where we don't know
 * what to send to it -- cold reset and bus reset seem to have little
 * effect. So the function iterates (in this case) through all the
 * known barkers and tries them all until an ACK is
 * received. Otherwise, it gives up.
 *
 * If we get a timeout after sending a warm reset, we do it again.
 */
int i2400m_bootrom_init(struct i2400m *i2400m, enum i2400m_bri flags)
{
	int result;
	struct device *dev = i2400m_dev(i2400m);
	struct i2400m_bootrom_header *cmd;
	struct i2400m_bootrom_header ack;
	int count = i2400m->bus_bm_retries;
	int ack_timeout_cnt = 1;
	unsigned i;

	BUILD_BUG_ON(sizeof(*cmd) != sizeof(i2400m_barker_db[0].data));
	BUILD_BUG_ON(sizeof(ack) != sizeof(i2400m_ACK_BARKER));

	d_fnstart(4, dev, "(i2400m %p flags 0x%08x)\n", i2400m, flags);
	result = -ENOMEM;
	cmd = i2400m->bm_cmd_buf;
	if (flags & I2400M_BRI_SOFT)
		goto do_reboot_ack;
do_reboot:
	ack_timeout_cnt = 1;
	if (--count < 0)
		goto error_timeout;
	d_printf(4, dev, "device reboot: reboot command [%d # left]\n",
		 count);
	if ((flags & I2400M_BRI_NO_REBOOT) == 0)
		i2400m_reset(i2400m, I2400M_RT_WARM);
	result = i2400m_bm_cmd(i2400m, NULL, 0, &ack, sizeof(ack),
			       I2400M_BM_CMD_RAW);
	flags &= ~I2400M_BRI_NO_REBOOT;
	switch (result) {
	case -ERESTARTSYS:
		/*
		 * at this point, i2400m_bm_cmd(), through
		 * __i2400m_bm_ack_process(), has updated
		 * i2400m->barker and we are good to go.
		 */
		d_printf(4, dev, "device reboot: got reboot barker\n");
		break;
	case -EISCONN:	/* we don't know how it got here...but we follow it */
		d_printf(4, dev, "device reboot: got ack barker - whatever\n");
		goto do_reboot;
	case -ETIMEDOUT:
		/*
		 * Device has timed out, we might be in boot mode
		 * already and expecting an ack; if we don't know what
		 * the barker is, we just send them all. Cold reset
		 * and bus reset don't work. Beats me.
		 */
		if (i2400m->barker != NULL) {
			dev_err(dev, "device boot: reboot barker timed out, "
				"trying (set) %08x echo/ack\n",
				le32_to_cpu(i2400m->barker->data[0]));
			goto do_reboot_ack;
		}
		for (i = 0; i < i2400m_barker_db_used; i++) {
			struct i2400m_barker_db *barker = &i2400m_barker_db[i];
			memcpy(cmd, barker->data, sizeof(barker->data));
			result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
					       &ack, sizeof(ack),
					       I2400M_BM_CMD_RAW);
			if (result == -EISCONN) {
				dev_warn(dev, "device boot: got ack barker "
					 "after sending echo/ack barker "
					 "#%d/%08x; rebooting j.i.c.\n",
					 i, le32_to_cpu(barker->data[0]));
				flags &= ~I2400M_BRI_NO_REBOOT;
				goto do_reboot;
			}
		}
		dev_err(dev, "device boot: tried all the echo/acks, could "
			"not get device to respond; giving up");
		result = -ESHUTDOWN;
	case -EPROTO:
	case -ESHUTDOWN:	/* dev is gone */
	case -EINTR:		/* user cancelled */
		goto error_dev_gone;
	default:
		dev_err(dev, "device reboot: error %d while waiting "
			"for reboot barker - rebooting\n", result);
		d_dump(1, dev, &ack, result);
		goto do_reboot;
	}
	/* At this point we ack back with 4 REBOOT barkers and expect
	 * 4 ACK barkers. This is ugly, as we send a raw command --
	 * hence the cast. _bm_cmd() will catch the reboot ack
	 * notification and report it as -EISCONN. */
do_reboot_ack:
	d_printf(4, dev, "device reboot ack: sending ack [%d # left]\n", count);
	memcpy(cmd, i2400m->barker->data, sizeof(i2400m->barker->data));
	result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
			       &ack, sizeof(ack), I2400M_BM_CMD_RAW);
	switch (result) {
	case -ERESTARTSYS:
		d_printf(4, dev, "reboot ack: got reboot barker - retrying\n");
		if (--count < 0)
			goto error_timeout;
		goto do_reboot_ack;
	case -EISCONN:
		d_printf(4, dev, "reboot ack: got ack barker - good\n");
		break;
	case -ETIMEDOUT:	/* no response, maybe it is the other type? */
		if (ack_timeout_cnt-- < 0) {
			d_printf(4, dev, "reboot ack timedout: retrying\n");
			goto do_reboot_ack;
		} else {
			dev_err(dev, "reboot ack timedout too long: "
				"trying reboot\n");
			goto do_reboot;
		}
		break;
	case -EPROTO:
	case -ESHUTDOWN:	/* dev is gone */
		goto error_dev_gone;
	default:
		dev_err(dev, "device reboot ack: error %d while waiting for "
			"reboot ack barker - rebooting\n", result);
		goto do_reboot;
	}
	d_printf(2, dev, "device reboot ack: got ack barker - boot done\n");
	result = 0;
exit_timeout:
error_dev_gone:
	d_fnend(4, dev, "(i2400m %p flags 0x%08x) = %d\n",
		i2400m, flags, result);
	return result;

error_timeout:
	dev_err(dev, "Timed out waiting for reboot ack\n");
	result = -ETIMEDOUT;
	goto exit_timeout;
}


/*
 * Read the MAC addr
 *
 * The position this function reads is fixed in device memory and
 * always available, even without firmware.
 *
 * Note we specify we want to read only six bytes, but provide space
 * for 16, as we always get it rounded up.
 */
int i2400m_read_mac_addr(struct i2400m *i2400m)
{
	int result;
	struct device *dev = i2400m_dev(i2400m);
	struct net_device *net_dev = i2400m->wimax_dev.net_dev;
	struct i2400m_bootrom_header *cmd;
	struct {
		struct i2400m_bootrom_header ack;
		u8 ack_pl[16];
	} __attribute__((packed)) ack_buf;

	d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
	cmd = i2400m->bm_cmd_buf;
	cmd->command = i2400m_brh_command(I2400M_BRH_READ, 0, 1);
	cmd->target_addr = cpu_to_le32(0x00203fe8);
	cmd->data_size = cpu_to_le32(6);
	result = i2400m_bm_cmd(i2400m, cmd, sizeof(*cmd),
			       &ack_buf.ack, sizeof(ack_buf), 0);
	if (result < 0) {
		dev_err(dev, "BM: read mac addr failed: %d\n", result);
		goto error_read_mac;
	}
	d_printf(2, dev,
		 "mac addr is %02x:%02x:%02x:%02x:%02x:%02x\n",
		 ack_buf.ack_pl[0], ack_buf.ack_pl[1],
		 ack_buf.ack_pl[2], ack_buf.ack_pl[3],
		 ack_buf.ack_pl[4], ack_buf.ack_pl[5]);
	if (i2400m->bus_bm_mac_addr_impaired == 1) {
		ack_buf.ack_pl[0] = 0x00;
		ack_buf.ack_pl[1] = 0x16;
		ack_buf.ack_pl[2] = 0xd3;
		get_random_bytes(&ack_buf.ack_pl[3], 3);
		dev_err(dev, "BM is MAC addr impaired, faking MAC addr to "
			"mac addr is %02x:%02x:%02x:%02x:%02x:%02x\n",
			ack_buf.ack_pl[0], ack_buf.ack_pl[1],
			ack_buf.ack_pl[2], ack_buf.ack_pl[3],
			ack_buf.ack_pl[4], ack_buf.ack_pl[5]);
		result = 0;
	}
	net_dev->addr_len = ETH_ALEN;
	memcpy(net_dev->perm_addr, ack_buf.ack_pl, ETH_ALEN);
	memcpy(net_dev->dev_addr, ack_buf.ack_pl, ETH_ALEN);
error_read_mac:
	d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, result);
	return result;
}


/*
 * Initialize a non signed boot
 *
 * This implies sending some magic values to the device's memory. Note
 * we convert the values to little endian in the same array
 * declaration.
 */
static
int i2400m_dnload_init_nonsigned(struct i2400m *i2400m)
{
	unsigned i = 0;
	int ret = 0;
	struct device *dev = i2400m_dev(i2400m);
	d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
	if (i2400m->bus_bm_pokes_table) {
		while (i2400m->bus_bm_pokes_table[i].address) {
			ret = i2400m_download_chunk(
				i2400m,
				&i2400m->bus_bm_pokes_table[i].data,
				sizeof(i2400m->bus_bm_pokes_table[i].data),
				i2400m->bus_bm_pokes_table[i].address, 1, 1);
			if (ret < 0)
				break;
			i++;
		}
	}
	d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
	return ret;
}


/*
 * Initialize the signed boot process
 *
 * @i2400m: device descriptor
 *
 * @bcf_hdr: pointer to the firmware header; assumes it is fully in
 *     memory (it has gone through basic validation).
 *
 * Returns: 0 if ok, < 0 errno code on error, -ERESTARTSYS if the hw
 *     rebooted.
 *
 * This writes the firmware BCF header to the device using the
 * HASH_PAYLOAD_ONLY command.
 */
static
int i2400m_dnload_init_signed(struct i2400m *i2400m,
			      const struct i2400m_bcf_hdr *bcf_hdr)
{
	int ret;
	struct device *dev = i2400m_dev(i2400m);
	struct {
		struct i2400m_bootrom_header cmd;
		struct i2400m_bcf_hdr cmd_pl;
	} __attribute__((packed)) *cmd_buf;
	struct i2400m_bootrom_header ack;

	d_fnstart(5, dev, "(i2400m %p bcf_hdr %p)\n", i2400m, bcf_hdr);
	cmd_buf = i2400m->bm_cmd_buf;
	cmd_buf->cmd.command =
		i2400m_brh_command(I2400M_BRH_HASH_PAYLOAD_ONLY, 0, 0);
	cmd_buf->cmd.target_addr = 0;
	cmd_buf->cmd.data_size = cpu_to_le32(sizeof(cmd_buf->cmd_pl));
	memcpy(&cmd_buf->cmd_pl, bcf_hdr, sizeof(*bcf_hdr));
	ret = i2400m_bm_cmd(i2400m, &cmd_buf->cmd, sizeof(*cmd_buf),
			    &ack, sizeof(ack), 0);
	if (ret >= 0)
		ret = 0;
	d_fnend(5, dev, "(i2400m %p bcf_hdr %p) = %d\n", i2400m, bcf_hdr, ret);
	return ret;
}


/*
 * Initialize the firmware download at the device size
 *
 * Multiplex to the one that matters based on the device's mode
 * (signed or non-signed).
 */
static
int i2400m_dnload_init(struct i2400m *i2400m,
		       const struct i2400m_bcf_hdr *bcf_hdr)
{
	int result;
	struct device *dev = i2400m_dev(i2400m);

	if (i2400m_boot_is_signed(i2400m)) {
		d_printf(1, dev, "signed boot\n");
		result = i2400m_dnload_init_signed(i2400m, bcf_hdr);
		if (result == -ERESTARTSYS)
			return result;
		if (result < 0)
			dev_err(dev, "firmware %s: signed boot download "
				"initialization failed: %d\n",
				i2400m->fw_name, result);
	} else {
		/* non-signed boot process without pokes */
		d_printf(1, dev, "non-signed boot\n");
		result = i2400m_dnload_init_nonsigned(i2400m);
		if (result == -ERESTARTSYS)
			return result;
		if (result < 0)
			dev_err(dev, "firmware %s: non-signed download "
				"initialization failed: %d\n",
				i2400m->fw_name, result);
	}
	return result;
}


/*
 * Run consistency tests on the firmware file and load up headers
 *
 * Check for the firmware being made for the i2400m device,
 * etc...These checks are mostly informative, as the device will make
 * them too; but the driver's response is more informative on what
 * went wrong.
 *
 * This will also look at all the headers present on the firmware
 * file, and update i2400m->fw_bcf_hdr to point to them.
 */
static
int i2400m_fw_hdr_check(struct i2400m *i2400m,
			const struct i2400m_bcf_hdr *bcf_hdr,
			size_t index, size_t offset)
{
	struct device *dev = i2400m_dev(i2400m);

	unsigned module_type, header_len, major_version, minor_version,
		module_id, module_vendor, date, size;

	module_type = bcf_hdr->module_type;
	header_len = sizeof(u32) * le32_to_cpu(bcf_hdr->header_len);
	major_version = (le32_to_cpu(bcf_hdr->header_version) & 0xffff0000)
		>> 16;
	minor_version = le32_to_cpu(bcf_hdr->header_version) & 0x0000ffff;
	module_id = le32_to_cpu(bcf_hdr->module_id);
	module_vendor = le32_to_cpu(bcf_hdr->module_vendor);
	date = le32_to_cpu(bcf_hdr->date);
	size = sizeof(u32) * le32_to_cpu(bcf_hdr->size);

	d_printf(1, dev, "firmware %s #%zd@%08zx: BCF header "
		 "type:vendor:id 0x%x:%x:%x v%u.%u (%u/%u B) built %08x\n",
		 i2400m->fw_name, index, offset,
		 module_type, module_vendor, module_id,
		 major_version, minor_version, header_len, size, date);

	/* Hard errors */
	if (major_version != 1) {
		dev_err(dev, "firmware %s #%zd@%08zx: major header version "
			"v%u.%u not supported\n",
			i2400m->fw_name, index, offset,
			major_version, minor_version);
		return -EBADF;
	}

	if (module_type != 6) {		/* built for the right hardware? */
		dev_err(dev, "firmware %s #%zd@%08zx: unexpected module "
			"type 0x%x; aborting\n",
			i2400m->fw_name, index, offset,
			module_type);
		return -EBADF;
	}

	if (module_vendor != 0x8086) {
		dev_err(dev, "firmware %s #%zd@%08zx: unexpected module "
			"vendor 0x%x; aborting\n",
			i2400m->fw_name, index, offset, module_vendor);
		return -EBADF;
	}

	if (date < 0x20080300)
		dev_warn(dev, "firmware %s #%zd@%08zx: build date %08x "
			 "too old; unsupported\n",
			 i2400m->fw_name, index, offset, date);
	return 0;
}


/*
 * Run consistency tests on the firmware file and load up headers
 *
 * Check for the firmware being made for the i2400m device,
 * etc...These checks are mostly informative, as the device will make
 * them too; but the driver's response is more informative on what
 * went wrong.
 *
 * This will also look at all the headers present on the firmware
 * file, and update i2400m->fw_hdrs to point to them.
 */
static
int i2400m_fw_check(struct i2400m *i2400m, const void *bcf, size_t bcf_size)
{
	int result;
	struct device *dev = i2400m_dev(i2400m);
	size_t headers = 0;
	const struct i2400m_bcf_hdr *bcf_hdr;
	const void *itr, *next, *top;
	size_t slots = 0, used_slots = 0;

	for (itr = bcf, top = itr + bcf_size;
	     itr < top;
	     headers++, itr = next) {
		size_t leftover, offset, header_len, size;

		leftover = top - itr;
		offset = itr - (const void *) bcf;
		if (leftover <= sizeof(*bcf_hdr)) {
			dev_err(dev, "firmware %s: %zu B left at @%zx, "
				"not enough for BCF header\n",
				i2400m->fw_name, leftover, offset);
			break;
		}
		bcf_hdr = itr;
		/* Only the first header is supposed to be followed by
		 * payload */
		header_len = sizeof(u32) * le32_to_cpu(bcf_hdr->header_len);
		size = sizeof(u32) * le32_to_cpu(bcf_hdr->size);
		if (headers == 0)
			next = itr + size;
		else
			next = itr + header_len;

		result = i2400m_fw_hdr_check(i2400m, bcf_hdr, headers, offset);
		if (result < 0)
			continue;
		if (used_slots + 1 >= slots) {
			/* +1 -> we need to account for the one we'll
			 * occupy and at least an extra one for
			 * always being NULL */
			result = i2400m_zrealloc_2x(
				(void **) &i2400m->fw_hdrs, &slots,
				sizeof(i2400m->fw_hdrs[0]),
				GFP_KERNEL);
			if (result < 0)
				goto error_zrealloc;
		}
		i2400m->fw_hdrs[used_slots] = bcf_hdr;
		used_slots++;
	}
	if (headers == 0) {
		dev_err(dev, "firmware %s: no usable headers found\n",
			i2400m->fw_name);
		result = -EBADF;
	} else
		result = 0;
error_zrealloc:
	return result;
}


/*
 * Match a barker to a BCF header module ID
 *
 * The device sends a barker which tells the firmware loader which
 * header in the BCF file has to be used. This does the matching.
 */
static
unsigned i2400m_bcf_hdr_match(struct i2400m *i2400m,
			      const struct i2400m_bcf_hdr *bcf_hdr)
{
	u32 barker = le32_to_cpu(i2400m->barker->data[0])
		& 0x7fffffff;
	u32 module_id = le32_to_cpu(bcf_hdr->module_id)
		& 0x7fffffff;	/* high bit used for something else */

	/* special case for 5x50 */
	if (barker == I2400M_SBOOT_BARKER && module_id == 0)
		return 1;
	if (module_id == barker)
		return 1;
	return 0;
}

static
const struct i2400m_bcf_hdr *i2400m_bcf_hdr_find(struct i2400m *i2400m)
{
	struct device *dev = i2400m_dev(i2400m);
	const struct i2400m_bcf_hdr **bcf_itr, *bcf_hdr;
	unsigned i = 0;
	u32 barker = le32_to_cpu(i2400m->barker->data[0]);

	d_printf(2, dev, "finding BCF header for barker %08x\n", barker);
	if (barker == I2400M_NBOOT_BARKER) {
		bcf_hdr = i2400m->fw_hdrs[0];
		d_printf(1, dev, "using BCF header #%u/%08x for non-signed "
			 "barker\n", 0, le32_to_cpu(bcf_hdr->module_id));
		return bcf_hdr;
	}
	for (bcf_itr = i2400m->fw_hdrs; *bcf_itr != NULL; bcf_itr++, i++) {
		bcf_hdr = *bcf_itr;
		if (i2400m_bcf_hdr_match(i2400m, bcf_hdr)) {
			d_printf(1, dev, "hit on BCF hdr #%u/%08x\n",
				 i, le32_to_cpu(bcf_hdr->module_id));
			return bcf_hdr;
		} else
			d_printf(1, dev, "miss on BCF hdr #%u/%08x\n",
				 i, le32_to_cpu(bcf_hdr->module_id));
	}
	dev_err(dev, "cannot find a matching BCF header for barker %08x\n",
		barker);
	return NULL;
}


/*
 * Download the firmware to the device
 *
 * @i2400m: device descriptor
 * @bcf: pointer to loaded (and minimally verified for consistency)
 *    firmware
 * @bcf_size: size of the @bcf buffer (header plus payloads)
 *
 * The process for doing this is described in this file's header.
 *
 * Note we only reinitialize boot-mode if the flags say so. Some hw
 * iterations need it, some don't. In any case, if we loop, we always
 * need to reinitialize the boot room, hence the flags modification.
 */
static
int i2400m_fw_dnload(struct i2400m *i2400m, const struct i2400m_bcf_hdr *bcf,
		     size_t fw_size, enum i2400m_bri flags)
{
	int ret = 0;
	struct device *dev = i2400m_dev(i2400m);
	int count = i2400m->bus_bm_retries;
	const struct i2400m_bcf_hdr *bcf_hdr;
	size_t bcf_size;

	d_fnstart(5, dev, "(i2400m %p bcf %p fw size %zu)\n",
		  i2400m, bcf, fw_size);
	i2400m->boot_mode = 1;
	wmb();		/* Make sure other readers see it */
hw_reboot:
	if (count-- == 0) {
		ret = -ERESTARTSYS;
		dev_err(dev, "device rebooted too many times, aborting\n");
		goto error_too_many_reboots;
	}
	if (flags & I2400M_BRI_MAC_REINIT) {
		ret = i2400m_bootrom_init(i2400m, flags);
		if (ret < 0) {
			dev_err(dev, "bootrom init failed: %d\n", ret);
			goto error_bootrom_init;
		}
	}
	flags |= I2400M_BRI_MAC_REINIT;

	/*
	 * Initialize the download, push the bytes to the device and
	 * then jump to the new firmware. Note @ret is passed with the
	 * offset of the jump instruction to _dnload_finalize()
	 *
	 * Note we need to use the BCF header in the firmware image
	 * that matches the barker that the device sent when it
	 * rebooted, so it has to be passed along.
	 */
	ret = -EBADF;
	bcf_hdr = i2400m_bcf_hdr_find(i2400m);
	if (bcf_hdr == NULL)
		goto error_bcf_hdr_find;

	ret = i2400m_dnload_init(i2400m, bcf_hdr);
	if (ret == -ERESTARTSYS)
		goto error_dev_rebooted;
	if (ret < 0)
		goto error_dnload_init;

	/*
	 * bcf_size refers to one header size plus the fw sections size
	 * indicated by the header,ie. if there are other extended headers
	 * at the tail, they are not counted
	 */
	bcf_size = sizeof(u32) * le32_to_cpu(bcf_hdr->size);
	ret = i2400m_dnload_bcf(i2400m, bcf, bcf_size);
	if (ret == -ERESTARTSYS)
		goto error_dev_rebooted;
	if (ret < 0) {
		dev_err(dev, "fw %s: download failed: %d\n",
			i2400m->fw_name, ret);
		goto error_dnload_bcf;
	}

	ret = i2400m_dnload_finalize(i2400m, bcf_hdr, bcf, ret);
	if (ret == -ERESTARTSYS)
		goto error_dev_rebooted;
	if (ret < 0) {
		dev_err(dev, "fw %s: "
			"download finalization failed: %d\n",
			i2400m->fw_name, ret);
		goto error_dnload_finalize;
	}

	d_printf(2, dev, "fw %s successfully uploaded\n",
		 i2400m->fw_name);
	i2400m->boot_mode = 0;
	wmb();		/* Make sure i2400m_msg_to_dev() sees boot_mode */
error_dnload_finalize:
error_dnload_bcf:
error_dnload_init:
error_bcf_hdr_find:
error_bootrom_init:
error_too_many_reboots:
	d_fnend(5, dev, "(i2400m %p bcf %p size %zu) = %d\n",
		i2400m, bcf, fw_size, ret);
	return ret;

error_dev_rebooted:
	dev_err(dev, "device rebooted, %d tries left\n", count);
	/* we got the notification already, no need to wait for it again */
	flags |= I2400M_BRI_SOFT;
	goto hw_reboot;
}

static
int i2400m_fw_bootstrap(struct i2400m *i2400m, const struct firmware *fw,
			enum i2400m_bri flags)
{
	int ret;
	struct device *dev = i2400m_dev(i2400m);
	const struct i2400m_bcf_hdr *bcf;	/* Firmware data */

	d_fnstart(5, dev, "(i2400m %p)\n", i2400m);
	bcf = (void *) fw->data;
	ret = i2400m_fw_check(i2400m, bcf, fw->size);
	if (ret >= 0)
		ret = i2400m_fw_dnload(i2400m, bcf, fw->size, flags);
	if (ret < 0)
		dev_err(dev, "%s: cannot use: %d, skipping\n",
			i2400m->fw_name, ret);
	kfree(i2400m->fw_hdrs);
	i2400m->fw_hdrs = NULL;
	d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
	return ret;
}


/* Refcounted container for firmware data */
struct i2400m_fw {
	struct kref kref;
	const struct firmware *fw;
};


static
void i2400m_fw_destroy(struct kref *kref)
{
	struct i2400m_fw *i2400m_fw =
		container_of(kref, struct i2400m_fw, kref);
	release_firmware(i2400m_fw->fw);
	kfree(i2400m_fw);
}


static
struct i2400m_fw *i2400m_fw_get(struct i2400m_fw *i2400m_fw)
{
	if (i2400m_fw != NULL && i2400m_fw != (void *) ~0)
		kref_get(&i2400m_fw->kref);
	return i2400m_fw;
}


static
void i2400m_fw_put(struct i2400m_fw *i2400m_fw)
{
	kref_put(&i2400m_fw->kref, i2400m_fw_destroy);
}


/**
 * i2400m_dev_bootstrap - Bring the device to a known state and upload firmware
 *
 * @i2400m: device descriptor
 *
 * Returns: >= 0 if ok, < 0 errno code on error.
 *
 * This sets up the firmware upload environment, loads the firmware
 * file from disk, verifies and then calls the firmware upload process
 * per se.
 *
 * Can be called either from probe, or after a warm reset.  Can not be
 * called from within an interrupt.  All the flow in this code is
 * single-threade; all I/Os are synchronous.
 */
int i2400m_dev_bootstrap(struct i2400m *i2400m, enum i2400m_bri flags)
{
	int ret, itr;
	struct device *dev = i2400m_dev(i2400m);
	struct i2400m_fw *i2400m_fw;
	const struct i2400m_bcf_hdr *bcf;	/* Firmware data */
	const struct firmware *fw;
	const char *fw_name;

	d_fnstart(5, dev, "(i2400m %p)\n", i2400m);

	ret = -ENODEV;
	spin_lock(&i2400m->rx_lock);
	i2400m_fw = i2400m_fw_get(i2400m->fw_cached);
	spin_unlock(&i2400m->rx_lock);
	if (i2400m_fw == (void *) ~0) {
		dev_err(dev, "can't load firmware now!");
		goto out;
	} else if (i2400m_fw != NULL) {
		dev_info(dev, "firmware %s: loading from cache\n",
			 i2400m->fw_name);
		ret = i2400m_fw_bootstrap(i2400m, i2400m_fw->fw, flags);
		i2400m_fw_put(i2400m_fw);
		goto out;
	}

	/* Load firmware files to memory. */
	for (itr = 0, bcf = NULL, ret = -ENOENT; ; itr++) {
		fw_name = i2400m->bus_fw_names[itr];
		if (fw_name == NULL) {
			dev_err(dev, "Could not find a usable firmware image\n");
			break;
		}
		d_printf(1, dev, "trying firmware %s (%d)\n", fw_name, itr);
		ret = request_firmware(&fw, fw_name, dev);
		if (ret < 0) {
			dev_err(dev, "fw %s: cannot load file: %d\n",
				fw_name, ret);
			continue;
		}
		i2400m->fw_name = fw_name;
		ret = i2400m_fw_bootstrap(i2400m, fw, flags);
		release_firmware(fw);
		if (ret >= 0)	/* firmware loaded succesfully */
			break;
		i2400m->fw_name = NULL;
	}
out:
	d_fnend(5, dev, "(i2400m %p) = %d\n", i2400m, ret);
	return ret;
}
EXPORT_SYMBOL_GPL(i2400m_dev_bootstrap);


void i2400m_fw_cache(struct i2400m *i2400m)
{
	int result;
	struct i2400m_fw *i2400m_fw;
	struct device *dev = i2400m_dev(i2400m);

	/* if there is anything there, free it -- now, this'd be weird */
	spin_lock(&i2400m->rx_lock);
	i2400m_fw = i2400m->fw_cached;
	spin_unlock(&i2400m->rx_lock);
	if (i2400m_fw != NULL && i2400m_fw != (void *) ~0) {
		i2400m_fw_put(i2400m_fw);
		WARN(1, "%s:%u: still cached fw still present?\n",
		     __func__, __LINE__);
	}

	if (i2400m->fw_name == NULL) {
		dev_err(dev, "firmware n/a: can't cache\n");
		i2400m_fw = (void *) ~0;
		goto out;
	}

	i2400m_fw = kzalloc(sizeof(*i2400m_fw), GFP_ATOMIC);
	if (i2400m_fw == NULL)
		goto out;
	kref_init(&i2400m_fw->kref);
	result = request_firmware(&i2400m_fw->fw, i2400m->fw_name, dev);
	if (result < 0) {
		dev_err(dev, "firmware %s: failed to cache: %d\n",
			i2400m->fw_name, result);
		kfree(i2400m_fw);
		i2400m_fw = (void *) ~0;
	} else
		dev_info(dev, "firmware %s: cached\n", i2400m->fw_name);
out:
	spin_lock(&i2400m->rx_lock);
	i2400m->fw_cached = i2400m_fw;
	spin_unlock(&i2400m->rx_lock);
}


void i2400m_fw_uncache(struct i2400m *i2400m)
{
	struct i2400m_fw *i2400m_fw;

	spin_lock(&i2400m->rx_lock);
	i2400m_fw = i2400m->fw_cached;
	i2400m->fw_cached = NULL;
	spin_unlock(&i2400m->rx_lock);

	if (i2400m_fw != NULL && i2400m_fw != (void *) ~0)
		i2400m_fw_put(i2400m_fw);
}

