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

            (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_intr.c
 *
 *  PURPOSE:
 *      Interrupt processing for the UniFi SDIO driver.
 *
 *      We may need another signal queue of responses to UniFi to hold
 *      bulk data commands generated by read_to_host_signals().
 *
 * ---------------------------------------------------------------------------
 */
#undef CSR_WIFI_HIP_NOISY

#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_conversions.h"
#include "csr_wifi_hip_card.h"
#include "csr_wifi_hip_xbv.h"


/*
 * If the SDIO link is idle for this time (in milliseconds),
 * signal UniFi to go into Deep Sleep.
 * Valid return value of unifi_bh().
 */
#define UNIFI_DEFAULT_HOST_IDLE_TIMEOUT 5
/*
 * If the UniFi has not woken up for this time (in milliseconds),
 * signal the bottom half to take action.
 * Valid return value of unifi_bh().
 */
#define UNIFI_DEFAULT_WAKE_TIMEOUT      1000


static CsrResult process_bh(card_t *card);
static CsrResult handle_host_protocol(card_t *card, u8 *processed_something);

static CsrResult flush_fh_buffer(card_t *card);

static CsrResult check_fh_sig_slots(card_t *card, u16 needed, s32 *space);

static CsrResult read_to_host_signals(card_t *card, s32 *processed);
static CsrResult process_to_host_signals(card_t *card, s32 *processed);

static CsrResult process_bulk_data_command(card_t *card,
                                           const u8 *cmdptr,
                                           s16 cmd, u16 len);
static CsrResult process_clear_slot_command(card_t         *card,
                                            const u8 *cmdptr);
static CsrResult process_fh_cmd_queue(card_t *card, s32 *processed);
static CsrResult process_fh_traffic_queue(card_t *card, s32 *processed);
static void restart_packet_flow(card_t *card);
static CsrResult process_clock_request(card_t *card);

#ifdef CSR_WIFI_HIP_NOISY
s16 dump_fh_buf = 0;
#endif /* CSR_WIFI_HIP_NOISY */

#ifdef CSR_WIFI_HIP_DEBUG_OFFLINE

/*
 * The unifi_debug_output buffer can be used to debug the HIP behaviour offline
 * i.e. without using the tracing functions that change the timing.
 *
 * Call unifi_debug_log_to_buf() with printf arguments to store a string into
 * unifi_debug_output. When unifi_debug_buf_dump() is called, the contents of the
 * buffer are dumped with dump_str() which has to be implemented in the
 * OS layer, during the porting exercise. The offset printed, holds the
 * offset where the last character is (always a zero).
 *
 */

#define UNIFI_DEBUG_GBUFFER_SIZE       8192
static char unifi_debug_output[UNIFI_DEBUG_GBUFFER_SIZE];
static char *unifi_dbgbuf_ptr = unifi_debug_output;
static char *unifi_dbgbuf_start = unifi_debug_output;

static void append_char(char c)
{
    /* write char and advance pointer */
    *unifi_dbgbuf_ptr++ = c;
    /* wrap pointer at end of buffer */
    if ((unifi_dbgbuf_ptr - unifi_debug_output) >= UNIFI_DEBUG_GBUFFER_SIZE)
    {
        unifi_dbgbuf_ptr = unifi_debug_output;
    }
} /* append_char() */


void unifi_debug_string_to_buf(const char *str)
{
    const char *p = str;
    while (*p)
    {
        append_char(*p);
        p++;
    }
    /* Update start-of-buffer pointer */
    unifi_dbgbuf_start = unifi_dbgbuf_ptr + 1;
    if ((unifi_dbgbuf_start - unifi_debug_output) >= UNIFI_DEBUG_GBUFFER_SIZE)
    {
        unifi_dbgbuf_start = unifi_debug_output;
    }
}


void unifi_debug_log_to_buf(const char *fmt, ...)
{
#define DEBUG_BUFFER_SIZE       80
    static char s[DEBUG_BUFFER_SIZE];
    va_list args;

    va_start(args, fmt);
    vsnprintf(s, DEBUG_BUFFER_SIZE, fmt, args);
    va_end(args);

    unifi_debug_string_to_buf(s);
} /* unifi_debug_log_to_buf() */


/* Convert signed 32 bit (or less) integer to string */
static void CsrUInt16ToHex(u16 number, char *str)
{
    u16 index;
    u16 currentValue;

    for (index = 0; index < 4; index++)
    {
        currentValue = (u16) (number & 0x000F);
        number >>= 4;
        str[3 - index] = (char) (currentValue > 9 ? currentValue + 55 : currentValue + '0');
    }
    str[4] = '\0';
}


/*
 * ---------------------------------------------------------------------------
 *  unifi_debug_hex_to_buf
 *
 *  puts the contents of the passed buffer into the debug buffer as a hex string
 *
 *  Arguments:
 *      buff         buffer to print as hex
 *      length       number of chars to print
 *
 *  Returns:
 *      None.
 *
 * ---------------------------------------------------------------------------
 */
void unifi_debug_hex_to_buf(const char *buff, u16 length)
{
    char s[5];
    u16 i;

    for (i = 0; i < length; i = i + 2)
    {
        CsrUInt16ToHex(*((u16 *)(buff + i)), s);
        unifi_debug_string_to_buf(s);
    }
}


void unifi_debug_buf_dump(void)
{
    s32 offset = unifi_dbgbuf_ptr - unifi_debug_output;

    unifi_error(NULL, "HIP debug buffer offset=%d\n", offset);
    dump_str(unifi_debug_output + offset, UNIFI_DEBUG_GBUFFER_SIZE - offset);
    dump_str(unifi_debug_output, offset);
} /* unifi_debug_buf_dump() */


#endif /* CSR_WIFI_HIP_DEBUG_OFFLINE */

#ifdef CSR_PRE_ALLOC_NET_DATA
#define NETDATA_PRE_ALLOC_BUF_SIZE 8000

void prealloc_netdata_free(card_t *card)
{
    unifi_warning(card->ospriv, "prealloc_netdata_free: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);

    while (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length != 0)
    {
        unifi_warning(card->ospriv, "prealloc_netdata_free: r=%d\n", card->prealloc_netdata_r);

        unifi_net_data_free(card->ospriv, &card->bulk_data_desc_list[card->prealloc_netdata_r]);
        card->prealloc_netdata_r++;
        card->prealloc_netdata_r %= BULK_DATA_PRE_ALLOC_NUM;
    }
    card->prealloc_netdata_r = card->prealloc_netdata_w = 0;

    unifi_warning(card->ospriv, "prealloc_netdata_free: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);
}


CsrResult prealloc_netdata_alloc(card_t *card)
{
    CsrResult r;

    unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_alloc: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);

    while (card->bulk_data_desc_list[card->prealloc_netdata_w].data_length == 0)
    {
        r = unifi_net_data_malloc(card->ospriv, &card->bulk_data_desc_list[card->prealloc_netdata_w], NETDATA_PRE_ALLOC_BUF_SIZE);
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "prealloc_netdata_alloc: Failed to allocate t-h bulk data\n");
            return CSR_RESULT_FAILURE;
        }
        card->prealloc_netdata_w++;
        card->prealloc_netdata_w %= BULK_DATA_PRE_ALLOC_NUM;
    }
    unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_alloc: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);

    return CSR_RESULT_SUCCESS;
}


static CsrResult prealloc_netdata_get(card_t *card, bulk_data_desc_t *bulk_data_slot, u32 size)
{
    CsrResult r;

    unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_get: IN: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);

    if (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length == 0)
    {
        unifi_error(card->ospriv, "prealloc_netdata_get: data_length = 0\n");
    }

    if ((size > NETDATA_PRE_ALLOC_BUF_SIZE) || (card->bulk_data_desc_list[card->prealloc_netdata_r].data_length == 0))
    {
        unifi_warning(card->ospriv, "prealloc_netdata_get: Calling net_data_malloc\n");

        r = unifi_net_data_malloc(card->ospriv, bulk_data_slot, size);
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "prealloc_netdata_get: Failed to allocate t-h bulk data\n");
            return CSR_RESULT_FAILURE;
        }
        return CSR_RESULT_SUCCESS;
    }

    *bulk_data_slot = card->bulk_data_desc_list[card->prealloc_netdata_r];
    card->bulk_data_desc_list[card->prealloc_netdata_r].os_data_ptr = NULL;
    card->bulk_data_desc_list[card->prealloc_netdata_r].os_net_buf_ptr = NULL;
    card->bulk_data_desc_list[card->prealloc_netdata_r].net_buf_length = 0;
    card->bulk_data_desc_list[card->prealloc_netdata_r].data_length = 0;

    card->prealloc_netdata_r++;
    card->prealloc_netdata_r %= BULK_DATA_PRE_ALLOC_NUM;

    unifi_trace(card->ospriv, UDBG5, "prealloc_netdata_get: OUT: w=%d r=%d\n", card->prealloc_netdata_w, card->prealloc_netdata_r);

    return CSR_RESULT_SUCCESS;
}


#endif

/*
 * ---------------------------------------------------------------------------
 *  unifi_sdio_interrupt_handler
 *
 *      This function should be called by the OS-dependent code to handle
 *      an SDIO interrupt from the UniFi.
 *
 *  Arguments:
 *      card            Pointer to card context structure.
 *
 *  Returns:
 *      None.
 *
 *  Notes: This function may be called in DRS context. In this case,
 *         tracing with the unifi_trace(), etc, is not allowed.
 * ---------------------------------------------------------------------------
 */
