/*****************************************************************************

            (c) Cambridge Silicon Radio Limited 2012
            All rights reserved and confidential information of CSR

            Refer to LICENSE.txt included with this source for details
            on the license terms.

*****************************************************************************/

/*
 * ---------------------------------------------------------------------------
 * FILE: csr_wifi_hip_card_sdio.c
 *
 * PURPOSE: Implementation of the Card API for SDIO.
 *
 * NOTES:
 *      CardInit() is called from the SDIO probe callback when a card is
 *      inserted. This performs the basic SDIO initialisation, enabling i/o
 *      etc.
 *
 * ---------------------------------------------------------------------------
 */
#include <linux/slab.h>
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_conversions.h"
#include "csr_wifi_hip_unifiversion.h"
#include "csr_wifi_hip_card.h"
#include "csr_wifi_hip_card_sdio.h"
#include "csr_wifi_hip_chiphelper.h"


/* Time to wait between attempts to read MAILBOX0 */
#define MAILBOX1_TIMEOUT                10  /* in millisecs */
#define MAILBOX1_ATTEMPTS               200 /* 2 seconds */

#define MAILBOX2_TIMEOUT                5   /* in millisecs */
#define MAILBOX2_ATTEMPTS               10  /* 50ms */

#define RESET_SETTLE_DELAY              25  /* in millisecs */

static CsrResult card_init_slots(card_t *card);
static CsrResult card_hw_init(card_t *card);
static CsrResult firmware_present_in_flash(card_t *card);
static void bootstrap_chip_hw(card_t *card);
static CsrResult unifi_reset_hardware(card_t *card);
static CsrResult unifi_hip_init(card_t *card);
static CsrResult card_access_panic(card_t *card);
static CsrResult unifi_read_chip_version(card_t *card);

/*
 * ---------------------------------------------------------------------------
 *  unifi_alloc_card
 *
 *      Allocate and initialise the card context structure.
 *
 *  Arguments:
 *      sdio            Pointer to SDIO context pointer to pass to low
 *                      level i/o functions.
 *      ospriv          Pointer to O/S private struct to pass when calling
 *                      callbacks to the higher level system.
 *
 *  Returns:
 *      Pointer to card struct, which represents the driver context or
 *      NULL if the allocation failed.
 * ---------------------------------------------------------------------------
 */
card_t* unifi_alloc_card(CsrSdioFunction *sdio, void *ospriv)
{
    card_t *card;
    u32 i;


    card = kzalloc(sizeof(card_t), GFP_KERNEL);
    if (card == NULL)
    {
        return NULL;
    }

    card->sdio_if = sdio;
    card->ospriv  = ospriv;

    card->unifi_interrupt_seq = 1;

    /* Make these invalid. */
    card->proc_select = (u32)(-1);
    card->dmem_page = (u32)(-1);
    card->pmem_page = (u32)(-1);

    card->bh_reason_host = 0;
    card->bh_reason_unifi = 0;

    for (i = 0; i < sizeof(card->tx_q_paused_flag) / sizeof(card->tx_q_paused_flag[0]); i++)
    {
        card->tx_q_paused_flag[i] = 0;
    }
    card->memory_resources_allocated = 0;

    card->low_power_mode = UNIFI_LOW_POWER_DISABLED;
    card->periodic_wake_mode = UNIFI_PERIODIC_WAKE_HOST_DISABLED;

    card->host_state = UNIFI_HOST_STATE_AWAKE;
    card->intmode = CSR_WIFI_INTMODE_DEFAULT;

    /*
     * Memory resources for buffers are allocated when the chip is initialised
     * because we need configuration information from the firmware.
     */

    /*
     * Initialise wait queues and lists
     */
    card->fh_command_queue.q_body = card->fh_command_q_body;
    card->fh_command_queue.q_length = UNIFI_SOFT_COMMAND_Q_LENGTH;

    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
    {
        card->fh_traffic_queue[i].q_body = card->fh_traffic_q_body[i];
        card->fh_traffic_queue[i].q_length = UNIFI_SOFT_TRAFFIC_Q_LENGTH;
    }


    /* Initialise mini-coredump pointers in case no coredump buffers
     * are requested by the OS layer.
     */
    card->request_coredump_on_reset = 0;
    card->dump_next_write = NULL;
    card->dump_cur_read = NULL;
    card->dump_buf = NULL;

#ifdef UNIFI_DEBUG
    /* Determine offset of LSB in pointer for later alignment sanity check.
     * Synergy integer types have specific widths, which cause compiler
     * warnings when casting pointer types, e.g. on 64-bit systems.
     */
    {
        u32 val = 0x01234567;

        if (*((u8 *)&val) == 0x01)
        {
            card->lsb = sizeof(void *) - 1;     /* BE */
        }
        else
        {
            card->lsb = 0;                      /* LE */
        }
    }
#endif
    return card;
} /* unifi_alloc_card() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_init_card
 *
 *      Reset the hardware and perform HIP initialization
 *
 *  Arguments:
 *      card        Pointer to card struct
 *
 *  Returns:
 *      CsrResult code
 *      CSR_RESULT_SUCCESS if successful
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_init_card(card_t *card, s32 led_mask)
{
    CsrResult r;


    if (card == NULL)
    {
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    r = unifi_init(card);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    r = unifi_hip_init(card);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to start host protocol.\n");
        return r;
    }

    return CSR_RESULT_SUCCESS;
}


/*
 * ---------------------------------------------------------------------------
 *  unifi_init
 *
 *      Init the hardware.
 *
 *  Arguments:
 *      card        Pointer to card struct
 *
 *  Returns:
 *      CsrResult code
 *      CSR_RESULT_SUCCESS if successful
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_init(card_t *card)
{
    CsrResult r;
    CsrResult csrResult;

    if (card == NULL)
    {
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    /*
     * Disable the SDIO interrupts while initialising UniFi.
     * Re-enable them when f/w is running.
     */
    csrResult = CsrSdioInterruptDisable(card->sdio_if);
    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
    {
        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
    }

    /*
     * UniFi's PLL may start with a slow clock (~ 1 MHz) so initially
     * set the SDIO bus clock to a similar value or SDIO accesses may
     * fail.
     */
    csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_SAFE_HZ);
    if (csrResult != CSR_RESULT_SUCCESS)
    {
        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
        return r;
    }
    card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ;

    /*
     * Reset UniFi. Note, this only resets the WLAN function part of the chip,
     * the SDIO interface is not reset.
     */
    unifi_trace(card->ospriv, UDBG1, "Resetting UniFi\n");
    r = unifi_reset_hardware(card);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to reset UniFi\n");
        return r;
    }

    /* Reset the power save mode, to be active until the MLME-reset is complete */
    r = unifi_configure_low_power_mode(card,
                                       UNIFI_LOW_POWER_DISABLED, UNIFI_PERIODIC_WAKE_HOST_DISABLED);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to set power save mode\n");
        return r;
    }

    /*
     * Set initial value of page registers.
     * The page registers will be maintained by unifi_read...() and
     * unifi_write...().
     */
    card->proc_select = (u32)(-1);
    card->dmem_page = (u32)(-1);
    card->pmem_page = (u32)(-1);
    r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, 0);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n");
        return r;
    }
    r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, 0);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to write PROG_MEM2_PAGE\n");
        return r;
    }

    /*
     * If the driver has reset UniFi due to previous SDIO failure, this may
     * have been due to a chip watchdog reset. In this case, the driver may
     * have requested a mini-coredump which needs to be captured now the
     * SDIO interface is alive.
     */
    (void)unifi_coredump_handle_request(card);

    /*
     * Probe to see if the UniFi has ROM/flash to boot from. CSR6xxx should do.
     */
    r = firmware_present_in_flash(card);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r == CSR_WIFI_HIP_RESULT_NOT_FOUND)
    {
        unifi_error(card->ospriv, "No firmware found\n");
    }
    else if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Probe for Flash failed\n");
    }

    return r;
} /* unifi_init() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_download
 *
 *      Load the firmware.
 *
 *  Arguments:
 *      card        Pointer to card struct
 *      led_mask    Loader LED mask
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success
 *      CsrResult error code on failure.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_download(card_t *card, s32 led_mask)
{
    CsrResult r;
    void *dlpriv;

    if (card == NULL)
    {
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    /* Set the loader led mask */
    card->loader_led_mask = led_mask;

    /* Get the firmware file information */
    unifi_trace(card->ospriv, UDBG1, "downloading firmware...\n");

    dlpriv = unifi_dl_fw_read_start(card, UNIFI_FW_STA);
    if (dlpriv == NULL)
    {
        return CSR_WIFI_HIP_RESULT_NOT_FOUND;
    }

    /* Download the firmware. */
    r = unifi_dl_firmware(card, dlpriv);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to download firmware\n");
        return r;
    }

    /* Free the firmware file information. */
    unifi_fw_read_stop(card->ospriv, dlpriv);

    return CSR_RESULT_SUCCESS;
} /* unifi_download() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_hip_init
 *
 *      This function performs the f/w initialisation sequence as described
 *      in the Unifi Host Interface Protocol Specification.
 *      It allocates memory for host-side slot data and signal queues.
 *
 *  Arguments:
 *      card        Pointer to card struct
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success or else a CSR error code
 *
 *  Notes:
 *      The firmware must have been downloaded.
 * ---------------------------------------------------------------------------
 */
static CsrResult unifi_hip_init(card_t *card)
{
    CsrResult r;
    CsrResult csrResult;

    r = card_hw_init(card);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to establish communication with UniFi\n");
        return r;
    }
#ifdef CSR_PRE_ALLOC_NET_DATA
    /* if there is any preallocated netdata left from the prev session free it now */
    prealloc_netdata_free(card);
#endif
    /*
     * Allocate memory for host-side slot data and signal queues.
     * We need the config info read from the firmware to know how much
     * memory to allocate.
     */
    r = card_init_slots(card);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Init slots failed: %d\n", r);
        return r;
    }

    unifi_trace(card->ospriv, UDBG2, "Sending first UniFi interrupt\n");

    r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    /* Enable the SDIO interrupts now that the f/w is running. */
    csrResult = CsrSdioInterruptEnable(card->sdio_if);
    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
    {
        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
    }

    /* Signal the UniFi to start handling messages */
    r = CardGenInt(card);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    return CSR_RESULT_SUCCESS;
} /* unifi_hip_init() */


/*
 * ---------------------------------------------------------------------------
 *  _build_sdio_config_data
 *
 *      Unpack the SDIO configuration information from a buffer read from
 *      UniFi into a host structure.
 *      The data is byte-swapped for a big-endian host if necessary by the
 *      UNPACK... macros.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *      cfg_data        Destination structure to unpack into.
 *      cfg_data_buf    Source buffer to read from. This should be the raw
 *                      data read from UniFi.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void _build_sdio_config_data(sdio_config_data_t *cfg_data,
                                    const u8     *cfg_data_buf)
{
    s16 offset = 0;

    cfg_data->version = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->sdio_ctrl_offset = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->fromhost_sigbuf_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->tohost_sigbuf_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->num_fromhost_sig_frags = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->num_tohost_sig_frags = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->num_fromhost_data_slots = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->num_tohost_data_slots = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->data_slot_size = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->initialised = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->overlay_size = CSR_GET_UINT32_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT32;

    cfg_data->data_slot_round = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->sig_frag_size = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
    offset += SIZEOF_UINT16;

    cfg_data->tohost_signal_padding = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cfg_data_buf + offset);
} /* _build_sdio_config_data() */


/*
 * - Function ----------------------------------------------------------------
 * card_hw_init()
 *
 *      Perform the initialisation procedure described in the UniFi Host
 *      Interface Protocol document (section 3.3.8) and read the run-time
 *      configuration information from the UniFi. This is stuff like number
 *      of bulk data slots etc.
 *
 *      The card enumeration and SD initialisation has already been done by
 *      the SDIO library, see card_sdio_init().
 *
 *      The initialisation is done when firmware is ready, i.e. this may need
 *      to be called after a f/w download operation.
 *
 *      The initialisation procedure goes like this:
 *       - Wait for UniFi to start-up by polling SHARED_MAILBOX1
 *       - Find the symbol table and look up SLT_SDIO_SLOT_CONFIG
 *       - Read the config structure
 *       - Check the "SDIO initialised" flag, if not zero do a h/w reset and
 *         start again
 *       - Decide the number of bulk data slots to allocate, allocate them and
 *         set "SDIO initialised" flag (and generate an interrupt) to say so.
 *
 * Arguments:
 *      card        Pointer to card struct
 *
 * Returns:
 *      CSR_RESULT_SUCEESS on success,
 *      a CSR error code on failure
 *
 * Notes:
 *      All data in the f/w is stored in a little endian format, without any
 *      padding bytes. Every read from this memory has to be transformed in
 *      host (cpu specific) format, before it is stored in driver's parameters
 *      or/and structures. Athough unifi_card_read16() and unifi_read32() do perform
 *      the convertion internally, unifi_readn() does not.
 * ---------------------------------------------------------------------------
 */
