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

            (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_mem.c
 *
 * PURPOSE: Implementation of the Card API for SDIO.
 *
 * ---------------------------------------------------------------------------
 */
#include "csr_wifi_hip_unifi.h"
#include "csr_wifi_hip_card.h"

#define SDIO_RETRIES    3
#define CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH 16


#define retryable_sdio_error(_csrResult) (((_csrResult) == CSR_SDIO_RESULT_CRC_ERROR) || ((_csrResult) == CSR_SDIO_RESULT_TIMEOUT))


/*
 * ---------------------------------------------------------------------------
 *  retrying_read8
 *  retrying_write8
 *
 *      These functions provide the first level of retry for SDIO operations.
 *      If an SDIO command fails for reason of a response timeout or CRC
 *      error, it is retried immediately. If three attempts fail we report a
 *      failure.
 *      If the command failed for any other reason, the failure is reported
 *      immediately.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      funcnum         The SDIO function to access.
 *                      Function 0 is the Card Configuration Register space,
 *                      function 1/2 is the UniFi register space.
 *      addr            Address to access
 *      pdata           Pointer in which to return the value read.
 *      data            Value to write.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS  on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 * ---------------------------------------------------------------------------
 */
static CsrResult retrying_read8(card_t *card, s16 funcnum, u32 addr, u8 *pdata)
{
    CsrSdioFunction *sdio = card->sdio_if;
    CsrResult r = CSR_RESULT_SUCCESS;
    s16 retries;
    CsrResult csrResult = CSR_RESULT_SUCCESS;

    retries = 0;
    while (retries++ < SDIO_RETRIES)
    {
        if (funcnum == 0)
        {
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
            unifi_debug_log_to_buf("r0@%02X", addr);
#endif
            csrResult = CsrSdioF0Read8(sdio, addr, pdata);
        }
        else
        {
#ifdef CSR_WIFI_TRANSPORT_CSPI
            unifi_error(card->ospriv,
                        "retrying_read_f0_8: F1 8-bit reads are not allowed.\n");
            return CSR_RESULT_FAILURE;
#else
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
            unifi_debug_log_to_buf("r@%02X", addr);
#endif
            csrResult = CsrSdioRead8(sdio, addr, pdata);
#endif
        }
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        if (csrResult != CSR_RESULT_SUCCESS)
        {
            unifi_debug_log_to_buf("error=%X\n", csrResult);
        }
        else
        {
            unifi_debug_log_to_buf("=%X\n", *pdata);
        }
#endif
        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
        {
            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
        }
        /*
         * Try again for retryable (CRC or TIMEOUT) errors,
         * break on success or fatal error
         */
        if (!retryable_sdio_error(csrResult))
        {
#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
            card->cmd_prof.cmd52_count++;
#endif
            break;
        }
        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr);
    }

    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
    {
        unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries);
    }

    if (csrResult != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
                    addr, retries - 1);
        /* Report any SDIO error as a general i/o error */
        r = CSR_RESULT_FAILURE;
    }

    return r;
} /* retrying_read8() */


static CsrResult retrying_write8(card_t *card, s16 funcnum, u32 addr, u8 data)
{
    CsrSdioFunction *sdio = card->sdio_if;
    CsrResult r = CSR_RESULT_SUCCESS;
    s16 retries;
    CsrResult csrResult = CSR_RESULT_SUCCESS;

    retries = 0;
    while (retries++ < SDIO_RETRIES)
    {
        if (funcnum == 0)
        {
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
            unifi_debug_log_to_buf("w0@%02X=%X", addr, data);
#endif
            csrResult = CsrSdioF0Write8(sdio, addr, data);
        }
        else
        {
#ifdef CSR_WIFI_TRANSPORT_CSPI
            unifi_error(card->ospriv,
                        "retrying_write_f0_8: F1 8-bit writes are not allowed.\n");
            return CSR_RESULT_FAILURE;
#else
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
            unifi_debug_log_to_buf("w@%02X=%X", addr, data);
#endif
            csrResult = CsrSdioWrite8(sdio, addr, data);
#endif
        }
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        if (csrResult != CSR_RESULT_SUCCESS)
        {
            unifi_debug_log_to_buf(",error=%X", csrResult);
        }
        unifi_debug_string_to_buf("\n");
#endif
        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
        {
            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
        }
        /*
         * Try again for retryable (CRC or TIMEOUT) errors,
         * break on success or fatal error
         */
        if (!retryable_sdio_error(csrResult))
        {
#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
            card->cmd_prof.cmd52_count++;
#endif
            break;
        }
        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n",
                    data, funcnum, addr);
    }

    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
    {
        unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries);
    }

    if (csrResult != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
                    addr, retries - 1);
        /* Report any SDIO error as a general i/o error */
        r = CSR_RESULT_FAILURE;
    }

    return r;
} /* retrying_write8() */