void unifi_sdio_interrupt_handler(card_t *card)
{
    /*
     * Set the flag to say reason for waking was SDIO interrupt.
     * Then ask the OS layer to run the unifi_bh to give attention to the UniFi.
     */
    card->bh_reason_unifi = 1;
    (void)unifi_run_bh(card->ospriv);
} /*  sdio_interrupt_handler() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_configure_low_power_mode
 *
 *      This function should be called by the OS-dependent when
 *      the deep sleep signaling needs to be enabled or disabled.
 *
 *  Arguments:
 *      card            Pointer to card context structure.
 *      low_power_mode  Disable/Enable the deep sleep signaling
 *      periodic_wake_mode UniFi wakes host periodically.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success or a CSR error code.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_configure_low_power_mode(card_t                       *card,
                                         enum unifi_low_power_mode     low_power_mode,
                                         enum unifi_periodic_wake_mode periodic_wake_mode)
{
    card->low_power_mode = low_power_mode;
    card->periodic_wake_mode = periodic_wake_mode;

    unifi_trace(card->ospriv, UDBG1,
                "unifi_configure_low_power_mode: new mode = %s, wake_host = %s\n",
                (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled",
                (periodic_wake_mode == UNIFI_PERIODIC_WAKE_HOST_DISABLED)?"FALSE" : "TRUE");

    (void)unifi_run_bh(card->ospriv);
    return CSR_RESULT_SUCCESS;
} /* unifi_configure_low_power_mode() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_force_low_power_mode
 *
 *      This function should be called by the OS-dependent when
 *      UniFi needs to be set to the low power mode (e.g. on suspend)
 *
 *  Arguments:
 *      card            Pointer to card context structure.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success or a CSR error code.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_force_low_power_mode(card_t *card)
{
    if (card->low_power_mode == UNIFI_LOW_POWER_DISABLED)
    {
        unifi_error(card->ospriv, "Attempt to set mode to TORPID when lower power mode is disabled\n");
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    return unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID);
} /* unifi_force_low_power_mode() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_bh
 *
 *      This function should be called by the OS-dependent code when
 *      host and/or UniFi has requested an exchange of messages.
 *
 *  Arguments:
 *      card            Pointer to card context structure.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success or a CSR error code.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_bh(card_t *card, u32 *remaining)
{
    CsrResult r;
    CsrResult csrResult;
    u8 pending;
    s32 iostate, j;
    const enum unifi_low_power_mode low_power_mode = card->low_power_mode;
    u16 data_slots_used = 0;


    /* Process request to raise the maximum SDIO clock */
    r = process_clock_request(card);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Error setting maximum SDIO clock\n");
        goto exit;
    }

    /*
     * Why was the BH thread woken?
     * If it was an SDIO interrupt, UniFi is awake and we need to process it.
     * If it was a host process queueing data, then we need to awaken UniFi.
     *
     * Priority of flags is top down.
     *
     * ----------------------------------------------------------+
     *    \state|   AWAKE      |    DROWSY      |    TORPID      |
     * flag\    |              |                |                |
     * ---------+--------------+----------------+----------------|
     *          | do the host  | go to AWAKE and| go to AWAKE and|
     *   unifi  | protocol     | do the host    | do the host    |
     *          |              | protocol       | protocol       |
     * ---------+--------------+----------------+----------------|
     *          | do the host  |                |                |
     *   host   | protocol     |  do nothing    | go to DROWSY   |
     *          |              |                |                |
     * ---------+--------------+----------------+----------------|
     *          |              |                | should not     |
     *  timeout | go to TORPID | error, unifi   | occur          |
     *          |              | didn't wake up | do nothing     |
     * ----------------------------------------------------------+
     *
     * Note that if we end up in the AWAKE state we always do the host protocol.
     */

    do
    {
        /*
         * When the host state is set to DROWSY, then we can not disable the
         * interrupts as UniFi can generate an interrupt even when the INT_ENABLE
         * register has the interrupts disabled. This interrupt will be lost.
         */
        if (card->host_state == UNIFI_HOST_STATE_DROWSY || card->host_state == UNIFI_HOST_STATE_TORPID)
        {
            u8 reason_unifi;

            /*
             * An interrupt may occur while or after we cache the reason.
             * This interrupt will cause the unifi_bh() to be scheduled again.
             * Any interrupt that has happened before the register is read
             * and is considered spurious has to acknowledged.
             */
            reason_unifi = card->bh_reason_unifi;

            /*
             * If an interrupt is received, check if it was a real one,
             * set the host state to AWAKE and run the BH.
             */
            r = CardPendingInt(card, &pending);
            if (r != CSR_RESULT_SUCCESS)
            {
                goto exit;
            }

            if (pending)
            {
                unifi_trace(card->ospriv, UDBG5,
                            "UNIFI_HOST_STATE_%s: Set state to AWAKE.\n",
                            (card->host_state == UNIFI_HOST_STATE_TORPID)?"TORPID" : "DROWSY");

                r = unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
                if (r == CSR_RESULT_SUCCESS)
                {
                    (*remaining) = 0;
                    break;
                }
            }
            else if (reason_unifi)
            {
                CsrSdioInterruptAcknowledge(card->sdio_if);
            }

            /*
             * If an chip is in TORPID, and the host wants to wake it up,
             * set the host state to DROWSY and wait for the wake-up interrupt.
             */
            if ((card->host_state == UNIFI_HOST_STATE_TORPID) && card->bh_reason_host)
            {
                r = unifi_set_host_state(card, UNIFI_HOST_STATE_DROWSY);
                if (r == CSR_RESULT_SUCCESS)
                {
                    /*
                     * set the timeout value to UNIFI_DEFAULT_WAKE_TIMEOUT
                     * to capture a wake error.
                     */
                    card->bh_reason_host = 0;
                    (*remaining) = UNIFI_DEFAULT_WAKE_TIMEOUT;
                    return CSR_RESULT_SUCCESS;
                }

                goto exit;
            }

            /*
             * If the chip is in DROWSY, and the timeout expires,
             * we need to reset the chip. This should never occur.
             * (If it does, check that the calling thread set "remaining"
             * according to the time remaining when unifi_bh() was called).
             */
            if ((card->host_state == UNIFI_HOST_STATE_DROWSY) && ((*remaining) == 0))
            {
                unifi_error(card->ospriv, "UniFi did not wake up on time...\n");

                /*
                 * Check if Function1 has gone away or
                 * if we missed an SDIO interrupt.
                 */
                r = unifi_check_io_status(card, &iostate);
                if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
                {
                    goto exit;
                }
                /* Need to reset and reboot */
                return CSR_RESULT_FAILURE;
            }
        }
        else
        {
            if (card->bh_reason_unifi || card->bh_reason_host)
            {
                break;
            }

            if (((*remaining) == 0) && (low_power_mode == UNIFI_LOW_POWER_ENABLED))
            {
                r = unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID);
                if (r == CSR_RESULT_SUCCESS)
                {
                    (*remaining) = 0;
                    return CSR_RESULT_SUCCESS;
                }

                goto exit;
            }
        }

        /* No need to run the host protocol */
        return CSR_RESULT_SUCCESS;
    } while (0);


    /* Disable the SDIO interrupts while doing SDIO ops */
    csrResult = CsrSdioInterruptDisable(card->sdio_if);
    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
    {
        r = CSR_WIFI_HIP_RESULT_NO_DEVICE;
        goto exit;
    }
    if (csrResult != CSR_RESULT_SUCCESS)
    {
        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
        unifi_error(card->ospriv, "Failed to disable SDIO interrupts. unifi_bh queues error.\n");
        goto exit;
    }

    /* Now that the interrupts are disabled, ack the interrupt */
    CsrSdioInterruptAcknowledge(card->sdio_if);

    /* Run the HIP */
    r = process_bh(card);
    if (r != CSR_RESULT_SUCCESS)
    {
        goto exit;
    }

    /*
     * If host is now idle, schedule a timer for the delay before we
     * let UniFi go into deep sleep.
     * If the timer goes off, we will move to TORPID state.
     * If UniFi raises an interrupt in the meantime, we will cancel
     * the timer and start a new one when we become idle.
     */
    for (j = 0; j < UNIFI_NO_OF_TX_QS; j++)
    {
        data_slots_used += CSR_WIFI_HIP_Q_SLOTS_USED(&card->fh_traffic_queue[j]);
    }

    if ((low_power_mode == UNIFI_LOW_POWER_ENABLED) && (data_slots_used == 0))
    {
#ifndef CSR_WIFI_HIP_TA_DISABLE
        if (card->ta_sampling.traffic_type != CSR_WIFI_ROUTER_CTRL_TRAFFIC_TYPE_PERIODIC)
        {
#endif
        /* return the UNIFI_DEFAULT_HOST_IDLE_TIMEOUT, so we can go to sleep. */
        unifi_trace(card->ospriv, UDBG5,
                    "Traffic is not periodic, set timer for TORPID.\n");
        (*remaining) = UNIFI_DEFAULT_HOST_IDLE_TIMEOUT;
#ifndef CSR_WIFI_HIP_TA_DISABLE
    }
    else
    {
        unifi_trace(card->ospriv, UDBG5,
                    "Traffic is periodic, set unifi to TORPID immediately.\n");
        if (CardAreAllFromHostDataSlotsEmpty(card) == 1)
        {
            r = unifi_set_host_state(card, UNIFI_HOST_STATE_TORPID);
            if (r != CSR_RESULT_SUCCESS)
            {
                goto exit;
            }
        }
    }
#endif
    }

    csrResult = CsrSdioInterruptEnable(card->sdio_if);
    if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
    {
        r = CSR_WIFI_HIP_RESULT_NO_DEVICE;
    }
    if (csrResult != CSR_RESULT_SUCCESS)
    {
        r = ConvertCsrSdioToCsrHipResult(card, csrResult);
        unifi_error(card->ospriv, "Failed to enable SDIO interrupt\n");
    }

exit:

    unifi_trace(card->ospriv, UDBG4, "New state=%d\n", card->host_state);

    if (r != CSR_RESULT_SUCCESS)
    {
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        unifi_debug_buf_dump();
#endif
        /* If an interrupt has been raised, ack it here */
        if (card->bh_reason_unifi)
        {
            CsrSdioInterruptAcknowledge(card->sdio_if);
        }

        unifi_error(card->ospriv,
                    "unifi_bh: state=%d %c, clock=%dkHz, interrupt=%d host=%d, power_save=%s\n",
                    card->host_state,
                    (card->host_state == UNIFI_HOST_STATE_AWAKE)?'A' : (card->host_state == UNIFI_HOST_STATE_DROWSY)?'D' : 'T',
                    card->sdio_clock_speed / 1000,
                    card->bh_reason_unifi, card->bh_reason_host,
                    (low_power_mode == UNIFI_LOW_POWER_DISABLED)?"disabled" : "enabled");

        /* Try to capture firmware panic codes */
        (void)unifi_capture_panic(card);

        /* Ask for a mini-coredump when the driver has reset UniFi */
        (void)unifi_coredump_request_at_next_reset(card, 1);
    }

    return r;
} /* unifi_bh() */


/*
 * ---------------------------------------------------------------------------
 *  process_clock_request
 *
 *      Handle request from the OS layer to increase the SDIO clock speed.
 *      The fast clock is limited until the firmware has indicated that it has
 *      completed initialisation to the OS layer.
 *
 *  Arguments:
 *      card            Pointer to card context structure.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success or CSR error code.
 * ---------------------------------------------------------------------------
 */