static CsrResult card_hw_init(card_t *card)
{
    u32 slut_address;
    u16 initialised;
    u16 finger_print;
    symbol_t slut;
    sdio_config_data_t *cfg_data;
    u8 cfg_data_buf[SDIO_CONFIG_DATA_SIZE];
    CsrResult r;
    void *dlpriv;
    s16 major, minor;
    s16 search_4slut_again;
    CsrResult csrResult;

    /*
     * The device revision from the TPLMID_MANF and TPLMID_CARD fields
     * of the CIS are available as
     *   card->sdio_if->pDevice->ManfID
     *   card->sdio_if->pDevice->AppID
     */

    /*
     * Run in a loop so we can patch.
     */
    do
    {
        /* Reset these each time around the loop. */
        search_4slut_again = 0;
        cfg_data = NULL;

        r = card_wait_for_firmware_to_start(card, &slut_address);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Firmware hasn't started\n");
            return r;
        }
        unifi_trace(card->ospriv, UDBG4, "SLUT addr 0x%lX\n", slut_address);

        /*
         * Firmware has started, but doesn't know full clock configuration yet
         * as some of the information may be in the MIB. Therefore we set an
         * initial SDIO clock speed, faster than UNIFI_SDIO_CLOCK_SAFE_HZ, for
         * the patch download and subsequent firmware initialisation, and
         * full speed UNIFI_SDIO_CLOCK_MAX_HZ will be set once the f/w tells us
         * that it is ready.
         */
        csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ);
        if (csrResult != CSR_RESULT_SUCCESS)
        {
            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
            return r;
        }
        card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;

        /*
         * Check the SLUT fingerprint.
         * The slut_address is a generic pointer so we must use unifi_card_read16().
         */
        unifi_trace(card->ospriv, UDBG4, "Looking for SLUT finger print\n");
        finger_print = 0;
        r = unifi_card_read16(card, slut_address, &finger_print);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to read SLUT finger print\n");
            return r;
        }

        if (finger_print != SLUT_FINGERPRINT)
        {
            unifi_error(card->ospriv, "Failed to find Symbol lookup table fingerprint\n");
            return CSR_RESULT_FAILURE;
        }

        /* Symbol table starts imedately after the fingerprint */
        slut_address += 2;

        /* Search the table until either the end marker is found, or the
         * loading of patch firmware invalidates the current table.
         */
        while (!search_4slut_again)
        {
            u16 s;
            u32 l;

            r = unifi_card_read16(card, slut_address, &s);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            slut_address += 2;

            if (s == CSR_SLT_END)
            {
                unifi_trace(card->ospriv, UDBG3, "  found CSR_SLT_END\n");
                break;
            }

            r = unifi_read32(card, slut_address, &l);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            slut_address += 4;

            slut.id = s;
            slut.obj = l;

            unifi_trace(card->ospriv, UDBG3, "  found SLUT id %02d.%08lx\n", slut.id, slut.obj);
            switch (slut.id)
            {
                case CSR_SLT_SDIO_SLOT_CONFIG:
                    cfg_data = &card->config_data;
                    /*
                     * unifi_card_readn reads n bytes from the card, where data is stored
                     * in a little endian format, without any padding bytes. So, we
                     * can not just pass the cfg_data pointer or use the
                     * sizeof(sdio_config_data_t) since the structure in the host can
                     * be big endian formatted or have padding bytes for alignment.
                     * We use a char buffer to read the data from the card.
                     */
                    r = unifi_card_readn(card, slut.obj, cfg_data_buf, SDIO_CONFIG_DATA_SIZE);
                    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
                    {
                        return r;
                    }
                    if (r != CSR_RESULT_SUCCESS)
                    {
                        unifi_error(card->ospriv, "Failed to read config data\n");
                        return r;
                    }
                    /* .. and then we copy the data to the host structure */
                    _build_sdio_config_data(cfg_data, cfg_data_buf);

                    /* Make sure the from host data slots are what we expect
                        we reserve 2 for commands and there should be at least
                        1 left for each access category */
                    if ((cfg_data->num_fromhost_data_slots < UNIFI_RESERVED_COMMAND_SLOTS)
                        || (cfg_data->num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS) / UNIFI_NO_OF_TX_QS == 0)
                    {
                        unifi_error(card->ospriv, "From host data slots %d\n", cfg_data->num_fromhost_data_slots);
                        unifi_error(card->ospriv, "need to be (queues * x + 2) (UNIFI_RESERVED_COMMAND_SLOTS for commands)\n");
                        return CSR_RESULT_FAILURE;
                    }

                    /* Configure SDIO to-block-size padding */
                    if (card->sdio_io_block_pad)
                    {
                    /*
                     * Firmware limits the maximum padding size via data_slot_round.
                     * Therefore when padding to whole block sizes, the block size
                     * must be configured correctly by adjusting CSR_WIFI_HIP_SDIO_BLOCK_SIZE.
                     */
                        if (cfg_data->data_slot_round < card->sdio_io_block_size)
                        {
                            unifi_error(card->ospriv,
                                        "Configuration error: Block size of %d exceeds f/w data_slot_round of %d\n",
                                        card->sdio_io_block_size, cfg_data->data_slot_round);
                            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
                        }

                        /*
                         * To force the To-Host signals to be rounded up to the SDIO block
                         * size, we need to write the To-Host Signal Padding Fragments
                         * field of the SDIO configuration in UniFi.
                         */
                        if ((card->sdio_io_block_size % cfg_data->sig_frag_size) != 0)
                        {
                            unifi_error(card->ospriv, "Configuration error: Can not pad to-host signals.\n");
                            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
                        }
                        cfg_data->tohost_signal_padding = (u16) (card->sdio_io_block_size / cfg_data->sig_frag_size);
                        unifi_info(card->ospriv, "SDIO block size %d requires %d padding chunks\n",
                                   card->sdio_io_block_size, cfg_data->tohost_signal_padding);
                        r = unifi_card_write16(card, slut.obj + SDIO_TO_HOST_SIG_PADDING_OFFSET, cfg_data->tohost_signal_padding);
                        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
                        {
                            return r;
                        }
                        if (r != CSR_RESULT_SUCCESS)
                        {
                            unifi_error(card->ospriv, "Failed to write To-Host Signal Padding Fragments\n");
                            return r;
                        }
                    }

                    /* Reconstruct the Generic Pointer address of the
                     * SDIO Control Data Struct.
                     */
                    card->sdio_ctrl_addr = cfg_data->sdio_ctrl_offset | (UNIFI_SH_DMEM << 24);
                    card->init_flag_addr = slut.obj + SDIO_INIT_FLAG_OFFSET;
                    break;

                case CSR_SLT_BUILD_ID_NUMBER:
                {
                    u32 n;
                    r = unifi_read32(card, slut.obj, &n);
                    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
                    {
                        return r;
                    }
                    if (r != CSR_RESULT_SUCCESS)
                    {
                        unifi_error(card->ospriv, "Failed to read build id\n");
                        return r;
                    }
                    card->build_id = n;
                }
                break;

                case CSR_SLT_BUILD_ID_STRING:
                    r = unifi_readnz(card, slut.obj, card->build_id_string,
                                     sizeof(card->build_id_string));
                    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
                    {
                        return r;
                    }
                    if (r != CSR_RESULT_SUCCESS)
                    {
                        unifi_error(card->ospriv, "Failed to read build string\n");
                        return r;
                    }
                    break;

                case CSR_SLT_PERSISTENT_STORE_DB:
                    break;

                case CSR_SLT_BOOT_LOADER_CONTROL:

                    /* This command copies most of the station firmware
                     * image from ROM into program RAM.  It also clears
                     * out the zerod data and sets up the initialised
                     * data. */
                    r = unifi_do_loader_op(card, slut.obj + 6, UNIFI_BOOT_LOADER_LOAD_STA);
                    if (r != CSR_RESULT_SUCCESS)
                    {
                        unifi_error(card->ospriv, "Failed to write loader load image command\n");
                        return r;
                    }

                    dlpriv = unifi_dl_fw_read_start(card, UNIFI_FW_STA);

                    /* dlpriv might be NULL, we still need to do the do_loader_op step. */
                    if (dlpriv != NULL)
                    {
                    /* Download the firmware. */
                        r = unifi_dl_patch(card, dlpriv, slut.obj);

                    /* Free the firmware file information. */
                        unifi_fw_read_stop(card->ospriv, dlpriv);

                        if (r != CSR_RESULT_SUCCESS)
                        {
                            unifi_error(card->ospriv, "Failed to patch firmware\n");
                            return r;
                        }
                    }

                    /* This command starts the firmware image that we want (the
                    * station by default) with any patches required applied. */
                    r = unifi_do_loader_op(card, slut.obj + 6, UNIFI_BOOT_LOADER_RESTART);
                    if (r != CSR_RESULT_SUCCESS)
                    {
                        unifi_error(card->ospriv, "Failed to write loader restart command\n");
                        return r;
                    }

                    /* The now running patch f/w defines a new SLUT data structure -
                     * the current one is no longer valid. We must drop out of the
                     * processing loop and enumerate the new SLUT (which may appear
                     * at a different offset).
                     */
                    search_4slut_again = 1;
                    break;

                case CSR_SLT_PANIC_DATA_PHY:
                    card->panic_data_phy_addr = slut.obj;
                    break;

                case CSR_SLT_PANIC_DATA_MAC:
                    card->panic_data_mac_addr = slut.obj;
                    break;

                default:
                    /* do nothing */
                    break;
            }
        } /* while */
    } while (search_4slut_again);

    /* Did we find the Config Data ? */
    if (cfg_data == NULL)
    {
        unifi_error(card->ospriv, "Failed to find SDIO_SLOT_CONFIG Symbol\n");
        return CSR_RESULT_FAILURE;
    }

    /*
     * Has ths card already been initialised?
     * If so, return an error so we do a h/w reset and start again.
     */
    r = unifi_card_read16(card, card->init_flag_addr, &initialised);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to read init flag at %08lx\n",
                    card->init_flag_addr);
        return r;
    }
    if (initialised != 0)
    {
        return CSR_RESULT_FAILURE;
    }


    /*
     * Now check the UniFi firmware version
     */
    major = (cfg_data->version >> 8) & 0xFF;
    minor = cfg_data->version & 0xFF;
    unifi_info(card->ospriv, "UniFi f/w protocol version %d.%d (driver %d.%d)\n",
               major, minor,
               UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);

    unifi_info(card->ospriv, "Firmware build %u: %s\n",
               card->build_id, card->build_id_string);

    if (major != UNIFI_HIP_MAJOR_VERSION)
    {
        unifi_error(card->ospriv, "UniFi f/w protocol major version (%d) is different from driver (v%d.%d)\n",
                    major, UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
#ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK
        return CSR_RESULT_FAILURE;
#endif
    }
    if (minor < UNIFI_HIP_MINOR_VERSION)
    {
        unifi_error(card->ospriv, "UniFi f/w protocol version (v%d.%d) is older than minimum required by driver (v%d.%d).\n",
                    major, minor,
                    UNIFI_HIP_MAJOR_VERSION, UNIFI_HIP_MINOR_VERSION);
#ifndef CSR_WIFI_DISABLE_HIP_VERSION_CHECK
        return CSR_RESULT_FAILURE;
#endif
    }

    /* Read panic codes from a previous firmware panic. If the firmware has
     * not panicked since power was applied (e.g. power-off hard reset)
     * the stored panic codes will not be updated.
     */
    unifi_read_panic(card);

    return CSR_RESULT_SUCCESS;
} /* card_hw_init() */


/*
 * ---------------------------------------------------------------------------
 *  card_wait_for_unifi_to_reset
 *
 *      Waits for a reset to complete by polling the WLAN function enable
 *      bit (which is cleared on reset).
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, CSR error code on failure.
 * ---------------------------------------------------------------------------
 */
static CsrResult card_wait_for_unifi_to_reset(card_t *card)
{
    s16 i;
    CsrResult r;
    u8 io_enable;
    CsrResult csrResult;

    r = CSR_RESULT_SUCCESS;
    for (i = 0; i < MAILBOX2_ATTEMPTS; i++)
    {
        unifi_trace(card->ospriv, UDBG1, "waiting for reset to complete, attempt %d\n", i);
        if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
        {
            /* It's quite likely that this read will timeout for the
             * first few tries - especially if we have reset via
             * DBG_RESET.
             */
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
            unifi_debug_log_to_buf("m0@%02X=", SDIO_IO_READY);
#endif
            csrResult = CsrSdioF0Read8(card->sdio_if, SDIO_IO_READY, &io_enable);
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
            if (csrResult != CSR_RESULT_SUCCESS)
            {
                unifi_debug_log_to_buf("error=%X\n", csrResult);
            }
            else
            {
                unifi_debug_log_to_buf("%X\n", io_enable);
            }
#endif
            if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
            {
                return CSR_WIFI_HIP_RESULT_NO_DEVICE;
            }
            r = CSR_RESULT_SUCCESS;
            if (csrResult != CSR_RESULT_SUCCESS)
            {
                r = ConvertCsrSdioToCsrHipResult(card, csrResult);
            }
        }
        else
        {
            r = sdio_read_f0(card, SDIO_IO_ENABLE, &io_enable);
        }
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r == CSR_RESULT_SUCCESS)
        {
            u16 mbox2;
            s16 enabled = io_enable & (1 << card->function);

            if (!enabled)
            {
                unifi_trace(card->ospriv, UDBG1,
                            "Reset complete (function %d is disabled) in ~ %u msecs\n",
                            card->function, i * MAILBOX2_TIMEOUT);

                /* Enable WLAN function and verify MAILBOX2 is zero'd */
                csrResult = CsrSdioFunctionEnable(card->sdio_if);
                if (csrResult != CSR_RESULT_SUCCESS)
                {
                    r = ConvertCsrSdioToCsrHipResult(card, csrResult);
                    unifi_error(card->ospriv, "CsrSdioFunctionEnable failed %d\n", r);
                    break;
                }
            }

            r = unifi_read_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, &mbox2);
            if (r != CSR_RESULT_SUCCESS)
            {
                unifi_error(card->ospriv, "read HIP_HANDSHAKE failed %d\n", r);
                break;
            }
            if (mbox2 != 0)
            {
                unifi_error(card->ospriv, "MAILBOX2 non-zero after reset (mbox2 = %04x)\n", mbox2);
                r = CSR_RESULT_FAILURE;
            }
            break;
        }
        else
        {
            if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
            {
                /* We ignore read failures for the first few reads,
                 * they are probably benign. */
                if (i > MAILBOX2_ATTEMPTS / 4)
                {
                    unifi_trace(card->ospriv, UDBG1, "Failed to read CCCR IO Ready register while polling for reset\n");
                }
            }
            else
            {
                unifi_trace(card->ospriv, UDBG1, "Failed to read CCCR IO Enable register while polling for reset\n");
            }
        }
        CsrThreadSleep(MAILBOX2_TIMEOUT);
    }

    if (r == CSR_RESULT_SUCCESS && i == MAILBOX2_ATTEMPTS)
    {
        unifi_trace(card->ospriv, UDBG1, "Timeout waiting for UniFi to complete reset\n");
        r = CSR_RESULT_FAILURE;
    }

    return r;
} /* card_wait_for_unifi_to_reset() */