static CsrResult retrying_read16(card_t *card, s16 funcnum,
                                 u32 addr, u16 *pdata)
{
    CsrSdioFunction *sdio = card->sdio_if;
    CsrResult r = CSR_RESULT_SUCCESS;
    s16 retries;
    CsrResult csrResult = CSR_RESULT_SUCCESS;

    retries = 0;
    while (retries++ < SDIO_RETRIES)
    {
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        unifi_debug_log_to_buf("r@%02X", addr);
#endif
        csrResult = CsrSdioRead16(sdio, addr, pdata);
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        if (csrResult != CSR_RESULT_SUCCESS)
        {
            unifi_debug_log_to_buf("error=%X\n", csrResult);
        }
        else
        {
            unifi_debug_log_to_buf("=%X\n", *pdata);
        }
#endif
        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
        {
            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
        }

        /*
         * Try again for retryable (CRC or TIMEOUT) errors,
         * break on success or fatal error
         */
        if (!retryable_sdio_error(csrResult))
        {
#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
            card->cmd_prof.cmd52_count++;
#endif
            break;
        }
        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error reading F%d 0x%lX\n", funcnum, addr);
    }

    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
    {
        unifi_warning(card->ospriv, "Read succeeded after %d attempts\n", retries);
    }

    if (csrResult != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
                    addr, retries - 1);
        /* Report any SDIO error as a general i/o error */
        r = CSR_RESULT_FAILURE;
    }

    return r;
} /* retrying_read16() */


static CsrResult retrying_write16(card_t *card, s16 funcnum,
                                  u32 addr, u16 data)
{
    CsrSdioFunction *sdio = card->sdio_if;
    CsrResult r = CSR_RESULT_SUCCESS;
    s16 retries;
    CsrResult csrResult = CSR_RESULT_SUCCESS;

    retries = 0;
    while (retries++ < SDIO_RETRIES)
    {
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        unifi_debug_log_to_buf("w@%02X=%X", addr, data);
#endif
        csrResult = CsrSdioWrite16(sdio, addr, data);
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        if (csrResult != CSR_RESULT_SUCCESS)
        {
            unifi_debug_log_to_buf(",error=%X", csrResult);
        }
        unifi_debug_string_to_buf("\n");
#endif
        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
        {
            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
        }

        /*
         * Try again for retryable (CRC or TIMEOUT) errors,
         * break on success or fatal error
         */
        if (!retryable_sdio_error(csrResult))
        {
#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
            card->cmd_prof.cmd52_count++;
#endif
            break;
        }
        unifi_trace(card->ospriv, UDBG2, "retryable SDIO error writing %02X to F%d 0x%lX\n",
                    data, funcnum, addr);
    }

    if ((csrResult == CSR_RESULT_SUCCESS) && (retries > 1))
    {
        unifi_warning(card->ospriv, "Write succeeded after %d attempts\n", retries);
    }

    if (csrResult != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
                    addr, retries - 1);
        /* Report any SDIO error as a general i/o error */
        r = CSR_RESULT_FAILURE;
    }

    return r;
} /* retrying_write16() */


/*
 * ---------------------------------------------------------------------------
 *  sdio_read_f0
 *
 *      Reads a byte value from the CCCR (func 0) area of UniFi.
 *
 *  Arguments:
 *      card    Pointer to card structure.
 *      addr    Address to read from
 *      pdata   Pointer in which to store the read value.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 * ---------------------------------------------------------------------------
 */
CsrResult sdio_read_f0(card_t *card, u32 addr, u8 *pdata)
{
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
    card->cmd_prof.cmd52_f0_r_count++;
#endif
    return retrying_read8(card, 0, addr, pdata);
} /* sdio_read_f0() */


/*
 * ---------------------------------------------------------------------------
 *  sdio_write_f0
 *
 *      Writes a byte value to the CCCR (func 0) area of UniFi.
 *
 *  Arguments:
 *      card    Pointer to card structure.
 *      addr    Address to read from
 *      data    Data value to write.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 * ---------------------------------------------------------------------------
 */
CsrResult sdio_write_f0(card_t *card, u32 addr, u8 data)
{
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
    card->cmd_prof.cmd52_f0_w_count++;
#endif
    return retrying_write8(card, 0, addr, data);
} /* sdio_write_f0() */