static CsrResult process_clock_request(card_t *card)
{
    CsrResult r = CSR_RESULT_SUCCESS;
    CsrResult csrResult;

    if (!card->request_max_clock)
    {
        return CSR_RESULT_SUCCESS;   /* No pending request */
    }

    /*
     * The SDIO clock speed request from the OS layer is only acted upon if
     * the UniFi is awake. If it was in any other state, the clock speed will
     * transition through SAFE to MAX while the host wakes it up, and the
     * final speed reached will be UNIFI_SDIO_CLOCK_MAX_HZ.
     * This assumes that the SME never requests low power mode while the f/w
     * initialisation takes place.
     */
    if (card->host_state == UNIFI_HOST_STATE_AWAKE)
    {
        unifi_trace(card->ospriv, UDBG1, "Set SDIO max clock\n");
        csrResult = CsrSdioMaxBusClockFrequencySet(card->sdio_if, UNIFI_SDIO_CLOCK_MAX_HZ);
        if (csrResult != CSR_RESULT_SUCCESS)
        {
            r = ConvertCsrSdioToCsrHipResult(card, csrResult);
        }
        else
        {
            card->sdio_clock_speed = UNIFI_SDIO_CLOCK_MAX_HZ;  /* log the new freq */
        }
    }
    else
    {
        unifi_trace(card->ospriv, UDBG1, "Will set SDIO max clock after wakeup\n");
    }

    /* Cancel the request now that it has been acted upon, or is about to be
     * by the wakeup mechanism
     */
    card->request_max_clock = 0;

    return r;
}


/*
 * ---------------------------------------------------------------------------
 *  process_bh
 *
 *      Exchange messages with UniFi
 *
 *  Arguments:
 *      card            Pointer to card context structure.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success or CSR error code.
 * ---------------------------------------------------------------------------
 */
static CsrResult process_bh(card_t *card)
{
    CsrResult r;
    u8 more;
    more = FALSE;

    /* Process the reasons (interrupt, signals) */
    do
    {
        /*
         * Run in a while loop, to save clearing the interrupts
         * every time around the outside loop.
         */
        do
        {
            /* If configured to run the HIP just once, skip first loop */
            if (card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE)
            {
                break;
            }

            r = handle_host_protocol(card, &more);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }

#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
            unifi_debug_log_to_buf("c52=%d c53=%d tx=%d txc=%d rx=%d s=%d t=%d fc=%d\n",
                                   card->cmd_prof.cmd52_count,
                                   card->cmd_prof.cmd53_count,
                                   card->cmd_prof.tx_count,
                                   card->cmd_prof.tx_cfm_count,
                                   card->cmd_prof.rx_count,
                                   card->cmd_prof.sdio_cmd_signal,
                                   card->cmd_prof.sdio_cmd_to_host,
                                   card->cmd_prof.sdio_cmd_from_host_and_clear
                                   );

            card->cmd_prof.cmd52_count = card->cmd_prof.cmd53_count = 0;
            card->cmd_prof.tx_count = card->cmd_prof.tx_cfm_count = card->cmd_prof.rx_count = 0;

            card->cmd_prof.cmd52_f0_r_count = 0;
            card->cmd_prof.cmd52_f0_w_count = 0;
            card->cmd_prof.cmd52_r8or16_count = 0;
            card->cmd_prof.cmd52_w8or16_count = 0;
            card->cmd_prof.cmd52_r16_count = 0;
            card->cmd_prof.cmd52_w16_count = 0;
            card->cmd_prof.cmd52_r32_count = 0;

            card->cmd_prof.sdio_cmd_signal = 0;
            card->cmd_prof.sdio_cmd_clear_slot = 0;
            card->cmd_prof.sdio_cmd_to_host = 0;
            card->cmd_prof.sdio_cmd_from_host = 0;
            card->cmd_prof.sdio_cmd_from_host_and_clear = 0;
#endif


        } while (more || card->bh_reason_unifi || card->bh_reason_host);

        /* Acknowledge the h/w interrupt */
        r = CardClearInt(card);
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to acknowledge interrupt.\n");
            return r;
        }

        /*
         * UniFi may have tried to generate an interrupt during the
         * CardClearInt() was running. So, we need to run the host
         * protocol again, to check if there are any pending requests.
         */
        r = handle_host_protocol(card, &more);
        if (r != CSR_RESULT_SUCCESS)
        {
            return r;
        }

#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
        unifi_debug_log_to_buf("c52=%d c53=%d tx=%d txc=%d rx=%d s=%d t=%d fc=%d\n",
                               card->cmd_prof.cmd52_count,
                               card->cmd_prof.cmd53_count,
                               card->cmd_prof.tx_count,
                               card->cmd_prof.tx_cfm_count,
                               card->cmd_prof.rx_count,
                               card->cmd_prof.sdio_cmd_signal,
                               card->cmd_prof.sdio_cmd_to_host,
                               card->cmd_prof.sdio_cmd_from_host_and_clear
                               );

        card->cmd_prof.cmd52_count = card->cmd_prof.cmd53_count = 0;
        card->cmd_prof.tx_count = card->cmd_prof.tx_cfm_count = card->cmd_prof.rx_count = 0;

        card->cmd_prof.cmd52_f0_r_count = 0;
        card->cmd_prof.cmd52_f0_w_count = 0;
        card->cmd_prof.cmd52_r8or16_count = 0;
        card->cmd_prof.cmd52_w8or16_count = 0;
        card->cmd_prof.cmd52_r16_count = 0;
        card->cmd_prof.cmd52_w16_count = 0;
        card->cmd_prof.cmd52_r32_count = 0;

        card->cmd_prof.sdio_cmd_signal = 0;
        card->cmd_prof.sdio_cmd_clear_slot = 0;
        card->cmd_prof.sdio_cmd_to_host = 0;
        card->cmd_prof.sdio_cmd_from_host = 0;
        card->cmd_prof.sdio_cmd_from_host_and_clear = 0;
#endif
        /* If configured to run the HIP just once, work is now done */
        if (card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE)
        {
            break;
        }

    } while (more || card->bh_reason_unifi || card->bh_reason_host);

#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
    if ((card->intmode & CSR_WIFI_INTMODE_RUN_BH_ONCE) == 0)
    {
        unifi_debug_log_to_buf("proc=%d\n",
                               card->cmd_prof.process_count);
    }
#endif

    return CSR_RESULT_SUCCESS;
} /* process_bh() */


/*
 * ---------------------------------------------------------------------------
 *  handle_host_protocol
 *
 *      This function implements the Host Interface Protocol (HIP) as
 *      described in the Host Interface Protocol Specification.
 *
 *  Arguments:
 *      card                 Pointer to card context structure.
 *      processed_something  Pointer to location to update processing status:
 *                              TRUE when data was transferred
 *                              FALSE when no data was transferred (queues empty)
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success or CSR error code.
 * ---------------------------------------------------------------------------
 */
static CsrResult handle_host_protocol(card_t *card, u8 *processed_something)
{
    CsrResult r;
    s32 done;

    *processed_something = FALSE;

#ifdef CSR_WIFI_HIP_NOISY
    unifi_error(card->ospriv, "   ========================     \n");
#endif /* CSR_WIFI_HIP_NOISY */

#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
    card->cmd_prof.process_count++;
#endif

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


    /*
     * (Re)fill the T-H signal buffer
     */
    r = read_to_host_signals(card, &done);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Error occured reading to-host signals\n");
        return r;
    }
    if (done > 0)
    {
        *processed_something = TRUE;
    }

    /*
     * Process any to-host signals.
     * Perform any requested CMD53 transfers here, but just queue any
     * bulk data command responses.
     */
    r = process_to_host_signals(card, &done);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Error occured processing to-host signals\n");
        return r;
    }

    /* Now send any signals in the F-H queues */
    /* Give precedence to the command queue */
    r = process_fh_cmd_queue(card, &done);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Error occured processing from-host signals\n");
        return r;
    }
    if (done > 0)
    {
        *processed_something = TRUE;
    }

    r = process_fh_traffic_queue(card, &done);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Error occured processing from-host data signals\n");
        return r;
    }
    if (done > 0)
    {
        *processed_something = TRUE;
    }

    /* Flush out the batch of signals to the UniFi. */
    r = flush_fh_buffer(card);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to copy from-host signals to UniFi\n");
        return r;
    }


    /*
     * Send the host interrupt to say the queues have been modified.
     */
    if (card->generate_interrupt)
    {
        r = CardGenInt(card);
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to notify UniFi that queues have been modified.\n");
            return r;
        }
    }

#ifdef CSR_WIFI_RX_PATH_SPLIT
#ifdef CSR_WIFI_RX_PATH_SPLIT_DONT_USE_WQ
    unifi_rx_queue_flush(card->ospriv);
#endif
#endif

    /* See if we can re-enable transmission now */
    restart_packet_flow(card);

#ifdef CSR_PRE_ALLOC_NET_DATA
    r = prealloc_netdata_alloc(card);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "prealloc_netdata failed\n");
        return r;
    }
#endif

    /*
     * Don't put the thread sleep if we just interacted with the chip,
     * there might be more to do if we look again.
     */
    return r;
} /* handle_host_protocol() */


/*
 *      Rounds the given signal length in bytes to a whole number
 *      of sig_frag_size.
 */
#define GET_CHUNKS_FOR(SIG_FRAG_SIZE, LENGTH) (((LENGTH) + ((SIG_FRAG_SIZE)-1)) / (SIG_FRAG_SIZE))


/*
 * ---------------------------------------------------------------------------
 *  read_to_host_signals
 *
 *      Read everything pending in the UniFi TH signal buffer.
 *      Only do it if the local buffer is empty.
 *
 *  Arguments:
 *      card        Pointer to card context struct
 *      processed   Number of signals read:
 *                      0 if there were no signals pending,
 *                      1 if we read at least one signal
 *  Returns:
 *      CSR error code if an error occurred.
 * ---------------------------------------------------------------------------
 */
static CsrResult read_to_host_signals(card_t *card, s32 *processed)
{
    s32 count_thw, count_thr;
    s32 unread_chunks, unread_bytes;
    CsrResult r;

    *processed = 0;

    /* Read any pending signals or bulk data commands */
    count_thw = unifi_read_shared_count(card, card->sdio_ctrl_addr + 4);
    if (count_thw < 0)
    {
        unifi_error(card->ospriv, "Failed to read to-host sig written count\n");
        return CSR_RESULT_FAILURE;
    }
    card->to_host_signals_w = count_thw; /* diag */

    count_thr = card->to_host_signals_r;

    if (count_thw == count_thr)
    {
        return CSR_RESULT_SUCCESS;
    }

    unread_chunks =
        (((count_thw - count_thr) + 128) % 128) - card->th_buffer.count;

    if (unread_chunks == 0)
    {
        return CSR_RESULT_SUCCESS;
    }

    unread_bytes = card->config_data.sig_frag_size * unread_chunks;


    r = unifi_bulk_rw(card,
                      card->config_data.tohost_sigbuf_handle,
                      card->th_buffer.ptr,
                      unread_bytes,
                      UNIFI_SDIO_READ);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to read ToHost signal\n");
        return r;
    }

    card->th_buffer.ptr += unread_bytes;
    card->th_buffer.count += (u16)unread_chunks;

    *processed = 1;

    return CSR_RESULT_SUCCESS;
} /* read_to_host_signals() */


