PageRenderTime 72ms CodeModel.GetById 36ms RepoModel.GetById 1ms app.codeStats 1ms

/drivers/net/wireless/tiwlan1251/common/src/TNETW_Driver/TNETWIF/BusTxn/whalHwAccess.c

https://bitbucket.org/cyanogenmod/cm-kernel
C | 2896 lines | 1656 code | 597 blank | 643 comment | 156 complexity | bd175b6898da28455cde86bd40125cfc MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0

Large files files are truncated, but you can click here to view the full file

  1. /****************************************************************************
  2. **+-----------------------------------------------------------------------+**
  3. **| |**
  4. **| Copyright(c) 1998 - 2008 Texas Instruments. All rights reserved. |**
  5. **| All rights reserved. |**
  6. **| |**
  7. **| Redistribution and use in source and binary forms, with or without |**
  8. **| modification, are permitted provided that the following conditions |**
  9. **| are met: |**
  10. **| |**
  11. **| * Redistributions of source code must retain the above copyright |**
  12. **| notice, this list of conditions and the following disclaimer. |**
  13. **| * Redistributions in binary form must reproduce the above copyright |**
  14. **| notice, this list of conditions and the following disclaimer in |**
  15. **| the documentation and/or other materials provided with the |**
  16. **| distribution. |**
  17. **| * Neither the name Texas Instruments nor the names of its |**
  18. **| contributors may be used to endorse or promote products derived |**
  19. **| from this software without specific prior written permission. |**
  20. **| |**
  21. **| THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |**
  22. **| "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |**
  23. **| LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |**
  24. **| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |**
  25. **| OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |**
  26. **| SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |**
  27. **| LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |**
  28. **| DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |**
  29. **| THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |**
  30. **| (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |**
  31. **| OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |**
  32. **| |**
  33. **+-----------------------------------------------------------------------+**
  34. ****************************************************************************/
  35. /****************************************************************************
  36. *
  37. * MODULE: hwAccess.c
  38. * PURPOSE: Support access to the wlan hardware registers and memory
  39. *
  40. * Direct Slave mode:
  41. * -----------------
  42. *
  43. * 1. 08 bit function
  44. * - access 16 bit (WA100 has no access to 8 bits)
  45. * - set/get the relevant byte according to the address (odd or even)
  46. * + ((char *)&DataShort)[Addr&0x1]
  47. * - no endian handle
  48. * 2. 16 bit function
  49. * - access 16 bit
  50. * - short endian handle
  51. * 3. 32 bit function
  52. * - access 32 bit
  53. * - long endian handle
  54. * 4. buffers copy to (stream of bytes)
  55. * - addresses must be even
  56. * - copy buffer as stream of 16 bits (in case of src/dst address ends with 0x2)
  57. * - handle case of more bytes to copy
  58. * * TempWord = (*shortDest & 0x00ff) | (*shortSrc & 0xff00);
  59. * - no endian handle
  60. * 5. registers
  61. * - access 32 bit
  62. * - long endian handle
  63. * - no use of wlan hardware capability to swap endian
  64. *
  65. * Indirect Slave mode:
  66. * -------------------
  67. *
  68. * 1. 08 bit function
  69. * - access 16 bit (WA100 has no access to 8 bits)
  70. * - set/get the relevant byte according to the address (odd or even)
  71. * + ((char *)&DataLong)[Addr&0x3]
  72. * - no endian handle
  73. * 2. 16 bit function
  74. * - access 32 bit (set addr reg , get data reg)
  75. * - set/get the relevant short according to the address (00 or 02)
  76. * + ((short *)&DataLong)[(Addr>>1)&0x1])
  77. * - short endian handle
  78. * 3. 32 bit function
  79. * - access 32 bit (set addr reg , get data reg)
  80. * - long endian handle
  81. * 4. buffers copy to (stream of bytes)
  82. * - addresses must be even
  83. * - handle case of dest(wlan hardware) address ends with 0x2 - read 32 from 0x0, set only high short
  84. * - now the dest(wlan hardware) address is long address
  85. * - use Auto Increment Mode
  86. * - copy buffer as stream of 16 bits (in case of source address ends with 0x2)
  87. * - handle case of more bytes to copy
  88. * * i=0..Len&3 ==> ((char *)&DataLong)[i] = ((char *)shortSrc)[i]
  89. * - no endian handle
  90. * 5. buffers copy from (stream of bytes)
  91. * - addresses must be even
  92. * - handle case of source(wlan hardware) address ends with 0x2 - read 32 from 0x0, set only high short
  93. * - now the source(wlan hardware) address is long address
  94. * - use Auto Increment Mode
  95. * - copy buffer as stream of 16 bits (in case of dest address ends with 0x2)
  96. * - handle case of more bytes to copy
  97. * * i=0..Len&3 ==> ((char *)shortDest)[i] = ((char *)&DataLong)[i]
  98. * - no endian handle
  99. * 6. registers
  100. * - access 32 bit
  101. * - long endian handle
  102. * - no use of wlan hardware capability to swap endian
  103. *
  104. ****************************************************************************/
  105. #include "osTIType.h"
  106. #include "osApi.h"
  107. #include "whalCommon.h"
  108. #include "whalHwDefs.h"
  109. #ifdef HW_ACCESS_SDIO
  110. #ifndef _WINDOWS /*Linux, Symbian, RVCT */
  111. #include "mmc_omap_api.h"
  112. #include "mmc_tnetw1150_api.h"
  113. #else /* ifdef _WINDOWS */
  114. #endif /* ifdef _WINDOWS */
  115. #elif defined(HW_ACCESS_WSPI)
  116. #include "wspi.h"
  117. #endif
  118. #include "TNETWIF.h"
  119. #include "whalHwAccess.h"
  120. /* #define __HWACCESS_DEBUG__ */
  121. /*
  122. * Define this flag to support SDIO asynchronous mode
  123. */
  124. #undef HW_ACCESS_SDIO_ASYNC_SUPPORT
  125. /************************************************************************
  126. * Types
  127. ************************************************************************/
  128. typedef struct _HWAccess_CB_T
  129. {
  130. HwAccess_callback_t CBFunc;
  131. void* CBArg;
  132. } HWAccess_CB_T;
  133. typedef void (*HwAccessErrorHandle)(TI_HANDLE theObjectHandle,char* Report , UINT32 strLen);
  134. typedef struct _partition_t
  135. {
  136. UINT32 size;
  137. UINT32 start;
  138. } partition_t;
  139. /* HwAccess context */
  140. typedef struct _HwAccess_T_new
  141. {
  142. void *hProtect;
  143. TI_HANDLE hOs;
  144. TI_HANDLE hReport;
  145. #if (defined(HW_ACCESS_SDIO)|defined(HW_ACCESS_WSPI))
  146. TI_HANDLE hDriver;
  147. UINT32 MemRegionAddr;
  148. UINT32 RegisterRegionAddr;
  149. UINT32 workingPartUpperLimit;
  150. UINT32 registerPartUpperLimit;
  151. #else /* HW_ACCESS_CARDBUS */
  152. UINT32 RegBaseAddr;
  153. UINT32 MemBaseAddr;
  154. #endif
  155. HWAccess_CB_T CB;
  156. UINT8 AsyncMode;
  157. UINT32 uBusError;
  158. HwAccessErrorHandle hwAccesserror_Cb;
  159. TI_HANDLE hBackReference;
  160. PADDING (partition_t partition [2])
  161. } HwAccess_T_new;
  162. /************************************************************************
  163. * Defines
  164. ************************************************************************/
  165. #ifdef HW_ACCESS_WSPI
  166. /*
  167. * Converts status from WSPI into TI_STATUS
  168. */
  169. #define WSPI2TNETWIF(pHwAccess,status,addr) \
  170. switch(status) { \
  171. case WSPI_TXN_PENDING: status = TNETWIF_PENDING; break; \
  172. case WSPI_TXN_COMPLETE: status = TNETWIF_COMPLETE; break; \
  173. default: \
  174. WLAN_REPORT_ERROR (pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG, \
  175. ("whal_hwAccess: Error in read/write async, addr=0x%08x status=%d\n", \
  176. addr, status)); \
  177. status = TNETWIF_ERROR; break; \
  178. }
  179. /*
  180. * Indicate the index position at which we should check if the HW is up -
  181. * i.e. (buf[HW_ACCESS_WSPI_FIXED_BUSY_LEN] & 0x1 == TRUE)
  182. */
  183. #ifdef TNETW1251
  184. #define HW_ACCESS_WSPI_FIXED_BUSY_LEN ((TNETWIF_READ_OFFSET_BYTES - 4 ) / sizeof(UINT32))
  185. #else
  186. #define HW_ACCESS_WSPI_FIXED_BUSY_LEN 0
  187. #endif
  188. #endif /* HW_ACCESS_WSPI */
  189. #define HW_ACCESS_WSPI_INIT_CMD_MASK 0
  190. #define HW_ACCESS_WSPI_ALIGNED_SIZE 4
  191. #define HW_ACCESS_NUM_OF_BIT_IN_BYTE 8
  192. #define HW_ACCESS_REGISTER_SIZE 4
  193. /* ELP CTRL register */
  194. #define HW_ACCESS_ELP_CTRL_REG_ADDR 0x1FFFC
  195. #define HW_ACCESS_1_BYTE_REMINDE_MASK 0x000000FF
  196. #define HW_ACCESS_2_BYTE_REMINDE_MASK 0x0000FFFF
  197. #define HW_ACCESS_3_BYTE_REMINDE_MASK 0x00FFFFFF
  198. /* translation registers */
  199. #define HW_ACCESS_PART0_SIZE_ADDR 0x1FFC0
  200. #define HW_ACCESS_PART0_START_ADDR 0x1FFC4
  201. #define HW_ACCESS_PART1_SIZE_ADDR 0x1FFC8
  202. #define HW_ACCESS_PART1_START_ADDR 0x1FFCC
  203. /************************************************************************
  204. * Macros
  205. ************************************************************************/
  206. #define EXTRACT_BYTE_FROM_WORD(DataShort, Addr) (((char *)&DataShort)[((int)Addr)&0x1])
  207. #define EXTRACT_BYTE_FROM_LONG(DataLong, Addr) (((char *)&DataLong )[((int)Addr)&0x3])
  208. #define EXTRACT_WORD_FROM_LONG(DataLong, Addr) (((short *)&DataLong)[(((int)Addr>>1))&0x1])
  209. #define EXTRACT_BYTE_LONG(DataLong, i) (((char *)&DataLong)[i])
  210. #define HW_MEM_SHORT(pHwAccess, Addr) (*(volatile UINT16 *)(pHwAccess->MemBaseAddr + (UINT32)(Addr)))
  211. #define HW_MEM_LONG(pHwAccess, Addr) (*(volatile UINT32 *)(pHwAccess->MemBaseAddr + (UINT32)(Addr)))
  212. #define TRANSLATE_ADDRESS_MEM(addr) ((addr) - pHwAccess->MemRegionAddr)
  213. #define TRANSLATE_ADDRESS_REG(addr) ((addr) + pHwAccess->RegisterRegionAddr)
  214. #if 1 /* 0 */
  215. #if (defined(HW_ACCESS_SDIO)|defined(HW_ACCESS_WSPI)) /* 1 */
  216. void HW_REG_LONG_WRITE(HwAccess_T_new *pHwAccess, UINT32 RegAddr, UINT32 BitVal);
  217. void HW_REG_LONG_READ(HwAccess_T_new *pHwAccess, UINT32 RegAddr, UINT32 *Val);
  218. #else /* 1 */
  219. #define HW_REG_SHORT_WRITE(pHwAccess, Addr, Data) ((*(volatile UINT16 *)(pHwAccess->RegBaseAddr + (UINT32)(Addr))) = (UINT16)(Data))
  220. #define HW_REG_SHORT_READ(pHwAccess, Addr, Data) ((*(Data)) = (*(volatile UINT16 *)(pHwAccess->RegBaseAddr + (UINT32)(Addr))) )
  221. #ifdef NOT_SUPPORT_32_BIT_ACCESS_COMMAND /* for example: iPAQ model 38xx */ /* 2 */
  222. #define HW_REG_LONG_WRITE(pHwAccess, Addr, Data) HW_REG_SHORT_WRITE(pHwAccess, Addr, Data); HW_REG_SHORT_WRITE(pHwAccess, Addr+2, ((UINT16)(Data>>16)))
  223. #define HW_REG_LONG_READ(pHwAccess, Addr, pData) HW_REG_SHORT_READ(pHwAccess, Addr, pData); HW_REG_SHORT_READ(pHwAccess, Addr+2, ((UINT16 *)pData+1))
  224. #else /* 2 */
  225. #define HW_REG_LONG_WRITE(pHwAccess, Addr, Data) ((*(volatile UINT32 *)(pHwAccess->RegBaseAddr + (UINT32)(Addr))) = (UINT32)(Data))
  226. #define HW_REG_LONG_READ(pHwAccess, Addr, Data) ((*(Data)) = (*(volatile UINT32 *)(pHwAccess->RegBaseAddr + (UINT32)(Addr))) )
  227. #endif /* 2 */
  228. #endif /* 1 */
  229. #else /* 0 */
  230. #endif /* 0 */
  231. /************************************************************************
  232. * Functions
  233. ************************************************************************/
  234. #if !defined(HW_ACCESS_SDIO) && !defined(HW_ACCESS_WSPI)
  235. static void whal_hwAccess_DirectCopy_new(HwAccess_T_new *pHwAccess, UINT8* Dest, UINT8* Src, UINT32 Len);
  236. #endif
  237. #ifdef HW_ACCESS_SDIO
  238. static void sdio_transaction_notify_read(struct SDIO_Request *req, int status);
  239. static void sdio_transaction_notify_write(struct SDIO_Request *req, int status);
  240. static void sdio_transaction_error(struct SDIO_Request *req, int stat);
  241. #ifdef CONFIG_ASYNC_API
  242. static void sdio_async_transaction_notify(struct SDIO_Request *req, int status);
  243. static void sdio_async_transaction_error(struct SDIO_Request *req, int status);
  244. #endif
  245. #endif
  246. /*
  247. ** Read/Write interface
  248. **----------------------------
  249. **
  250. ** the memory space shell be divided to 2 Partions: Memory, and Registers.
  251. ** 1. The memory Region will be set at init to point to the FW Ram,
  252. ** and after FW init complete, the Memory Region will be set to point the Packet Ram.
  253. ** 2. Registry Region.
  254. **
  255. **
  256. */
  257. /************************************************************************
  258. * new API
  259. ************************************************************************/
  260. /****************************************************************************
  261. * whal_hwAccess_Create
  262. ****************************************************************************
  263. * DESCRIPTION: create the HwAccess module. allocate the module context and create the sublayers
  264. *
  265. * INPUTS: hOs - handle to the OS module
  266. *
  267. * OUTPUT: TI_HANDLE - the handle to the context that was created
  268. *
  269. * RETURNS: NULL = failure.
  270. * otherwise = success
  271. ****************************************************************************/
  272. TI_HANDLE whal_hwAccess_Create(TI_HANDLE hOs)
  273. {
  274. HwAccess_T_new *pHwAccess;
  275. int status = OK;
  276. #ifdef HW_ACCESS_SDIO
  277. SDIO_ConfigParams configParams;
  278. #endif
  279. pHwAccess = os_memoryAlloc(hOs, sizeof(HwAccess_T_new));
  280. if (pHwAccess == NULL)
  281. return NULL;
  282. os_memoryZero(hOs, pHwAccess, sizeof(HwAccess_T_new));
  283. pHwAccess->hOs = hOs;
  284. pHwAccess->hProtect = os_protectCreate(pHwAccess->hOs);
  285. if (pHwAccess->hProtect == NULL)
  286. {
  287. whal_hwAccess_Destroy(pHwAccess);
  288. return NULL;
  289. }
  290. #ifdef HW_ACCESS_SDIO
  291. pHwAccess->AsyncMode = FALSE;
  292. os_memoryZero(hOs, &configParams, sizeof(SDIO_ConfigParams));
  293. configParams.fnotify_read = sdio_transaction_notify_read;
  294. configParams.fnotify_write = sdio_transaction_notify_write;
  295. configParams.ferror = sdio_transaction_error;
  296. configParams.fconfig_peripheral = SDIO_TNETWConfig;
  297. configParams.fconvert = NULL;
  298. configParams.owner = pHwAccess;
  299. status = SDIO_Init(&configParams, &pHwAccess->hDriver);
  300. #elif defined(HW_ACCESS_WSPI)
  301. pHwAccess->AsyncMode = TRUE;
  302. pHwAccess->hDriver = WSPI_Open (pHwAccess->hOs);
  303. status = pHwAccess->hDriver == NULL;
  304. #else
  305. pHwAccess->AsyncMode = FALSE;
  306. #endif
  307. if (status != 0)
  308. {
  309. if (pHwAccess->hProtect)
  310. os_protectDestroy(pHwAccess->hOs, pHwAccess->hProtect);
  311. os_memoryFree(pHwAccess->hOs, pHwAccess, sizeof(HwAccess_T_new));
  312. return NULL;
  313. }
  314. return pHwAccess;
  315. }
  316. /****************************************************************************
  317. * whal_hwAccess_Destroy
  318. ****************************************************************************
  319. * DESCRIPTION: destroy the module. deallocate the cmodule context.
  320. *
  321. * INPUTS: hHwAccess - handle to the module context
  322. *
  323. * OUTPUT: none.
  324. *
  325. * RETURNS: one of the error codes (0 => OK)
  326. ****************************************************************************/
  327. int whal_hwAccess_Destroy(TI_HANDLE hHwAccess)
  328. {
  329. HwAccess_T_new *pHwAccess = (HwAccess_T_new*)hHwAccess;
  330. if (pHwAccess)
  331. {
  332. #ifdef HW_ACCESS_SDIO
  333. SDIO_Stop(pHwAccess->hDriver, 0);
  334. SDIO_Shutdown(pHwAccess->hDriver);
  335. #elif defined(HW_ACCESS_WSPI)
  336. WSPI_Close(pHwAccess->hDriver);
  337. #endif
  338. if (pHwAccess->hProtect)
  339. os_protectDestroy(pHwAccess->hOs, pHwAccess->hProtect);
  340. os_memoryFree(pHwAccess->hOs, pHwAccess, sizeof(HwAccess_T_new));
  341. }
  342. return OK;
  343. }
  344. /****************************************************************************
  345. * whal_hwAccess_Config
  346. ****************************************************************************
  347. * DESCRIPTION: config the module.
  348. *
  349. * INPUTS: hHwAccess - handle to the module context
  350. * hReport - handle to report module context that is used when we output debug messages
  351. *
  352. * OUTPUT: none.
  353. *
  354. * RETURNS: one of the error codes (0 => OK)
  355. ****************************************************************************/
  356. int whal_hwAccess_Config(TI_HANDLE hHwAccess, TI_HANDLE hReport,UINT32 RegBaseAddr, UINT32 MemBaseAddr, HwAccess_callback_t CBFunc,void* CBArg)
  357. {
  358. HwAccess_T_new *pHwAccess = (HwAccess_T_new*) hHwAccess;
  359. int status = OK;
  360. #ifdef HW_ACCESS_WSPI
  361. WSPIConfig_t wspi_config;
  362. #endif
  363. pHwAccess->hReport = hReport;
  364. #ifdef GWSI_SPI_TEST
  365. /* For GWSI_API_TEST this parameter should be maximum allowed because we don't use setPartition */
  366. pHwAccess->workingPartUpperLimit = 0xFFFFFFFF;
  367. #endif /* GWSI_API_TEST */
  368. /*
  369. Wait 200 usec for memory repair process to finish and device is ready.
  370. */
  371. os_StalluSec(pHwAccess->hOs, 200);
  372. pHwAccess->CB.CBFunc = CBFunc;
  373. pHwAccess->CB.CBArg = CBArg;
  374. #ifdef HW_ACCESS_SDIO
  375. pHwAccess->RegisterRegionAddr = HW_ACCESS_DOWN_PART0_SIZE;
  376. pHwAccess->MemRegionAddr = HW_ACCESS_DOWN_PART0_ADDR;
  377. pHwAccess->uBusError = 0;
  378. status = SDIO_Start (pHwAccess->hDriver);
  379. status = (status == SDIO_SUCCESS) ? TNETWIF_COMPLETE : TNETWIF_ERROR;
  380. #elif defined(HW_ACCESS_WSPI)
  381. wspi_config.isFixedAddress = FALSE;
  382. wspi_config.fixedBusyLength = HW_ACCESS_WSPI_FIXED_BUSY_LEN;
  383. wspi_config.mask = HW_ACCESS_WSPI_INIT_CMD_MASK;
  384. status = WSPI_Configure (pHwAccess->hDriver,
  385. pHwAccess->hReport,
  386. &wspi_config,
  387. (WSPI_CB_T*)&pHwAccess->CB);
  388. WSPI_SetErrLog(pHwAccess->hDriver, TNETWIF_printErrorLog);
  389. WSPI2TNETWIF (pHwAccess, status, 0x0);
  390. #else /* HW_ACCESS_CARDBUS */
  391. pHwAccess->RegBaseAddr = RegBaseAddr;
  392. pHwAccess->MemBaseAddr = MemBaseAddr;
  393. #endif
  394. return status;
  395. }
  396. /****************************************************************************
  397. * whal_hwAccess_ReConfig()
  398. ****************************************************************************
  399. * DESCRIPTION:
  400. *
  401. * INPUTS: None
  402. *
  403. * OUTPUT: None
  404. *
  405. * RETURNS:
  406. ****************************************************************************/
  407. int whal_hwAccess_ReConfig(TI_HANDLE hHwAccess)
  408. {
  409. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  410. #ifdef _WINDOWS
  411. #else /* _WINDOWS */
  412. /* unbclock the access to the bus */
  413. pHwAccess->uBusError = 0;
  414. #ifdef HW_ACCESS_SDIO
  415. SDIO_Stop (pHwAccess->hDriver, 0);
  416. SDIO_Start (pHwAccess->hDriver);
  417. #elif defined(HW_ACCESS_WSPI)
  418. /* TODO*/
  419. #endif
  420. #endif /* _WINDOWS */
  421. return OK;
  422. }
  423. #ifdef USE_SYNC_API
  424. /****************************************************************************
  425. * whal_hwAccess_WriteELP
  426. ****************************************************************************
  427. * DESCRIPTION: write data synchronously to the TNET ELP register (1byte)
  428. *
  429. * INPUTS: pHwAccess - TI_HANDLE * - the HwAccess context
  430. * data - UINT8 - the data to write
  431. *
  432. * OUTPUT: none
  433. *
  434. * RETURNS: one of the error codes (0 => OK)
  435. ****************************************************************************/
  436. int whal_hwAccess_WriteELP (TI_HANDLE hHwAccess, UINT32 data)
  437. {
  438. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  439. int status = OK;
  440. os_profile (pHwAccess->hOs, 2, 0);
  441. #ifdef HW_ACCESS_SDIO
  442. status = SDIO_TNETW_Set_ELP_Reg(pHwAccess->hDriver, HW_ACCESS_ELP_CTRL_REG_ADDR, data);
  443. #elif defined(HW_ACCESS_WSPI)
  444. status = WSPI_WriteSync (pHwAccess->hDriver, HW_ACCESS_ELP_CTRL_REG_ADDR, (UINT8*)&data, HW_ACCESS_REGISTER_SIZE);
  445. #endif
  446. os_profile (pHwAccess->hOs, 3, 0);
  447. if (status != OK)
  448. {
  449. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  450. ("whal_hwAccess_WriteReg_ELP: Error in ELP reg write status=%d\n",
  451. status));
  452. return NOK;
  453. }
  454. return OK;
  455. }
  456. #endif /* USE_SYNC_API */
  457. /****************************************************************************
  458. * whal_hwAccess_WriteELPAsync
  459. ****************************************************************************
  460. * DESCRIPTION: write data synchronously from the TNET using the defined access (WSPI/SDIO).
  461. * the length of data is always 4bytes cause this is the size of the TNET registers
  462. * the function is passed a call-back function that will be called after the read request ends.
  463. *
  464. * INPUTS: pHwAccess - TI_HANDLE * - the HwAccess context
  465. * addr - UINT32 - the address offset inside the TNET
  466. * data - UINT8* - a pointer to the buffer that holds the data to write
  467. * bMore - indicate whether more txn on the bus are about to happen (FALSE only when setting
  468. * the HW to sleep).
  469. *
  470. * OUTPUT: none
  471. *
  472. * RETURNS: one of the error codes (0 => OK)
  473. ****************************************************************************/
  474. int whal_hwAccess_WriteELPAsync (TI_HANDLE hHwAccess, UINT32 data, BOOL bCb, BOOL bMore)
  475. {
  476. #if defined(HW_ACCESS_SDIO)
  477. #if defined(HW_ACCESS_SDIO_ASYNC_SUPPORT)
  478. #error "SDIO asynchronous mode is not supported"
  479. /* Not implemented yet */
  480. return OK;
  481. #else
  482. /* Just call to synchronous API */
  483. return (whal_hwAccess_WriteELP (hHwAccess, data) == OK) ?
  484. TNETWIF_COMPLETE :
  485. TNETWIF_ERROR;
  486. #endif
  487. #else /* HW_ACCESS_WSPI */
  488. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  489. WSPI_CB_T Cb = { NULL, NULL }, *pCb;
  490. int status;
  491. pCb = (bCb) ? ((WSPI_CB_T*)&pHwAccess->CB) : &Cb;
  492. os_profile (pHwAccess->hOs, 2, 0);
  493. /* since we are writing a register - no extra space is needed */
  494. status = WSPI_WriteAsync (pHwAccess->hDriver,
  495. HW_ACCESS_ELP_CTRL_REG_ADDR,
  496. (UINT8*)&data,
  497. HW_ACCESS_REGISTER_SIZE,
  498. pCb,
  499. bMore,
  500. FALSE);
  501. os_profile (pHwAccess->hOs, 3, 0);
  502. WSPI2TNETWIF (pHwAccess, status, HW_ACCESS_ELP_CTRL_REG_ADDR);
  503. return status;
  504. #endif
  505. }
  506. /****************************************************************************
  507. * whal_hwAccess_ReadELPAsync
  508. ****************************************************************************
  509. * DESCRIPTION: Read the ELP register
  510. *
  511. * INPUTS: pHwAccess - TI_HANDLE * - the HwAccess context
  512. * addr - UINT32 - the address offset inside the TNET
  513. * data - UINT8* - a pointer to the buffer to read data into
  514. * bMore - indicate whether more txn on the bus are about to happen (FALSE only when setting
  515. * the HW to sleep).
  516. *
  517. * OUTPUT: none
  518. *
  519. * RETURNS: one of the error codes (0 => OK)
  520. ****************************************************************************/
  521. int whal_hwAccess_ReadELPAsync (TI_HANDLE hHwAccess, UINT8 *data, BOOL bCb, BOOL bMore)
  522. {
  523. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  524. int status;
  525. #ifdef HW_ACCESS_SDIO
  526. #ifndef _WINDOWS
  527. status = SDIO_TNETW_Get_ELP_Reg(pHwAccess->hDriver, HW_ACCESS_ELP_CTRL_REG_ADDR, (UINT32*)data);
  528. #else
  529. #endif
  530. if (status != OK)
  531. {
  532. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  533. ("whal_hwAccess_ReadELPAsync: Error in ELP reg raed status=%d\n",
  534. status));
  535. return TNETWIF_ERROR;
  536. }
  537. return TNETWIF_COMPLETE;
  538. #else /* HW_ACCESS_WSPI */
  539. os_profile (pHwAccess->hOs, 2, 0);
  540. /* In registers we don't save place */
  541. status = WSPI_ReadAsync (pHwAccess->hDriver,
  542. HW_ACCESS_ELP_CTRL_REG_ADDR,
  543. (UINT8*)data,
  544. HW_ACCESS_REGISTER_SIZE,
  545. (WSPI_CB_T*)&pHwAccess->CB,
  546. TRUE,
  547. FALSE);
  548. os_profile (pHwAccess->hOs, 3, 0);
  549. WSPI2TNETWIF (pHwAccess, status, HW_ACCESS_ELP_CTRL_REG_ADDR);
  550. return status;
  551. #endif
  552. }
  553. #ifdef USE_SYNC_API
  554. /****************************************************************************
  555. * whal_hwAccess_ReadMem_Align
  556. ****************************************************************************
  557. * DESCRIPTION: read data synchronously from the TNET using the defined access (WSPI/SDIO).
  558. * the length of data specified is rounded up so the length will be multiple of 4 (bytes)
  559. *
  560. * INPUTS: hHwAccess - the handle of HwAccess module
  561. * addr - UINT32 - the address offset inside the TNET
  562. * len - int - the length of the data to read
  563. *
  564. * OUTPUT: data - UINT8* - a pointer to the buffer to fill with the read data
  565. *
  566. * RETURNS: one of the error codes (0 => OK)
  567. ****************************************************************************/
  568. int whal_hwAccess_ReadMem_Align(TI_HANDLE hHwAccess, UINT32 addr, UINT8* data, UINT16 len)
  569. {
  570. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  571. int status = OK;
  572. #ifdef HW_ACCESS_SDIO
  573. struct SDIO_Request request;
  574. #endif
  575. /* round up the length so it will be multiple of 4bytes */
  576. if(len&0x3)
  577. len = (len&0xFFFFFFFC)+4;
  578. #ifdef HW_ACCESS_SDIO
  579. /* check address */
  580. if (((addr+len) > pHwAccess->workingPartUpperLimit) || (addr < pHwAccess->MemRegionAddr))
  581. {
  582. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  583. ("whal_hwAccess_ReadMem_Align: Error in addr 0x%x (lower:0x%x,upper:0x%x)\n",
  584. addr, pHwAccess->MemRegionAddr, pHwAccess->workingPartUpperLimit));
  585. return ERROR_HW_ACCEESS_ADDR;
  586. }
  587. request.buffer = data; /* Pointer to the data buffer aligned address. */
  588. request.buffer_len = len; /* Data buffer length in bytes */
  589. request.status = SDIO_Request_None;
  590. request.peripheral_addr = (SDIO_Address)TRANSLATE_ADDRESS_MEM(addr); /*SDIO peripheral address*/
  591. request.acquire_window = 0; /*Time out value is not set*/
  592. request.block_len = 0; /*Block length. Assigned by driver*/
  593. request.physical_buffer = 0; /*Physical address of data buffer is not set*/
  594. request.owner = (SDIO_Owner) pHwAccess;
  595. request.mode = MMC_DEV_BYTE_INCREMENTAL_MODE;
  596. request.access_flag = 1;
  597. os_profile (pHwAccess->hOs, 2, 0);
  598. status = SDIO_SyncRead(pHwAccess->hDriver, &request);
  599. os_profile (pHwAccess->hOs, 3, 0);
  600. #elif defined(HW_ACCESS_WSPI)
  601. /* check address */
  602. if (((addr+len) > pHwAccess->workingPartUpperLimit) || (addr < pHwAccess->MemRegionAddr))
  603. {
  604. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  605. ("whal_hwAccess_ReadMem_Align: Error in addr 0x%x (lower:0x%x,upper:0x%x)\n",
  606. addr, pHwAccess->MemRegionAddr, pHwAccess->workingPartUpperLimit));
  607. return ERROR_HW_ACCEESS_ADDR;
  608. }
  609. os_profile (pHwAccess->hOs, 2, 0);
  610. status = WSPI_ReadSync(pHwAccess->hDriver,TRANSLATE_ADDRESS_MEM(addr),data,len);
  611. os_profile (pHwAccess->hOs, 3, 0);
  612. #else
  613. whal_hwAccess_DirectCopy_new(pHwAccess, data, (UINT8*)addr, len);
  614. #endif
  615. if (status != OK)
  616. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  617. ("whal_hwAccess_ReadMem_Align: Error in read, addr=0x%08x status=%d\n",
  618. addr, status));
  619. #ifdef HW_ACCESS_SDIO
  620. if (pHwAccess->uBusError)
  621. {
  622. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  623. ("whal_hwAccess_ReadMem_Align: SDIO Error status=%d\n",
  624. request.status));
  625. if (pHwAccess->hwAccesserror_Cb)
  626. {
  627. UINT8 failure_reason = HEALTH_REPORT_BUS_ERROR;
  628. pHwAccess->hwAccesserror_Cb(pHwAccess->hBackReference,(char*)&failure_reason,2);
  629. }
  630. else
  631. pHwAccess->uBusError = 0;
  632. }
  633. #endif
  634. return status;
  635. }
  636. /****************************************************************************
  637. * whal_hwAccess_WriteMem_Align
  638. ****************************************************************************
  639. * DESCRIPTION: write data synchronously to the TNET using the defined access (WSPI/SDIO).
  640. * the length of data specified is rounded up so the length will be multiple of 4 (bytes)
  641. *
  642. * INPUTS: hHwAccess - the handle of HwAccess module
  643. * addr - UINT32 - the address offset inside the TNET
  644. * data - UINT8* - a pointer to the buffer that holds the data to write
  645. * len - int - the length of the data to read
  646. *
  647. * OUTPUT: none
  648. *
  649. * RETURNS: one of the error codes (0 => OK)
  650. ****************************************************************************/
  651. int whal_hwAccess_WriteMem_Align(TI_HANDLE hHwAccess, UINT32 addr, UINT8* data, UINT16 len)
  652. {
  653. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  654. int status = OK;
  655. #ifdef HW_ACCESS_SDIO
  656. struct SDIO_Request request;
  657. #endif
  658. /* round the length so it will be multiple of 4bytes */
  659. if(len&0x3)
  660. len = (len&0xFFFFFFFC)+4;
  661. #ifdef HW_ACCESS_SDIO
  662. /* check address */
  663. if (((addr+len) > pHwAccess->workingPartUpperLimit) || (addr < pHwAccess->MemRegionAddr))
  664. {
  665. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  666. ("whal_hwAccess_WriteMem_Align: Error in addr 0x%x (lower:0x%x,upper:0x%x)\n",
  667. addr, pHwAccess->MemRegionAddr, pHwAccess->workingPartUpperLimit));
  668. return ERROR_HW_ACCEESS_ADDR;
  669. }
  670. request.buffer = data; /* Pointer to the data buffer aligned address. */
  671. request.buffer_len = len; /* Data buffer length in bytes */
  672. request.status = SDIO_Request_None;
  673. request.peripheral_addr = (SDIO_Address)TRANSLATE_ADDRESS_MEM(addr); /*SDIO peripheral address*/
  674. request.acquire_window = 0; /*Time out value is not set*/
  675. request.block_len = 0; /*Block length. Assigned by driver*/
  676. request.physical_buffer = 0; /*Physical address of data buffer is not set*/
  677. request.owner = (SDIO_Owner) pHwAccess;
  678. request.mode = MMC_DEV_BYTE_INCREMENTAL_MODE;
  679. request.access_flag = 0;
  680. os_profile (pHwAccess->hOs, 2, 0);
  681. status = SDIO_SyncWrite(pHwAccess->hDriver, &request);
  682. os_profile (pHwAccess->hOs, 3, 0);
  683. #elif defined(HW_ACCESS_WSPI)
  684. /* check address */
  685. if (((addr+len) > pHwAccess->workingPartUpperLimit) || (addr < pHwAccess->MemRegionAddr))
  686. {
  687. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  688. ("whal_hwAccess_WriteMem_Align: Error in addr 0x%x (lower:0x%x,upper:0x%x)\n",
  689. addr, pHwAccess->MemRegionAddr, pHwAccess->workingPartUpperLimit));
  690. return ERROR_HW_ACCEESS_ADDR;
  691. }
  692. os_profile (pHwAccess->hOs, 2, 0);
  693. status = WSPI_WriteSync(pHwAccess->hDriver,TRANSLATE_ADDRESS_MEM(addr),data,len);
  694. os_profile (pHwAccess->hOs, 3, 0);
  695. #else
  696. whal_hwAccess_DirectCopy_new(pHwAccess, (UINT8*)addr, data, len);
  697. #endif
  698. if (status != OK)
  699. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  700. ("whal_hwAccess_WriteMem_Align: Error in write, addr=0x%08x status=%d\n",
  701. addr, status));
  702. #ifdef HW_ACCESS_SDIO
  703. if (pHwAccess->uBusError)
  704. {
  705. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  706. ("whal_hwAccess_WriteMem_Align: SDIO Error in write status=%d\n",
  707. request.status));
  708. if (pHwAccess->hwAccesserror_Cb)
  709. {
  710. UINT8 failure_reason = HEALTH_REPORT_BUS_ERROR;
  711. pHwAccess->hwAccesserror_Cb(pHwAccess->hBackReference,(char*)&failure_reason,2);
  712. }
  713. else
  714. pHwAccess->uBusError = 0;
  715. }
  716. #endif
  717. return status;
  718. }
  719. #endif /* USE_SYNC_API */
  720. /****************************************************************************
  721. * whal_hwAccess_ReadMemAsync_Align
  722. ****************************************************************************
  723. * DESCRIPTION: read data asynchronously from the TNET using the defined access (WSPI/SDIO).
  724. * the length of data specified is rounded up so the length will be multiple of 4 (bytes)
  725. * the function is passed a call-back function that will be called after the read request ends.
  726. *
  727. * INPUTS: hHwAccess - the handle of HwAccess module
  728. * addr - UINT32 - the address offset inside the TNET
  729. * len - int - the length of the data to read
  730. * CB - HWAccess_CB_T* - a pointer to a structure that holds the CB function and the passed arg.
  731. *
  732. * OUTPUT: data - UINT8* - a pointer to the buffer to fill with the read data
  733. *
  734. * RETURNS: one of the error codes (0 => OK)
  735. ****************************************************************************/
  736. int whal_hwAccess_ReadMemAsync_Align(TI_HANDLE hHwAccess, UINT32 addr, UINT8* data, UINT16 len)
  737. {
  738. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  739. /* Round the length so it will be multiple of 4bytes */
  740. if ((len & 0x3) != 0)
  741. len = (len & ~3) + 4;
  742. /* Check address */
  743. if (addr + len > pHwAccess->workingPartUpperLimit || addr < pHwAccess->MemRegionAddr)
  744. {
  745. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  746. ("whal_hwAccess_ReadMemAsync_Align: Error in addr 0x%x (lower:0x%x,upper:0x%x)\n",
  747. addr, pHwAccess->MemRegionAddr, pHwAccess->workingPartUpperLimit));
  748. return ERROR_HW_ACCEESS_ADDR;
  749. }
  750. #if defined(HW_ACCESS_SDIO)
  751. #if defined(HW_ACCESS_SDIO_ASYNC_SUPPORT)
  752. {
  753. struct SDIO_Request request;
  754. int status = OK;
  755. request.buffer = data; /* Pointer to the data buffer aligned address. */
  756. request.buffer_len = len; /* Data buffer length in bytes */
  757. request.status = SDIO_Request_None;
  758. request.peripheral_addr = (SDIO_Address)TRANSLATE_ADDRESS_MEM(addr); /*SDIO peripheral address*/
  759. request.acquire_window = 0; /*Time out value is not set*/
  760. request.block_len = 0; /*Block length. Assigned by driver*/
  761. request.physical_buffer = 0; /*Physical address of data buffer is not set*/
  762. request.owner = (SDIO_Owner) pHwAccess;
  763. request.mode = MMC_DEV_BYTE_INCREMENTAL_MODE;
  764. request.access_flag = 1;
  765. request.fnotify = sdio_async_transaction_notify; /* completion notification */
  766. request.ferror = sdio_async_transaction_error; /* error notification */
  767. os_profile (pHwAccess->hOs, 2, 0);
  768. status = SDIO_AsyncRead (pHwAccess->hDriver, &request);
  769. os_profile (pHwAccess->hOs, 3, 0);
  770. if (status != OK)
  771. {
  772. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  773. ("whal_hwAccess_ReadMemAsync_Align: Error in read async, addr=0x%08x status=%d\n",
  774. addr, status));
  775. return TNETWIF_ERROR;
  776. }
  777. if (pHwAccess->uBusError)
  778. {
  779. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  780. ("whal_hwAccess_ReadMemAsync_Align: SDIO Error status=%d\n",
  781. request.status));
  782. if (pHwAccess->hwAccesserror_Cb)
  783. {
  784. UINT16 failure_reason = HEALTH_REPORT_BUS_ERROR;
  785. pHwAccess->hwAccesserror_Cb(pHwAccess->hBackReference,&failure_reason,2);
  786. }
  787. else
  788. pHwAccess->uBusError = 0;
  789. }
  790. return TNETWIF_COMPLETE;
  791. }
  792. #else
  793. return TNETWIF_COMPLETE;
  794. #endif
  795. #else /*HW_ACCESS_WSPI*/
  796. {
  797. int status;
  798. os_profile (pHwAccess->hOs, 2, 0);
  799. status = WSPI_ReadAsync (pHwAccess->hDriver,
  800. TRANSLATE_ADDRESS_MEM(addr),
  801. data,
  802. len,
  803. (WSPI_CB_T*)&pHwAccess->CB,
  804. TRUE,
  805. 0);
  806. os_profile (pHwAccess->hOs, 3, 0);
  807. WSPI2TNETWIF (pHwAccess, status, addr);
  808. return status;
  809. }
  810. #endif
  811. }
  812. /****************************************************************************
  813. * whal_hwAccess_WriteAsync_Align
  814. ****************************************************************************
  815. * DESCRIPTION: write data synchronously from the TNET using the defined access (WSPI/SDIO).
  816. * the length of data specified is rounded up so the length will be multiple of 4 (bytes)
  817. * the function is passed a call-back function that will be called after the read request ends.
  818. *
  819. * INPUTS: pHwAccess - HwAccess_T* - the HwAccess context
  820. * addr - UINT32 - the address offset inside the TNET
  821. * data - UINT8* - a pointer to the buffer that holds the data to write
  822. * Len - int - the length of the data to read
  823. * CB - HWAccess_CB_T* - a pointer to a structure that holds the CB function and the passed arg.
  824. *
  825. * OUTPUT: none
  826. *
  827. * RETURNS: one of the error codes (0 => OK)
  828. ****************************************************************************/
  829. int whal_hwAccess_WriteMemAsync_Align(TI_HANDLE hHwAccess, UINT32 addr, UINT8* data, UINT16 len)
  830. {
  831. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  832. /* Round the length so it will be multiple of 4bytes */
  833. if ((len & 0x3) != 0)
  834. len = (len & ~3) + 4;
  835. /* Check address */
  836. if (addr + len > pHwAccess->workingPartUpperLimit || addr < pHwAccess->MemRegionAddr)
  837. {
  838. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  839. ("whal_hwAccess_WriteMemAsync_Align: Error in addr 0x%x (lower:0x%x,upper:0x%x)\n",
  840. addr, pHwAccess->MemRegionAddr, pHwAccess->workingPartUpperLimit));
  841. return ERROR_HW_ACCEESS_ADDR;
  842. }
  843. #if defined(HW_ACCESS_SDIO)
  844. #if defined(HW_ACCESS_SDIO_ASYNC_SUPPORT)
  845. {
  846. struct SDIO_Request request;
  847. int status = OK;
  848. request.buffer = data; /*Pointer to the data buffer aligned address*/
  849. request.buffer_len = len; /*Data buffer length in bytes*/
  850. request.status = SDIO_Request_None;
  851. request.peripheral_addr = (SDIO_Address)TRANSLATE_ADDRESS_MEM(addr); /*SDIO peripheral address*/
  852. request.acquire_window = 0; /* Time out value is not set */
  853. request.block_len = 0; /* Block length. Assigned by driver */
  854. request.physical_buffer = 0; /* Physical address of data buffer is not set */
  855. request.owner = (SDIO_Owner) pHwAccess;
  856. request.mode = MMC_DEV_BYTE_INCREMENTAL_MODE;
  857. request.access_flag = 0;
  858. request.fnotify = sdio_async_transaction_notify; /* completion notification */
  859. request.ferror = sdio_async_transaction_error; /* error notification */
  860. os_profile (pHwAccess->hOs, 2, 0);
  861. status = SDIO_AsyncWrite (pHwAccess->hDriver, &request);
  862. os_profile (pHwAccess->hOs, 3, 0);
  863. if (status != OK)
  864. {
  865. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  866. ("whal_hwAccess_WriteMemAsync_Align: Error in write async, addr=0x%08x status=%d\n",
  867. addr, status));
  868. return TNETWIF_ERROR;
  869. }
  870. return TNETWIF_COMPLETE;
  871. }
  872. #else
  873. return TNETWIF_COMPLETE;
  874. #endif
  875. #else /*HW_ACCESS_WSPI*/
  876. {
  877. int status;
  878. os_profile (pHwAccess->hOs, 2, 0);
  879. status = WSPI_WriteAsync (pHwAccess->hDriver,
  880. TRANSLATE_ADDRESS_MEM(addr),
  881. data,
  882. len,
  883. (WSPI_CB_T*)&pHwAccess->CB,
  884. TRUE,
  885. FALSE);
  886. os_profile (pHwAccess->hOs, 3, 0);
  887. WSPI2TNETWIF (pHwAccess, status, addr);
  888. return status;
  889. }
  890. #endif
  891. }
  892. #ifdef USE_SYNC_API
  893. /****************************************************************************
  894. * whal_hwAccess_ReadMem
  895. ****************************************************************************
  896. * DESCRIPTION: read data synchronously from the TNET using the defined access (WSPI/SDIO).
  897. * the length of data is checked and the remnant (length%4) is completed with read-modify
  898. *
  899. * INPUTS: pHwAccess - HwAccess_T* - the HwAccess context
  900. * AddrOffset - UINT32 - the address offset inside the TNET
  901. * Len - int - the length of the data to read
  902. *
  903. * OUTPUT: data - UINT8* - a pointer to the buffer to fill with the read data
  904. *
  905. * RETURNS: one of the error codes (0 => OK)
  906. ****************************************************************************/
  907. int whal_hwAccess_ReadMem(TI_HANDLE hHwAccess, UINT32 addr, UINT8* data, UINT16 len)
  908. {
  909. int status = OK;
  910. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  911. #ifdef HW_ACCESS_SDIO
  912. struct SDIO_Request request;
  913. #elif defined(HW_ACCESS_WSPI)
  914. int reminder = len%HW_ACCESS_WSPI_ALIGNED_SIZE;
  915. int tempLen = len - reminder;
  916. UINT32 mask = 0;
  917. status = whal_hwAccess_ReadMemAsync(hHwAccess, addr, data, len);
  918. if (status == TNETWIF_COMPLETE)
  919. {
  920. status = OK;
  921. }
  922. return status;
  923. #endif
  924. /* access is blocked */
  925. if (pHwAccess->uBusError)
  926. {
  927. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_CTRL_MODULE_LOG,
  928. ("Bus is blocked \n"));
  929. return ERROR_HW_ACCEESS_ADDR;
  930. }
  931. #ifdef __HWACCESS_DEBUG__
  932. /* check address alignment */
  933. if(addr & 0x3)
  934. {
  935. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  936. ("whal_hwAccess_ReadMem: addr is not aligned 0x%x\n",
  937. addr));
  938. }
  939. #endif
  940. #ifdef HW_ACCESS_SDIO
  941. /* check address */
  942. if (((addr+len) > pHwAccess->workingPartUpperLimit) || (addr < pHwAccess->MemRegionAddr))
  943. {
  944. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  945. ("whal_hwAccess_ReadMem: Error in addr 0x%x (lower:0x%x,upper:0x%x)\n",
  946. addr, pHwAccess->MemRegionAddr, pHwAccess->workingPartUpperLimit));
  947. return ERROR_HW_ACCEESS_ADDR;
  948. }
  949. request.buffer = data; /* Pointer to the data buffer aligned address. */
  950. request.buffer_len = len; /* Data buffer length in bytes */
  951. request.status = SDIO_Request_None;
  952. request.peripheral_addr = (SDIO_Address)TRANSLATE_ADDRESS_MEM(addr); /*SDIO peripheral address*/
  953. request.acquire_window = 0; /*Time out value is not set*/
  954. request.block_len = 0; /*Block length. Assigned by driver*/
  955. request.physical_buffer = 0; /*Physical address of data buffer is not set*/
  956. request.owner = (SDIO_Owner) pHwAccess;
  957. request.mode = MMC_DEV_BYTE_INCREMENTAL_MODE;
  958. request.access_flag = 1;
  959. os_profile (pHwAccess->hOs, 2, 0);
  960. status = SDIO_SyncRead(pHwAccess->hDriver, &request);
  961. os_profile (pHwAccess->hOs, 3, 0);
  962. if (status != OK)
  963. {
  964. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  965. ("whal_hwAccess_ReadMem: SDIO Error in read\n"));
  966. return status;
  967. }
  968. #elif defined(HW_ACCESS_WSPI)
  969. /* check address */
  970. if (((addr+len) > pHwAccess->workingPartUpperLimit) || (addr < pHwAccess->MemRegionAddr))
  971. {
  972. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  973. ("whal_hwAccess_ReadMem: Error in addr 0x%x (lower:0x%x,upper:0x%x)\n",
  974. addr, pHwAccess->MemRegionAddr, pHwAccess->workingPartUpperLimit));
  975. return ERROR_HW_ACCEESS_ADDR;
  976. }
  977. os_profile (pHwAccess->hOs, 2, 0);
  978. /* read the aligned size */
  979. status = WSPI_ReadSync(pHwAccess->hDriver,TRANSLATE_ADDRESS_MEM(addr),data,tempLen);
  980. os_profile (pHwAccess->hOs, 3, 0);
  981. if (status != OK)
  982. {
  983. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  984. ("whal_hwAccess_ReadMem: WSPI Error in read\n"));
  985. return status;
  986. }
  987. /* read the non aligned reminder */
  988. if(reminder)
  989. {
  990. UINT32 tempVal = 0;
  991. os_profile (pHwAccess->hOs, 2, 0);
  992. /* read the extra data*/
  993. status |= WSPI_ReadSync(pHwAccess->hDriver,TRANSLATE_ADDRESS_MEM(addr+tempLen),(UINT8*)&tempVal,HW_ACCESS_WSPI_ALIGNED_SIZE);
  994. os_profile (pHwAccess->hOs, 3, 0);
  995. if (status != OK)
  996. {
  997. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  998. ("whal_hwAccess_ReadMem: WSPI Error in read\n"));
  999. return status;
  1000. }
  1001. /* extract the relevant data */
  1002. switch(reminder)
  1003. {
  1004. case 1:
  1005. mask = HW_ACCESS_1_BYTE_REMINDE_MASK;
  1006. break;
  1007. case 2:
  1008. mask = HW_ACCESS_2_BYTE_REMINDE_MASK;
  1009. break;
  1010. case 3:
  1011. mask = HW_ACCESS_3_BYTE_REMINDE_MASK;
  1012. break;
  1013. }
  1014. *(UINT32*)&data[tempLen] &= ~mask;
  1015. *(UINT32*)&data[tempLen] |= tempVal & mask;
  1016. }
  1017. #else
  1018. whal_hwAccess_DirectCopy_new(pHwAccess, data, (UINT8*)(pHwAccess->MemBaseAddr+addr), len);
  1019. #endif
  1020. #ifdef HW_ACCESS_SDIO
  1021. if (pHwAccess->uBusError)
  1022. {
  1023. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  1024. ("whal_hwAccess_ReadMem: SDIO Error status=%d\n",
  1025. request.status));
  1026. if (pHwAccess->hwAccesserror_Cb)
  1027. {
  1028. UINT8 failure_reason = HEALTH_REPORT_BUS_ERROR;
  1029. pHwAccess->hwAccesserror_Cb(pHwAccess->hBackReference,(char*)&failure_reason,2);
  1030. }
  1031. else
  1032. pHwAccess->uBusError = 0;
  1033. }
  1034. #endif
  1035. return OK;
  1036. }
  1037. /****************************************************************************
  1038. * whal_hwAccess_WriteMem
  1039. ****************************************************************************
  1040. * DESCRIPTION: write data synchronously to the TNET using the defined access (WSPI/SDIO).
  1041. * the length of data is checked and the remnant (length%4) is completed with read-modify-write
  1042. *
  1043. * INPUTS: pHwAccess - TI_HANDLE* - the HwAccess context
  1044. * addr - UINT32 - the address offset inside the TNET
  1045. * data - UINT8* - a pointer to the buffer that holds the data to write
  1046. * Len - int - the length of the data to read
  1047. *
  1048. * OUTPUT: none
  1049. *
  1050. * RETURNS: one of the error codes (0 => OK)
  1051. ****************************************************************************/
  1052. int whal_hwAccess_WriteMem(TI_HANDLE hHwAccess, UINT32 addr, UINT8* data, UINT16 len)
  1053. {
  1054. int status = OK;
  1055. HwAccess_T_new* pHwAccess = (HwAccess_T_new*)hHwAccess;
  1056. #ifdef HW_ACCESS_SDIO
  1057. struct SDIO_Request request;
  1058. #elif defined(HW_ACCESS_WSPI)
  1059. int reminder = len % HW_ACCESS_WSPI_ALIGNED_SIZE;
  1060. int tempLen = len - reminder;
  1061. UINT32 mask = 0;
  1062. status = whal_hwAccess_WriteMemAsync(hHwAccess, addr, data, len);
  1063. if (status == TNETWIF_COMPLETE)
  1064. {
  1065. status = OK;
  1066. }
  1067. return status;
  1068. #endif
  1069. /* access is blocked */
  1070. if (pHwAccess->uBusError)
  1071. {
  1072. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_CTRL_MODULE_LOG,
  1073. ("Bus is blocked \n"));
  1074. return ERROR_HW_ACCEESS_ADDR;
  1075. }
  1076. #ifdef __HWACCESS_DEBUG__
  1077. /* check address alignment */
  1078. if(addr & 0x3)
  1079. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  1080. ("whal_hwAccess_WriteMem: addr is not aligned 0x%x\n",
  1081. addr));
  1082. #endif
  1083. #ifdef HW_ACCESS_SDIO
  1084. /* check address */
  1085. if (((addr+len) > pHwAccess->workingPartUpperLimit) || (addr < pHwAccess->MemRegionAddr))
  1086. {
  1087. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  1088. ("whal_hwAccess_WriteMem: Error in addr 0x%x (lower:0x%x,upper:0x%x)\n",
  1089. addr, pHwAccess->MemRegionAddr, pHwAccess->workingPartUpperLimit));
  1090. return ERROR_HW_ACCEESS_ADDR;
  1091. }
  1092. request.buffer = data; /* Pointer to the data buffer aligned address. */
  1093. request.buffer_len = len; /* Data buffer length in bytes */
  1094. request.status = SDIO_Request_None;
  1095. request.peripheral_addr = (SDIO_Address)TRANSLATE_ADDRESS_MEM(addr); /*SDIO peripheral address*/
  1096. request.acquire_window = 0; /*Time out value is not set*/
  1097. request.block_len = 0; /*Block length. Assigned by driver*/
  1098. request.physical_buffer = 0; /*Physical address of data buffer is not set*/
  1099. request.owner = (SDIO_Owner) pHwAccess;
  1100. request.mode = MMC_DEV_BYTE_INCREMENTAL_MODE;
  1101. request.access_flag = 0;
  1102. os_profile (pHwAccess->hOs, 2, 0);
  1103. status = SDIO_SyncWrite(pHwAccess->hDriver, &request);
  1104. os_profile (pHwAccess->hOs, 3, 0);
  1105. if (status != OK)
  1106. {
  1107. WLAN_REPORT_ERROR(pHwAccess->hReport, HAL_HW_CTRL_MODULE_LOG,
  1108. ("whal_hwAccess_…

Large files files are truncated, but you can click here to view the full file