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

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