/*
 * ---------------------------------------------------------------------------
 *  card_wait_for_unifi_to_disable
 *
 *      Waits for the function to become disabled by polling the
 *      IO_READY bit.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, CSR error code on failure.
 *
 *  Notes: This function can only be used with
 *         card->chip_id > SDIO_CARD_ID_UNIFI_2
 * ---------------------------------------------------------------------------
 */
static CsrResult card_wait_for_unifi_to_disable(card_t *card)
{
    s16 i;
    CsrResult r;
    u8 io_enable;
    CsrResult csrResult;

    if (card->chip_id <= SDIO_CARD_ID_UNIFI_2)
    {
        unifi_error(card->ospriv,
                    "Function reset method not supported for chip_id=%d\n",
                    card->chip_id);
        return CSR_RESULT_FAILURE;
    }

    r = CSR_RESULT_SUCCESS;
    for (i = 0; i < MAILBOX2_ATTEMPTS; i++)
    {
        unifi_trace(card->ospriv, UDBG1, "waiting for disable to complete, attempt %d\n", i);

        /*
         * It's quite likely that this read will timeout for the
         * first few tries - especially if we have reset via
         * DBG_RESET.
         */
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        unifi_debug_log_to_buf("r0@%02X=", SDIO_IO_READY);
#endif
        csrResult = CsrSdioF0Read8(card->sdio_if, SDIO_IO_READY, &io_enable);
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        if (csrResult != CSR_RESULT_SUCCESS)
        {
            unifi_debug_log_to_buf("error=%X\n", csrResult);
        }
        else
        {
            unifi_debug_log_to_buf("%X\n", io_enable);
        }
#endif
        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
        {
            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
        }
        if (csrResult == CSR_RESULT_SUCCESS)
        {
            s16 enabled = io_enable & (1 << card->function);
            r = CSR_RESULT_SUCCESS;
            if (!enabled)
            {
                unifi_trace(card->ospriv, UDBG1,
                            "Disable complete (function %d is disabled) in ~ %u msecs\n",
                            card->function, i * MAILBOX2_TIMEOUT);

                break;
            }
        }
        else
        {
            /*
             * We ignore read failures for the first few reads,
             * they are probably benign.
             */
            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
            if (i > (MAILBOX2_ATTEMPTS / 4))
            {
                unifi_trace(card->ospriv, UDBG1,
                            "Failed to read CCCR IO Ready register while polling for disable\n");
            }
        }
        CsrThreadSleep(MAILBOX2_TIMEOUT);
    }

    if ((r == CSR_RESULT_SUCCESS) && (i == MAILBOX2_ATTEMPTS))
    {
        unifi_trace(card->ospriv, UDBG1, "Timeout waiting for UniFi to complete disable\n");
        r = CSR_RESULT_FAILURE;
    }

    return r;
} /* card_wait_for_unifi_to_reset() */


/*
 * ---------------------------------------------------------------------------
 *  card_wait_for_firmware_to_start
 *
 *      Polls the MAILBOX1 register for a non-zero value.
 *      Then reads MAILBOX0 and forms the two values into a 32-bit address
 *      which is returned to the caller.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *      paddr           Pointer to receive the UniFi address formed
 *                      by concatenating MAILBOX1 and MAILBOX0.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, CSR error code on failure.
 * ---------------------------------------------------------------------------
 */
CsrResult card_wait_for_firmware_to_start(card_t *card, u32 *paddr)
{
    s32 i;
    u16 mbox0, mbox1;
    CsrResult r;

    /*
     * Wait for UniFi to initialise its data structures by polling
     * the SHARED_MAILBOX1 register.
     * Experience shows this is typically 120ms.
     */
    CsrThreadSleep(MAILBOX1_TIMEOUT);

    mbox1 = 0;
    unifi_trace(card->ospriv, UDBG1, "waiting for MAILBOX1 to be non-zero...\n");
    for (i = 0; i < MAILBOX1_ATTEMPTS; i++)
    {
        r = unifi_read_direct16(card, ChipHelper_MAILBOX1(card->helper) * 2, &mbox1);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            /* These reads can fail if UniFi isn't up yet, so try again */
            unifi_warning(card->ospriv, "Failed to read UniFi Mailbox1 register\n");
        }

        if ((r == CSR_RESULT_SUCCESS) && (mbox1 != 0))
        {
            unifi_trace(card->ospriv, UDBG1, "MAILBOX1 ready (0x%04X) in %u millisecs\n",
                        mbox1, i * MAILBOX1_TIMEOUT);

            /* Read the MAILBOX1 again in case we caught the value as it
             * changed. */
            r = unifi_read_direct16(card, ChipHelper_MAILBOX1(card->helper) * 2, &mbox1);
            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
            {
                return r;
            }
            if (r != CSR_RESULT_SUCCESS)
            {
                unifi_error(card->ospriv, "Failed to read UniFi Mailbox1 register for second time\n");
                return r;
            }
            unifi_trace(card->ospriv, UDBG1, "MAILBOX1 value=0x%04X\n", mbox1);

            break;
        }

        CsrThreadSleep(MAILBOX1_TIMEOUT);
        if ((i % 100) == 99)
        {
            unifi_trace(card->ospriv, UDBG2, "MAILBOX1 not ready (0x%X), still trying...\n", mbox1);
        }
    }

    if ((r == CSR_RESULT_SUCCESS) && (mbox1 == 0))
    {
        unifi_trace(card->ospriv, UDBG1, "Timeout waiting for firmware to start, Mailbox1 still 0 after %d ms\n",
                    MAILBOX1_ATTEMPTS * MAILBOX1_TIMEOUT);
        return CSR_RESULT_FAILURE;
    }


    /*
     * Complete the reset handshake by setting MAILBOX2 to 0xFFFF
     */
    r = unifi_write_direct16(card, ChipHelper_SDIO_HIP_HANDSHAKE(card->helper) * 2, 0xFFFF);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to write f/w startup handshake to MAILBOX2\n");
        return r;
    }


    /*
     * Read the Symbol Look Up Table (SLUT) offset.
     * Top 16 bits are in mbox1, read the lower 16 bits from mbox0.
     */
    mbox0 = 0;
    r = unifi_read_direct16(card, ChipHelper_MAILBOX0(card->helper) * 2, &mbox0);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to read UniFi Mailbox0 register\n");
        return r;
    }

    *paddr = (((u32)mbox1 << 16) | mbox0);

    return CSR_RESULT_SUCCESS;
} /* card_wait_for_firmware_to_start() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_capture_panic
 *
 *      Attempt to capture panic codes from the firmware. This may involve
 *      warm reset of the chip to regain access following a watchdog reset.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS if panic codes were captured, or none available
 *      CSR_RESULT_FAILURE if the driver could not access function 1
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_capture_panic(card_t *card)
{

    /* The firmware must have previously initialised to read the panic addresses
     * from the SLUT
     */
    if (!card->panic_data_phy_addr || !card->panic_data_mac_addr)
    {
        return CSR_RESULT_SUCCESS;
    }

    /* Ensure we can access function 1 following a panic/watchdog reset */
    if (card_access_panic(card) == CSR_RESULT_SUCCESS)
    {
        /* Read the panic codes */
        unifi_read_panic(card);
    }
    else
    {
        unifi_info(card->ospriv, "Unable to read panic codes");
    }

    return CSR_RESULT_SUCCESS;
}


/*
 * ---------------------------------------------------------------------------
 *  card_access_panic
 *      Attempt to read the WLAN SDIO function in order to read panic codes
 *      and perform various reset steps to regain access if the read fails.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS if panic codes can be read
 *      CSR error code if panic codes can not be read
 * ---------------------------------------------------------------------------
 */
static CsrResult card_access_panic(card_t *card)
{
    u16 data_u16 = 0;
    s32 i;
    CsrResult r, sr;

    /* A chip version of zero means that the version never got succesfully read
     * during reset. In this case give up because it will not be possible to
     * verify the chip version.
     */
    if (!card->chip_version)
    {
        unifi_info(card->ospriv, "Unknown chip version\n");
        return CSR_RESULT_FAILURE;
    }

    /* Ensure chip is awake or access to function 1 will fail */
    r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "unifi_set_host_state() failed %d\n", r);
        return CSR_RESULT_FAILURE; /* Card is probably unpowered */
    }
    CsrThreadSleep(20);

    for (i = 0; i < 3; i++)
    {
        sr = CsrSdioRead16(card->sdio_if, CHIP_HELPER_UNIFI_GBL_CHIP_VERSION * 2, &data_u16);
        if (sr != CSR_RESULT_SUCCESS || data_u16 != card->chip_version)
        {
            unifi_info(card->ospriv, "Failed to read valid chip version sr=%d (0x%04x want 0x%04x) try %d\n",
                       sr, data_u16, card->chip_version, i);

            /* Set clock speed low */
            sr = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_SAFE_HZ);
            if (sr != CSR_RESULT_SUCCESS)
            {
                unifi_error(card->ospriv, "CsrSdioMaxBusClockFrequencySet() failed1 %d\n", sr);
                r = ConvertCsrSdioToCsrHipResult(card, sr);
            }
            card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ;

            /* First try re-enabling function in case a f/w watchdog reset disabled it */
            if (i == 0)
            {
                unifi_info(card->ospriv, "Try function enable\n");
                sr = CsrSdioFunctionEnable(card->sdio_if);
                if (sr != CSR_RESULT_SUCCESS)
                {
                    r = ConvertCsrSdioToCsrHipResult(card, sr);
                    unifi_error(card->ospriv, "CsrSdioFunctionEnable failed %d (HIP %d)\n", sr, r);
                }
                continue;
            }

            /* Second try, set awake */
            unifi_info(card->ospriv, "Try set awake\n");

            /* Ensure chip is awake */
            r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
            {
                return r;
            }
            if (r != CSR_RESULT_SUCCESS)
            {
                unifi_error(card->ospriv, "unifi_set_host_state() failed2 %d\n", r);
            }

            /* Set clock speed low in case setting the host state raised it, which
             * would only happen if host state was previously TORPID
             */
            sr = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_SAFE_HZ);
            if (sr != CSR_RESULT_SUCCESS)
            {
                unifi_error(card->ospriv, "CsrSdioMaxBusClockFrequencySet() failed2 %d\n", sr);
            }
            card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ;

            if (i == 1)
            {
                continue;
            }

            /* Perform a s/w reset to preserve as much as the card state as possible,
             * (mainly the preserve RAM). The context will be lost for coredump - but as we
             * were unable to access the WLAN function for panic, the coredump would have
             * also failed without a reset.
             */
            unifi_info(card->ospriv, "Try s/w reset\n");

            r = unifi_card_hard_reset(card);
            if (r != CSR_RESULT_SUCCESS)
            {
                unifi_error(card->ospriv, "unifi_card_hard_reset() failed %d\n", r);
            }
        }
        else
        {
            if (i > 0)
            {
                unifi_info(card->ospriv, "Read chip version 0x%x after %d retries\n", data_u16, i);
            }
            break;
        }
    }

    r = ConvertCsrSdioToCsrHipResult(card, sr);
    return r;
}


/*
 * ---------------------------------------------------------------------------
 *  unifi_read_panic
 *      Reads, saves and prints panic codes stored by the firmware in UniFi's
 *      preserve RAM by the last panic that occurred since chip was powered.
 *      Nothing is saved if the panic codes are read as zero.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 * ---------------------------------------------------------------------------
 */