/*
 * ---------------------------------------------------------------------------
 *  update_to_host_signals_r
 *
 *      Advance the shared-memory count of chunks read from the to-host
 *      signal buffer.
 *      Raise a UniFi internal interrupt to tell the firmware that the
 *      count has changed.
 *
 *  Arguments:
 *      card            Pointer to card context struct
 *      pending         Number of chunks remaining
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success or CSR error code
 * ---------------------------------------------------------------------------
 */
static CsrResult update_to_host_signals_r(card_t *card, s16 pending)
{
    CsrResult r;

    card->to_host_signals_r =
        (card->to_host_signals_r + (card->th_buffer.count - pending)) % 128;
    card->th_buffer.count = pending;

    /* Update the count of signals read */
    r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 6,
                            (u8)card->to_host_signals_r);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to update to-host signals read\n");
        return r;
    }

    r = CardGenInt(card);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to notify UniFi that we processed to-host signals.\n");
        return r;
    }

    card->generate_interrupt = 0;

    return CSR_RESULT_SUCCESS;
} /* update_to_host_signals_r() */


/*
 * ---------------------------------------------------------------------------
 *  read_unpack_cmd
 *
 *      Converts a wire-formatted command to the host bulk_data_cmd_t structure.
 *
 *  Arguments:
 *      ptr             Pointer to the command
 *      bulk_data_cmd   Pointer to the host structure
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void read_unpack_cmd(const u8 *ptr, bulk_data_cmd_t *bulk_data_cmd)
{
    s16 index = 0;
    bulk_data_cmd->cmd_and_len = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
    index += SIZEOF_UINT16;
    bulk_data_cmd->data_slot = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
    index += SIZEOF_UINT16;
    bulk_data_cmd->offset = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
    index += SIZEOF_UINT16;
    bulk_data_cmd->buffer_handle = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(ptr + index);
    index += SIZEOF_UINT16;
} /* read_unpack_cmd */


/*
 * ---------------------------------------------------------------------------
 *  process_to_host_signals
 *
 *      Read and dispatch signals from the UniFi
 *
 *  Arguments:
 *      card        Pointer to card context struct
 *      processed   Pointer to location to write processing result:
 *                      0 if there were no signals pending,
 *                      1 if we read at least one signal
 *
 *  Returns:
 *      CSR error code if there was an error
 *
 *  Notes:
 *      Since bulk data transfers can take a long time, if we wait until
 *      all are done before we acknowledge the signals, the UniFi runs out
 *      of buffer space. Therefore we keep a count of the bytes transferred
 *      in bulk data commands, and update the to-host-signals-read count
 *      if we've done a large transfer.
 *
 *      All data in the f/w is stored in a little endian format, without any
 *      padding bytes. Every read from the memory has to be transformed in
 *      host (cpu specific) format, before we can process it. Therefore we
 *      use read_unpack_cmd() and read_unpack_signal() to convert the raw data
 *      contained in the card->th_buffer.buf to host structures.
 *      Important: UDI clients use wire-formatted structures, so we need to
 *      indicate all data, as we have read it from the device.
 * ---------------------------------------------------------------------------
 */
static CsrResult process_to_host_signals(card_t *card, s32 *processed)
{
    s16 pending;
    s16 remaining;
    u8 *bufptr;
    bulk_data_param_t data_ptrs;
    s16 cmd;
    u16 sig_len;
    s16 i;
    u16 chunks_in_buf;
    u16 bytes_transferred = 0;
    CsrResult r = CSR_RESULT_SUCCESS;

    *processed = 0;

    pending = card->th_buffer.count;

    /* Are there new to-host signals? */
    unifi_trace(card->ospriv, UDBG4, "handling %d to-host chunks\n", pending);

    if (!pending)
    {
        return CSR_RESULT_SUCCESS;
    }

    /*
     * This is a pointer to the raw data we have read from the f/w.
     * Can be a signal or a command. Note that we need to convert
     * it to a host structure before we process it.
     */
    bufptr = card->th_buffer.buf;

    while (pending > 0)
    {
        s16 f_flush_count = 0;

        /*
         * Command and length are common to signal and bulk data msgs.
         * If command == 0 (i.e. a signal), len is number of bytes
         * *following* the 2-byte header.
         */
        cmd = bufptr[1] >> 4;
        sig_len = bufptr[0] + ((bufptr[1] & 0x0F) << 8);

#ifdef CSR_WIFI_HIP_NOISY
        unifi_error(card->ospriv, "Received UniFi msg cmd=%d, len=%d\n",
                    cmd, sig_len);
#endif  /* CSR_WIFI_HIP_NOISY */

        if ((sig_len == 0) &&
            ((cmd != SDIO_CMD_CLEAR_SLOT) && (cmd != SDIO_CMD_PADDING)))
        {
            unifi_error(card->ospriv, "incomplete signal or command: has size zero\n");
            return CSR_RESULT_FAILURE;
        }
        /*
         * Make sure the buffer contains a complete message.
         * Signals may occupy multiple chunks, bulk-data commands occupy
         * one chunk.
         */
        if (cmd == SDIO_CMD_SIGNAL)
        {
            chunks_in_buf = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(sig_len + 2));
        }
        else
        {
            chunks_in_buf = 1;
        }

        if (chunks_in_buf > (u16)pending)
        {
            unifi_error(card->ospriv, "incomplete signal (0x%x?): need %d chunks, got %d\n",
                        GET_SIGNAL_ID(bufptr + 2),
                        chunks_in_buf, pending);
            unifi_error(card->ospriv, " thsw=%d, thsr=%d\n",
                        card->to_host_signals_w,
                        card->to_host_signals_r);
            return CSR_RESULT_FAILURE;
        }


        switch (cmd)
        {
            case SDIO_CMD_SIGNAL:
                /* This is a signal. Read the rest of it and then handle it. */
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
                card->cmd_prof.sdio_cmd_signal++;
#endif

                for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
                {
                    /* Retrieve dataRefs[i].DataLength */
                    u16 data_len = GET_PACKED_DATAREF_LEN(bufptr + 2, i);

                    /*
                     * The bulk data length in the signal can not be greater than
                     * the maximun length allowed by the SDIO config structure.
                     */
                    if (data_len > card->config_data.data_slot_size)
                    {
                        unifi_error(card->ospriv,
                                    "Bulk Data length (%d) exceeds Maximum Bulk Data length (%d)\n",
                                    data_len, card->config_data.data_slot_size);
                        return CSR_RESULT_FAILURE;
                    }

                    /*
                     * Len here might not be the same as the length in the
                     * bulk data slot.  The slot length will always be even,
                     * but len could be odd.
                     */
                    if (data_len != 0)
                    {
                    /* Retrieve dataRefs[i].SlotNumber */
                        s16 slot = GET_PACKED_DATAREF_SLOT(bufptr + 2, i);

                        if (slot >= card->config_data.num_tohost_data_slots)
                        {
                            unifi_error(card->ospriv, "!!!bad slot number in to-host signal: %d, sig 0x%X\n",
                                        slot, cmd);
                            return CSR_RESULT_FAILURE;
                        }

                        data_ptrs.d[i].os_data_ptr = card->to_host_data[slot].os_data_ptr;
                        data_ptrs.d[i].os_net_buf_ptr = card->to_host_data[slot].os_net_buf_ptr;
                        data_ptrs.d[i].net_buf_length = card->to_host_data[slot].net_buf_length;
                        data_ptrs.d[i].data_length = data_len;
                    }
                    else
                    {
                        UNIFI_INIT_BULK_DATA(&data_ptrs.d[i]);
                    }
                }

            /*
             * Log the signal to the UDI, before call unifi_receive_event() as
             * it can modify the bulk data.
             */
                if (card->udi_hook)
                {
                    (*card->udi_hook)(card->ospriv, bufptr + 2, sig_len,
                                      &data_ptrs, UDI_LOG_TO_HOST);
                }

#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
                if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_CONFIRM_ID)
                {
                    card->cmd_prof.tx_cfm_count++;
                }
                else if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_INDICATION_ID)
                {
                    if (data_ptrs.d[0].os_data_ptr)
                    {
                        if ((*data_ptrs.d[0].os_data_ptr) & 0x08)
                        {
                            card->cmd_prof.rx_count++;
                        }
                    }
                }
#endif
                /*
                 * Check if the signal is MA-PACKET.cfm and if so check the status.
                 * If the status is failure, search through the slot records to find
                 * if any slots are occupied for this host tag. This can happen if
                 * f/w has not downloaded the bulkdata and before that itself it has
                 * signalled the confirm with failure. If it finds a slot with that
                 * host tag then, it clears the corresponding slot
                 */

                if (GET_SIGNAL_ID(bufptr + 2) == CSR_MA_PACKET_CONFIRM_ID)
                {
                    /* Get host tag and transmission status */
                    u32 host_tag = GET_PACKED_MA_PACKET_CONFIRM_HOST_TAG(bufptr + 2);
                    u16 status = GET_PACKED_MA_PACKET_CONFIRM_TRANSMISSION_STATUS(bufptr + 2);

                    unifi_trace(card->ospriv, UDBG4, "process_to_host_signals signal ID=%x host Tag=%x status=%x\n",
                                GET_SIGNAL_ID(bufptr + 2), host_tag, status);

                    /* If transmission status is failure then search through the slot records
                     * and if for any slot records the clear slot is not done then do it now
                     */

                    if (status && (card->fh_slot_host_tag_record))
                    {
                        u16 num_fh_slots = card->config_data.num_fromhost_data_slots;

                        /* search through the list of slot records and match with host tag
                         * If a slot is not yet cleared then clear the slot from here
                         */
                        for (i = 0; i < num_fh_slots; i++)
                        {
                            if (card->fh_slot_host_tag_record[i] == host_tag)
                            {
#ifdef CSR_WIFI_REQUEUE_PACKET_TO_HAL
                                /* Invoke the HAL module function to requeue it back to HAL Queues */
                                r = unifi_reque_ma_packet_request(card->ospriv, host_tag, status, &card->from_host_data[i].bd);
                                card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
                                if (CSR_RESULT_SUCCESS != r)
                                {
                                    unifi_trace(card->ospriv, UDBG5, "process_to_host_signals: Failed to requeue Packet(hTag:%x) back to HAL \n", host_tag);
                                    CardClearFromHostDataSlot(card, i);
                                }
                                else
                                {
                                    CardClearFromHostDataSlotWithoutFreeingBulkData(card, i);
                                }

#else
                                unifi_trace(card->ospriv, UDBG4, "process_to_host_signals Clear slot=%x host tag=%x\n", i, host_tag);
                                card->fh_slot_host_tag_record[i] = CSR_WIFI_HIP_RESERVED_HOST_TAG;

                                /* Set length field in from_host_data array to 0 */
                                CardClearFromHostDataSlot(card, i);
#endif
                                break;
                            }
                        }
                    }
                }

                /* Pass event to OS layer */
                unifi_receive_event(card->ospriv, bufptr + 2, sig_len, &data_ptrs);

                /* Initialise the to_host data, so it can be re-used. */
                for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
                {
                /* The slot is only valid if the length is non-zero. */
                    if (GET_PACKED_DATAREF_LEN(bufptr + 2, i) != 0)
                    {
                        s16 slot = GET_PACKED_DATAREF_SLOT(bufptr + 2, i);
                        if (slot < card->config_data.num_tohost_data_slots)
                        {
                            UNIFI_INIT_BULK_DATA(&card->to_host_data[slot]);
                        }
                    }
                }

