aboutsummaryrefslogtreecommitdiff
path: root/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-07-20 15:42:38 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2013-07-20 15:42:38 -0700
commitf6a0d9d585699d4ab634cfd26fa9ce9c7cb864a1 (patch)
tree31a9a5f572f97c869b17396be694208f30db1619 /drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c
parent36231d255b8df9cb4698e9a3902c16067d5c1398 (diff)
parent78077256bc08348d587e318957ceb41fe4d4afae (diff)
Merge tag 'staging-3.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull staging tree fixes from Greg KH: "Here are a few iio driver fixes for 3.11-rc2. They are still spread across drivers/iio and drivers/staging/iio so they are coming in through this tree. I've also removed the drivers/staging/csr/ driver as the developers who originally sent it to me have moved on to other companies, and CSR still will not send us the specs for the device, making the driver pretty much obsolete and impossible to fix up. Deleting it now prevents people from sending in lots of tiny codingsyle fixes that will never go anywhere. It also helps to offset the large lustre filesystem merge that happened in 3.11-rc1 in the overall 3.11.0 diffstat. :)" * tag 'staging-3.11-rc2' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: staging: csr: remove driver iio: lps331ap: Fix wrong in_pressure_scale output value iio staging: fix lis3l02dq, read error handling staging:iio:ad7291: add missing .driver_module to struct iio_info iio: ti_am335x_adc: add missing .driver_module to struct iio_info iio: mxs-lradc: Remove useless check in read_raw iio: mxs-lradc: Fix misuse of iio->trig iio: inkern: fix iio_convert_raw_to_processed_unlocked iio: Fix iio_channel_has_info iio:trigger: device_unregister->device_del to avoid double free iio: dac: ad7303: fix error return code in ad7303_probe()
Diffstat (limited to 'drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c')
-rw-r--r--drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c1713
1 files changed, 0 insertions, 1713 deletions
diff --git a/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c b/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c
deleted file mode 100644
index 17867f60df1..00000000000
--- a/drivers/staging/csr/csr_wifi_hip_card_sdio_mem.c
+++ /dev/null
@@ -1,1713 +0,0 @@
-/*****************************************************************************
-
- (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() */
-
-