void unifi_read_panic(card_t *card)
{
    CsrResult r;
    u16 p_code, p_arg;

    /* The firmware must have previously initialised to read the panic addresses
     * from the SLUT
     */
    if (!card->panic_data_phy_addr || !card->panic_data_mac_addr)
    {
        return;
    }

    /* Get the panic data from PHY */
    r = unifi_card_read16(card, card->panic_data_phy_addr, &p_code);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_phy_addr, r);
        p_code = 0;
    }
    if (p_code)
    {
        r = unifi_card_read16(card, card->panic_data_phy_addr + 2, &p_arg);
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_phy_addr + 2, r);
        }
        unifi_error(card->ospriv, "Last UniFi PHY PANIC %04x arg %04x\n", p_code, p_arg);
        card->last_phy_panic_code = p_code;
        card->last_phy_panic_arg = p_arg;
    }

    /* Get the panic data from MAC */
    r = unifi_card_read16(card, card->panic_data_mac_addr, &p_code);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_mac_addr, r);
        p_code = 0;
    }
    if (p_code)
    {
        r = unifi_card_read16(card, card->panic_data_mac_addr + 2, &p_arg);
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "capture_panic: unifi_read16 %08x failed %d\n", card->panic_data_mac_addr + 2, r);
        }
        unifi_error(card->ospriv, "Last UniFi MAC PANIC %04x arg %04x\n", p_code, p_arg);
        card->last_mac_panic_code = p_code;
        card->last_mac_panic_arg = p_arg;
    }

}


/*
 * ---------------------------------------------------------------------------
 *  card_allocate_memory_resources
 *
 *      Allocates memory for the from-host, to-host bulk data slots,
 *      soft queue buffers and bulk data buffers.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, CSR error code on failure.
 * ---------------------------------------------------------------------------
 */
static CsrResult card_allocate_memory_resources(card_t *card)
{
    s16 n, i, k, r;
    sdio_config_data_t *cfg_data;

    /* Reset any state carried forward from a previous life */
    card->fh_command_queue.q_rd_ptr = 0;
    card->fh_command_queue.q_wr_ptr = 0;
    (void)scnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
                      "fh_cmd_q");
    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
    {
        card->fh_traffic_queue[i].q_rd_ptr = 0;
        card->fh_traffic_queue[i].q_wr_ptr = 0;
        (void)scnprintf(card->fh_traffic_queue[i].name,
                          UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
    }
#ifndef CSR_WIFI_HIP_TA_DISABLE
    unifi_ta_sampling_init(card);
#endif
    /* Convenience short-cut */
    cfg_data = &card->config_data;

    /*
     * Allocate memory for the from-host and to-host signal buffers.
     */
    card->fh_buffer.buf = kmalloc(UNIFI_FH_BUF_SIZE, GFP_KERNEL);
    if (card->fh_buffer.buf == NULL)
    {
        unifi_error(card->ospriv, "Failed to allocate memory for F-H signals\n");
        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
    }
    card->fh_buffer.bufsize = UNIFI_FH_BUF_SIZE;
    card->fh_buffer.ptr = card->fh_buffer.buf;
    card->fh_buffer.count = 0;

    card->th_buffer.buf = kmalloc(UNIFI_FH_BUF_SIZE, GFP_KERNEL);
    if (card->th_buffer.buf == NULL)
    {
        unifi_error(card->ospriv, "Failed to allocate memory for T-H signals\n");
        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
    }
    card->th_buffer.bufsize = UNIFI_FH_BUF_SIZE;
    card->th_buffer.ptr = card->th_buffer.buf;
    card->th_buffer.count = 0;


    /*
     * Allocate memory for the from-host and to-host bulk data slots.
     * This is done as separate kmallocs because lots of smaller
     * allocations are more likely to succeed than one huge one.
     */

    /* Allocate memory for the array of pointers */
    n = cfg_data->num_fromhost_data_slots;

    unifi_trace(card->ospriv, UDBG3, "Alloc from-host resources, %d slots.\n", n);
    card->from_host_data = kmalloc(n * sizeof(slot_desc_t), GFP_KERNEL);
    if (card->from_host_data == NULL)
    {
        unifi_error(card->ospriv, "Failed to allocate memory for F-H bulk data array\n");
        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
    }

    /* Initialise from-host bulk data slots */
    for (i = 0; i < n; i++)
    {
        UNIFI_INIT_BULK_DATA(&card->from_host_data[i].bd);
    }

    /* Allocate memory for the array used for slot host tag mapping */
    card->fh_slot_host_tag_record = kmalloc(n * sizeof(u32), GFP_KERNEL);

    if (card->fh_slot_host_tag_record == NULL)
    {
        unifi_error(card->ospriv, "Failed to allocate memory for F-H slot host tag mapping array\n");
        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
    }

    /* Initialise host tag entries for from-host bulk data slots */
    for (i = 0; i < n; i++)
    {
        card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
    }


    /* Allocate memory for the array of pointers */
    n = cfg_data->num_tohost_data_slots;

    unifi_trace(card->ospriv, UDBG3, "Alloc to-host resources, %d slots.\n", n);
    card->to_host_data = kmalloc(n * sizeof(bulk_data_desc_t), GFP_KERNEL);
    if (card->to_host_data == NULL)
    {
        unifi_error(card->ospriv, "Failed to allocate memory for T-H bulk data array\n");
        return CSR_WIFI_HIP_RESULT_NO_MEMORY;
    }

    /* Initialise to-host bulk data slots */
    for (i = 0; i < n; i++)
    {
        UNIFI_INIT_BULK_DATA(&card->to_host_data[i]);
    }

    /*
     * Initialise buffers for soft Q
     */
    for (i = 0; i < UNIFI_SOFT_COMMAND_Q_LENGTH; i++)
    {
        for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++)
        {
            UNIFI_INIT_BULK_DATA(&card->fh_command_q_body[i].bulkdata[r]);
        }
    }

    for (k = 0; k < UNIFI_NO_OF_TX_QS; k++)
    {
        for (i = 0; i < UNIFI_SOFT_TRAFFIC_Q_LENGTH; i++)
        {
            for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++)
            {
                UNIFI_INIT_BULK_DATA(&card->fh_traffic_q_body[k][i].bulkdata[r]);
            }
        }
    }

    card->memory_resources_allocated = 1;

    return CSR_RESULT_SUCCESS;
} /* card_allocate_memory_resources() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_free_bulk_data
 *
 *      Free the data associated to a bulk data structure.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *      bulk_data_slot  Pointer to bulk data structure
 *
 *  Returns:
 *      None.
 *
 * ---------------------------------------------------------------------------
 */
static void unifi_free_bulk_data(card_t *card, bulk_data_desc_t *bulk_data_slot)
{
    if (bulk_data_slot->data_length != 0)
    {
        unifi_net_data_free(card->ospriv, bulk_data_slot);
    }
} /* unifi_free_bulk_data() */


/*
 * ---------------------------------------------------------------------------
 *  card_free_memory_resources
 *
 *      Frees memory allocated for the from-host, to-host bulk data slots,
 *      soft queue buffers and bulk data buffers.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void card_free_memory_resources(card_t *card)
{

    unifi_trace(card->ospriv, UDBG1, "Freeing card memory resources.\n");

    /* Clear our internal queues */
    unifi_cancel_pending_signals(card);


    kfree(card->to_host_data);
    card->to_host_data = NULL;

    kfree(card->from_host_data);
    card->from_host_data = NULL;

    /* free the memory for slot host tag mapping array */
    kfree(card->fh_slot_host_tag_record);
    card->fh_slot_host_tag_record = NULL;

    kfree(card->fh_buffer.buf);
    card->fh_buffer.ptr = card->fh_buffer.buf = NULL;
    card->fh_buffer.bufsize = 0;
    card->fh_buffer.count = 0;

    kfree(card->th_buffer.buf);
    card->th_buffer.ptr = card->th_buffer.buf = NULL;
    card->th_buffer.bufsize = 0;
    card->th_buffer.count = 0;


    card->memory_resources_allocated = 0;

} /* card_free_memory_resources() */


static void card_init_soft_queues(card_t *card)
{
    s16 i;

    unifi_trace(card->ospriv, UDBG1, "Initialising internal signal queues.\n");
    /* Reset any state carried forward from a previous life */
    card->fh_command_queue.q_rd_ptr = 0;
    card->fh_command_queue.q_wr_ptr = 0;
    (void)scnprintf(card->fh_command_queue.name, UNIFI_QUEUE_NAME_MAX_LENGTH,
                      "fh_cmd_q");
    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
    {
        card->fh_traffic_queue[i].q_rd_ptr = 0;
        card->fh_traffic_queue[i].q_wr_ptr = 0;
        (void)scnprintf(card->fh_traffic_queue[i].name,
                          UNIFI_QUEUE_NAME_MAX_LENGTH, "fh_data_q%d", i);
    }
#ifndef CSR_WIFI_HIP_TA_DISABLE
    unifi_ta_sampling_init(card);
#endif
}


/*
 * ---------------------------------------------------------------------------
 *  unifi_cancel_pending_signals
 *
 *      Free the signals and associated bulk data, pending in the core.
 *
 *  Arguments:
 *      card        Pointer to card struct
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
void unifi_cancel_pending_signals(card_t *card)
{
    s16 i, n, r;

    unifi_trace(card->ospriv, UDBG1, "Canceling pending signals.\n");

    if (card->to_host_data)
    {
        /*
         * Free any bulk data buffers allocated for the t-h slots
         * This will clear all buffers that did not make it to
         * unifi_receive_event() before cancel was request.
         */
        n = card->config_data.num_tohost_data_slots;
        unifi_trace(card->ospriv, UDBG3, "Freeing to-host resources, %d slots.\n", n);
        for (i = 0; i < n; i++)
        {
            unifi_free_bulk_data(card, &card->to_host_data[i]);
        }
    }

    /*
     * If any of the from-host bulk data has reached the card->from_host_data
     * but not UniFi, we need to free the buffers here.
     */
    if (card->from_host_data)
    {
        /* Free any bulk data buffers allocated for the f-h slots */
        n = card->config_data.num_fromhost_data_slots;
        unifi_trace(card->ospriv, UDBG3, "Freeing from-host resources, %d slots.\n", n);
        for (i = 0; i < n; i++)
        {
            unifi_free_bulk_data(card, &card->from_host_data[i].bd);
        }

        for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
        {
            card->dynamic_slot_data.from_host_used_slots[i] = 0;
            card->dynamic_slot_data.from_host_max_slots[i] = 0;
            card->dynamic_slot_data.from_host_reserved_slots[i] = 0;
        }
    }

    /*
     * Free any bulk data buffers allocated in the soft queues.
     * This covers the case where a bulk data pointer has reached the soft queue
     * but not the card->from_host_data.
     */
    unifi_trace(card->ospriv, UDBG3, "Freeing cmd q resources.\n");
    for (i = 0; i < UNIFI_SOFT_COMMAND_Q_LENGTH; i++)
    {
        for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++)
        {
            unifi_free_bulk_data(card, &card->fh_command_q_body[i].bulkdata[r]);
        }
    }

    unifi_trace(card->ospriv, UDBG3, "Freeing traffic q resources.\n");
    for (n = 0; n < UNIFI_NO_OF_TX_QS; n++)
    {
        for (i = 0; i < UNIFI_SOFT_TRAFFIC_Q_LENGTH; i++)
        {
            for (r = 0; r < UNIFI_MAX_DATA_REFERENCES; r++)
            {
                unifi_free_bulk_data(card, &card->fh_traffic_q_body[n][i].bulkdata[r]);
            }
        }
    }

    card_init_soft_queues(card);

} /* unifi_cancel_pending_signals() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_free_card
 *
 *      Free the memory allocated for the card structure and buffers.
 *
 *  Notes:
 *      The porting layer is responsible for freeing any mini-coredump buffers
 *      allocated when it called unifi_coredump_init(), by calling
 *      unifi_coredump_free() before calling this function.
 *
 *  Arguments:
 *      card        Pointer to card struct
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
void unifi_free_card(card_t *card)
{
#ifdef CSR_PRE_ALLOC_NET_DATA
    prealloc_netdata_free(card);
#endif
    /* Free any memory allocated. */
    card_free_memory_resources(card);

    /* Warn if caller didn't free coredump buffers */
    if (card->dump_buf)
    {
        unifi_error(card->ospriv, "Caller should call unifi_coredump_free()\n");
        unifi_coredump_free(card); /* free anyway to prevent memory leak */
    }

    kfree(card);

} /* unifi_free_card() */


/*
 * ---------------------------------------------------------------------------
 *  card_init_slots
 *
 *      Allocate memory for host-side slot data and signal queues.
 *
 * Arguments:
 *      card            Pointer to card object
 *
 * Returns:
 *      CSR error code.
 * ---------------------------------------------------------------------------
 */