#ifndef CSR_WIFI_DEFER_TH_FLUSH
                /*
                 * If we have previously transferred a lot of data, ack
                 * the signals read so far, so f/w can reclaim the buffer
                 * memory sooner.
                 */
                if (bytes_transferred >= TO_HOST_FLUSH_THRESHOLD)
                {
                    f_flush_count = 1;
                }
#endif
                break;


            case SDIO_CMD_CLEAR_SLOT:
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
                card->cmd_prof.sdio_cmd_clear_slot++;
#endif
                /* This is a clear slot command. */
                if (sig_len != 0)
                {
                    unifi_error(card->ospriv, "process_to_host_signals: clear slot, bad data len: 0x%X at offset %d\n",
                                sig_len, bufptr - card->th_buffer.buf);
                    return CSR_RESULT_FAILURE;
                }

                r = process_clear_slot_command(card, bufptr);
                if (r != CSR_RESULT_SUCCESS)
                {
                    unifi_error(card->ospriv, "Failed to process clear slot\n");
                    return r;
                }
                break;

            case SDIO_CMD_TO_HOST_TRANSFER:
            case SDIO_CMD_FROM_HOST_TRANSFER:
            case SDIO_CMD_FROM_HOST_AND_CLEAR:
            case SDIO_CMD_OVERLAY_TRANSFER:
                /* This is a bulk data command. */
                if (sig_len & 1)
                {
                    unifi_error(card->ospriv, "process_to_host_signals: bulk data, bad data len: 0x%X at offset %d\n",
                                sig_len, bufptr - card->th_buffer.buf);
                    return CSR_RESULT_FAILURE;
                }

                r = process_bulk_data_command(card, bufptr, cmd, sig_len);
                if (r != CSR_RESULT_SUCCESS)
                {
                    unifi_error(card->ospriv, "Failed to process bulk cmd\n");
                    return r;
                }
                /* Count the bytes transferred */
                bytes_transferred += sig_len;

                if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR)
                {
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
                    card->cmd_prof.sdio_cmd_from_host_and_clear++;
#endif
#ifndef CSR_WIFI_DEFER_TH_FLUSH
                    f_flush_count = 1;
#endif
                }
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
                else if (cmd == SDIO_CMD_FROM_HOST_TRANSFER)
                {
                    card->cmd_prof.sdio_cmd_from_host++;
                }
                else if (cmd == SDIO_CMD_TO_HOST_TRANSFER)
                {
                    card->cmd_prof.sdio_cmd_to_host++;
                }
#endif
                break;

            case SDIO_CMD_PADDING:
                break;

            default:
                unifi_error(card->ospriv, "Unrecognised to-host command: %d\n", cmd);
                break;
        }

        bufptr += chunks_in_buf * card->config_data.sig_frag_size;
        pending -= chunks_in_buf;

        /*
         * Write out the host signal count when a significant
         * number of bytes of bulk data have been transferred or
         * when we have performed a CopyFromHostAndClear.
         */
        if (f_flush_count)
        {
            r = update_to_host_signals_r(card, pending);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            bytes_transferred = 0;
        }
    }

    if (pending)
    {
        unifi_warning(card->ospriv, "proc_th_sigs: %d unprocessed\n", pending);
    }

    /* If we processed any signals, write the updated count to UniFi */
    if (card->th_buffer.count != pending)
    {
        r = update_to_host_signals_r(card, pending);
        if (r != CSR_RESULT_SUCCESS)
        {
            return r;
        }
    }

    /*
     * Reset the buffer pointer, copying down any un-processed signals.
     * This can happen if we enable the optimisation in read_to_host_signals()
     * that limits the length to whole blocks.
     */
    remaining = card->th_buffer.ptr - bufptr;
    if (remaining < 0)
    {
        unifi_error(card->ospriv, "Processing TH signals overran the buffer\n");
        return CSR_RESULT_FAILURE;
    }
    if (remaining > 0)
    {
        /* Use a safe copy because source and destination may overlap */
        u8 *d = card->th_buffer.buf;
        u8 *s = bufptr;
        s32 n = remaining;
        while (n--)
        {
            *d++ = *s++;
        }
    }
    card->th_buffer.ptr = card->th_buffer.buf + remaining;


    /* If we reach here then we processed something */
    *processed = 1;
    return CSR_RESULT_SUCCESS;
} /* process_to_host_signals() */


/*
 * ---------------------------------------------------------------------------
 *  process_clear_slot_command
 *
 *      Process a clear slot command fom the UniFi.
 *
 *  Arguments:
 *   card       Pointer to card context struct
 *   bdcmd      Pointer to bulk-data command msg from UniFi
 *
 *  Returns:
 *      0 on success, CSR error code on error
 * ---------------------------------------------------------------------------
 */
static CsrResult process_clear_slot_command(card_t *card, const u8 *cmdptr)
{
    u16 data_slot;
    s16 slot;

    data_slot = CSR_GET_UINT16_FROM_LITTLE_ENDIAN(cmdptr + SIZEOF_UINT16);

    unifi_trace(card->ospriv, UDBG4, "Processing clear slot cmd, slot=0x%X\n",
                data_slot);

    slot = data_slot & 0x7FFF;

#ifdef CSR_WIFI_HIP_NOISY
    unifi_error(card->ospriv, "CMD clear data slot 0x%04x\n", data_slot);
#endif /* CSR_WIFI_HIP_NOISY */

    if (data_slot & SLOT_DIR_TO_HOST)
    {
        if (slot >= card->config_data.num_tohost_data_slots)
        {
            unifi_error(card->ospriv,
                        "Invalid to-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n",
                        slot);
            return CSR_RESULT_FAILURE;
        }
        /* clear to-host data slot */
        unifi_warning(card->ospriv, "Unexpected clear to-host data slot cmd: 0x%04x\n",
                      data_slot);
    }
    else
    {
        if (slot >= card->config_data.num_fromhost_data_slots)
        {
            unifi_error(card->ospriv,
                        "Invalid from-host data slot in SDIO_CMD_CLEAR_SLOT: %d\n",
                        slot);
            return CSR_RESULT_FAILURE;
        }

        /*
         * The driver is the owner to clear all slots now
         * Ref - comment in process_fh_traffic_queue
         * so it will just ignore the clear slot command from firmware
         * and return success
         */
        return CSR_RESULT_SUCCESS;

        /* Set length field in from_host_data array to 0 */
        /* CardClearFromHostDataSlot(card, slot); */
    }

    return CSR_RESULT_SUCCESS;
} /* process_clear_slot_command() */


/*
 * ---------------------------------------------------------------------------
 *  process_bulk_data_command
 *
 *      Process a bulk data request from the UniFi.
 *
 *  Arguments:
 *   card       Pointer to card context struct
 *   bdcmd      Pointer to bulk-data command msg from UniFi
 *   cmd, len   Decoded values of command and length from the msg header
 *              Cmd will only be one of:
 *                      SDIO_CMD_TO_HOST_TRANSFER
 *                      SDIO_CMD_FROM_HOST_TRANSFER
 *                      SDIO_CMD_FROM_HOST_AND_CLEAR
 *                      SDIO_CMD_OVERLAY_TRANSFER
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, CSR error code on error
 * ---------------------------------------------------------------------------
 */