/*
 * ---------------------------------------------------------------------------
 * unifi_read_direct_8_or_16
 *
 *      Read a 8-bit value from the UniFi SDIO interface.
 *
 *  Arguments:
 *      card    Pointer to card structure.
 *      addr    Address to read from
 *      pdata   Pointer in which to return data.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_read_direct_8_or_16(card_t *card, u32 addr, u8 *pdata)
{
#ifdef CSR_WIFI_TRANSPORT_CSPI
    u16 w;
    CsrResult r;

    r = retrying_read16(card, card->function, addr, &w);
    *pdata = (u8)(w & 0xFF);
    return r;
#else
    return retrying_read8(card, card->function, addr, pdata);
#endif
} /* unifi_read_direct_8_or_16() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_write_direct_8_or_16
 *
 *      Write a byte value to the UniFi SDIO interface.
 *
 *  Arguments:
 *      card    Pointer to card structure.
 *      addr    Address to write to
 *      data    Value to write.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error
 *
 *  Notes:
 *      If 8-bit write is used, the even address *must* be written second.
 *      This is because writes to odd bytes are cached and not committed
 *      to memory until the preceding even address is written.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_write_direct_8_or_16(card_t *card, u32 addr, u8 data)
{
    if (addr & 1)
    {
        unifi_warning(card->ospriv,
                      "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
                      addr);
    }

#ifdef CSR_WIFI_TRANSPORT_CSPI
    return retrying_write16(card, card->function, addr, (u16)data);
#else
    return retrying_write8(card, card->function, addr, data);
#endif
} /* unifi_write_direct_8_or_16() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_read_direct16
 *
 *      Read a 16-bit value from the UniFi SDIO interface.
 *
 *  Arguments:
 *      card    Pointer to card structure.
 *      addr    Address to read from
 *      pdata   Pointer in which to return data.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *
 *  Notes:
 *      The even address *must* be read first. This is because reads from
 *      odd bytes are cached and read from memory when the preceding
 *      even address is read.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_read_direct16(card_t *card, u32 addr, u16 *pdata)
{
    return retrying_read16(card, card->function, addr, pdata);
} /* unifi_read_direct16() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_write_direct16
 *
 *      Write a 16-bit value to the UniFi SDIO interface.
 *
 *  Arguments:
 *      card    Pointer to card structure.
 *      addr    Address to write to
 *      data    Value to write.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *
 *  Notes:
 *      The even address *must* be written second. This is because writes to
 *      odd bytes are cached and not committed to memory until the preceding
 *      even address is written.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_write_direct16(card_t *card, u32 addr, u16 data)
{
    return retrying_write16(card, card->function, addr, data);
} /* unifi_write_direct16() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_read_direct32
 *
 *      Read a 32-bit value from the UniFi SDIO interface.
 *
 *  Arguments:
 *      card    Pointer to card structure.
 *      addr    Address to read from
 *      pdata   Pointer in which to return data.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_read_direct32(card_t *card, u32 addr, u32 *pdata)
{
    CsrResult r;
    u16 w0, w1;

    r = retrying_read16(card, card->function, addr, &w0);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    r = retrying_read16(card, card->function, addr + 2, &w1);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    *pdata = ((u32)w1 << 16) | (u32)w0;

    return CSR_RESULT_SUCCESS;
} /* unifi_read_direct32() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_read_directn_match
 *
 *      Read multiple 8-bit values from the UniFi SDIO interface,
 *      stopping when either we have read 'len' bytes or we have read
 *      a octet equal to 'match'.  If 'match' is not a valid octet
 *      then this function is the same as 'unifi_read_directn'.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      addr            Start address to read from.
 *      pdata           Pointer to which to write data.
 *      len             Maximum umber of bytes to read
 *      match           The value to stop reading at.
 *      num             Pointer to buffer to write number of bytes read
 *
 *  Returns:
 *      number of octets read on success, negative error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *
 *  Notes:
 *      The even address *must* be read first. This is because reads from
 *      odd bytes are cached and read from memory when the preceding
 *      even address is read.
 * ---------------------------------------------------------------------------
 */
static CsrResult unifi_read_directn_match(card_t *card, u32 addr, void *pdata, u16 len, s8 m, u32 *num)
{
    CsrResult r;
    u32 i;
    u8 *cptr;
    u16 w;

    *num = 0;

    cptr = (u8 *)pdata;
    for (i = 0; i < len; i += 2)
    {
        r = retrying_read16(card, card->function, addr, &w);
        if (r != CSR_RESULT_SUCCESS)
        {
            return r;
        }

        *cptr++ = ((u8)w & 0xFF);
        if ((m >= 0) && (((s8)w & 0xFF) == m))
        {
            break;
        }

        if (i + 1 == len)
        {
            /* The len is odd. Ignore the last high byte */
            break;
        }

        *cptr++ = ((u8)(w >> 8) & 0xFF);
        if ((m >= 0) && (((s8)(w >> 8) & 0xFF) == m))
        {
            break;
        }

        addr += 2;
    }

    *num = (s32)(cptr - (u8 *)pdata);
    return CSR_RESULT_SUCCESS;
}


/*
 * ---------------------------------------------------------------------------
 *  unifi_read_directn
 *
 *      Read multiple 8-bit values from the UniFi SDIO interface.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      addr            Start address to read from.
 *      pdata           Pointer to which to write data.
 *      len             Number of bytes to read
 *
 *  Returns:
 *      0 on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *
 *  Notes:
 *      The even address *must* be read first. This is because reads from
 *      odd bytes are cached and read from memory when the preceding
 *      even address is read.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_read_directn(card_t *card, u32 addr, void *pdata, u16 len)
{
    u32 num;

    return unifi_read_directn_match(card, addr, pdata, len, -1, &num);
} /* unifi_read_directn() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_write_directn
 *
 *      Write multiple 8-bit values to the UniFi SDIO interface.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      addr            Start address to write to.
 *      pdata           Source data pointer.
 *      len             Number of bytes to write, must be even.
 *
 *  Returns:
 *      0 on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *
 *  Notes:
 *      The UniFi has a peculiar 16-bit bus architecture. Writes are only
 *      committed to memory when an even address is accessed. Writes to
 *      odd addresses are cached and only committed if the next write is
 *      to the preceding address.
 *      This means we must write data as pairs of bytes in reverse order.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_write_directn(card_t *card, u32 addr, void *pdata, u16 len)
{
    CsrResult r;
    u8 *cptr;
    s16 signed_len;

    cptr = (u8 *)pdata;
    signed_len = (s16)len;
    while (signed_len > 0)
    {
        /* This is UniFi-1 specific code. CSPI not supported so 8-bit write allowed */
        r = retrying_write16(card, card->function, addr, *cptr);
        if (r != CSR_RESULT_SUCCESS)
        {
            return r;
        }

        cptr += 2;
        addr += 2;
        signed_len -= 2;
    }

    return CSR_RESULT_SUCCESS;
} /* unifi_write_directn() */