static CsrResult card_init_slots(card_t *card)
{
    CsrResult r;
    u8 i;

    /* Allocate the buffers we need, only once. */
    if (card->memory_resources_allocated == 1)
    {
        card_free_memory_resources(card);
    }
    else
    {
        /* Initialise our internal command and traffic queues */
        card_init_soft_queues(card);
    }

    r = card_allocate_memory_resources(card);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to allocate card memory resources.\n");
        card_free_memory_resources(card);
        return r;
    }

    if (card->sdio_ctrl_addr == 0)
    {
        unifi_error(card->ospriv, "Failed to find config struct!\n");
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    /*
     * Set initial counts.
     */

    card->from_host_data_head = 0;

    /* Get initial signal counts from UniFi, in case it has not been reset. */
    {
        u16 s;

        /* Get the from-host-signals-written count */
        r = unifi_card_read16(card, card->sdio_ctrl_addr + 0, &s);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to read from-host sig written count\n");
            return r;
        }
        card->from_host_signals_w = (s16)s;

        /* Get the to-host-signals-written count */
        r = unifi_card_read16(card, card->sdio_ctrl_addr + 6, &s);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to read to-host sig read count\n");
            return r;
        }
        card->to_host_signals_r = (s16)s;
    }

    /* Set Initialised flag. */
    r = unifi_card_write16(card, card->init_flag_addr, 0x0001);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to write initialised flag\n");
        return r;
    }

    /* Dynamic queue reservation */
    memset(&card->dynamic_slot_data, 0, sizeof(card_dynamic_slot_t));

    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
    {
        card->dynamic_slot_data.from_host_max_slots[i] = card->config_data.num_fromhost_data_slots -
                                                         UNIFI_RESERVED_COMMAND_SLOTS;
        card->dynamic_slot_data.queue_stable[i] = FALSE;
    }

    card->dynamic_slot_data.packets_interval = UNIFI_PACKETS_INTERVAL;

    return CSR_RESULT_SUCCESS;
} /* card_init_slots() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_set_udi_hook
 *
 *      Registers the udi hook that reports the sent signals to the core.
 *
 *  Arguments:
 *      card            Pointer to the card context struct
 *      udi_fn          Pointer to the callback function.
 *
 *  Returns:
 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE if the card pointer is invalid,
 *      CSR_RESULT_SUCCESS on success.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_set_udi_hook(card_t *card, udi_func_t udi_fn)
{
    if (card == NULL)
    {
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    if (card->udi_hook == NULL)
    {
        card->udi_hook = udi_fn;
    }

    return CSR_RESULT_SUCCESS;
} /* unifi_set_udi_hook() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_remove_udi_hook
 *
 *      Removes the udi hook that reports the sent signals from the core.
 *
 *  Arguments:
 *      card            Pointer to the card context struct
 *      udi_fn          Pointer to the callback function.
 *
 *  Returns:
 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE if the card pointer is invalid,
 *      CSR_RESULT_SUCCESS on success.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_remove_udi_hook(card_t *card, udi_func_t udi_fn)
{
    if (card == NULL)
    {
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    if (card->udi_hook == udi_fn)
    {
        card->udi_hook = NULL;
    }

    return CSR_RESULT_SUCCESS;
} /* unifi_remove_udi_hook() */


static void CardReassignDynamicReservation(card_t *card)
{
    u8 i;

    unifi_trace(card->ospriv, UDBG5, "Packets Txed %d %d %d %d\n",
                card->dynamic_slot_data.packets_txed[0],
                card->dynamic_slot_data.packets_txed[1],
                card->dynamic_slot_data.packets_txed[2],
                card->dynamic_slot_data.packets_txed[3]);

    /* Clear reservation and recalculate max slots */
    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
    {
        card->dynamic_slot_data.queue_stable[i] = FALSE;
        card->dynamic_slot_data.from_host_reserved_slots[i] = 0;
        card->dynamic_slot_data.from_host_max_slots[i] = card->config_data.num_fromhost_data_slots -
                                                         UNIFI_RESERVED_COMMAND_SLOTS;
        card->dynamic_slot_data.packets_txed[i] = 0;

        unifi_trace(card->ospriv, UDBG5, "CardReassignDynamicReservation: queue %d reserved %d Max %d\n", i,
                    card->dynamic_slot_data.from_host_reserved_slots[i],
                    card->dynamic_slot_data.from_host_max_slots[i]);
    }

    card->dynamic_slot_data.total_packets_txed = 0;
}


/* Algorithm to dynamically reserve slots. The logic is based mainly on the outstanding queue
 * length. Slots are reserved for particular queues during an interval and cleared after the interval.
 * Each queue has three associated variables.. a) used slots - the number of slots currently occupied
 * by the queue b) reserved slots - number of slots reserved specifically for the queue c) max slots - total
 * slots that this queue can actually use (may be higher than reserved slots and is dependent on reserved slots
 * for other queues).
 * This function is called when there are no slots available for a queue. It checks to see if there are enough
 * unreserved slots sufficient for this request. If available these slots are reserved for the queue.
 * If there are not enough unreserved slots, a fair share for each queue is calculated based on the total slots
 * and the number of active queues (any queue with existing reservation is considered active). Queues needing
 * less than their fair share are allowed to have the previously reserved slots. The remaining slots are
 * distributed evenly among queues that need more than the fair share
 *
 * A better scheme would take current bandwidth per AC into consideration when reserving slots. An
 * implementation scheme could consider the relative time/service period for slots in an AC. If the firmware
 * services other ACs faster than a particular AC (packets wait in the slots longer) then it is fair to reserve
 * less slots for the AC
 */
static void CardCheckDynamicReservation(card_t *card, unifi_TrafficQueue queue)
{
    u16 q_len, active_queues = 0, excess_queue_slots, div_extra_slots,
              queue_fair_share, reserved_slots = 0, q, excess_need_queues = 0, unmovable_slots = 0;
    s32 i;
    q_t *sigq;
    u16 num_data_slots = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS;

    /* Calculate the pending queue length */
    sigq = &card->fh_traffic_queue[queue];
    q_len = CSR_WIFI_HIP_Q_SLOTS_USED(sigq);

    if (q_len <= card->dynamic_slot_data.from_host_reserved_slots[queue])
    {
        unifi_trace(card->ospriv, UDBG5, "queue %d q_len %d already has that many reserved slots, exiting\n", queue, q_len);
        return;
    }

    /* Upper limit */
    if (q_len > num_data_slots)
    {
        q_len = num_data_slots;
    }

    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
    {
        if (i != (s32)queue)
        {
            reserved_slots += card->dynamic_slot_data.from_host_reserved_slots[i];
        }
        if ((i == (s32)queue) || (card->dynamic_slot_data.from_host_reserved_slots[i] > 0))
        {
            active_queues++;
        }
    }

    unifi_trace(card->ospriv, UDBG5, "CardCheckDynamicReservation: queue %d q_len %d\n", queue, q_len);
    unifi_trace(card->ospriv, UDBG5, "Active queues %d reserved slots on other queues %d\n",
                active_queues, reserved_slots);

    if (reserved_slots + q_len <= num_data_slots)
    {
        card->dynamic_slot_data.from_host_reserved_slots[queue] = q_len;
        if (q_len == num_data_slots)
        {
            /* This is the common case when just 1 stream is going */
            card->dynamic_slot_data.queue_stable[queue] = TRUE;
        }
    }
    else
    {
        queue_fair_share = num_data_slots / active_queues;
        unifi_trace(card->ospriv, UDBG5, "queue fair share %d\n", queue_fair_share);

        /* Evenly distribute slots among active queues */
        /* Find out the queues that need excess of fair share. Also find slots allocated
         * to queues less than their fair share, these slots cannot be reallocated (unmovable slots) */

        card->dynamic_slot_data.from_host_reserved_slots[queue] = q_len;

        for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
        {
            if (card->dynamic_slot_data.from_host_reserved_slots[i] > queue_fair_share)
            {
                excess_need_queues++;
            }
            else
            {
                unmovable_slots += card->dynamic_slot_data.from_host_reserved_slots[i];
            }
        }

        unifi_trace(card->ospriv, UDBG5, "Excess need queues %d\n", excess_need_queues);

        /* Now find the slots per excess demand queue */
        excess_queue_slots = (num_data_slots - unmovable_slots) / excess_need_queues;
        div_extra_slots = (num_data_slots - unmovable_slots) - excess_queue_slots * excess_need_queues;
        for (i = UNIFI_NO_OF_TX_QS - 1; i >= 0; i--)
        {
            if (card->dynamic_slot_data.from_host_reserved_slots[i] > excess_queue_slots)
            {
                card->dynamic_slot_data.from_host_reserved_slots[i] = excess_queue_slots;
                if (div_extra_slots > 0)
                {
                    card->dynamic_slot_data.from_host_reserved_slots[i]++;
                    div_extra_slots--;
                }
                /* No more slots will be allocated to this queue during the current interval */
                card->dynamic_slot_data.queue_stable[i] = TRUE;
                unifi_trace(card->ospriv, UDBG5, "queue stable %d\n", i);
            }
        }
    }

    /* Redistribute max slots */
    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
    {
        reserved_slots = 0;
        for (q = 0; q < UNIFI_NO_OF_TX_QS; q++)
        {
            if (i != q)
            {
                reserved_slots += card->dynamic_slot_data.from_host_reserved_slots[q];
            }
        }

        card->dynamic_slot_data.from_host_max_slots[i] = num_data_slots - reserved_slots;
        unifi_trace(card->ospriv, UDBG5, "queue %d reserved %d Max %d\n", i,
                    card->dynamic_slot_data.from_host_reserved_slots[i],
                    card->dynamic_slot_data.from_host_max_slots[i]);
    }

}


/*
 * ---------------------------------------------------------------------------
 *  CardClearFromHostDataSlot
 *
 *      Clear a the given data slot, making it available again.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *      slot            Index of the signal slot to clear.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
void CardClearFromHostDataSlot(card_t *card, const s16 slot)
{
    u8 queue = card->from_host_data[slot].queue;
    const void *os_data_ptr = card->from_host_data[slot].bd.os_data_ptr;

    if (card->from_host_data[slot].bd.data_length == 0)
    {
        unifi_warning(card->ospriv,
                      "Surprise: request to clear an already free FH data slot: %d\n",
                      slot);
        return;
    }

    if (os_data_ptr == NULL)
    {
        unifi_warning(card->ospriv,
                      "Clearing FH data slot %d: has null payload, len=%d\n",
                      slot, card->from_host_data[slot].bd.data_length);
    }

    /* Free card->from_host_data[slot].bd.os_net_ptr here. */
    /* Mark slot as free by setting length to 0. */
    unifi_free_bulk_data(card, &card->from_host_data[slot].bd);
    if (queue < UNIFI_NO_OF_TX_QS)
    {
        if (card->dynamic_slot_data.from_host_used_slots[queue] == 0)
        {
            unifi_error(card->ospriv, "Goofed up used slots q = %d used slots = %d\n",
                        queue,
                        card->dynamic_slot_data.from_host_used_slots[queue]);
        }
        else
        {
            card->dynamic_slot_data.from_host_used_slots[queue]--;
        }
        card->dynamic_slot_data.packets_txed[queue]++;
        card->dynamic_slot_data.total_packets_txed++;
        if (card->dynamic_slot_data.total_packets_txed >= card->dynamic_slot_data.packets_interval)
        {
            CardReassignDynamicReservation(card);
        }
    }

    unifi_trace(card->ospriv, UDBG4, "CardClearFromHostDataSlot: slot %d recycled %p\n", slot, os_data_ptr);

} /* CardClearFromHostDataSlot() */


#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
/*
 * ---------------------------------------------------------------------------
 *  CardClearFromHostDataSlotWithoutFreeingBulkData
 *
 *      Clear the given data slot with out freeing the bulk data.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *      slot            Index of the signal slot to clear.
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
void CardClearFromHostDataSlotWithoutFreeingBulkData(card_t *card, const s16 slot)
{
    u8 queue = card->from_host_data[slot].queue;

    /* Initialise the from_host data slot so it can be re-used,
     * Set length field in from_host_data array to 0.
     */
    UNIFI_INIT_BULK_DATA(&card->from_host_data[slot].bd);

    queue = card->from_host_data[slot].queue;

    if (queue < UNIFI_NO_OF_TX_QS)
    {
        if (card->dynamic_slot_data.from_host_used_slots[queue] == 0)
        {
            unifi_error(card->ospriv, "Goofed up used slots q = %d used slots = %d\n",
                        queue,
                        card->dynamic_slot_data.from_host_used_slots[queue]);
        }
        else
        {
            card->dynamic_slot_data.from_host_used_slots[queue]--;
        }
        card->dynamic_slot_data.packets_txed[queue]++;
        card->dynamic_slot_data.total_packets_txed++;
        if (card->dynamic_slot_data.total_packets_txed >=
            card->dynamic_slot_data.packets_interval)
        {
            CardReassignDynamicReservation(card);
        }
    }
} /* CardClearFromHostDataSlotWithoutFreeingBulkData() */


#endif

u16 CardGetDataSlotSize(card_t *card)
{
    return card->config_data.data_slot_size;
} /* CardGetDataSlotSize() */


/*
 * ---------------------------------------------------------------------------
 *  CardGetFreeFromHostDataSlots
 *
 *      Retrieve the number of from-host bulk data slots available.
 *
 *  Arguments:
 *      card            Pointer to the card context struct
 *
 *  Returns:
 *      Number of free from-host bulk data slots.
 * ---------------------------------------------------------------------------
 */
u16 CardGetFreeFromHostDataSlots(card_t *card)
{
    u16 i, n = 0;

    /* First two slots reserved for MLME */
    for (i = 0; i < card->config_data.num_fromhost_data_slots; i++)
    {
        if (card->from_host_data[i].bd.data_length == 0)
        {
            /* Free slot */
            n++;
        }
    }

    return n;
} /* CardGetFreeFromHostDataSlots() */


/*
 * ---------------------------------------------------------------------------
 *  CardAreAllFromHostDataSlotsEmpty
 *
 *      Returns the state of from-host bulk data slots.
 *
 *  Arguments:
 *      card            Pointer to the card context struct
 *
 *  Returns:
 *      1       The from-host bulk data slots are all empty (available).
 *      0       Some or all the from-host bulk data slots are in use.
 * ---------------------------------------------------------------------------
 */
u16 CardAreAllFromHostDataSlotsEmpty(card_t *card)
{
    u16 i;

    for (i = 0; i < card->config_data.num_fromhost_data_slots; i++)
    {
        if (card->from_host_data[i].bd.data_length != 0)
        {
            return 0;
        }
    }

    return 1;
} /* CardGetFreeFromHostDataSlots() */