static CsrResult process_bulk_data_command(card_t *card, const u8 *cmdptr,
                                           s16 cmd, u16 len)
{
    bulk_data_desc_t *bdslot;
#ifdef CSR_WIFI_ALIGNMENT_WORKAROUND
    u8 *host_bulk_data_slot;
#endif
    bulk_data_cmd_t bdcmd;
    s16 offset;
    s16 slot;
    s16 dir;
    CsrResult r;

    read_unpack_cmd(cmdptr, &bdcmd);

    unifi_trace(card->ospriv, UDBG4, "Processing bulk data cmd %d %s, len=%d, slot=0x%X\n",
                cmd, lookup_bulkcmd_name(cmd), len, bdcmd.data_slot);

    /*
     * Round up the transfer length if required.
     * This is useful to force all transfers to be a multiple of the SDIO block
     * size, so the SDIO driver won't try to use a byte-mode CMD53. These are
     * broken on some hardware platforms.
     */
    if (card->sdio_io_block_pad)
    {
        len = (len + card->sdio_io_block_size - 1) & ~(card->sdio_io_block_size - 1);
        unifi_trace(card->ospriv, UDBG4, "Rounded bulk data length up to %d\n", len);
    }

    slot = bdcmd.data_slot & 0x7FFF;

    if (cmd == SDIO_CMD_OVERLAY_TRANSFER)
    {
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;     /* Not used on CSR6xxx */
    }
    else
    {
        if (bdcmd.data_slot & SLOT_DIR_TO_HOST)
        {
            /* Request is for to-host bulk data */

            /* Check sanity of slot number */
            if (slot >= card->config_data.num_tohost_data_slots)
            {
                unifi_error(card->ospriv,
                            "Invalid to-host data slot in SDIO bulk xfr req: %d\n",
                            slot);
                return CSR_RESULT_FAILURE;
            }

            /* Allocate memory for card->to_host_data[slot] bulk data here. */
#ifdef CSR_PRE_ALLOC_NET_DATA
            r = prealloc_netdata_get(card, &card->to_host_data[slot], len);
#else
            r = unifi_net_data_malloc(card->ospriv, &card->to_host_data[slot], len);
#endif
            if (r != CSR_RESULT_SUCCESS)
            {
                unifi_error(card->ospriv, "Failed to allocate t-h bulk data\n");
                return CSR_RESULT_FAILURE;
            }

            bdslot = &card->to_host_data[slot];

            /* Make sure that the buffer is 4-bytes aligned */
            r = unifi_net_dma_align(card->ospriv, bdslot);
            if (r != CSR_RESULT_SUCCESS)
            {
                unifi_error(card->ospriv, "Failed to align t-h bulk data buffer for DMA\n");
                return CSR_RESULT_FAILURE;
            }
        }
        else
        {
            /* Request is for from-host bulk data */

            if (slot >= card->config_data.num_fromhost_data_slots)
            {
                unifi_error(card->ospriv,
                            "Invalid from-host data slot in SDIO bulk xfr req: %d\n",
                            slot);
                return CSR_RESULT_FAILURE;
            }
            bdslot = &card->from_host_data[slot].bd;
        }
        offset = bdcmd.offset;
    }
    /* Do the transfer */
    dir = (cmd == SDIO_CMD_TO_HOST_TRANSFER)?
          UNIFI_SDIO_READ : UNIFI_SDIO_WRITE;

    unifi_trace(card->ospriv, UDBG4,
                "Bulk %c %s len=%d, handle %d - slot=%d %p+(%d)\n",
                (dir == UNIFI_SDIO_READ)?'R' : 'W',
                lookup_bulkcmd_name(cmd),
                len,
                bdcmd.buffer_handle,
                slot, bdslot->os_data_ptr, offset);
#ifdef CSR_WIFI_HIP_NOISY
    unifi_error(card->ospriv, "Bulk %s len=%d, handle %d - slot=%d %p+(%d)\n",
                lookup_bulkcmd_name(cmd),
                len,
                bdcmd.buffer_handle,
                slot, bdslot->os_data_ptr, offset);
#endif /* CSR_WIFI_HIP_NOISY */


    if (bdslot->os_data_ptr == NULL)
    {
        unifi_error(card->ospriv, "Null os_data_ptr - Bulk %s handle %d - slot=%d o=(%d)\n",
                    lookup_bulkcmd_name(cmd),
                    bdcmd.buffer_handle,
                    slot,
                    offset);
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

#ifdef CSR_WIFI_ALIGNMENT_WORKAROUND
    /* if os_data_ptr is not 4-byte aligned, then allocate a new buffer and copy data
    to new buffer to ensure the address passed to unifi_bulk_rw is 4-byte aligned */

    if (len != 0 && (dir == UNIFI_SDIO_WRITE) && (((ptrdiff_t)bdslot->os_data_ptr + offset) & 3))
    {
        host_bulk_data_slot = kmalloc(len, GFP_KERNEL);

        if (!host_bulk_data_slot)
        {
            unifi_error(card->ospriv, " failed to allocate request_data before unifi_bulk_rw\n");
            return -1;
        }

        memcpy((void *)host_bulk_data_slot,
                  (void *)(bdslot->os_data_ptr + offset), len);

        r = unifi_bulk_rw(card,
                          bdcmd.buffer_handle,
                          (void *)host_bulk_data_slot,
                          len,
                          dir);
    }
    else
#endif
    {
        r = unifi_bulk_rw(card,
                          bdcmd.buffer_handle,
                          (void *)(bdslot->os_data_ptr + offset),
                          len,
                          dir);
    }

    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv,
                    "Failed: %s hlen=%d, slen=%d, handle %d - slot=%d %p+0x%X\n",
                    lookup_bulkcmd_name(cmd),
                    len,                    /* Header length */
                    bdslot->data_length,    /* Length stored in slot */
                    bdcmd.buffer_handle,
                    slot, bdslot->os_data_ptr, offset);
        return r;
    }

    bdslot->data_length = len;

    if (cmd == SDIO_CMD_FROM_HOST_AND_CLEAR)
    {
        if (slot >= card->config_data.num_fromhost_data_slots)
        {
            unifi_error(card->ospriv,
                        "Invalid from-host data slot in SDIO_CMD_FROM_HOST_AND_CLEAR: %d\n",
                        slot);
            return CSR_RESULT_FAILURE;
        }

#ifdef CSR_WIFI_ALIGNMENT_WORKAROUND
        /* moving this check before we clear host data slot */
        if ((len != 0) && (dir == UNIFI_SDIO_WRITE) && (((ptrdiff_t)bdslot->os_data_ptr + offset) & 3))
        {
            kfree(host_bulk_data_slot);
        }
#endif

        if (card->fh_slot_host_tag_record)
        {
            unifi_trace(card->ospriv, UDBG5, "CopyFromHostAndClearSlot Reset entry for slot=%d\n", slot);

            /* reset the host tag entry for the corresponding slot */
            card->fh_slot_host_tag_record[slot] = CSR_WIFI_HIP_RESERVED_HOST_TAG;
        }


        /* Set length field in from_host_data array to 0 */
        CardClearFromHostDataSlot(card, slot);
    }

    return CSR_RESULT_SUCCESS;
} /* process_bulk_data_command() */


/*
 * ---------------------------------------------------------------------------
 *  check_fh_sig_slots
 *
 *      Check whether there are <n> free signal slots available on UniFi.
 *      This takes into account the signals already batched since the
 *      from_host_signal counts were last read.
 *      If the from_host_signal counts indicate not enough space, we read
 *      the latest count from UniFi to see if some more have been freed.
 *
 *  Arguments:
 *      None.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS, otherwise CSR error code on error.
 * ---------------------------------------------------------------------------
 */
static CsrResult check_fh_sig_slots(card_t *card, u16 needed, s32 *space_fh)
{
    u32 count_fhw;
    u32 occupied_fh, slots_fh;
    s32 count_fhr;

    count_fhw = card->from_host_signals_w;
    count_fhr = card->from_host_signals_r;
    slots_fh = card->config_data.num_fromhost_sig_frags;

    /* Only read the space in from-host queue if necessary */
    occupied_fh = (count_fhw - count_fhr) % 128;

    if (slots_fh < occupied_fh)
    {
        *space_fh = 0;
    }
    else
    {
        *space_fh = slots_fh - occupied_fh;
    }

    if ((occupied_fh != 0) && (*space_fh < needed))
    {
        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\n");
            return CSR_RESULT_FAILURE;
        }
        card->from_host_signals_r = count_fhr; /* diag */

        occupied_fh = (count_fhw - count_fhr) % 128;
        *space_fh = slots_fh - occupied_fh;
    }

    return CSR_RESULT_SUCCESS;
} /* check_fh_sig_slots() */


/*
* If we are padding the From-Host signals to the SDIO block size,
* we need to round up the needed_chunks to the SDIO block size.
*/
#define ROUND_UP_NEEDED_CHUNKS(_card, _needed_chunks) \
    { \
        u16 _chunks_per_block; \
        u16 _chunks_in_last_block; \
 \
        if (_card->sdio_io_block_pad) \
        { \
            _chunks_per_block = _card->sdio_io_block_size / _card->config_data.sig_frag_size; \
            _chunks_in_last_block = _needed_chunks % _chunks_per_block; \
            if (_chunks_in_last_block != 0) \
            { \
                _needed_chunks = _needed_chunks + (_chunks_per_block - _chunks_in_last_block); \
            } \
        } \
    }


#define ROUND_UP_SPACE_CHUNKS(_card, _space_chunks) \
    { \
        u16 _chunks_per_block; \
 \
        if (_card->sdio_io_block_pad) \
        { \
            _chunks_per_block = _card->sdio_io_block_size / _card->config_data.sig_frag_size; \
            _space_chunks = ((_space_chunks / _chunks_per_block) * _chunks_per_block); \
        } \
    }





/*
 * ---------------------------------------------------------------------------
 *  process_fh_cmd_queue
 *
 *      Take one signal off the from-host queue and copy it to the UniFi.
 *      Does nothing if the UniFi has no slots free.
 *
 *  Arguments:
 *      card       Pointer to card context struct
 *      processed  Location to write:
 *                      0 if there is nothing on the queue to process
 *                      1 if a signal was successfully processed
 *
 *  Returns:
 *      CSR error code if an error occurred.
 *
 *  Notes:
 *      The from-host queue contains signal requests from the network driver
 *      and any UDI clients interspersed. UDI clients' requests have been stored
 *      in the from-host queue using the wire-format structures, as they arrive.
 *      All other requests are stored in the from-host queue using the host
 *      (cpu specific) structures. We use the is_packed member of the card_signal_t
 *      structure that describes the queue to make the distiction.
 * ---------------------------------------------------------------------------
 */
static CsrResult process_fh_cmd_queue(card_t *card, s32 *processed)
{
    q_t *sigq = &card->fh_command_queue;

    CsrResult r;
    u16 pending_sigs;
    u16 pending_chunks;
    u16 needed_chunks;
    s32 space_chunks;
    u16 q_index;

    *processed = 0;

    /* Get the number of pending signals. */
    pending_sigs = CSR_WIFI_HIP_Q_SLOTS_USED(sigq);
    unifi_trace(card->ospriv, UDBG5, "proc_fh: %d pending\n", pending_sigs);
    if (pending_sigs == 0)
    {
        /* Nothing to do */
        return CSR_RESULT_SUCCESS;
    }

    /* Work out how many chunks we have waiting to send */
    for (pending_chunks = 0, q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(sigq);
         q_index != CSR_WIFI_HIP_Q_NEXT_W_SLOT(sigq);
         q_index = CSR_WIFI_HIP_Q_WRAP(sigq, q_index + 1))
    {
        card_signal_t *csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, q_index);

        /*
         * Note that GET_CHUNKS_FOR() needs the size of the packed
         * (wire-formatted) structure
         */
        pending_chunks += GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(csptr->signal_length + 2));
    }

    /*
     * Check whether UniFi has space for all the buffered bulk-data
     * commands and signals as well.
     */
    needed_chunks = pending_chunks + card->fh_buffer.count;

    /* Round up to the block size if necessary */
    ROUND_UP_NEEDED_CHUNKS(card, needed_chunks);

    r = check_fh_sig_slots(card, needed_chunks, &space_chunks);
    if (r != CSR_RESULT_SUCCESS)
    {
        /* Error */
        unifi_error(card->ospriv, "Failed to read fh sig count\n");
        return r;
    }

#ifdef CSR_WIFI_HIP_NOISY
    unifi_error(card->ospriv, "proc_fh: %d chunks free, need %d\n",
                space_chunks, needed_chunks);