/*
 * ---------------------------------------------------------------------------
 *  set_dmem_page
 *  set_pmem_page
 *
 *      Set up the page register for the shared data memory window or program
 *      memory window.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      dmem_addr       UniFi shared-data-memory address to access.
 *      pmem_addr       UniFi program memory address to access. This includes
 *                        External FLASH memory at    0x000000
 *                        Processor program memory at 0x200000
 *                        External SRAM at memory     0x400000
 *      paddr           Location to write an SDIO address (24-bit) for
 *                       use in a unifi_read_direct or unifi_write_direct call.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
 *      CSR_RESULT_FAILURE an SDIO error occurred
 * ---------------------------------------------------------------------------
 */
static CsrResult set_dmem_page(card_t *card, u32 dmem_addr, u32 *paddr)
{
    u16 page, addr;
    u32 len;
    CsrResult r;

    *paddr = 0;

    if (!ChipHelper_DecodeWindow(card->helper,
                                 CHIP_HELPER_WINDOW_3,
                                 CHIP_HELPER_WT_SHARED,
                                 dmem_addr / 2,
                                 &page, &addr, &len))
    {
        unifi_error(card->ospriv, "Failed to decode SHARED_DMEM_PAGE %08lx\n", dmem_addr);
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    if (page != card->dmem_page)
    {
        unifi_trace(card->ospriv, UDBG6, "setting dmem page=0x%X, addr=0x%lX\n", page, addr);

        /* change page register */
        r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW3_PAGE(card->helper) * 2, page);
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to write SHARED_DMEM_PAGE\n");
            return r;
        }

        card->dmem_page = page;
    }

    *paddr = ((s32)addr * 2) + (dmem_addr & 1);

    return CSR_RESULT_SUCCESS;
} /* set_dmem_page() */


static CsrResult set_pmem_page(card_t *card, u32 pmem_addr,
                               enum chip_helper_window_type mem_type, u32 *paddr)
{
    u16 page, addr;
    u32 len;
    CsrResult r;

    *paddr = 0;

    if (!ChipHelper_DecodeWindow(card->helper,
                                 CHIP_HELPER_WINDOW_2,
                                 mem_type,
                                 pmem_addr / 2,
                                 &page, &addr, &len))
    {
        unifi_error(card->ospriv, "Failed to decode PROG MEM PAGE %08lx %d\n", pmem_addr, mem_type);
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    if (page != card->pmem_page)
    {
        unifi_trace(card->ospriv, UDBG6, "setting pmem page=0x%X, addr=0x%lX\n", page, addr);

        /* change page register */
        r = unifi_write_direct16(card, ChipHelper_HOST_WINDOW2_PAGE(card->helper) * 2, page);
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to write PROG MEM PAGE\n");
            return r;
        }

        card->pmem_page = page;
    }

    *paddr = ((s32)addr * 2) + (pmem_addr & 1);

    return CSR_RESULT_SUCCESS;
} /* set_pmem_page() */


/*
 * ---------------------------------------------------------------------------
 *  set_page
 *
 *      Sets up the appropriate page register to access the given address.
 *      Returns the sdio address at which the unifi address can be accessed.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      generic_addr    UniFi internal address to access, in Generic Pointer
 *                      format, i.e. top byte is space indicator.
 *      paddr           Location to write page address
 *                          SDIO address (24-bit) for use in a unifi_read_direct or
 *                          unifi_write_direct call
 *
 *  Returns:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  the address is invalid
 * ---------------------------------------------------------------------------
 */