static CsrResult unifi_identify_hw(card_t *card)
{

    card->chip_id = card->sdio_if->sdioId.cardId;
    card->function = card->sdio_if->sdioId.sdioFunction;
    card->sdio_io_block_size = card->sdio_if->blockSize;

    /* If SDIO controller doesn't support byte mode CMD53, pad transfers to block sizes */
    card->sdio_io_block_pad = (card->sdio_if->features & CSR_SDIO_FEATURE_BYTE_MODE)?FALSE : TRUE;

    /*
     * Setup the chip helper so that we can access the registers (and
     * also tell what sub-type of HIP we should use).
     */
    card->helper = ChipHelper_GetVersionSdio((u8)card->chip_id);
    if (!card->helper)
    {
        unifi_error(card->ospriv, "Null ChipHelper\n");
    }

    unifi_info(card->ospriv, "Chip ID 0x%02X  Function %u  Block Size %u  Name %s(%s)\n",
               card->chip_id, card->function, card->sdio_io_block_size,
               ChipHelper_MarketingName(card->helper),
               ChipHelper_FriendlyName(card->helper));

    return CSR_RESULT_SUCCESS;
} /* unifi_identify_hw() */


static CsrResult unifi_prepare_hw(card_t *card)
{
    CsrResult r;
    CsrResult csrResult;
    enum unifi_host_state old_state = card->host_state;

    r = unifi_identify_hw(card);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to identify hw\n");
        return r;
    }

    unifi_trace(card->ospriv, UDBG1,
                "%s mode SDIO\n", card->sdio_io_block_pad?"Block" : "Byte");
    /*
     * Chip must be a awake or blocks that are asleep may not get
     * reset.  We can only do this after we have read the chip_id.
     */
    r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }

    if (old_state == UNIFI_HOST_STATE_TORPID)
    {
        /* Ensure the initial clock rate is set; if a reset occured when the chip was
         * TORPID, unifi_set_host_state() may have raised it to MAX.
         */
        csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_INIT_HZ);
        if (csrResult != CSR_RESULT_SUCCESS)
        {
            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
            return r;
        }
        card->sdio_clock_speed = UNIFI_SDIO_CLOCK_INIT_HZ;
    }

    /*
     * The WLAN function must be enabled to access MAILBOX2 and DEBUG_RST
     * registers.
     */
    csrResult = CsrSdioFunctionEnable(card->sdio_if);
    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
    {
        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
    }
    if (csrResult != CSR_RESULT_SUCCESS)
    {
        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
        /* Can't enable WLAN function. Try resetting the SDIO block. */
        unifi_error(card->ospriv, "Failed to re-enable function %d.\n", card->function);
        return r;
    }

    /*
     * Poke some registers to make sure the PLL has started,
     * otherwise memory accesses are likely to fail.
     */
    bootstrap_chip_hw(card);

    /* Try to read the chip version from register. */
    r = unifi_read_chip_version(card);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    return CSR_RESULT_SUCCESS;
} /* unifi_prepare_hw() */


static CsrResult unifi_read_chip_version(card_t *card)
{
    u32 gbl_chip_version;
    CsrResult r;
    u16 ver;

    gbl_chip_version = ChipHelper_GBL_CHIP_VERSION(card->helper);

    /* Try to read the chip version from register. */
    if (gbl_chip_version != 0)
    {
        r = unifi_read_direct16(card, gbl_chip_version * 2, &ver);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to read GBL_CHIP_VERSION\n");
            return r;
        }
        card->chip_version = ver;
    }
    else
    {
        unifi_info(card->ospriv, "Unknown Chip ID, cannot locate GBL_CHIP_VERSION\n");
        r = CSR_RESULT_FAILURE;
    }

    unifi_info(card->ospriv, "Chip Version 0x%04X\n", card->chip_version);

    return r;
} /* unifi_read_chip_version() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_reset_hardware
 *
 *      Execute the UniFi reset sequence.
 *
 *      Note: This may fail if the chip is going TORPID so retry at
 *      least once.
 *
 *  Arguments:
 *      card - pointer to card context structure
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, CSR error otherwise.
 *
 *  Notes:
 *      Some platforms (e.g. Windows Vista) do not allow access to registers
 *      that are necessary for a software soft reset.
 * ---------------------------------------------------------------------------
 */
static CsrResult unifi_reset_hardware(card_t *card)
{
    CsrResult r;
    u16 new_block_size = UNIFI_IO_BLOCK_SIZE;
    CsrResult csrResult;

    /* Errors returned by unifi_prepare_hw() are not critical at this point */
    r = unifi_prepare_hw(card);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }

    /* First try SDIO controller reset, which may power cycle the UniFi, assert
     * its reset line, or not be implemented depending on the platform.
     */
    unifi_info(card->ospriv, "Calling CsrSdioHardReset\n");
    csrResult = CsrSdioHardReset(card->sdio_if);
    if (csrResult == CSR_RESULT_SUCCESS)
    {
        unifi_info(card->ospriv, "CsrSdioHardReset succeeded on reseting UniFi\n");
        r = unifi_prepare_hw(card);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "unifi_prepare_hw failed after hard reset\n");
            return r;
        }
    }
    else if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
    {
        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
    }
    else
    {
        /* Falling back to software hard reset methods */
        unifi_info(card->ospriv, "Falling back to software hard reset\n");
        r = unifi_card_hard_reset(card);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "software hard reset failed\n");
            return r;
        }

        /* If we fell back to unifi_card_hard_reset() methods, chip version may
         * not have been read. (Note in the unlikely event that it is zero,
         * it will be harmlessly read again)
         */
        if (card->chip_version == 0)
        {
            r = unifi_read_chip_version(card);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
        }
    }

#ifdef CSR_WIFI_HIP_SDIO_BLOCK_SIZE
    new_block_size = CSR_WIFI_HIP_SDIO_BLOCK_SIZE;
#endif

    /* After hard reset, we need to restore the SDIO block size */
    csrResult = CsrSdioBlockSizeSet(card->sdio_if, new_block_size);
    r = ConvertCsrSdioToCsrHipResult(card, csrResult);

    /* Warn if a different block size was achieved by the transport */
    if (card->sdio_if->blockSize != new_block_size)
    {
        unifi_info(card->ospriv,
                   "Actually got block size %d\n", card->sdio_if->blockSize);
    }

    /* sdio_io_block_size always needs be updated from the achieved block size,
     * as it is used by the OS layer to allocate memory in unifi_net_malloc().
     * Controllers which don't support block mode (e.g. CSPI) will report a
     * block size of zero.
     */
    if (card->sdio_if->blockSize == 0)
    {
        unifi_info(card->ospriv, "Block size 0, block mode not available\n");

        /* Set sdio_io_block_size to 1 so that unifi_net_data_malloc() has a
         * sensible rounding value. Elsewhere padding will already be
         * disabled because the controller supports byte mode.
         */
        card->sdio_io_block_size = 1;

        /* Controller features must declare support for byte mode */
        if (!(card->sdio_if->features & CSR_SDIO_FEATURE_BYTE_MODE))
        {
            unifi_error(card->ospriv, "Requires byte mode\n");
            r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
        }
    }
    else
    {
        /* Padding will be enabled if CSR_SDIO_FEATURE_BYTE_MODE isn't set */
        card->sdio_io_block_size = card->sdio_if->blockSize;
    }


    return r;
} /* unifi_reset_hardware() */


/*
 * ---------------------------------------------------------------------------
 *  card_reset_method_io_enable
 *
 *      Issue a hard reset to the hw writing the IO_ENABLE.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *
 *  Returns:
 *      0 on success,
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE   if the card was ejected
 *      CSR_RESULT_FAILURE         if an SDIO error occurred or if a response
 *                                 was not seen in the expected time
 * ---------------------------------------------------------------------------
 */
static CsrResult card_reset_method_io_enable(card_t *card)
{
    CsrResult r;
    CsrResult csrResult;

    /*
     * This resets only function 1, so should be used in
     * preference to the method below (CSR_FUNC_EN)
     */
    unifi_trace(card->ospriv, UDBG1, "Hard reset (IO_ENABLE)\n");

    csrResult = CsrSdioFunctionDisable(card->sdio_if);
    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
    {
        return CSR_WIFI_HIP_RESULT_NO_DEVICE;
    }
    if (csrResult != CSR_RESULT_SUCCESS)
    {
        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
        unifi_warning(card->ospriv, "SDIO error writing IO_ENABLE: %d\n", r);
    }
    else
    {
        /* Delay here to let the reset take affect. */
        CsrThreadSleep(RESET_SETTLE_DELAY);

        r = card_wait_for_unifi_to_disable(card);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }

        if (r == CSR_RESULT_SUCCESS)
        {
            r = card_wait_for_unifi_to_reset(card);
            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
            {
                return r;
            }
        }
    }

    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_trace(card->ospriv, UDBG1, "Hard reset (CSR_FUNC_EN)\n");

        r = sdio_write_f0(card, SDIO_CSR_FUNC_EN, 0);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_warning(card->ospriv, "SDIO error writing SDIO_CSR_FUNC_EN: %d\n", r);
            return r;
        }
        else
        {
            /* Delay here to let the reset take affect. */
            CsrThreadSleep(RESET_SETTLE_DELAY);

            r = card_wait_for_unifi_to_reset(card);
            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
            {
                return r;
            }
        }
    }

    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_warning(card->ospriv, "card_reset_method_io_enable failed to reset UniFi\n");
    }

    return r;
} /* card_reset_method_io_enable() */


/*
 * ---------------------------------------------------------------------------
 *  card_reset_method_dbg_reset
 *
 *      Issue a hard reset to the hw writing the DBG_RESET.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS         on success,
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE   if the card was ejected
 *      CSR_RESULT_FAILURE         if an SDIO error occurred or if a response
 *                                 was not seen in the expected time
 * ---------------------------------------------------------------------------
 */
static CsrResult card_reset_method_dbg_reset(card_t *card)
{
    CsrResult r;

    /*
     * Prepare UniFi for h/w reset
     */
    if (card->host_state == UNIFI_HOST_STATE_TORPID)
    {
        r = unifi_set_host_state(card, UNIFI_HOST_STATE_DROWSY);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to set UNIFI_HOST_STATE_DROWSY\n");
            return r;
        }
        CsrThreadSleep(5);
    }

    r = unifi_card_stop_processor(card, UNIFI_PROC_BOTH);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Can't stop processors\n");
        return r;
    }

    unifi_trace(card->ospriv, UDBG1, "Hard reset (DBG_RESET)\n");

    /*
     * This register write may fail. The debug reset resets
     * parts of the Function 0 sections of the chip, and
     * therefore the response cannot be sent back to the host.
     */
    r = unifi_write_direct_8_or_16(card, ChipHelper_DBG_RESET(card->helper) * 2, 1);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_warning(card->ospriv, "SDIO error writing DBG_RESET: %d\n", r);
        return r;
    }

    /* Delay here to let the reset take affect. */
    CsrThreadSleep(RESET_SETTLE_DELAY);

    r = card_wait_for_unifi_to_reset(card);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_warning(card->ospriv, "card_reset_method_dbg_reset failed to reset UniFi\n");
    }

    return r;
} /* card_reset_method_dbg_reset() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_card_hard_reset
 *
 *      Issue reset to hardware, by writing to registers on the card.
 *      Power to the card is preserved.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS         on success,
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE   if the card was ejected
 *      CSR_RESULT_FAILURE         if an SDIO error occurred or if a response
 *                                 was not seen in the expected time
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_card_hard_reset(card_t *card)
{
    CsrResult r;
    const struct chip_helper_reset_values *init_data;
    u32 chunks;

    /* Clear cache of page registers */
    card->proc_select = (u32)(-1);
    card->dmem_page = (u32)(-1);
    card->pmem_page = (u32)(-1);

    /*
     * We need to have a valid card->helper before we use software hard reset.
     * If unifi_identify_hw() fails to get the card ID, it probably means
     * that there is no way to talk to the h/w.
     */
    r = unifi_identify_hw(card);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "unifi_card_hard_reset failed to identify h/w\n");
        return r;
    }

    /* Search for some reset code. */
    chunks = ChipHelper_HostResetSequence(card->helper, &init_data);
    if (chunks != 0)
    {
        unifi_error(card->ospriv,
                    "Hard reset (Code download) is unsupported\n");

        return CSR_RESULT_FAILURE;
    }

    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
    {
        /* The HIP spec considers this a bus-specific reset.
         * This resets only function 1, so should be used in
         * preference to the method below (CSR_FUNC_EN)
         * If this method fails, it means that the f/w is probably
         * not running. In this case, try the DBG_RESET method.
         */
        r = card_reset_method_io_enable(card);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r == CSR_RESULT_SUCCESS)
        {
            return r;
        }
    }

    /* Software hard reset */
    r = card_reset_method_dbg_reset(card);

    return r;
} /* unifi_card_hard_reset() */


/*
 * ---------------------------------------------------------------------------
 *
 *  CardGenInt
 *
 *      Prod the card.
 *      This function causes an internal interrupt to be raised in the
 *      UniFi chip. It is used to signal the firmware that some action has
 *      been completed.
 *      The UniFi Host Interface asks that the value used increments for
 *      debugging purposes.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS         on success,
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE   if the card was ejected
 *      CSR_RESULT_FAILURE         if an SDIO error occurred or if a response
 *                                 was not seen in the expected time
 * ---------------------------------------------------------------------------
 */