#endif /* CSR_WIFI_HIP_NOISY */


    /*
     * Coalesce as many from-host signals as possible
     * into a single block and write using a single CMD53
     */
    if (needed_chunks > (u16)space_chunks)
    {
        /* Round up to the block size if necessary */
        ROUND_UP_SPACE_CHUNKS(card, space_chunks);

        /*
         * If the f/w has less free chunks than those already pending
         * return immediately.
         */
        if ((u16)space_chunks <= card->fh_buffer.count)
        {
            /*
             * No room in UniFi for any signals after the buffered bulk
             * data commands have been sent.
             */
            unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n",
                        card->fh_buffer.count, space_chunks);
            card->generate_interrupt = 1;
            return CSR_RESULT_SUCCESS;
        }
        pending_chunks = (u16)(space_chunks - card->fh_buffer.count);
    }

    while (pending_sigs-- && pending_chunks > 0)
    {
        card_signal_t *csptr;
        s16 i;
        u16 sig_chunks, total_length, free_chunks_in_fh_buffer;
        bulk_data_param_t bulkdata;
        u8 *packed_sigptr;
        u16 signal_length = 0;

        /* Retrieve the entry at the head of the queue */
        q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(sigq);

        /* Get a pointer to the containing card_signal_t struct */
        csptr = CSR_WIFI_HIP_Q_SLOT_DATA(sigq, q_index);

        /* Get the new length of the packed signal */
        signal_length = csptr->signal_length;

        if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE))
        {
            unifi_error(card->ospriv, "process_fh_queue: Bad len: %d\n", signal_length);
            return CSR_RESULT_FAILURE;
        }

        /* Need space for 2-byte SDIO protocol header + signal */
        sig_chunks = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(signal_length + 2));

        free_chunks_in_fh_buffer = GET_CHUNKS_FOR(card->config_data.sig_frag_size,
                                                  (u16)((card->fh_buffer.buf + UNIFI_FH_BUF_SIZE) - card->fh_buffer.ptr));
        if (free_chunks_in_fh_buffer < sig_chunks)
        {
            /* No more room */
            unifi_notice(card->ospriv, "proc_fh_cmd_q: no room in fh buffer for 0x%.4X, deferring\n",
                         (u16)(GET_SIGNAL_ID(csptr->sigbuf)));
            break;
        }

        packed_sigptr = csptr->sigbuf;

        /* Claim and set up a from-host data slot */
        if (CSR_RESULT_FAILURE == CardWriteBulkData(card, csptr, UNIFI_TRAFFIC_Q_MLME))
        {
            unifi_notice(card->ospriv, "proc_fh_cmd_q: no fh data slots for 0x%.4X, deferring\n",
                         (u16)(GET_SIGNAL_ID(csptr->sigbuf)));
            break;
        }

        for (i = 0; i < UNIFI_MAX_DATA_REFERENCES; i++)
        {
            if (csptr->bulkdata[i].data_length == 0)
            {
                UNIFI_INIT_BULK_DATA(&bulkdata.d[i]);
            }
            else
            {
                bulkdata.d[i].os_data_ptr = csptr->bulkdata[i].os_data_ptr;
                bulkdata.d[i].data_length = csptr->bulkdata[i].data_length;
            }

            /* Pass the free responsibility to the lower layer. */
            UNIFI_INIT_BULK_DATA(&csptr->bulkdata[i]);
        }

        unifi_trace(card->ospriv, UDBG2, "Sending signal 0x%.4X\n",
                    GET_SIGNAL_ID(packed_sigptr));
#ifdef CSR_WIFI_HIP_NOISY
        unifi_error(card->ospriv, "Sending signal 0x%.4X\n",
                    GET_SIGNAL_ID(packed_sigptr));
#endif  /* CSR_WIFI_HIP_NOISY */


        /* Append packed signal to F-H buffer */
        total_length = sig_chunks * card->config_data.sig_frag_size;

        card->fh_buffer.ptr[0] = (u8)(signal_length & 0xff);
        card->fh_buffer.ptr[1] =
            (u8)(((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4));

        memcpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length);
        memset(card->fh_buffer.ptr + 2 + signal_length, 0,
                  total_length - (2 + signal_length));

#ifdef CSR_WIFI_HIP_NOISY
        unifi_error(card->ospriv, "proc_fh: fh_buffer %d bytes \n",
                    signal_length + 2);
        dump(card->fh_buffer.ptr, signal_length + 2);
        unifi_trace(card->ospriv, UDBG1, " \n");
#endif  /* CSR_WIFI_HIP_NOISY */

        card->fh_buffer.ptr += total_length;
        card->fh_buffer.count += sig_chunks;

#ifdef CSR_WIFI_HIP_NOISY
        unifi_error(card->ospriv, "Added %d to fh buf, len now %d, count %d\n",
                    signal_length,
                    card->fh_buffer.ptr - card->fh_buffer.buf,
                    card->fh_buffer.count);
#endif  /* CSR_WIFI_HIP_NOISY */

        (*processed)++;
        pending_chunks -= sig_chunks;

        /* Log the signal to the UDI. */
        /* UDI will get the packed structure */
        /* Can not log the unpacked signal, unless we reconstruct it! */
        if (card->udi_hook)
        {
            (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length,
                              &bulkdata, UDI_LOG_FROM_HOST);
        }

        /* Remove entry from q */
        csptr->signal_length = 0;
        CSR_WIFI_HIP_Q_INC_R(sigq);
    }

    return CSR_RESULT_SUCCESS;
} /* process_fh_cmd_queue() */


/*
 * ---------------------------------------------------------------------------
 *  process_fh_traffic_queue
 *
 *      Take signals off the from-host queue and copy them to the UniFi.
 *      Does nothing if the UniFi has no slots free.
 *
 *  Arguments:
 *      card       Pointer to card context struct
 *      sigq       Pointer to the traffic queue
 *      processed  Pointer to location to write:
 *                      0 if there is nothing on the queue to process
 *                      1 if a signal was successfully processed
 *
 *  Returns:
 *      CSR error code if an error occurred.
 *
 *  Notes:
 *      The from-host queue contains signal requests from the network driver
 *      and any UDI clients interspersed.
 * ---------------------------------------------------------------------------
 */
static CsrResult process_fh_traffic_queue(card_t *card, s32 *processed)
{
    q_t *sigq = card->fh_traffic_queue;

    CsrResult r;
    s16 n = 0;
    s32 q_no;
    u16 pending_sigs = 0;
    u16 pending_chunks = 0;
    u16 needed_chunks;
    s32 space_chunks;
    u16 q_index;
    u32 host_tag = 0;
    u16 slot_num = 0;

    *processed = 0;

    /* calculate how many signals are in queues and how many chunks are needed. */
    for (n = UNIFI_NO_OF_TX_QS - 1; n >= 0; n--)
    {
        /* Get the number of pending signals. */
        pending_sigs += CSR_WIFI_HIP_Q_SLOTS_USED(&sigq[n]);
        unifi_trace(card->ospriv, UDBG5, "proc_fh%d: %d pending\n", n, pending_sigs);

        /* Work out how many chunks we have waiting to send */
        for (q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(&sigq[n]);
             q_index != CSR_WIFI_HIP_Q_NEXT_W_SLOT(&sigq[n]);
             q_index = CSR_WIFI_HIP_Q_WRAP(&sigq[n], q_index + 1))
        {
            card_signal_t *csptr = CSR_WIFI_HIP_Q_SLOT_DATA(&sigq[n], q_index);

            /*
             * Note that GET_CHUNKS_FOR() needs the size of the packed
             * (wire-formatted) structure
             */
            pending_chunks += GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(csptr->signal_length + 2));
        }
    }

    /* If there are no pending signals, just return */
    if (pending_sigs == 0)
    {
        /* Nothing to do */
        return CSR_RESULT_SUCCESS;
    }

    /*
     * Check whether UniFi has space for all the buffered bulk-data
     * commands and signals as well.
     */
    needed_chunks = pending_chunks + card->fh_buffer.count;

    /* Round up to the block size if necessary */
    ROUND_UP_NEEDED_CHUNKS(card, needed_chunks);

    r = check_fh_sig_slots(card, needed_chunks, &space_chunks);
    if (r != CSR_RESULT_SUCCESS)
    {
        /* Error */
        unifi_error(card->ospriv, "Failed to read fh sig count\n");
        return r;
    }

#ifdef CSR_WIFI_HIP_NOISY
    unifi_error(card->ospriv,
                "process_fh_traffic_queue: %d chunks free, need %d\n",
                space_chunks, needed_chunks);
    read_fhsr(card);            /* debugging only */