static CsrResult set_page(card_t *card, u32 generic_addr, u32 *paddr)
{
    s32 space;
    u32 addr;
    CsrResult r = CSR_RESULT_SUCCESS;

    if (!paddr)
    {
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }
    *paddr = 0;
    space = UNIFI_GP_SPACE(generic_addr);
    addr = UNIFI_GP_OFFSET(generic_addr);
    switch (space)
    {
        case UNIFI_SH_DMEM:
            /* Shared Data Memory is accessed via the Shared Data Memory window */
            r = set_dmem_page(card, addr, paddr);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            break;

        case UNIFI_EXT_FLASH:
            if (!ChipHelper_HasFlash(card->helper))
            {
                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
                            generic_addr, card->helper);
                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
            }
            /* External FLASH is accessed via the Program Memory window */
            r = set_pmem_page(card, addr, CHIP_HELPER_WT_FLASH, paddr);
            break;

        case UNIFI_EXT_SRAM:
            if (!ChipHelper_HasExtSram(card->helper))
            {
                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08l (helper=0x%x)\n",
                            generic_addr, card->helper);
                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
            }
            /* External SRAM is accessed via the Program Memory window */
            r = set_pmem_page(card, addr, CHIP_HELPER_WT_EXT_SRAM, paddr);
            break;

        case UNIFI_REGISTERS:
            /* Registers are accessed directly */
            *paddr = addr;
            break;

        case UNIFI_PHY_DMEM:
            r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
            break;

        case UNIFI_MAC_DMEM:
            r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
            break;

        case UNIFI_BT_DMEM:
            if (!ChipHelper_HasBt(card->helper))
            {
                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
                            generic_addr, card->helper);
                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
            }
            r = unifi_set_proc_select(card, UNIFI_PROC_BT);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            *paddr = ChipHelper_DATA_MEMORY_RAM_OFFSET(card->helper) * 2 + addr;
            break;

        case UNIFI_PHY_PMEM:
            r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
            break;

        case UNIFI_MAC_PMEM:
            r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
            break;

        case UNIFI_BT_PMEM:
            if (!ChipHelper_HasBt(card->helper))
            {
                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
                            generic_addr, card->helper);
                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
            }
            r = unifi_set_proc_select(card, UNIFI_PROC_BT);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            r = set_pmem_page(card, addr, CHIP_HELPER_WT_CODE_RAM, paddr);
            break;

        case UNIFI_PHY_ROM:
            if (!ChipHelper_HasRom(card->helper))
            {
                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
                            generic_addr, card->helper);
                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
            }
            r = unifi_set_proc_select(card, UNIFI_PROC_PHY);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
            break;

        case UNIFI_MAC_ROM:
            if (!ChipHelper_HasRom(card->helper))
            {
                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
                            generic_addr, card->helper);
                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
            }
            r = unifi_set_proc_select(card, UNIFI_PROC_MAC);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
            break;

        case UNIFI_BT_ROM:
            if (!ChipHelper_HasRom(card->helper) || !ChipHelper_HasBt(card->helper))
            {
                unifi_error(card->ospriv, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
                            generic_addr, card->helper);
                return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
            }
            r = unifi_set_proc_select(card, UNIFI_PROC_BT);
            if (r != CSR_RESULT_SUCCESS)
            {
                return r;
            }
            r = set_pmem_page(card, addr, CHIP_HELPER_WT_ROM, paddr);
            break;

        default:
            unifi_error(card->ospriv, "Bad address space %d in generic pointer 0x%08lX (helper=0x%x)\n",
                        space, generic_addr, card->helper);
            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    return r;
} /* set_page() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_set_proc_select
 *
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      select          Which XAP core to select
 *
 *  Returns:
 *      0 on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_set_proc_select(card_t *card, enum unifi_dbg_processors_select select)
{
    CsrResult r;

    /* Verify the the select value is allowed. */
    switch (select)
    {
        case UNIFI_PROC_MAC:
        case UNIFI_PROC_PHY:
        case UNIFI_PROC_BOTH:
            break;


        default:
            return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    if (card->proc_select != (u32)select)
    {
        r = unifi_write_direct16(card,
                                 ChipHelper_DBG_HOST_PROC_SELECT(card->helper) * 2,
                                 (u8)select);
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            unifi_error(card->ospriv, "Failed to write to Proc Select register\n");
            return r;
        }

        card->proc_select = (u32)select;
    }

    return CSR_RESULT_SUCCESS;
}


/*
 * ---------------------------------------------------------------------------
 * unifi_read_8_or_16
 *
 * Performs a byte read of the given address in shared data memory.
 * Set up the shared data memory page register as required.
 *
 * Arguments:
 * card Pointer to card structure.
 * unifi_addr UniFi shared-data-memory address to access.
 * pdata Pointer to a byte variable for the value read.
 *
 * Returns:
 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
 * CSR_RESULT_FAILURE an SDIO error occurred
 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_read_8_or_16(card_t *card, u32 unifi_addr, u8 *pdata)
{
    u32 sdio_addr;
    CsrResult r;
#ifdef CSR_WIFI_TRANSPORT_CSPI
    u16 w;
#endif

    r = set_page(card, unifi_addr, &sdio_addr);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
    card->cmd_prof.cmd52_r8or16_count++;
#endif
#ifdef CSR_WIFI_TRANSPORT_CSPI
    r = retrying_read16(card, card->function, sdio_addr, &w);
    *pdata = (u8)(w & 0xFF);
    return r;
#else
    return retrying_read8(card, card->function, sdio_addr, pdata);
#endif
} /* unifi_read_8_or_16() */