CsrResult CardGenInt(card_t *card)
{
    CsrResult r;

    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
    {
        r = sdio_write_f0(card, SDIO_CSR_FROM_HOST_SCRATCH0,
                          (u8)card->unifi_interrupt_seq);
    }
    else
    {
        r = unifi_write_direct_8_or_16(card,
                                       ChipHelper_SHARED_IO_INTERRUPT(card->helper) * 2,
                                       (u8)card->unifi_interrupt_seq);
    }
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "SDIO error writing UNIFI_SHARED_IO_INTERRUPT: %d\n", r);
        return r;
    }

    card->unifi_interrupt_seq++;

    return CSR_RESULT_SUCCESS;
} /* CardGenInt() */


/*
 * ---------------------------------------------------------------------------
 *  CardEnableInt
 *
 *      Enable the outgoing SDIO interrupt from UniFi to the host.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS            on success,
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
 *      CSR_RESULT_FAILURE            if an SDIO error occurred,
 * ---------------------------------------------------------------------------
 */
CsrResult CardEnableInt(card_t *card)
{
    CsrResult r;
    u8 int_enable;

    r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n");
        return r;
    }

    int_enable |= (1 << card->function) | UNIFI_SD_INT_ENABLE_IENM;

    r = sdio_write_f0(card, SDIO_INT_ENABLE, int_enable);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "SDIO error writing SDIO_INT_ENABLE\n");
        return r;
    }

    return CSR_RESULT_SUCCESS;
} /* CardEnableInt() */


/*
 * ---------------------------------------------------------------------------
 *  CardDisableInt
 *
 *      Disable the outgoing SDIO interrupt from UniFi to the host.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS            on success,
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
 *      CSR_RESULT_FAILURE            if an SDIO error occurred,
 * ---------------------------------------------------------------------------
 */
CsrResult CardDisableInt(card_t *card)
{
    CsrResult r;
    u8 int_enable;

    r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n");
        return r;
    }

    int_enable &= ~(1 << card->function);

    r = sdio_write_f0(card, SDIO_INT_ENABLE, int_enable);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "SDIO error writing SDIO_INT_ENABLE\n");
        return r;
    }

    return CSR_RESULT_SUCCESS;
} /* CardDisableInt() */


/*
 * ---------------------------------------------------------------------------
 *  CardPendingInt
 *
 *      Determine whether UniFi is currently asserting the SDIO interrupt
 *      request.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *      pintr           Pointer to location to write interrupt status,
 *                          TRUE if interrupt pending,
 *                          FALSE if no interrupt pending.
 *  Returns:
 *      CSR_RESULT_SUCCESS            interrupt status read successfully
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
 *      CSR_RESULT_FAILURE            if an SDIO error occurred,
 * ---------------------------------------------------------------------------
 */
CsrResult CardPendingInt(card_t *card, u8 *pintr)
{
    CsrResult r;
    u8 pending;

    *pintr = FALSE;

    r = sdio_read_f0(card, SDIO_INT_PENDING, &pending);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "SDIO error reading SDIO_INT_PENDING\n");
        return r;
    }

    *pintr = (pending & (1 << card->function))?TRUE : FALSE;

    return CSR_RESULT_SUCCESS;
} /* CardPendingInt() */


/*
 * ---------------------------------------------------------------------------
 *  CardClearInt
 *
 *      Clear the UniFi SDIO interrupt request.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS          if pending interrupt was cleared, or no pending interrupt.
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE    if the card was ejected
 *      CSR_RESULT_FAILURE          if an SDIO error occurred,
 * ---------------------------------------------------------------------------
 */
CsrResult CardClearInt(card_t *card)
{
    CsrResult r;
    u8 intr;

    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
    {
        /* CardPendingInt() sets intr, if there is a pending interrupt */
        r = CardPendingInt(card, &intr);
        if (intr == FALSE)
        {
            return r;
        }

        r = sdio_write_f0(card, SDIO_CSR_HOST_INT_CLEAR, 1);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "SDIO error writing SDIO_CSR_HOST_INT_CLEAR\n");
        }
    }
    else
    {
        r = unifi_write_direct_8_or_16(card,
                                       ChipHelper_SDIO_HOST_INT(card->helper) * 2,
                                       0);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "SDIO error writing UNIFI_SDIO_HOST_INT\n");
        }
    }

    return r;
} /* CardClearInt() */


/*
 * ---------------------------------------------------------------------------
 *  CardIntEnabled
 *
 *      Determine whether UniFi is currently asserting the SDIO interrupt
 *      request.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *      enabled         Pointer to location to write interrupt enable status,
 *                          TRUE if interrupts enabled,
 *                          FALSE if interupts disabled.
 *
 *  Returns:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
 *      CSR_RESULT_FAILURE            if an SDIO error occurred,
 * ---------------------------------------------------------------------------
 */
CsrResult CardIntEnabled(card_t *card, u8 *enabled)
{
    CsrResult r;
    u8 int_enable;

    r = sdio_read_f0(card, SDIO_INT_ENABLE, &int_enable);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "SDIO error reading SDIO_INT_ENABLE\n");
        return r;
    }

    *enabled = (int_enable & (1 << card->function))?TRUE : FALSE;

    return CSR_RESULT_SUCCESS;
} /* CardIntEnabled() */


/*
 * ---------------------------------------------------------------------------
 *  CardWriteBulkData
 *      Allocate slot in the pending bulkdata arrays and assign it to a signal's
 *      bulkdata reference. The slot is then ready for UniFi's bulkdata commands
 *      to transfer the data to/from the host.
 *
 *  Arguments:
 *      card            Pointer to Card object
 *      csptr           Pending signal pointer, including bulkdata ref
 *      queue           Traffic queue that this signal is using
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS if a free slot was assigned
 *      CSR_RESULT_FAILURE if no slot was available
 * ---------------------------------------------------------------------------
 */
CsrResult CardWriteBulkData(card_t *card, card_signal_t *csptr, unifi_TrafficQueue queue)
{
    u16 i, slots[UNIFI_MAX_DATA_REFERENCES], j = 0;
    u8 *packed_sigptr, num_slots_required = 0;
    bulk_data_desc_t *bulkdata = csptr->bulkdata;
    s16 h, nslots;

    /* Count the number of slots required */
    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
    {
        if (bulkdata[i].data_length != 0)
        {
            num_slots_required++;
        }
    }

    /* Get the slot numbers */
    if (num_slots_required != 0)
    {
        /* Last 2 slots for MLME */
        if (queue == UNIFI_TRAFFIC_Q_MLME)
        {
            h = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS;
            for (i = 0; i < card->config_data.num_fromhost_data_slots; i++)
            {
                if (card->from_host_data[h].bd.data_length == 0)
                {
                    /* Free data slot, claim it */
                    slots[j++] = h;
                    if (j == num_slots_required)
                    {
                        break;
                    }
                }

                if (++h >= card->config_data.num_fromhost_data_slots)
                {
                    h = 0;
                }
            }
        }
        else
        {
            if (card->dynamic_slot_data.from_host_used_slots[queue]
                < card->dynamic_slot_data.from_host_max_slots[queue])
            {
                /* Data commands get a free slot only after a few checks */
                nslots = card->config_data.num_fromhost_data_slots - UNIFI_RESERVED_COMMAND_SLOTS;

                h = card->from_host_data_head;

                for (i = 0; i < nslots; i++)
                {
                    if (card->from_host_data[h].bd.data_length == 0)
                    {
                        /* Free data slot, claim it */
                        slots[j++] = h;
                        if (j == num_slots_required)
                        {
                            break;
                        }
                    }

                    if (++h >= nslots)
                    {
                        h = 0;
                    }
                }
                card->from_host_data_head = h;
            }
        }

        /* Required number of slots are not available, bail out */
        if (j != num_slots_required)
        {
            unifi_trace(card->ospriv, UDBG5, "CardWriteBulkData: didn't find free slot/s\n");

            /* If we haven't already reached the stable state we can ask for reservation */
            if ((queue != UNIFI_TRAFFIC_Q_MLME) && (card->dynamic_slot_data.queue_stable[queue] == FALSE))
            {
                CardCheckDynamicReservation(card, queue);
            }

            for (i = 0; i < card->config_data.num_fromhost_data_slots; i++)
            {
                unifi_trace(card->ospriv, UDBG5, "fh data slot %d: %d\n", i, card->from_host_data[i].bd.data_length);
            }
            return CSR_RESULT_FAILURE;
        }
    }

    packed_sigptr = csptr->sigbuf;

    /* Fill in the slots with data */
    j = 0;
    for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
    {
        if (bulkdata[i].data_length == 0)
        {
            /* Zero-out the DATAREF in the signal */
            SET_PACKED_DATAREF_SLOT(packed_sigptr, i, 0);
            SET_PACKED_DATAREF_LEN(packed_sigptr, i, 0);
        }
        else
        {
            /*
             * Fill in the slot number in the SIGNAL structure but
             * preserve the offset already in there
             */
            SET_PACKED_DATAREF_SLOT(packed_sigptr, i, slots[j] | (((u16)packed_sigptr[SIZEOF_SIGNAL_HEADER + (i * SIZEOF_DATAREF) + 1]) << 8));
            SET_PACKED_DATAREF_LEN(packed_sigptr, i, bulkdata[i].data_length);

            /* Do not copy the data, just store the information to them */
            card->from_host_data[slots[j]].bd.os_data_ptr = bulkdata[i].os_data_ptr;
            card->from_host_data[slots[j]].bd.os_net_buf_ptr = bulkdata[i].os_net_buf_ptr;
            card->from_host_data[slots[j]].bd.data_length = bulkdata[i].data_length;
            card->from_host_data[slots[j]].bd.net_buf_length = bulkdata[i].net_buf_length;
            card->from_host_data[slots[j]].queue = queue;

            unifi_trace(card->ospriv, UDBG4, "CardWriteBulkData sig=0x%x, fh slot %d = %p\n",
                        GET_SIGNAL_ID(packed_sigptr), i, bulkdata[i].os_data_ptr);

            /* Sanity-check that the bulk data desc being assigned to the slot
             * actually has a payload.
             */
            if (!bulkdata[i].os_data_ptr)
            {
                unifi_error(card->ospriv, "Assign null os_data_ptr (len=%d) fh slot %d, i=%d, q=%d, sig=0x%x",
                            bulkdata[i].data_length, slots[j], i, queue, GET_SIGNAL_ID(packed_sigptr));
            }

            j++;
            if (queue < UNIFI_NO_OF_TX_QS)
            {
                card->dynamic_slot_data.from_host_used_slots[queue]++;
            }
        }
    }

    return CSR_RESULT_SUCCESS;
} /*  CardWriteBulkData() */


/*
 * ---------------------------------------------------------------------------
 *  card_find_data_slot
 *
 *      Dereference references to bulk data slots into pointers to real data.
 *
 *  Arguments:
 *      card            Pointer to the card struct.
 *      slot            Slot number from a signal structure
 *
 *  Returns:
 *      Pointer to entry in bulk_data_slot array.
 * ---------------------------------------------------------------------------
 */
bulk_data_desc_t* card_find_data_slot(card_t *card, s16 slot)
{
    s16 sn;
    bulk_data_desc_t *bd;

    sn = slot & 0x7FFF;

    /* ?? check sanity of slot number ?? */

    if (slot & SLOT_DIR_TO_HOST)
    {
        bd = &card->to_host_data[sn];
    }
    else
    {
        bd = &card->from_host_data[sn].bd;
    }

    return bd;
} /* card_find_data_slot() */


/*
 * ---------------------------------------------------------------------------
 *  firmware_present_in_flash
 *
 *      Probe for external Flash that looks like it might contain firmware.
 *
 *      If Flash is not present, reads always return 0x0008.
 *      If Flash is present, but empty, reads return 0xFFFF.
 *      Anything else is considered to be firmware.
 *
 *  Arguments:
 *      card        Pointer to card struct
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS                 firmware is present in ROM or flash
 *      CSR_WIFI_HIP_RESULT_NOT_FOUND      firmware is not present in ROM or flash
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
 *      CSR_RESULT_FAILURE                 if an SDIO error occurred
 * ---------------------------------------------------------------------------
 */
static CsrResult firmware_present_in_flash(card_t *card)
{
    CsrResult r;
    u16 m1, m5;

    if (ChipHelper_HasRom(card->helper))
    {
        return CSR_RESULT_SUCCESS;
    }
    if (!ChipHelper_HasFlash(card->helper))
    {
        return CSR_WIFI_HIP_RESULT_NOT_FOUND;
    }

    /*
     * Examine the Flash locations that are the power-on default reset
     * vectors of the XAP processors.
     * These are words 1 and 5 in Flash.
     */
    r = unifi_card_read16(card, UNIFI_MAKE_GP(EXT_FLASH, 2), &m1);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    r = unifi_card_read16(card, UNIFI_MAKE_GP(EXT_FLASH, 10), &m5);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    /* Check for uninitialised/missing flash */
    if ((m1 == 0x0008) || (m1 == 0xFFFF) ||
        (m1 == 0x0004) || (m5 == 0x0004) ||
        (m5 == 0x0008) || (m5 == 0xFFFF))
    {
        return CSR_WIFI_HIP_RESULT_NOT_FOUND;
    }

    return CSR_RESULT_SUCCESS;
} /* firmware_present_in_flash() */