#endif /* CSR_WIFI_HIP_NOISY */

    /* Coalesce as many from-host signals as possible
       into a single block and write using a single CMD53 */
    if (needed_chunks > (u16)space_chunks)
    {
        /* Round up to the block size if necessary */
        ROUND_UP_SPACE_CHUNKS(card, space_chunks);

        if ((u16)space_chunks <= card->fh_buffer.count)
        {
            /*
             * No room in UniFi for any signals after the buffered bulk
             * data commands have been sent.
             */
            unifi_error(card->ospriv, "not enough room to send signals, need %d chunks, %d free\n",
                        card->fh_buffer.count, space_chunks);
            card->generate_interrupt = 1;
            return 0;
        }

        pending_chunks = (u16)space_chunks - card->fh_buffer.count;
    }

    q_no = UNIFI_NO_OF_TX_QS - 1;

    /*
     * pending_sigs will be exhausted if there are is no restriction to the pending
     * signals per queue. pending_chunks may be exhausted if there is a restriction.
     * q_no check will be exhausted if there is a restriction and our round-robin
     * algorith fails to fill all chunks.
     */
    do
    {
        card_signal_t *csptr;
        u16 sig_chunks, total_length, free_chunks_in_fh_buffer;
        bulk_data_param_t bulkdata;
        u8 *packed_sigptr;
        u16 signal_length = 0;

        /* if this queue is empty go to next one. */
        if (CSR_WIFI_HIP_Q_SLOTS_USED(&sigq[q_no]) == 0)
        {
            q_no--;
            continue;
        }

        /* Retrieve the entry at the head of the queue */
        q_index = CSR_WIFI_HIP_Q_NEXT_R_SLOT(&sigq[q_no]);

        /* Get a pointer to the containing card_signal_t struct */
        csptr = CSR_WIFI_HIP_Q_SLOT_DATA(&sigq[q_no], q_index);

        /* Get the new length of the packed signal */
        signal_length = csptr->signal_length;

        if ((signal_length & 1) || (signal_length > UNIFI_PACKED_SIGBUF_SIZE))
        {
            unifi_error(card->ospriv, "process_fh_traffic_queue: Bad len: %d\n", signal_length);
            return CSR_RESULT_FAILURE;
        }

        /* Need space for 2-byte SDIO protocol header + signal */
        sig_chunks = GET_CHUNKS_FOR(card->config_data.sig_frag_size, (u16)(signal_length + 2));
        free_chunks_in_fh_buffer = GET_CHUNKS_FOR(card->config_data.sig_frag_size,
                                                  (u16)((card->fh_buffer.buf + UNIFI_FH_BUF_SIZE) - card->fh_buffer.ptr));
        if (free_chunks_in_fh_buffer < sig_chunks)
        {
            /* No more room */
            unifi_notice(card->ospriv, "process_fh_traffic_queue: no more chunks.\n");
            break;
        }

        packed_sigptr = csptr->sigbuf;
        /* Claim and set up a from-host data slot */
        if (CSR_RESULT_FAILURE == CardWriteBulkData(card, csptr, (unifi_TrafficQueue)q_no))
        {
            q_no--;
            continue;
        }

        /* Sanity check: MA-PACKET.req must have a valid bulk data */
        if ((csptr->bulkdata[0].data_length == 0) || (csptr->bulkdata[0].os_data_ptr == NULL))
        {
            unifi_error(card->ospriv, "MA-PACKET.req with empty bulk data (%d bytes in %p)\n",
                        csptr->bulkdata[0].data_length, csptr->bulkdata[0].os_data_ptr);
            dump(packed_sigptr, signal_length);
            return CSR_RESULT_FAILURE;
        }

        bulkdata.d[0].os_data_ptr = csptr->bulkdata[0].os_data_ptr;
        bulkdata.d[0].data_length = csptr->bulkdata[0].data_length;
        bulkdata.d[0].os_net_buf_ptr = csptr->bulkdata[0].os_net_buf_ptr;
        bulkdata.d[0].net_buf_length = csptr->bulkdata[0].net_buf_length;

        /* The driver owns clearing of HIP slots for following scenario
         * - driver has requested a MA-PACKET.req signal
         * - The f/w after receiving the signal decides it can't send it out due to various reasons
         * - So the f/w without downloading the bulk data decides to just send a confirmation with fail
         * - and then sends a clear slot signal to HIP
         *
         * But in some cases the clear slot signal never comes and the slot remains --NOT-- freed for ever
         *
         * To handle this, HIP will keep the record of host tag for each occupied slot
         * and then based on status of that Host tag and slot the driver will decide if the slot is
         * cleared by f/w signal or the slot has to be freed by driver
         */

        if (card->fh_slot_host_tag_record)
        {
            /* Update the f-h slot record for the corresponding host tag */
            host_tag = GET_PACKED_MA_PACKET_REQUEST_HOST_TAG(packed_sigptr);
            slot_num = GET_PACKED_DATAREF_SLOT(packed_sigptr, 0) & 0x00FF;

            unifi_trace(card->ospriv, UDBG5,
                        "process_fh_traffic_queue signal ID =%x fh slot=%x Host tag =%x\n",
                        GET_SIGNAL_ID(packed_sigptr), slot_num, host_tag);
            card->fh_slot_host_tag_record[slot_num] = host_tag;
        }
        UNIFI_INIT_BULK_DATA(&bulkdata.d[1]);
        UNIFI_INIT_BULK_DATA(&csptr->bulkdata[0]);
        UNIFI_INIT_BULK_DATA(&csptr->bulkdata[1]);

#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
        if (bulkdata.d[0].os_data_ptr)
        {
            if ((*bulkdata.d[0].os_data_ptr) & 0x08)
            {
                card->cmd_prof.tx_count++;
            }
        }
#endif
        unifi_trace(card->ospriv, UDBG3, "Sending signal 0x%.4X\n",
                    GET_SIGNAL_ID(packed_sigptr));
#ifdef CSR_WIFI_HIP_NOISY
        unifi_error(card->ospriv, "Sending signal 0x%.4X\n",
                    GET_SIGNAL_ID(packed_sigptr));
#endif  /* CSR_WIFI_HIP_NOISY */

        /* Append packed signal to F-H buffer */
        total_length = sig_chunks * card->config_data.sig_frag_size;

        card->fh_buffer.ptr[0] = (u8)(signal_length & 0xff);
        card->fh_buffer.ptr[1] =
            (u8)(((signal_length >> 8) & 0xf) | (SDIO_CMD_SIGNAL << 4));

        memcpy(card->fh_buffer.ptr + 2, packed_sigptr, signal_length);
        memset(card->fh_buffer.ptr + 2 + signal_length, 0,
                  total_length - (2 + signal_length));

#ifdef CSR_WIFI_HIP_NOISY
        unifi_error(card->ospriv, "proc_fh: fh_buffer %d bytes \n",
                    signal_length + 2);
        dump(card->fh_buffer.ptr, signal_length + 2);
        unifi_trace(card->ospriv, UDBG1, " \n");
#endif  /* CSR_WIFI_HIP_NOISY */

        card->fh_buffer.ptr += total_length;
        card->fh_buffer.count += sig_chunks;

#ifdef CSR_WIFI_HIP_NOISY
        unifi_error(card->ospriv, "Added %d to fh buf, len now %d, count %d\n",
                    signal_length,
                    card->fh_buffer.ptr - card->fh_buffer.buf,
                    card->fh_buffer.count);
#endif  /* CSR_WIFI_HIP_NOISY */

        (*processed)++;
        pending_sigs--;
        pending_chunks -= sig_chunks;

        /* Log the signal to the UDI. */
        /* UDI will get the packed structure */
        /* Can not log the unpacked signal, unless we reconstruct it! */
        if (card->udi_hook)
        {
            (*card->udi_hook)(card->ospriv, packed_sigptr, signal_length,
                              &bulkdata, UDI_LOG_FROM_HOST);
        }

        /* Remove entry from q */
        csptr->signal_length = 0;
        /* Note that the traffic queue has only one valid bulk data buffer. */
        csptr->bulkdata[0].data_length = 0;

        CSR_WIFI_HIP_Q_INC_R(&sigq[q_no]);
    } while ((pending_sigs > 0) && (pending_chunks > 0) && (q_no >= 0));

    return CSR_RESULT_SUCCESS;
} /* process_fh_traffic_queue() */


/*
 * ---------------------------------------------------------------------------
 *  flush_fh_buffer
 *
 *      Write out the cache from-hosts signals to the UniFi.
 *
 *  Arguments:
 *      card       Pointer to card context struct
 *
 *  Returns:
 *      CSR error code if an SDIO error occurred.
 * ---------------------------------------------------------------------------
 */
static CsrResult flush_fh_buffer(card_t *card)
{
    CsrResult r;
    u16 len;
    u16 sig_units;
    u16 data_round;
    u16 chunks_in_last_block;
    u16 padding_chunks;
    u16 i;

    len = card->fh_buffer.ptr - card->fh_buffer.buf;

#ifdef CSR_WIFI_HIP_NOISY
    unifi_error(card->ospriv, "fh_buffer is at %p, ptr= %p\n",
                card->fh_buffer.buf, card->fh_buffer.ptr);
#endif /* CSR_WIFI_HIP_NOISY */

    if (len == 0)
    {
        return CSR_RESULT_SUCCESS;
    }

#ifdef CSR_WIFI_HIP_NOISY
    if (dump_fh_buf)
    {
        dump(card->fh_buffer.buf, len);
        dump_fh_buf = 0;
    }
#endif /* CSR_WIFI_HIP_NOISY */

    if (card->sdio_io_block_pad)
    {
        /* Both of these are powers of 2 */
        sig_units = card->config_data.sig_frag_size;
        data_round = card->sdio_io_block_size;

        if (data_round > sig_units)
        {
            chunks_in_last_block = (len % data_round) / sig_units;

            if (chunks_in_last_block != 0)
            {
                padding_chunks = (data_round / sig_units) - chunks_in_last_block;

                memset(card->fh_buffer.ptr, 0, padding_chunks * sig_units);
                for (i = 0; i < padding_chunks; i++)
                {
                    card->fh_buffer.ptr[1] = SDIO_CMD_PADDING << 4;
                    card->fh_buffer.ptr += sig_units;
                }

                card->fh_buffer.count += padding_chunks;
                len += padding_chunks * sig_units;
            }
        }
    }

    r = unifi_bulk_rw(card,
                      card->config_data.fromhost_sigbuf_handle,
                      card->fh_buffer.buf,
                      len, UNIFI_SDIO_WRITE);
    if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
    {
        return r;
    }
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to write fh signals: %u bytes, error %d\n", len, r);
        return r;
    }

    /* Update from-host-signals-written signal count */
    card->from_host_signals_w =
        (card->from_host_signals_w + card->fh_buffer.count) % 128u;
    r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 0,
                            (u8)card->from_host_signals_w);
    if (r != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to write fh signal count %u with error %d\n",
                    card->from_host_signals_w, r);
        return r;
    }
    card->generate_interrupt = 1;

    /* Reset the fh buffer pointer */
    card->fh_buffer.ptr = card->fh_buffer.buf;
    card->fh_buffer.count = 0;

#ifdef CSR_WIFI_HIP_NOISY
    unifi_error(card->ospriv, "END flush: fh len %d, count %d\n",
                card->fh_buffer.ptr - card->fh_buffer.buf,
                card->fh_buffer.count);
#endif /* CSR_WIFI_HIP_NOISY */

    return CSR_RESULT_SUCCESS;
} /* flush_fh_buffer() */


/*
 * ---------------------------------------------------------------------------
 *  restart_packet_flow
 *
 *      This function is called before the bottom-half thread sleeps.
 *      It checks whether both data and signal resources are available and
 *      then calls the OS-layer function to re-enable packet transmission.
 *
 *  Arguments:
 *      card       Pointer to card context struct
 *
 *  Returns:
 *      None.
 * ---------------------------------------------------------------------------
 */
static void restart_packet_flow(card_t *card)
{
    u8 q;

    /*
     * We only look at the fh_traffic_queue, because that is where packets from
     * the network stack are placed.
     */
    for (q = 0; q <= UNIFI_TRAFFIC_Q_VO; q++)
    {
        if (card_is_tx_q_paused(card, q) &&
            CSR_WIFI_HIP_Q_SLOTS_FREE(&card->fh_traffic_queue[q]) >= RESUME_XMIT_THRESHOLD)
        {
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
            unifi_debug_log_to_buf("U");
#endif
            card_tx_q_unpause(card, q);
            unifi_restart_xmit(card->ospriv, (unifi_TrafficQueue)q);
        }
    }
} /* restart_packet_flow() */


