1 /*****************************************************************************
3 (c) Cambridge Silicon Radio Limited 2012
4 All rights reserved and confidential information of CSR
6 Refer to LICENSE.txt included with this source for details
9 *****************************************************************************/
12 * ---------------------------------------------------------------------------
13 * FILE: csr_wifi_hip_card_sdio_mem.c
15 * PURPOSE: Implementation of the Card API for SDIO.
17 * ---------------------------------------------------------------------------
19 #include "csr_wifi_hip_unifi.h"
20 #include "csr_wifi_hip_card.h"
22 #define SDIO_RETRIES 3
23 #define CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH 16
26 #define retryable_sdio_error(_csrResult) (((_csrResult) == CSR_SDIO_RESULT_CRC_ERROR) || ((_csrResult) == CSR_SDIO_RESULT_TIMEOUT))
30 * ---------------------------------------------------------------------------
34 * These functions provide the first level of retry for SDIO operations.
35 * If an SDIO command fails for reason of a response timeout or CRC
36 * error, it is retried immediately. If three attempts fail we report a
38 * If the command failed for any other reason, the failure is reported
42 * card Pointer to card structure.
43 * funcnum The SDIO function to access.
44 * Function 0 is the Card Configuration Register space,
45 * function 1/2 is the UniFi register space.
46 * addr Address to access
47 * pdata Pointer in which to return the value read.
48 * data Value to write.
51 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
52 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
53 * CSR_RESULT_FAILURE an SDIO error occurred
54 * ---------------------------------------------------------------------------
56 static CsrResult
retrying_read8(card_t
*card
, s16 funcnum
, u32 addr
, u8
*pdata
)
58 CsrSdioFunction
*sdio
= card
->sdio_if
;
59 CsrResult r
= CSR_RESULT_SUCCESS
;
61 CsrResult csrResult
= CSR_RESULT_SUCCESS
;
64 while (retries
++ < SDIO_RETRIES
)
68 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
69 unifi_debug_log_to_buf("r0@%02X", addr
);
71 csrResult
= CsrSdioF0Read8(sdio
, addr
, pdata
);
75 #ifdef CSR_WIFI_TRANSPORT_CSPI
76 unifi_error(card
->ospriv
,
77 "retrying_read_f0_8: F1 8-bit reads are not allowed.\n");
78 return CSR_RESULT_FAILURE
;
80 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
81 unifi_debug_log_to_buf("r@%02X", addr
);
83 csrResult
= CsrSdioRead8(sdio
, addr
, pdata
);
86 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
87 if (csrResult
!= CSR_RESULT_SUCCESS
)
89 unifi_debug_log_to_buf("error=%X\n", csrResult
);
93 unifi_debug_log_to_buf("=%X\n", *pdata
);
96 if (csrResult
== CSR_SDIO_RESULT_NO_DEVICE
)
98 return CSR_WIFI_HIP_RESULT_NO_DEVICE
;
101 * Try again for retryable (CRC or TIMEOUT) errors,
102 * break on success or fatal error
104 if (!retryable_sdio_error(csrResult
))
106 #ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
107 card
->cmd_prof
.cmd52_count
++;
111 unifi_trace(card
->ospriv
, UDBG2
, "retryable SDIO error reading F%d 0x%lX\n", funcnum
, addr
);
114 if ((csrResult
== CSR_RESULT_SUCCESS
) && (retries
> 1))
116 unifi_warning(card
->ospriv
, "Read succeeded after %d attempts\n", retries
);
119 if (csrResult
!= CSR_RESULT_SUCCESS
)
121 unifi_error(card
->ospriv
, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
123 /* Report any SDIO error as a general i/o error */
124 r
= CSR_RESULT_FAILURE
;
128 } /* retrying_read8() */
131 static CsrResult
retrying_write8(card_t
*card
, s16 funcnum
, u32 addr
, u8 data
)
133 CsrSdioFunction
*sdio
= card
->sdio_if
;
134 CsrResult r
= CSR_RESULT_SUCCESS
;
136 CsrResult csrResult
= CSR_RESULT_SUCCESS
;
139 while (retries
++ < SDIO_RETRIES
)
143 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
144 unifi_debug_log_to_buf("w0@%02X=%X", addr
, data
);
146 csrResult
= CsrSdioF0Write8(sdio
, addr
, data
);
150 #ifdef CSR_WIFI_TRANSPORT_CSPI
151 unifi_error(card
->ospriv
,
152 "retrying_write_f0_8: F1 8-bit writes are not allowed.\n");
153 return CSR_RESULT_FAILURE
;
155 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
156 unifi_debug_log_to_buf("w@%02X=%X", addr
, data
);
158 csrResult
= CsrSdioWrite8(sdio
, addr
, data
);
161 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
162 if (csrResult
!= CSR_RESULT_SUCCESS
)
164 unifi_debug_log_to_buf(",error=%X", csrResult
);
166 unifi_debug_string_to_buf("\n");
168 if (csrResult
== CSR_SDIO_RESULT_NO_DEVICE
)
170 return CSR_WIFI_HIP_RESULT_NO_DEVICE
;
173 * Try again for retryable (CRC or TIMEOUT) errors,
174 * break on success or fatal error
176 if (!retryable_sdio_error(csrResult
))
178 #ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
179 card
->cmd_prof
.cmd52_count
++;
183 unifi_trace(card
->ospriv
, UDBG2
, "retryable SDIO error writing %02X to F%d 0x%lX\n",
184 data
, funcnum
, addr
);
187 if ((csrResult
== CSR_RESULT_SUCCESS
) && (retries
> 1))
189 unifi_warning(card
->ospriv
, "Write succeeded after %d attempts\n", retries
);
192 if (csrResult
!= CSR_RESULT_SUCCESS
)
194 unifi_error(card
->ospriv
, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
196 /* Report any SDIO error as a general i/o error */
197 r
= CSR_RESULT_FAILURE
;
201 } /* retrying_write8() */
204 static CsrResult
retrying_read16(card_t
*card
, s16 funcnum
,
205 u32 addr
, u16
*pdata
)
207 CsrSdioFunction
*sdio
= card
->sdio_if
;
208 CsrResult r
= CSR_RESULT_SUCCESS
;
210 CsrResult csrResult
= CSR_RESULT_SUCCESS
;
213 while (retries
++ < SDIO_RETRIES
)
215 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
216 unifi_debug_log_to_buf("r@%02X", addr
);
218 csrResult
= CsrSdioRead16(sdio
, addr
, pdata
);
219 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
220 if (csrResult
!= CSR_RESULT_SUCCESS
)
222 unifi_debug_log_to_buf("error=%X\n", csrResult
);
226 unifi_debug_log_to_buf("=%X\n", *pdata
);
229 if (csrResult
== CSR_SDIO_RESULT_NO_DEVICE
)
231 return CSR_WIFI_HIP_RESULT_NO_DEVICE
;
235 * Try again for retryable (CRC or TIMEOUT) errors,
236 * break on success or fatal error
238 if (!retryable_sdio_error(csrResult
))
240 #ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
241 card
->cmd_prof
.cmd52_count
++;
245 unifi_trace(card
->ospriv
, UDBG2
, "retryable SDIO error reading F%d 0x%lX\n", funcnum
, addr
);
248 if ((csrResult
== CSR_RESULT_SUCCESS
) && (retries
> 1))
250 unifi_warning(card
->ospriv
, "Read succeeded after %d attempts\n", retries
);
253 if (csrResult
!= CSR_RESULT_SUCCESS
)
255 unifi_error(card
->ospriv
, "Failed to read from UniFi (addr 0x%lX) after %d tries\n",
257 /* Report any SDIO error as a general i/o error */
258 r
= CSR_RESULT_FAILURE
;
262 } /* retrying_read16() */
265 static CsrResult
retrying_write16(card_t
*card
, s16 funcnum
,
268 CsrSdioFunction
*sdio
= card
->sdio_if
;
269 CsrResult r
= CSR_RESULT_SUCCESS
;
271 CsrResult csrResult
= CSR_RESULT_SUCCESS
;
274 while (retries
++ < SDIO_RETRIES
)
276 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
277 unifi_debug_log_to_buf("w@%02X=%X", addr
, data
);
279 csrResult
= CsrSdioWrite16(sdio
, addr
, data
);
280 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
281 if (csrResult
!= CSR_RESULT_SUCCESS
)
283 unifi_debug_log_to_buf(",error=%X", csrResult
);
285 unifi_debug_string_to_buf("\n");
287 if (csrResult
== CSR_SDIO_RESULT_NO_DEVICE
)
289 return CSR_WIFI_HIP_RESULT_NO_DEVICE
;
293 * Try again for retryable (CRC or TIMEOUT) errors,
294 * break on success or fatal error
296 if (!retryable_sdio_error(csrResult
))
298 #ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
299 card
->cmd_prof
.cmd52_count
++;
303 unifi_trace(card
->ospriv
, UDBG2
, "retryable SDIO error writing %02X to F%d 0x%lX\n",
304 data
, funcnum
, addr
);
307 if ((csrResult
== CSR_RESULT_SUCCESS
) && (retries
> 1))
309 unifi_warning(card
->ospriv
, "Write succeeded after %d attempts\n", retries
);
312 if (csrResult
!= CSR_RESULT_SUCCESS
)
314 unifi_error(card
->ospriv
, "Failed to write to UniFi (addr 0x%lX) after %d tries\n",
316 /* Report any SDIO error as a general i/o error */
317 r
= CSR_RESULT_FAILURE
;
321 } /* retrying_write16() */
325 * ---------------------------------------------------------------------------
328 * Reads a byte value from the CCCR (func 0) area of UniFi.
331 * card Pointer to card structure.
332 * addr Address to read from
333 * pdata Pointer in which to store the read value.
336 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
337 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
338 * CSR_RESULT_FAILURE an SDIO error occurred
339 * ---------------------------------------------------------------------------
341 CsrResult
sdio_read_f0(card_t
*card
, u32 addr
, u8
*pdata
)
343 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
344 card
->cmd_prof
.cmd52_f0_r_count
++;
346 return retrying_read8(card
, 0, addr
, pdata
);
347 } /* sdio_read_f0() */
351 * ---------------------------------------------------------------------------
354 * Writes a byte value to the CCCR (func 0) area of UniFi.
357 * card Pointer to card structure.
358 * addr Address to read from
359 * data Data value to write.
362 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
363 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
364 * CSR_RESULT_FAILURE an SDIO error occurred
365 * ---------------------------------------------------------------------------
367 CsrResult
sdio_write_f0(card_t
*card
, u32 addr
, u8 data
)
369 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
370 card
->cmd_prof
.cmd52_f0_w_count
++;
372 return retrying_write8(card
, 0, addr
, data
);
373 } /* sdio_write_f0() */
377 * ---------------------------------------------------------------------------
378 * unifi_read_direct_8_or_16
380 * Read a 8-bit value from the UniFi SDIO interface.
383 * card Pointer to card structure.
384 * addr Address to read from
385 * pdata Pointer in which to return data.
388 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
389 * ---------------------------------------------------------------------------
391 CsrResult
unifi_read_direct_8_or_16(card_t
*card
, u32 addr
, u8
*pdata
)
393 #ifdef CSR_WIFI_TRANSPORT_CSPI
397 r
= retrying_read16(card
, card
->function
, addr
, &w
);
398 *pdata
= (u8
)(w
& 0xFF);
401 return retrying_read8(card
, card
->function
, addr
, pdata
);
403 } /* unifi_read_direct_8_or_16() */
407 * ---------------------------------------------------------------------------
408 * unifi_write_direct_8_or_16
410 * Write a byte value to the UniFi SDIO interface.
413 * card Pointer to card structure.
414 * addr Address to write to
415 * data Value to write.
418 * CSR_RESULT_SUCCESS on success, non-zero error code on error
421 * If 8-bit write is used, the even address *must* be written second.
422 * This is because writes to odd bytes are cached and not committed
423 * to memory until the preceding even address is written.
424 * ---------------------------------------------------------------------------
426 CsrResult
unifi_write_direct_8_or_16(card_t
*card
, u32 addr
, u8 data
)
430 unifi_warning(card
->ospriv
,
431 "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
435 #ifdef CSR_WIFI_TRANSPORT_CSPI
436 return retrying_write16(card
, card
->function
, addr
, (u16
)data
);
438 return retrying_write8(card
, card
->function
, addr
, data
);
440 } /* unifi_write_direct_8_or_16() */
444 * ---------------------------------------------------------------------------
445 * unifi_read_direct16
447 * Read a 16-bit value from the UniFi SDIO interface.
450 * card Pointer to card structure.
451 * addr Address to read from
452 * pdata Pointer in which to return data.
455 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
456 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
457 * CSR_RESULT_FAILURE an SDIO error occurred
460 * The even address *must* be read first. This is because reads from
461 * odd bytes are cached and read from memory when the preceding
462 * even address is read.
463 * ---------------------------------------------------------------------------
465 CsrResult
unifi_read_direct16(card_t
*card
, u32 addr
, u16
*pdata
)
467 return retrying_read16(card
, card
->function
, addr
, pdata
);
468 } /* unifi_read_direct16() */
472 * ---------------------------------------------------------------------------
473 * unifi_write_direct16
475 * Write a 16-bit value to the UniFi SDIO interface.
478 * card Pointer to card structure.
479 * addr Address to write to
480 * data Value to write.
483 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
484 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
485 * CSR_RESULT_FAILURE an SDIO error occurred
488 * The even address *must* be written second. This is because writes to
489 * odd bytes are cached and not committed to memory until the preceding
490 * even address is written.
491 * ---------------------------------------------------------------------------
493 CsrResult
unifi_write_direct16(card_t
*card
, u32 addr
, u16 data
)
495 return retrying_write16(card
, card
->function
, addr
, data
);
496 } /* unifi_write_direct16() */
500 * ---------------------------------------------------------------------------
501 * unifi_read_direct32
503 * Read a 32-bit value from the UniFi SDIO interface.
506 * card Pointer to card structure.
507 * addr Address to read from
508 * pdata Pointer in which to return data.
511 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
512 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
513 * CSR_RESULT_FAILURE an SDIO error occurred
514 * ---------------------------------------------------------------------------
516 CsrResult
unifi_read_direct32(card_t
*card
, u32 addr
, u32
*pdata
)
521 r
= retrying_read16(card
, card
->function
, addr
, &w0
);
522 if (r
!= CSR_RESULT_SUCCESS
)
527 r
= retrying_read16(card
, card
->function
, addr
+ 2, &w1
);
528 if (r
!= CSR_RESULT_SUCCESS
)
533 *pdata
= ((u32
)w1
<< 16) | (u32
)w0
;
535 return CSR_RESULT_SUCCESS
;
536 } /* unifi_read_direct32() */
540 * ---------------------------------------------------------------------------
541 * unifi_read_directn_match
543 * Read multiple 8-bit values from the UniFi SDIO interface,
544 * stopping when either we have read 'len' bytes or we have read
545 * a octet equal to 'match'. If 'match' is not a valid octet
546 * then this function is the same as 'unifi_read_directn'.
549 * card Pointer to card structure.
550 * addr Start address to read from.
551 * pdata Pointer to which to write data.
552 * len Maximum umber of bytes to read
553 * match The value to stop reading at.
554 * num Pointer to buffer to write number of bytes read
557 * number of octets read on success, negative error code on error:
558 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
559 * CSR_RESULT_FAILURE an SDIO error occurred
562 * The even address *must* be read first. This is because reads from
563 * odd bytes are cached and read from memory when the preceding
564 * even address is read.
565 * ---------------------------------------------------------------------------
567 static CsrResult
unifi_read_directn_match(card_t
*card
, u32 addr
, void *pdata
, u16 len
, s8 m
, u32
*num
)
577 for (i
= 0; i
< len
; i
+= 2)
579 r
= retrying_read16(card
, card
->function
, addr
, &w
);
580 if (r
!= CSR_RESULT_SUCCESS
)
585 *cptr
++ = ((u8
)w
& 0xFF);
586 if ((m
>= 0) && (((s8
)w
& 0xFF) == m
))
593 /* The len is odd. Ignore the last high byte */
597 *cptr
++ = ((u8
)(w
>> 8) & 0xFF);
598 if ((m
>= 0) && (((s8
)(w
>> 8) & 0xFF) == m
))
606 *num
= (s32
)(cptr
- (u8
*)pdata
);
607 return CSR_RESULT_SUCCESS
;
612 * ---------------------------------------------------------------------------
615 * Read multiple 8-bit values from the UniFi SDIO interface.
618 * card Pointer to card structure.
619 * addr Start address to read from.
620 * pdata Pointer to which to write data.
621 * len Number of bytes to read
624 * 0 on success, non-zero error code on error:
625 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
626 * CSR_RESULT_FAILURE an SDIO error occurred
629 * The even address *must* be read first. This is because reads from
630 * odd bytes are cached and read from memory when the preceding
631 * even address is read.
632 * ---------------------------------------------------------------------------
634 CsrResult
unifi_read_directn(card_t
*card
, u32 addr
, void *pdata
, u16 len
)
638 return unifi_read_directn_match(card
, addr
, pdata
, len
, -1, &num
);
639 } /* unifi_read_directn() */
643 * ---------------------------------------------------------------------------
644 * unifi_write_directn
646 * Write multiple 8-bit values to the UniFi SDIO interface.
649 * card Pointer to card structure.
650 * addr Start address to write to.
651 * pdata Source data pointer.
652 * len Number of bytes to write, must be even.
655 * 0 on success, non-zero error code on error:
656 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
657 * CSR_RESULT_FAILURE an SDIO error occurred
660 * The UniFi has a peculiar 16-bit bus architecture. Writes are only
661 * committed to memory when an even address is accessed. Writes to
662 * odd addresses are cached and only committed if the next write is
663 * to the preceding address.
664 * This means we must write data as pairs of bytes in reverse order.
665 * ---------------------------------------------------------------------------
667 CsrResult
unifi_write_directn(card_t
*card
, u32 addr
, void *pdata
, u16 len
)
674 signed_len
= (s16
)len
;
675 while (signed_len
> 0)
677 /* This is UniFi-1 specific code. CSPI not supported so 8-bit write allowed */
678 r
= retrying_write16(card
, card
->function
, addr
, *cptr
);
679 if (r
!= CSR_RESULT_SUCCESS
)
689 return CSR_RESULT_SUCCESS
;
690 } /* unifi_write_directn() */
694 * ---------------------------------------------------------------------------
698 * Set up the page register for the shared data memory window or program
702 * card Pointer to card structure.
703 * dmem_addr UniFi shared-data-memory address to access.
704 * pmem_addr UniFi program memory address to access. This includes
705 * External FLASH memory at 0x000000
706 * Processor program memory at 0x200000
707 * External SRAM at memory 0x400000
708 * paddr Location to write an SDIO address (24-bit) for
709 * use in a unifi_read_direct or unifi_write_direct call.
712 * CSR_RESULT_SUCCESS on success
713 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
714 * CSR_RESULT_FAILURE an SDIO error occurred
715 * ---------------------------------------------------------------------------
717 static CsrResult
set_dmem_page(card_t
*card
, u32 dmem_addr
, u32
*paddr
)
725 if (!ChipHelper_DecodeWindow(card
->helper
,
726 CHIP_HELPER_WINDOW_3
,
727 CHIP_HELPER_WT_SHARED
,
731 unifi_error(card
->ospriv
, "Failed to decode SHARED_DMEM_PAGE %08lx\n", dmem_addr
);
732 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
735 if (page
!= card
->dmem_page
)
737 unifi_trace(card
->ospriv
, UDBG6
, "setting dmem page=0x%X, addr=0x%lX\n", page
, addr
);
739 /* change page register */
740 r
= unifi_write_direct16(card
, ChipHelper_HOST_WINDOW3_PAGE(card
->helper
) * 2, page
);
741 if (r
!= CSR_RESULT_SUCCESS
)
743 unifi_error(card
->ospriv
, "Failed to write SHARED_DMEM_PAGE\n");
747 card
->dmem_page
= page
;
750 *paddr
= ((s32
)addr
* 2) + (dmem_addr
& 1);
752 return CSR_RESULT_SUCCESS
;
753 } /* set_dmem_page() */
756 static CsrResult
set_pmem_page(card_t
*card
, u32 pmem_addr
,
757 enum chip_helper_window_type mem_type
, u32
*paddr
)
765 if (!ChipHelper_DecodeWindow(card
->helper
,
766 CHIP_HELPER_WINDOW_2
,
771 unifi_error(card
->ospriv
, "Failed to decode PROG MEM PAGE %08lx %d\n", pmem_addr
, mem_type
);
772 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
775 if (page
!= card
->pmem_page
)
777 unifi_trace(card
->ospriv
, UDBG6
, "setting pmem page=0x%X, addr=0x%lX\n", page
, addr
);
779 /* change page register */
780 r
= unifi_write_direct16(card
, ChipHelper_HOST_WINDOW2_PAGE(card
->helper
) * 2, page
);
781 if (r
!= CSR_RESULT_SUCCESS
)
783 unifi_error(card
->ospriv
, "Failed to write PROG MEM PAGE\n");
787 card
->pmem_page
= page
;
790 *paddr
= ((s32
)addr
* 2) + (pmem_addr
& 1);
792 return CSR_RESULT_SUCCESS
;
793 } /* set_pmem_page() */
797 * ---------------------------------------------------------------------------
800 * Sets up the appropriate page register to access the given address.
801 * Returns the sdio address at which the unifi address can be accessed.
804 * card Pointer to card structure.
805 * generic_addr UniFi internal address to access, in Generic Pointer
806 * format, i.e. top byte is space indicator.
807 * paddr Location to write page address
808 * SDIO address (24-bit) for use in a unifi_read_direct or
809 * unifi_write_direct call
812 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
813 * CSR_RESULT_FAILURE an SDIO error occurred
814 * CSR_WIFI_HIP_RESULT_INVALID_VALUE the address is invalid
815 * ---------------------------------------------------------------------------
817 static CsrResult
set_page(card_t
*card
, u32 generic_addr
, u32
*paddr
)
821 CsrResult r
= CSR_RESULT_SUCCESS
;
825 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
828 space
= UNIFI_GP_SPACE(generic_addr
);
829 addr
= UNIFI_GP_OFFSET(generic_addr
);
833 /* Shared Data Memory is accessed via the Shared Data Memory window */
834 r
= set_dmem_page(card
, addr
, paddr
);
835 if (r
!= CSR_RESULT_SUCCESS
)
841 case UNIFI_EXT_FLASH
:
842 if (!ChipHelper_HasFlash(card
->helper
))
844 unifi_error(card
->ospriv
, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
845 generic_addr
, card
->helper
);
846 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
848 /* External FLASH is accessed via the Program Memory window */
849 r
= set_pmem_page(card
, addr
, CHIP_HELPER_WT_FLASH
, paddr
);
853 if (!ChipHelper_HasExtSram(card
->helper
))
855 unifi_error(card
->ospriv
, "Bad address space for chip in generic pointer 0x%08l (helper=0x%x)\n",
856 generic_addr
, card
->helper
);
857 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
859 /* External SRAM is accessed via the Program Memory window */
860 r
= set_pmem_page(card
, addr
, CHIP_HELPER_WT_EXT_SRAM
, paddr
);
863 case UNIFI_REGISTERS
:
864 /* Registers are accessed directly */
869 r
= unifi_set_proc_select(card
, UNIFI_PROC_PHY
);
870 if (r
!= CSR_RESULT_SUCCESS
)
874 *paddr
= ChipHelper_DATA_MEMORY_RAM_OFFSET(card
->helper
) * 2 + addr
;
878 r
= unifi_set_proc_select(card
, UNIFI_PROC_MAC
);
879 if (r
!= CSR_RESULT_SUCCESS
)
883 *paddr
= ChipHelper_DATA_MEMORY_RAM_OFFSET(card
->helper
) * 2 + addr
;
887 if (!ChipHelper_HasBt(card
->helper
))
889 unifi_error(card
->ospriv
, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
890 generic_addr
, card
->helper
);
891 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
893 r
= unifi_set_proc_select(card
, UNIFI_PROC_BT
);
894 if (r
!= CSR_RESULT_SUCCESS
)
898 *paddr
= ChipHelper_DATA_MEMORY_RAM_OFFSET(card
->helper
) * 2 + addr
;
902 r
= unifi_set_proc_select(card
, UNIFI_PROC_PHY
);
903 if (r
!= CSR_RESULT_SUCCESS
)
907 r
= set_pmem_page(card
, addr
, CHIP_HELPER_WT_CODE_RAM
, paddr
);
911 r
= unifi_set_proc_select(card
, UNIFI_PROC_MAC
);
912 if (r
!= CSR_RESULT_SUCCESS
)
916 r
= set_pmem_page(card
, addr
, CHIP_HELPER_WT_CODE_RAM
, paddr
);
920 if (!ChipHelper_HasBt(card
->helper
))
922 unifi_error(card
->ospriv
, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
923 generic_addr
, card
->helper
);
924 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
926 r
= unifi_set_proc_select(card
, UNIFI_PROC_BT
);
927 if (r
!= CSR_RESULT_SUCCESS
)
931 r
= set_pmem_page(card
, addr
, CHIP_HELPER_WT_CODE_RAM
, paddr
);
935 if (!ChipHelper_HasRom(card
->helper
))
937 unifi_error(card
->ospriv
, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
938 generic_addr
, card
->helper
);
939 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
941 r
= unifi_set_proc_select(card
, UNIFI_PROC_PHY
);
942 if (r
!= CSR_RESULT_SUCCESS
)
946 r
= set_pmem_page(card
, addr
, CHIP_HELPER_WT_ROM
, paddr
);
950 if (!ChipHelper_HasRom(card
->helper
))
952 unifi_error(card
->ospriv
, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
953 generic_addr
, card
->helper
);
954 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
956 r
= unifi_set_proc_select(card
, UNIFI_PROC_MAC
);
957 if (r
!= CSR_RESULT_SUCCESS
)
961 r
= set_pmem_page(card
, addr
, CHIP_HELPER_WT_ROM
, paddr
);
965 if (!ChipHelper_HasRom(card
->helper
) || !ChipHelper_HasBt(card
->helper
))
967 unifi_error(card
->ospriv
, "Bad address space for chip in generic pointer 0x%08lX (helper=0x%x)\n",
968 generic_addr
, card
->helper
);
969 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
971 r
= unifi_set_proc_select(card
, UNIFI_PROC_BT
);
972 if (r
!= CSR_RESULT_SUCCESS
)
976 r
= set_pmem_page(card
, addr
, CHIP_HELPER_WT_ROM
, paddr
);
980 unifi_error(card
->ospriv
, "Bad address space %d in generic pointer 0x%08lX (helper=0x%x)\n",
981 space
, generic_addr
, card
->helper
);
982 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
990 * ---------------------------------------------------------------------------
991 * unifi_set_proc_select
995 * card Pointer to card structure.
996 * select Which XAP core to select
999 * 0 on success, non-zero error code on error:
1000 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1001 * CSR_RESULT_FAILURE an SDIO error occurred
1002 * ---------------------------------------------------------------------------
1004 CsrResult
unifi_set_proc_select(card_t
*card
, enum unifi_dbg_processors_select select
)
1008 /* Verify the the select value is allowed. */
1011 case UNIFI_PROC_MAC
:
1012 case UNIFI_PROC_PHY
:
1013 case UNIFI_PROC_BOTH
:
1018 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
1021 if (card
->proc_select
!= (u32
)select
)
1023 r
= unifi_write_direct16(card
,
1024 ChipHelper_DBG_HOST_PROC_SELECT(card
->helper
) * 2,
1026 if (r
== CSR_WIFI_HIP_RESULT_NO_DEVICE
)
1030 if (r
!= CSR_RESULT_SUCCESS
)
1032 unifi_error(card
->ospriv
, "Failed to write to Proc Select register\n");
1036 card
->proc_select
= (u32
)select
;
1039 return CSR_RESULT_SUCCESS
;
1044 * ---------------------------------------------------------------------------
1045 * unifi_read_8_or_16
1047 * Performs a byte read of the given address in shared data memory.
1048 * Set up the shared data memory page register as required.
1051 * card Pointer to card structure.
1052 * unifi_addr UniFi shared-data-memory address to access.
1053 * pdata Pointer to a byte variable for the value read.
1056 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
1057 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1058 * CSR_RESULT_FAILURE an SDIO error occurred
1059 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
1060 * ---------------------------------------------------------------------------
1062 CsrResult
unifi_read_8_or_16(card_t
*card
, u32 unifi_addr
, u8
*pdata
)
1066 #ifdef CSR_WIFI_TRANSPORT_CSPI
1070 r
= set_page(card
, unifi_addr
, &sdio_addr
);
1071 if (r
!= CSR_RESULT_SUCCESS
)
1076 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1077 card
->cmd_prof
.cmd52_r8or16_count
++;
1079 #ifdef CSR_WIFI_TRANSPORT_CSPI
1080 r
= retrying_read16(card
, card
->function
, sdio_addr
, &w
);
1081 *pdata
= (u8
)(w
& 0xFF);
1084 return retrying_read8(card
, card
->function
, sdio_addr
, pdata
);
1086 } /* unifi_read_8_or_16() */
1090 * ---------------------------------------------------------------------------
1091 * unifi_write_8_or_16
1093 * Performs a byte write of the given address in shared data memory.
1094 * Set up the shared data memory page register as required.
1097 * card Pointer to card context struct.
1098 * unifi_addr UniFi shared-data-memory address to access.
1099 * data Value to write.
1102 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
1103 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1104 * CSR_RESULT_FAILURE an SDIO error occurred
1105 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
1108 * Beware using unifi_write8() because byte writes are not safe on UniFi.
1109 * Writes to odd bytes are cached, writes to even bytes perform a 16-bit
1110 * write with the previously cached odd byte.
1111 * ---------------------------------------------------------------------------
1113 CsrResult
unifi_write_8_or_16(card_t
*card
, u32 unifi_addr
, u8 data
)
1117 #ifdef CSR_WIFI_TRANSPORT_CSPI
1121 r
= set_page(card
, unifi_addr
, &sdio_addr
);
1122 if (r
!= CSR_RESULT_SUCCESS
)
1129 unifi_warning(card
->ospriv
,
1130 "Warning: Byte write to an odd address (0x%lX) is dangerous\n",
1134 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1135 card
->cmd_prof
.cmd52_w8or16_count
++;
1137 #ifdef CSR_WIFI_TRANSPORT_CSPI
1139 return retrying_write16(card
, card
->function
, sdio_addr
, w
);
1141 return retrying_write8(card
, card
->function
, sdio_addr
, data
);
1143 } /* unifi_write_8_or_16() */
1147 * ---------------------------------------------------------------------------
1150 * Performs a 16-bit read of the given address in shared data memory.
1151 * Set up the shared data memory page register as required.
1154 * card Pointer to card structure.
1155 * unifi_addr UniFi shared-data-memory address to access.
1156 * pdata Pointer to a 16-bit int variable for the value read.
1159 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
1160 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1161 * CSR_RESULT_FAILURE an SDIO error occurred
1162 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
1163 * ---------------------------------------------------------------------------
1165 CsrResult
unifi_card_read16(card_t
*card
, u32 unifi_addr
, u16
*pdata
)
1170 r
= set_page(card
, unifi_addr
, &sdio_addr
);
1171 if (r
!= CSR_RESULT_SUCCESS
)
1176 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1177 card
->cmd_prof
.cmd52_r16_count
++;
1179 return unifi_read_direct16(card
, sdio_addr
, pdata
);
1180 } /* unifi_card_read16() */
1184 * ---------------------------------------------------------------------------
1185 * unifi_card_write16
1187 * Performs a 16-bit write of the given address in shared data memory.
1188 * Set up the shared data memory page register as required.
1191 * card Pointer to card structure.
1192 * unifi_addr UniFi shared-data-memory address to access.
1193 * pdata Pointer to a byte variable for the value write.
1196 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
1197 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1198 * CSR_RESULT_FAILURE an SDIO error occurred
1199 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
1200 * ---------------------------------------------------------------------------
1202 CsrResult
unifi_card_write16(card_t
*card
, u32 unifi_addr
, u16 data
)
1207 r
= set_page(card
, unifi_addr
, &sdio_addr
);
1208 if (r
!= CSR_RESULT_SUCCESS
)
1213 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1214 card
->cmd_prof
.cmd52_w16_count
++;
1216 return unifi_write_direct16(card
, sdio_addr
, data
);
1217 } /* unifi_card_write16() */
1221 * ---------------------------------------------------------------------------
1224 * Performs a 32-bit read of the given address in shared data memory.
1225 * Set up the shared data memory page register as required.
1228 * card Pointer to card structure.
1229 * unifi_addr UniFi shared-data-memory address to access.
1230 * pdata Pointer to a int variable for the value read.
1233 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
1234 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1235 * CSR_RESULT_FAILURE an SDIO error occurred
1236 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
1237 * ---------------------------------------------------------------------------
1239 CsrResult
unifi_read32(card_t
*card
, u32 unifi_addr
, u32
*pdata
)
1244 r
= set_page(card
, unifi_addr
, &sdio_addr
);
1245 if (r
!= CSR_RESULT_SUCCESS
)
1250 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1251 card
->cmd_prof
.cmd52_r32_count
++;
1253 return unifi_read_direct32(card
, sdio_addr
, pdata
);
1254 } /* unifi_read32() */
1258 * ---------------------------------------------------------------------------
1262 * Read multiple 8-bit values from the UniFi SDIO interface.
1263 * This function interprets the address as a GenericPointer as
1264 * defined in the UniFi Host Interface Protocol Specification.
1265 * The readnz version of this function will stop when it reads a
1269 * card Pointer to card structure.
1270 * unifi_addr UniFi shared-data-memory address to access.
1271 * pdata Pointer to which to write data.
1272 * len Number of bytes to read
1275 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
1276 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1277 * CSR_RESULT_FAILURE an SDIO error occurred
1278 * CSR_WIFI_HIP_RESULT_INVALID_VALUE a bad generic pointer was specified
1279 * ---------------------------------------------------------------------------
1281 CsrResult
unifi_readn_match(card_t
*card
, u32 unifi_addr
, void *pdata
, u16 len
, s8 match
)
1287 r
= set_page(card
, unifi_addr
, &sdio_addr
);
1288 if (r
!= CSR_RESULT_SUCCESS
)
1293 r
= unifi_read_directn_match(card
, sdio_addr
, pdata
, len
, match
, &num
);
1295 } /* unifi_readn_match() */
1298 CsrResult
unifi_card_readn(card_t
*card
, u32 unifi_addr
, void *pdata
, u16 len
)
1300 return unifi_readn_match(card
, unifi_addr
, pdata
, len
, -1);
1301 } /* unifi_card_readn() */
1304 CsrResult
unifi_readnz(card_t
*card
, u32 unifi_addr
, void *pdata
, u16 len
)
1306 return unifi_readn_match(card
, unifi_addr
, pdata
, len
, 0);
1307 } /* unifi_readnz() */
1311 * ---------------------------------------------------------------------------
1312 * unifi_read_shared_count
1314 * Read signal count locations, checking for an SDIO error. The
1315 * signal count locations only contain a valid number if the
1316 * highest bit isn't set.
1319 * card Pointer to card context structure.
1320 * addr Shared-memory address to read.
1323 * Value read from memory (0-127) or -1 on error
1324 * ---------------------------------------------------------------------------
1326 s32
unifi_read_shared_count(card_t
*card
, u32 addr
)
1329 /* I've increased this count, because I have seen cases where
1330 * there were three reads in a row with the top bit set. I'm not
1331 * sure why this might have happened, but I can't see a problem
1332 * with increasing this limit. It's better to take a while to
1333 * recover than to fail. */
1334 #define SHARED_READ_RETRY_LIMIT 10
1338 * Get the to-host-signals-written count.
1339 * The top-bit will be set if the firmware was in the process of
1340 * changing the value, in which case we read again.
1342 /* Limit the number of repeats so we don't freeze */
1343 for (i
= 0; i
< SHARED_READ_RETRY_LIMIT
; i
++)
1346 r
= unifi_read_8_or_16(card
, addr
, &b
);
1347 if (r
!= CSR_RESULT_SUCCESS
)
1353 /* There is a chance that the MSB may have contained invalid data
1354 * (overflow) at the time it was read. Therefore mask off the MSB.
1355 * This avoids a race between driver read and firmware write of the
1356 * word, the value we need is in the lower 8 bits anway.
1358 return (s32
)(b
& 0xff);
1362 return -1; /* this function has changed in WMM mods */
1363 } /* unifi_read_shared_count() */
1367 * ---------------------------------------------------------------------------
1370 * Write multiple 8-bit values to the UniFi SDIO interface using CMD52
1371 * This function interprets the address as a GenericPointer as
1372 * defined in the UniFi Host Interface Protocol Specification.
1375 * card Pointer to card structure.
1376 * unifi_addr UniFi shared-data-memory address to access.
1377 * pdata Pointer to which to write data.
1378 * len Number of bytes to write
1381 * 0 on success, non-zero error code on error:
1382 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1383 * CSR_RESULT_FAILURE an SDIO error occurred
1384 * CSR_WIFI_HIP_RESULT_INVALID_VALUE an odd length or length too big.
1385 * ---------------------------------------------------------------------------
1387 CsrResult
unifi_writen(card_t
*card
, u32 unifi_addr
, void *pdata
, u16 len
)
1392 r
= set_page(card
, unifi_addr
, &sdio_addr
);
1393 if (r
!= CSR_RESULT_SUCCESS
)
1398 return unifi_write_directn(card
, sdio_addr
, pdata
, len
);
1399 } /* unifi_writen() */
1402 static CsrResult
csr_sdio_block_rw(card_t
*card
, s16 funcnum
,
1403 u32 addr
, u8
*pdata
,
1404 u16 count
, s16 dir_is_write
)
1406 CsrResult csrResult
;
1408 if (dir_is_write
== UNIFI_SDIO_READ
)
1410 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
1411 unifi_debug_log_to_buf("r@%02X#%X=", addr
, count
);
1413 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1414 unifi_debug_log_to_buf("R");
1416 csrResult
= CsrSdioRead(card
->sdio_if
, addr
, pdata
, count
);
1417 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1418 unifi_debug_log_to_buf("<");
1423 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
1424 unifi_debug_log_to_buf("w@%02X#%X=", addr
, count
);
1425 unifi_debug_hex_to_buf(pdata
, count
> CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH
?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH
: count
);
1427 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1428 unifi_debug_log_to_buf("W");
1430 csrResult
= CsrSdioWrite(card
->sdio_if
, addr
, pdata
, count
);
1431 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_DATA_PLANE_PROFILE)
1432 unifi_debug_log_to_buf(">");
1435 #ifdef CSR_WIFI_HIP_DATA_PLANE_PROFILE
1436 card
->cmd_prof
.cmd53_count
++;
1438 #if defined (CSR_WIFI_HIP_DEBUG_OFFLINE) && defined (CSR_WIFI_HIP_SDIO_TRACE)
1439 if (csrResult
!= CSR_RESULT_SUCCESS
)
1441 unifi_debug_log_to_buf("error=%X", csrResult
);
1443 else if (dir_is_write
== UNIFI_SDIO_READ
)
1445 unifi_debug_hex_to_buf(pdata
, count
> CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH
?CSR_WIFI_HIP_SDIO_TRACE_DATA_LENGTH
: count
);
1447 unifi_debug_string_to_buf("\n");
1449 return csrResult
; /* CSR SDIO (not HIP) error code */
1454 * ---------------------------------------------------------------------------
1457 * Transfer bulk data to or from the UniFi SDIO interface.
1458 * This function is used to read or write signals and bulk data.
1461 * card Pointer to card structure.
1462 * handle Value to put in the Register Address field of the CMD53 req.
1463 * data Pointer to data to write.
1464 * direction One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
1467 * CSR_RESULT_SUCCESS on success, non-zero error code on error:
1468 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1469 * CSR_RESULT_FAILURE an SDIO error occurred
1472 * This function uses SDIO CMD53, which is the block transfer mode.
1473 * ---------------------------------------------------------------------------
1475 CsrResult
unifi_bulk_rw(card_t
*card
, u32 handle
, void *pdata
,
1476 u32 len
, s16 direction
)
1478 #define CMD53_RETRIES 3
1480 * Ideally instead of sleeping, we want to busy wait.
1481 * Currently there is no framework API to do this. When it becomes available,
1482 * we can use it to busy wait using usecs
1484 #define REWIND_RETRIES 15 /* when REWIND_DELAY==1msec, or 250 when REWIND_DELAY==50usecs */
1485 #define REWIND_POLLING_RETRIES 5
1486 #define REWIND_DELAY 1 /* msec or 50usecs */
1487 CsrResult csrResult
; /* SDIO error code */
1488 CsrResult r
= CSR_RESULT_SUCCESS
; /* HIP error code */
1489 s16 retries
= CMD53_RETRIES
;
1494 u8
*pdata_lsb
= ((u8
*)&pdata
) + card
->lsb
;
1496 #ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
1497 static s16 fake_error
;
1504 unifi_notice(card
->ospriv
, "CD53 request on a unaligned buffer (addr: 0x%X) dir %s-Host\n",
1505 pdata
, (direction
== UNIFI_SDIO_READ
)?"To" : "From");
1506 if (direction
== UNIFI_SDIO_WRITE
)
1508 dump(pdata
, (u16
)len
);
1517 /* Defensive checks */
1520 unifi_error(card
->ospriv
, "Null pdata for unifi_bulk_rw() len: %d\n", len
);
1521 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
1523 if ((len
& 1) || (len
> 0xffff))
1525 unifi_error(card
->ospriv
, "Impossible CMD53 length requested: %d\n", len
);
1526 return CSR_WIFI_HIP_RESULT_INVALID_VALUE
;
1531 csrResult
= csr_sdio_block_rw(card
, card
->function
, handle
,
1532 (u8
*)pdata
, (u16
)len
,
1534 if (csrResult
== CSR_SDIO_RESULT_NO_DEVICE
)
1536 return CSR_WIFI_HIP_RESULT_NO_DEVICE
;
1538 #ifdef CSR_WIFI_MAKE_FAKE_CMD53_ERRORS
1539 if (++fake_error
> 100)
1542 unifi_warning(card
->ospriv
, "Faking a CMD53 error,\n");
1543 if (csrResult
== CSR_RESULT_SUCCESS
)
1545 csrResult
= CSR_RESULT_FAILURE
;
1549 if (csrResult
== CSR_RESULT_SUCCESS
)
1553 dump(pdata
, (u16
)len
);
1559 * At this point the SDIO driver should have written the I/O Abort
1560 * register to notify UniFi that the command has failed.
1561 * UniFi-1 and UniFi-2 (not UF6xxx) use the same register to store the
1562 * Deep Sleep State. This means we have to restore the Deep Sleep
1563 * State (AWAKE in any case since we can not perform a CD53 in any other
1564 * state) by rewriting the I/O Abort register to its previous value.
1566 if (card
->chip_id
<= SDIO_CARD_ID_UNIFI_2
)
1568 (void)unifi_set_host_state(card
, UNIFI_HOST_STATE_AWAKE
);
1571 /* If csr_sdio_block_rw() failed in a non-retryable way, or retries exhausted
1572 * then stop retrying
1574 if (!retryable_sdio_error(csrResult
))
1576 unifi_error(card
->ospriv
, "Fatal error in a CMD53 transfer\n");
1581 * These happen from time to time, try again
1588 unifi_trace(card
->ospriv
, UDBG4
,
1589 "Error in a CMD53 transfer, retrying (h:%d,l:%u)...\n",
1590 (s16
)handle
& 0xff, len
);
1592 /* The transfer failed, rewind and try again */
1593 r
= unifi_write_8_or_16(card
, card
->sdio_ctrl_addr
+ 8,
1594 (u8
)(handle
& 0xff));
1595 if (r
== CSR_WIFI_HIP_RESULT_NO_DEVICE
)
1599 if (r
!= CSR_RESULT_SUCCESS
)
1602 * If we can't even do CMD52 (register read/write) then
1605 unifi_error(card
->ospriv
, "Failed to write REWIND cmd\n");
1609 /* Signal the UniFi to look for the rewind request. */
1610 r
= CardGenInt(card
);
1611 if (r
!= CSR_RESULT_SUCCESS
)
1616 /* Wait for UniFi to acknowledge the rewind */
1617 stat_retries
= REWIND_RETRIES
;
1620 r
= unifi_read_8_or_16(card
, card
->sdio_ctrl_addr
+ 8, &stat
);
1621 if (r
== CSR_WIFI_HIP_RESULT_NO_DEVICE
)
1625 if (r
!= CSR_RESULT_SUCCESS
)
1627 unifi_error(card
->ospriv
, "Failed to read REWIND status\n");
1628 return CSR_RESULT_FAILURE
;
1635 if (--stat_retries
== 0)
1637 unifi_error(card
->ospriv
, "Timeout waiting for REWIND ready\n");
1638 return CSR_RESULT_FAILURE
;
1641 /* Poll for the ack a few times */
1642 if (stat_retries
< REWIND_RETRIES
- REWIND_POLLING_RETRIES
)
1644 CsrThreadSleep(REWIND_DELAY
);
1649 /* The call to csr_sdio_block_rw() still failed after retrying */
1650 if (csrResult
!= CSR_RESULT_SUCCESS
)
1652 unifi_error(card
->ospriv
, "Block %s failed after %d retries\n",
1653 (direction
== UNIFI_SDIO_READ
)?"read" : "write",
1654 CMD53_RETRIES
- retries
);
1655 /* Report any SDIO error as a general i/o error */
1656 return CSR_RESULT_FAILURE
;
1659 /* Collect some stats */
1660 if (direction
== UNIFI_SDIO_READ
)
1662 card
->sdio_bytes_read
+= len
;
1666 card
->sdio_bytes_written
+= len
;
1669 return CSR_RESULT_SUCCESS
;
1670 } /* unifi_bulk_rw() */
1674 * ---------------------------------------------------------------------------
1675 * unifi_bulk_rw_noretry
1677 * Transfer bulk data to or from the UniFi SDIO interface.
1678 * This function is used to read or write signals and bulk data.
1681 * card Pointer to card structure.
1682 * handle Value to put in the Register Address field of
1684 * data Pointer to data to write.
1685 * direction One of UNIFI_SDIO_READ or UNIFI_SDIO_WRITE
1688 * 0 on success, non-zero error code on error:
1689 * CSR_WIFI_HIP_RESULT_NO_DEVICE card was ejected
1690 * CSR_RESULT_FAILURE an SDIO error occurred
1693 * This function uses SDIO CMD53, which is the block transfer mode.
1694 * ---------------------------------------------------------------------------
1696 CsrResult
unifi_bulk_rw_noretry(card_t
*card
, u32 handle
, void *pdata
,
1697 u32 len
, s16 direction
)
1699 CsrResult csrResult
;
1701 csrResult
= csr_sdio_block_rw(card
, card
->function
, handle
,
1702 (u8
*)pdata
, (u16
)len
, direction
);
1703 if (csrResult
!= CSR_RESULT_SUCCESS
)
1705 unifi_error(card
->ospriv
, "Block %s failed\n",
1706 (direction
== UNIFI_SDIO_READ
)?"read" : "write");
1710 return CSR_RESULT_SUCCESS
;
1711 } /* unifi_bulk_rw_noretry() */