/*
 * ---------------------------------------------------------------------------
 *  bootstrap_chip_hw
 *
 *      Perform chip specific magic to "Get It Working" TM.  This will
 *      increase speed of PLLs in analogue and maybe enable some
 *      on-chip regulators.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void bootstrap_chip_hw(card_t *card)
{
    const struct chip_helper_init_values *vals;
    u32 i, len;
    void *sdio = card->sdio_if;
    CsrResult csrResult;

    len = ChipHelper_ClockStartupSequence(card->helper, &vals);
    if (len != 0)
    {
        for (i = 0; i < len; i++)
        {
            csrResult = CsrSdioWrite16(sdio, vals[i].addr * 2, vals[i].value);
            if (csrResult != CSR_RESULT_SUCCESS)
            {
                unifi_warning(card->ospriv, "Failed to write bootstrap value %d\n", i);
                /* Might not be fatal */
            }

            CsrThreadSleep(1);
        }
    }
} /* bootstrap_chip_hw() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_card_stop_processor
 *
 *      Stop the UniFi XAP processors.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *      which           One of UNIFI_PROC_MAC, UNIFI_PROC_PHY, UNIFI_PROC_BOTH
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS if successful, or CSR error code
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_card_stop_processor(card_t *card, enum unifi_dbg_processors_select which)
{
    CsrResult r = CSR_RESULT_SUCCESS;
    u8 status;
    s16 retry = 100;

    while (retry--)
    {
        /* Select both XAPs */
        r = unifi_set_proc_select(card, which);
        if (r != CSR_RESULT_SUCCESS)
        {
            break;
        }

        /* Stop processors */
        r = unifi_write_direct16(card, ChipHelper_DBG_EMU_CMD(card->helper) * 2, 2);
        if (r != CSR_RESULT_SUCCESS)
        {
            break;
        }

        /* Read status */
        r = unifi_read_direct_8_or_16(card,
                                      ChipHelper_DBG_HOST_STOP_STATUS(card->helper) * 2,
                                      &status);
        if (r != CSR_RESULT_SUCCESS)
        {
            break;
        }

        if ((status & 1) == 1)
        {
            /* Success! */
            return CSR_RESULT_SUCCESS;
        }

        /* Processors didn't stop, try again */
    }

    if (r != CSR_RESULT_SUCCESS)
    {
        /* An SDIO error occurred */
        unifi_error(card->ospriv, "Failed to stop processors: SDIO error\n");
    }
    else
    {
        /* If we reach here, we didn't the status in time. */
        unifi_error(card->ospriv, "Failed to stop processors: timeout waiting for stopped status\n");
        r = CSR_RESULT_FAILURE;
    }

    return r;
} /* unifi_card_stop_processor() */


/*
 * ---------------------------------------------------------------------------
 *  card_start_processor
 *
 *      Start the UniFi XAP processors.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *      which           One of UNIFI_PROC_MAC, UNIFI_PROC_PHY, UNIFI_PROC_BOTH
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS or CSR error code
 * ---------------------------------------------------------------------------
 */
CsrResult card_start_processor(card_t *card, enum unifi_dbg_processors_select which)
{
    CsrResult r;

    /* Select both XAPs */
    r = unifi_set_proc_select(card, which);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "unifi_set_proc_select failed: %d.\n", r);
        return r;
    }


    r = unifi_write_direct_8_or_16(card,
                                   ChipHelper_DBG_EMU_CMD(card->helper) * 2, 8);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    r = unifi_write_direct_8_or_16(card,
                                   ChipHelper_DBG_EMU_CMD(card->helper) * 2, 0);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    return CSR_RESULT_SUCCESS;
} /* card_start_processor() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_set_interrupt_mode
 *
 *      Configure the interrupt processing mode used by the HIP
 *
 *  Arguments:
 *      card            Pointer to card struct
 *      mode            Interrupt mode to apply
 *
 *  Returns:
 *      None
 * ---------------------------------------------------------------------------
 */
void unifi_set_interrupt_mode(card_t *card, u32 mode)
{
    if (mode == CSR_WIFI_INTMODE_RUN_BH_ONCE)
    {
        unifi_info(card->ospriv, "Scheduled interrupt mode");
    }
    card->intmode = mode;
} /* unifi_set_interrupt_mode() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_start_processors
 *
 *      Start all UniFi XAP processors.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, CSR error code on error
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_start_processors(card_t *card)
{
    return card_start_processor(card, UNIFI_PROC_BOTH);
} /* unifi_start_processors() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_request_max_sdio_clock
 *
 *      Requests that the maximum SDIO clock rate is set at the next suitable
 *      opportunity (e.g. when the BH next runs, so as not to interfere with
 *      any current operation).
 *
 *  Arguments:
 *      card            Pointer to card struct
 *
 *  Returns:
 *      None
 * ---------------------------------------------------------------------------
 */
void unifi_request_max_sdio_clock(card_t *card)
{
    card->request_max_clock = 1;
} /* unifi_request_max_sdio_clock() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_set_host_state
 *
 *      Set the host deep-sleep state.
 *
 *      If transitioning to TORPID, the SDIO driver will be notified
 *      that the SD bus will be unused (idle) and conversely, when
 *      transitioning from TORPID that the bus will be used (active).
 *
 *  Arguments:
 *      card            Pointer to card struct
 *      state           New deep-sleep state.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS            on success
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE      if the card was ejected
 *      CSR_RESULT_FAILURE            if an SDIO error occurred
 *
 *  Notes:
 *      We need to reduce the SDIO clock speed before trying to wake up the
 *      chip. Actually, in the implementation below we reduce the clock speed
 *      not just before we try to wake up the chip, but when we put the chip to
 *      deep sleep. This means that if the f/w wakes up on its' own, we waste
 *      a reduce/increace cycle. However, trying to eliminate this overhead is
 *      proved difficult, as the current state machine in the HIP lib does at
 *      least a CMD52 to disable the interrupts before we configure the host
 *      state.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_set_host_state(card_t *card, enum unifi_host_state state)
{
    CsrResult r = CSR_RESULT_SUCCESS;
    CsrResult csrResult;
    static const char *const states[] = {
        "AWAKE", "DROWSY", "TORPID"
    };
    static const u8 state_csr_host_wakeup[] = {
        1, 3, 0
    };
    static const u8 state_io_abort[] = {
        0, 2, 3
    };

    unifi_trace(card->ospriv, UDBG4, "State %s to %s\n",
                states[card->host_state], states[state]);

    if (card->host_state == UNIFI_HOST_STATE_TORPID)
    {
        CsrSdioFunctionActive(card->sdio_if);
    }

    /* Write the new state to UniFi. */
    if (card->chip_id > SDIO_CARD_ID_UNIFI_2)
    {
        r = sdio_write_f0(card, SDIO_CSR_HOST_WAKEUP,
                          (u8)((card->function << 4) | state_csr_host_wakeup[state]));
    }
    else
    {
        r = sdio_write_f0(card, SDIO_IO_ABORT, state_io_abort[state]);
    }

    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to write UniFi deep sleep state\n");
    }
    else
    {
        /*
         * If the chip was in state TORPID then we can now increase
         * the maximum bus clock speed.
         */
        if (card->host_state == UNIFI_HOST_STATE_TORPID)
        {
            csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if,
                                                       UNIFI_SDIO_CLOCK_MAX_HZ);
            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
            /* Non-fatal error */
            if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE)
            {
                unifi_warning(card->ospriv,
                              "Failed to increase the SDIO clock speed\n");
            }
            else
            {
                card->sdio_clock_speed = UNIFI_SDIO_CLOCK_MAX_HZ;
            }
        }

        /*
         * Cache the current state in the card structure to avoid
         * unnecessary SDIO reads.
         */
        card->host_state = state;

        if (state == UNIFI_HOST_STATE_TORPID)
        {
            /*
             * If the chip is now in state TORPID then we must now decrease
             * the maximum bus clock speed.
             */
            csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if,
                                                       UNIFI_SDIO_CLOCK_SAFE_HZ);
            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
            if (r != CSR_RESULT_SUCCESS && r != CSR_WIFI_HIP_RESULT_NO_DEVICE)
            {
                unifi_warning(card->ospriv,
                              "Failed to decrease the SDIO clock speed\n");
            }
            else
            {
                card->sdio_clock_speed = UNIFI_SDIO_CLOCK_SAFE_HZ;
            }
            CsrSdioFunctionIdle(card->sdio_if);
        }
    }

    return r;
} /* unifi_set_host_state() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_card_info
 *
 *      Update the card information data structure
 *
 *  Arguments:
 *      card            Pointer to card struct
 *      card_info       Pointer to info structure to update
 *
 *  Returns:
 *      None
 * ---------------------------------------------------------------------------
 */
void unifi_card_info(card_t *card, card_info_t *card_info)
{
    card_info->chip_id = card->chip_id;
    card_info->chip_version = card->chip_version;
    card_info->fw_build = card->build_id;
    card_info->fw_hip_version = card->config_data.version;
    card_info->sdio_block_size = card->sdio_io_block_size;
} /* unifi_card_info() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_check_io_status
 *
 *      Check UniFi for spontaneous reset and pending interrupt.
 *
 *  Arguments:
 *      card            Pointer to card struct
 *      status          Pointer to location to write chip status:
 *                        0 if UniFi is running, and no interrupt pending
 *                        1 if UniFi has spontaneously reset
 *                        2 if there is a pending interrupt
 *  Returns:
 *      CSR_RESULT_SUCCESS if OK, or CSR error
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_check_io_status(card_t *card, s32 *status)
{
    u8 io_en;
    CsrResult r;
    u8 pending;

    *status = 0;

    r = sdio_read_f0(card, SDIO_IO_ENABLE, &io_en);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to read SDIO_IO_ENABLE to check for spontaneous reset\n");
        return r;
    }

    if ((io_en & (1 << card->function)) == 0)
    {
        s32 fw_count;
        *status = 1;
        unifi_error(card->ospriv, "UniFi has spontaneously reset.\n");

        /*
         * These reads are very likely to fail. We want to know if the function is really
         * disabled or the SDIO driver just returns rubbish.
         */
        fw_count = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4);
        if (fw_count < 0)
        {
            unifi_error(card->ospriv, "Failed to read to-host sig written count\n");
        }
        else
        {
            unifi_error(card->ospriv, "thsw: %u (driver thinks is %u)\n",
                        fw_count, card->to_host_signals_w);
        }
        fw_count = unifi_read_shared_count(card, card->sdio_ctrl_addr + 2);
        if (fw_count < 0)
        {
            unifi_error(card->ospriv, "Failed to read from-host sig read count\n");
        }
        else
        {
            unifi_error(card->ospriv, "fhsr: %u (driver thinks is %u)\n",
                        fw_count, card->from_host_signals_r);
        }

        return r;
    }

    unifi_info(card->ospriv, "UniFi function %d is enabled.\n", card->function);

    /* See if we missed an SDIO interrupt */
    r = CardPendingInt(card, &pending);
    if (pending)
    {
        unifi_error(card->ospriv, "There is an unhandled pending interrupt.\n");
        *status = 2;
        return r;
    }

    return r;
} /* unifi_check_io_status() */


void unifi_get_hip_qos_info(card_t *card, unifi_HipQosInfo *hipqosinfo)
{
    s32 count_fhr;
    s16 t;
    u32 occupied_fh;

    q_t *sigq;
    u16 nslots, i;

    memset(hipqosinfo, 0, sizeof(unifi_HipQosInfo));

    nslots = card->config_data.num_fromhost_data_slots;

    for (i = 0; i < nslots; i++)
    {
        if (card->from_host_data[i].bd.data_length == 0)
        {
            hipqosinfo->free_fh_bulkdata_slots++;
        }
    }

    for (i = 0; i < UNIFI_NO_OF_TX_QS; i++)
    {
        sigq = &card->fh_traffic_queue[i];
        t = sigq->q_wr_ptr - sigq->q_rd_ptr;
        if (t < 0)
        {
            t += sigq->q_length;
        }
        hipqosinfo->free_fh_sig_queue_slots[i] = (sigq->q_length - t) - 1;
    }

    count_fhr = unifi_read_shared_count(card, card->sdio_ctrl_addr + 2);
    if (count_fhr < 0)
    {
        unifi_error(card->ospriv, "Failed to read from-host sig read count - %d\n", count_fhr);
        hipqosinfo->free_fh_fw_slots = 0xfa;
        return;
    }

    occupied_fh = (card->from_host_signals_w - count_fhr) % 128;

    hipqosinfo->free_fh_fw_slots = (u16)(card->config_data.num_fromhost_sig_frags - occupied_fh);
}



CsrResult ConvertCsrSdioToCsrHipResult(card_t *card, CsrResult csrResult)
{
    CsrResult r = CSR_RESULT_FAILURE;

    switch (csrResult)
    {
        case CSR_RESULT_SUCCESS:
            r = CSR_RESULT_SUCCESS;
            break;
        /* Timeout errors */
        case CSR_SDIO_RESULT_TIMEOUT:
        /* Integrity errors */
        case CSR_SDIO_RESULT_CRC_ERROR:
            r = CSR_RESULT_FAILURE;
            break;
        case CSR_SDIO_RESULT_NO_DEVICE:
            r = CSR_WIFI_HIP_RESULT_NO_DEVICE;
            break;
        case CSR_SDIO_RESULT_INVALID_VALUE:
            r = CSR_WIFI_HIP_RESULT_INVALID_VALUE;
            break;
        case CSR_RESULT_FAILURE:
            r = CSR_RESULT_FAILURE;
            break;
        default:
            unifi_warning(card->ospriv, "Unrecognised csrResult error code: %d\n", csrResult);
            break;
    }

    return r;
} /* ConvertCsrSdioToCsrHipResult() */