/*
 * ---------------------------------------------------------------------------
 * unifi_write_8_or_16
 *
 * Performs a byte write of the given address in shared data memory.
 * Set up the shared data memory page register as required.
 *
 * Arguments:
 * card Pointer to card context struct.
 * unifi_addr UniFi shared-data-memory address to access.
 * data Value to write.
 *
 * Returns:
 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
 * CSR_RESULT_FAILURE an SDIO error occurred
 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
 *
 * Notes:
 * Beware using unifi_write8() because byte writes are not safe on UniFi.
 * Writes to odd bytes are cached, writes to even bytes perform a 16-bit
 * write with the previously cached odd byte.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_write_8_or_16(card_t *card, u32 unifi_addr, u8 data)
{
    u32 sdio_addr;
    CsrResult r;
#ifdef CSR_WIFI_TRANSPORT_CSPI
    u16 w;
#endif

    r = set_page(card, unifi_addr, &sdio_addr);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    if (sdio_addr & 1)
    {
        unifi_warning(card->ospriv,
                      "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
                      sdio_addr);
    }

#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
    card->cmd_prof.cmd52_w8or16_count++;
#endif
#ifdef CSR_WIFI_TRANSPORT_CSPI
    w = data;
    return retrying_write16(card, card->function, sdio_addr, w);
#else
    return retrying_write8(card, card->function, sdio_addr, data);
#endif
} /* unifi_write_8_or_16() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_card_read16
 *
 *      Performs a 16-bit read of the given address in shared data memory.
 *      Set up the shared data memory page register as required.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      unifi_addr      UniFi shared-data-memory address to access.
 *      pdata           Pointer to a 16-bit int variable for the value read.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_card_read16(card_t *card, u32 unifi_addr, u16 *pdata)
{
    u32 sdio_addr;
    CsrResult r;

    r = set_page(card, unifi_addr, &sdio_addr);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
    card->cmd_prof.cmd52_r16_count++;
#endif
    return unifi_read_direct16(card, sdio_addr, pdata);
} /* unifi_card_read16() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_card_write16
 *
 *      Performs a 16-bit write of the given address in shared data memory.
 *      Set up the shared data memory page register as required.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      unifi_addr      UniFi shared-data-memory address to access.
 *      pdata           Pointer to a byte variable for the value write.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_card_write16(card_t *card, u32 unifi_addr, u16 data)
{
    u32 sdio_addr;
    CsrResult r;

    r = set_page(card, unifi_addr, &sdio_addr);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
    card->cmd_prof.cmd52_w16_count++;
#endif
    return unifi_write_direct16(card, sdio_addr, data);
} /* unifi_card_write16() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_read32
 *
 *      Performs a 32-bit read of the given address in shared data memory.
 *      Set up the shared data memory page register as required.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      unifi_addr      UniFi shared-data-memory address to access.
 *      pdata           Pointer to a int variable for the value read.
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_read32(card_t *card, u32 unifi_addr, u32 *pdata)
{
    u32 sdio_addr;
    CsrResult r;

    r = set_page(card, unifi_addr, &sdio_addr);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
    card->cmd_prof.cmd52_r32_count++;
#endif
    return unifi_read_direct32(card, sdio_addr, pdata);
} /* unifi_read32() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_card_readn
 *  unifi_readnz
 *
 *      Read multiple 8-bit values from the UniFi SDIO interface.
 *      This function interprets the address as a GenericPointer as
 *      defined in the UniFi Host Interface Protocol Specification.
 *      The readnz version of this function will stop when it reads a
 *      zero octet.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      unifi_addr      UniFi shared-data-memory address to access.
 *      pdata           Pointer to which to write data.
 *      len             Number of bytes to read
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE  a bad generic pointer was specified
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_readn_match(card_t *card, u32 unifi_addr, void *pdata, u16 len, s8 match)
{
    u32 sdio_addr;
    CsrResult r;
    u32 num;

    r = set_page(card, unifi_addr, &sdio_addr);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    r = unifi_read_directn_match(card, sdio_addr, pdata, len, match, &num);
    return r;
} /* unifi_readn_match() */


CsrResult unifi_card_readn(card_t *card, u32 unifi_addr, void *pdata, u16 len)
{
    return unifi_readn_match(card, unifi_addr, pdata, len, -1);
} /* unifi_card_readn() */


CsrResult unifi_readnz(card_t *card, u32 unifi_addr, void *pdata, u16 len)
{
    return unifi_readn_match(card, unifi_addr, pdata, len, 0);
} /* unifi_readnz() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_read_shared_count
 *
 *      Read signal count locations, checking for an SDIO error.  The
 *      signal count locations only contain a valid number if the
 *      highest bit isn't set.
 *
 *  Arguments:
 *      card            Pointer to card context structure.
 *      addr            Shared-memory address to read.
 *
 *  Returns:
 *      Value read from memory (0-127) or -1 on error
 * ---------------------------------------------------------------------------
 */
s32 unifi_read_shared_count(card_t *card, u32 addr)
{
    u8 b;
    /* I've increased this count, because I have seen cases where
     * there were three reads in a row with the top bit set.  I'm not
     * sure why this might have happened, but I can't see a problem
     * with increasing this limit.  It's better to take a while to
     * recover than to fail. */
#define SHARED_READ_RETRY_LIMIT 10
    s32 i;

    /*
     * Get the to-host-signals-written count.
     * The top-bit will be set if the firmware was in the process of
     * changing the value, in which case we read again.
     */
    /* Limit the number of repeats so we don't freeze */
    for (i = 0; i < SHARED_READ_RETRY_LIMIT; i++)
    {
        CsrResult r;
        r = unifi_read_8_or_16(card, addr, &b);
        if (r != CSR_RESULT_SUCCESS)
        {
            return -1;
        }
        if (!(b & 0x80))
        {
            /* There is a chance that the MSB may have contained invalid data
             * (overflow) at the time it was read. Therefore mask off the MSB.
             * This avoids a race between driver read and firmware write of the
             * word, the value we need is in the lower 8 bits anway.
             */
            return (s32)(b & 0xff);
        }
    }

    return -1;                  /* this function has changed in WMM mods */
} /* unifi_read_shared_count() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_writen
 *
 *      Write multiple 8-bit values to the UniFi SDIO interface using CMD52
 *      This function interprets the address as a GenericPointer as
 *      defined in the UniFi Host Interface Protocol Specification.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      unifi_addr      UniFi shared-data-memory address to access.
 *      pdata           Pointer to which to write data.
 *      len             Number of bytes to write
 *
 *  Returns:
 *      0 on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *      CSR_WIFI_HIP_RESULT_INVALID_VALUE    an odd length or length too big.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_writen(card_t *card, u32 unifi_addr, void *pdata, u16 len)
{
    u32 sdio_addr;
    CsrResult r;

    r = set_page(card, unifi_addr, &sdio_addr);
    if (r != CSR_RESULT_SUCCESS)
    {
        return r;
    }

    return unifi_write_directn(card, sdio_addr, pdata, len);
} /* unifi_writen() */


