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

            (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;

    func_enter();


    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
    func_exit();
    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;

    func_enter();

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

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

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

    func_exit();
    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;

    func_enter();

    if (card == NULL)
    {
        func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE);
        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);
        func_exit_r(r);
        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");
        func_exit_r(r);
        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");
        func_exit_r(r);
        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");
        func_exit_r(r);
        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");
        func_exit_r(r);
        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");
    }

    func_exit_r(r);
    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;

    func_enter();

    if (card == NULL)
    {
        func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE);
        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)
    {
        func_exit_r(CSR_WIFI_HIP_RESULT_NOT_FOUND);
        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");
        func_exit_r(r);
        return r;
    }

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

    func_exit();

    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;

    func_enter();

    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");
        func_exit_r(r);
        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);
        func_exit_r(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)
    {
        func_exit_r(r);
        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)
    {
        func_exit_r(r);
        return r;
    }

    func_exit();

    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;

    func_enter();

    /*
     * 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");
            func_exit_r(r);
            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);
            func_exit_r(r);
            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");
            func_exit_r(r);
            return r;
        }

        if (finger_print != SLUT_FINGERPRINT)
        {
            unifi_error(card->ospriv, "Failed to find Symbol lookup table fingerprint\n");
            func_exit_r(CSR_RESULT_FAILURE);
            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)
            {
                func_exit_r(r);
                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)
            {
                func_exit_r(r);
                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");
                        func_exit_r(r);
                        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");
                        func_exit_r(CSR_RESULT_FAILURE);
                        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");
                            func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE);
                            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");
                            func_exit_r(r);
                            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");
                        func_exit_r(r);
                        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");
                        func_exit_r(r);
                        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");
                        func_exit_r(r);
                        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");
                            func_exit_r(r);
                            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");
                        func_exit_r(r);
                        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");
        func_exit_r(CSR_RESULT_FAILURE);
        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);
        func_exit_r(r);
        return r;
    }
    if (initialised != 0)
    {
        func_exit_r(CSR_RESULT_FAILURE);
        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
        func_exit_r(CSR_RESULT_FAILURE);
        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
        func_exit_r(CSR_RESULT_FAILURE);
        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);

    func_exit();
    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;

    func_enter();

    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;
    }

    func_exit();
    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;

    func_enter();

    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);
        func_exit();
        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;
    }

    func_exit();
    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;

    func_enter();

    /*
     * 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");
                func_exit_r(r);
                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);
        func_exit_r(CSR_RESULT_FAILURE);
        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");
        func_exit_r(r);
        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");
        func_exit_r(r);
        return r;
    }

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

    func_exit();
    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)
{
    func_enter();

    /* 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)
    {
        func_exit();
        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");
    }

    func_exit();
    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;

    func_enter();

    /* 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);
    func_exit_r(r);
    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;

    func_enter();

    /* 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;
    }

    func_exit();
}


/*
 * ---------------------------------------------------------------------------
 *  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;

    func_enter();

    /* 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");
        func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
        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");
        func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
        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");
        func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
        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");
        func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
        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");
        func_exit_r(CSR_WIFI_HIP_RESULT_NO_MEMORY);
        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;

    func_exit();
    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)
{
    func_enter();

    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;

    func_exit();
} /* card_free_memory_resources() */


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

    func_enter();

    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
    func_exit();
}


/*
 * ---------------------------------------------------------------------------
 *  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;
    func_enter();

    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);

    func_exit();
} /* 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)
{
    func_enter();
#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);

    func_exit();
} /* 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;

    func_enter();

    /* 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);
        func_exit_r(r);
        return r;
    }

    if (card->sdio_ctrl_addr == 0)
    {
        unifi_error(card->ospriv, "Failed to find config struct!\n");
        func_exit_r(CSR_WIFI_HIP_RESULT_INVALID_VALUE);
        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");
            func_exit_r(r);
            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");
            func_exit_r(r);
            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");
        func_exit_r(r);
        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;

    func_exit();
    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;

    func_enter();

    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;
    func_exit();
}


/* 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;

    func_enter();

    /* 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);
        func_exit();
        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]);
    }

    func_exit();
}


/*
 * ---------------------------------------------------------------------------
 *  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;

    func_enter();

    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);
        func_exit();
        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);

    func_exit();
} /* 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;

    func_enter();

    /* 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++;
        }
    }

    func_exit();
    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)
{
    func_enter();

    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));

    func_exit();
    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;

    func_enter();

    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");
        func_exit_r(r);
        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);
            func_exit_r(r);
            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);
        func_exit_r(r);
        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)
    {
        func_exit_r(r);
        return r;
    }

    func_exit();
    return CSR_RESULT_SUCCESS;
} /* unifi_prepare_hw() */


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

    func_enter();

    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");
            func_exit_r(r);
            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);

    func_exit_r(r);
    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;

    func_enter();

    /* 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");
            func_exit_r(r);
            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");
            func_exit_r(r);
            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)
            {
                func_exit_r(r);
                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;
    }


    func_exit_r(r);
    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;

    func_enter();

    /*
     * 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);
            func_exit_r(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");
    }

    func_exit();
    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;

    func_enter();

    /*
     * 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");
            func_exit_r(r);
            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");
        func_exit();
        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);
        func_exit_r(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");
    }

    func_exit();
    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;

    func_enter();

    /* 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");
        func_exit();
        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");

        func_exit_r(CSR_RESULT_FAILURE);
        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)
        {
            func_exit();
            return r;
        }
    }

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

    func_exit_r(r);
    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;

    func_enter();

    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);
        func_exit_r(r);
        return r;
    }

    card->unifi_interrupt_seq++;

    func_exit();
    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;

    func_enter();

    /* 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);
            }
            func_exit();
            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]++;
            }
        }
    }

    func_exit();

    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() */