static CsrResult csr_sdio_block_rw(card_t *card, s16 funcnum,
                                   u32 addr, u8 *pdata,
                                   u16 count, s16 dir_is_write)
{
    CsrResult csrResult;

    if (dir_is_write == UNIFI_SDIO_READ)
    {
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        unifi_debug_log_to_buf("r@%02X#%X=", addr, count);
#endif
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
        unifi_debug_log_to_buf("R");
#endif
        csrResult = CsrSdioRead(card->sdio_if, addr, pdata, count);
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
        unifi_debug_log_to_buf("<");
#endif
    }
    else
    {
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
        unifi_debug_log_to_buf("w@%02X#%X=", addr, count);
        unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count);
#endif
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
        unifi_debug_log_to_buf("W");
#endif
        csrResult = CsrSdioWrite(card->sdio_if, addr, pdata, count);
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
        unifi_debug_log_to_buf(">");
#endif
    }
#ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
    card->cmd_prof.cmd53_count++;
#endif
#if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
    if (csrResult != CSR_RESULT_SUCCESS)
    {
        unifi_debug_log_to_buf("error=%X", csrResult);
    }
    else if (dir_is_write == UNIFI_SDIO_READ)
    {
        unifi_debug_hex_to_buf(pdata, count > CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH : count);
    }
    unifi_debug_string_to_buf("\n");
#endif
    return csrResult;  /* CSR SDIO (not HIP) error code */
}


/*
 * ---------------------------------------------------------------------------
 *  unifi_bulk_rw
 *
 *      Transfer bulk data to or from the UniFi SDIO interface.
 *      This function is used to read or write signals and bulk data.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      handle          Value to put in the Register Address field of the CMD53 req.
 *      data            Pointer to data to write.
 *      direction       One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
 *
 *  Returns:
 *      CSR_RESULT_SUCCESS on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *
 *  Notes:
 *      This function uses SDIO CMD53, which is the block transfer mode.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_bulk_rw(card_t *card, u32 handle, void *pdata,
                        u32 len, s16 direction)
{
#define CMD53_RETRIES 3
    /*
     * Ideally instead of sleeping, we want to busy wait.
     * Currently there is no framework API to do this. When it becomes available,
     * we can use it to busy wait using usecs
     */
#define REWIND_RETRIES          15    /* when REWIND_DELAY==1msec, or 250 when REWIND_DELAY==50usecs */
#define REWIND_POLLING_RETRIES  5
#define REWIND_DELAY            1     /* msec or 50usecs */
    CsrResult csrResult;              /* SDIO error code */
    CsrResult r = CSR_RESULT_SUCCESS; /* HIP error code */
    s16 retries = CMD53_RETRIES;
    s16 stat_retries;
    u8 stat;
    s16 dump_read;
#ifdef UNIFI_DEBUG
    u8 *pdata_lsb = ((u8 *)&pdata) + card->lsb;
#endif
#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
    static s16 fake_error;
#endif

    dump_read = 0;
#ifdef UNIFI_DEBUG
    if (*pdata_lsb & 1)
    {
        unifi_notice(card->ospriv, "CD53 request on a unaligned buffer (addr: 0x%X) dir %s-Host\n",
                     pdata, (direction == UNIFI_SDIO_READ)?"To" : "From");
        if (direction == UNIFI_SDIO_WRITE)
        {
            dump(pdata, (u16)len);
        }
        else
        {
            dump_read = 1;
        }
    }
#endif

    /* Defensive checks */
    if (!pdata)
    {
        unifi_error(card->ospriv, "Null pdata for unifi_bulk_rw() len: %d\n", len);
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }
    if ((len & 1) || (len > 0xffff))
    {
        unifi_error(card->ospriv, "Impossible CMD53 length requested: %d\n", len);
        return CSR_WIFI_HIP_RESULT_INVALID_VALUE;
    }

    while (1)
    {
        csrResult = csr_sdio_block_rw(card, card->function, handle,
                                      (u8 *)pdata, (u16)len,
                                      direction);
        if (csrResult == CSR_SDIO_RESULT_NO_DEVICE)
        {
            return CSR_WIFI_HIP_RESULT_NO_DEVICE;
        }
#ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
        if (++fake_error > 100)
        {
            fake_error = 90;
            unifi_warning(card->ospriv, "Faking a CMD53 error,\n");
            if (csrResult == CSR_RESULT_SUCCESS)
            {
                csrResult = CSR_RESULT_FAILURE;
            }
        }
#endif
        if (csrResult == CSR_RESULT_SUCCESS)
        {
            if (dump_read)
            {
                dump(pdata, (u16)len);
            }
            break;
        }

        /*
         * At this point the SDIO driver should have written the I/O Abort
         * register to notify UniFi that the command has failed.
         * UniFi-1 and UniFi-2 (not UF6xxx) use the same register to store the
         * Deep Sleep State. This means we have to restore the Deep Sleep
         * State (AWAKE in any case since we can not perform a CD53 in any other
         * state) by rewriting the I/O Abort register to its previous value.
         */
        if (card->chip_id <= SDIO_CARD_ID_UNIFI_2)
        {
            (void)unifi_set_host_state(card, UNIFI_HOST_STATE_AWAKE);
        }

        /* If csr_sdio_block_rw() failed in a non-retryable way, or retries exhausted
         * then stop retrying
         */
        if (!retryable_sdio_error(csrResult))
        {
            unifi_error(card->ospriv, "Fatal error in a CMD53 transfer\n");
            break;
        }

        /*
         * These happen from time to time, try again
         */
        if (--retries == 0)
        {
            break;
        }

        unifi_trace(card->ospriv, UDBG4,
                    "Error in a CMD53 transfer, retrying (h:%d,l:%u)...\n",
                    (s16)handle & 0xff, len);

        /* The transfer failed, rewind and try again */
        r = unifi_write_8_or_16(card, card->sdio_ctrl_addr + 8,
                                (u8)(handle & 0xff));
        if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
        {
            return r;
        }
        if (r != CSR_RESULT_SUCCESS)
        {
            /*
             * If we can't even do CMD52 (register read/write) then
             * stop here.
             */
            unifi_error(card->ospriv, "Failed to write REWIND cmd\n");
            return r;
        }

        /* Signal the UniFi to look for the rewind request. */
        r = CardGenInt(card);
        if (r != CSR_RESULT_SUCCESS)
        {
            return r;
        }

        /* Wait for UniFi to acknowledge the rewind */
        stat_retries = REWIND_RETRIES;
        while (1)
        {
            r = unifi_read_8_or_16(card, card->sdio_ctrl_addr + 8, &stat);
            if (r == CSR_WIFI_HIP_RESULT_NO_DEVICE)
            {
                return r;
            }
            if (r != CSR_RESULT_SUCCESS)
            {
                unifi_error(card->ospriv, "Failed to read REWIND status\n");
                return CSR_RESULT_FAILURE;
            }

            if (stat == 0)
            {
                break;
            }
            if (--stat_retries == 0)
            {
                unifi_error(card->ospriv, "Timeout waiting for REWIND ready\n");
                return CSR_RESULT_FAILURE;
            }

            /* Poll for the ack a few times */
            if (stat_retries < REWIND_RETRIES - REWIND_POLLING_RETRIES)
            {
                CsrThreadSleep(REWIND_DELAY);
            }
        }
    }

    /* The call to csr_sdio_block_rw() still failed after retrying */
    if (csrResult != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Block %s failed after %d retries\n",
                    (direction == UNIFI_SDIO_READ)?"read" : "write",
                    CMD53_RETRIES - retries);
        /* Report any SDIO error as a general i/o error */
        return CSR_RESULT_FAILURE;
    }

    /* Collect some stats */
    if (direction == UNIFI_SDIO_READ)
    {
        card->sdio_bytes_read += len;
    }
    else
    {
        card->sdio_bytes_written += len;
    }

    return CSR_RESULT_SUCCESS;
} /* unifi_bulk_rw() */


/*
 * ---------------------------------------------------------------------------
 *  unifi_bulk_rw_noretry
 *
 *      Transfer bulk data to or from the UniFi SDIO interface.
 *      This function is used to read or write signals and bulk data.
 *
 *  Arguments:
 *      card            Pointer to card structure.
 *      handle          Value to put in the Register Address field of
 *                      the CMD53 req.
 *      data            Pointer to data to write.
 *      direction       One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
 *
 *  Returns:
 *      0 on success, non-zero error code on error:
 *      CSR_WIFI_HIP_RESULT_NO_DEVICE  card was ejected
 *      CSR_RESULT_FAILURE     an SDIO error occurred
 *
 *  Notes:
 *      This function uses SDIO CMD53, which is the block transfer mode.
 * ---------------------------------------------------------------------------
 */
CsrResult unifi_bulk_rw_noretry(card_t *card, u32 handle, void *pdata,
                                u32 len, s16 direction)
{
    CsrResult csrResult;

    csrResult = csr_sdio_block_rw(card, card->function, handle,
                                  (u8 *)pdata, (u16)len, direction);
    if (csrResult != CSR_RESULT_SUCCESS)
    {
        unifi_error(card->ospriv, "Block %s failed\n",
                    (direction == UNIFI_SDIO_READ)?"read" : "write");
        return csrResult;
    }

    return CSR_RESULT_SUCCESS;
} /* unifi_bulk_rw_noretry() */


