PageRenderTime 70ms CodeModel.GetById 32ms RepoModel.GetById 0ms app.codeStats 0ms

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

https://bitbucket.org/cyanogenmod/cm-kernel
C | 1433 lines | 725 code | 193 blank | 515 comment | 122 complexity | cac3d746a186542a49eb549504ed99f4 MD5 | raw file
Possible License(s): GPL-2.0, LGPL-2.0, AGPL-1.0
  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: wspi.c
  38. * PURPOSE:
  39. *
  40. ****************************************************************************/
  41. #include "osTIType.h"
  42. #include "osApi.h"
  43. #include "whalCommon.h"
  44. #include "spi_api.h"
  45. #include "wspi.h"
  46. /* WSPI INIT CMD
  47. -----------------------------------------------------------------
  48. | start | tx | command |
  49. -----------------------------------------------------------------
  50. 47 46 45 40
  51. -----------------------------------------------------------------
  52. | reserve |
  53. -----------------------------------------------------------------
  54. 39 32
  55. -----------------------------------------------------------------
  56. | reserve |
  57. -----------------------------------------------------------------
  58. 31 24
  59. -----------------------------------------------------------------
  60. | reserve | 1250 | fixed busy length |
  61. -----------------------------------------------------------------
  62. 23 16
  63. -----------------------------------------------------------------
  64. | fixed | | | | | | | |
  65. | busy | iod | ip | cs | ws | bs | de | wspi |
  66. | enable| | | | | | | |
  67. -----------------------------------------------------------------
  68. 15 14 13 12 11 10 9 8
  69. -----------------------------------------------------------------
  70. | CRC7 | end |
  71. -----------------------------------------------------------------
  72. 7 1 0
  73. */
  74. #define WSPI_SIZEOF_UINT32 sizeof (UINT32)
  75. #define WSPI_INIT_CMD_CRC_LEN 5
  76. #define WSPI_INIT_CMD_START 0x00
  77. #define WSPI_INIT_CMD_TX 0x40
  78. #define WSPI_INIT_CMD_BYPASS_BIT 0x80 /* the extra bypass bit is sampled by the TNET as '1' */
  79. #define WSPI_INIT_CMD_FIXEDBUSY_LEN 0x07
  80. #define WSPI_INIT_CMD_EN_FIXEDBUSY 0x80
  81. #define WSPI_INIT_CMD_DIS_FIXEDBUSY 0x00
  82. #define WSPI_INIT_CMD_IOD 0x40
  83. #define WSPI_INIT_CMD_IP 0x20
  84. #define WSPI_INIT_CMD_CS 0x10
  85. #define WSPI_INIT_CMD_WS 0x08
  86. #define WSPI_INIT_CMD_WSPI 0x01
  87. #define WSPI_INIT_CMD_END 0x01
  88. #define WSPI_INIT_CMD_CRC_INPUT_LEN 40
  89. #define PRINT_TEST_REGION_SIZE 100
  90. #define PRINT_TEST_REGION_START 0x305674 /* the device ID register */
  91. #define PRINT_TEST_SIZE_REG 0x1FFC0
  92. #define PRINT_TEST_ADDR_REG 0x1FFC4
  93. /* WSPI CMD
  94. -----------------------------------------------------------------
  95. | start | tx | fixed | byte length |
  96. -----------------------------------------------------------------
  97. 31 30 29 28 24
  98. -----------------------------------------------------------------
  99. | byte length | a16 |
  100. -----------------------------------------------------------------
  101. 23 17 16
  102. -----------------------------------------------------------------
  103. | byte address |
  104. -----------------------------------------------------------------
  105. 15 8
  106. -----------------------------------------------------------------
  107. | byte address |
  108. -----------------------------------------------------------------
  109. 7 0
  110. */
  111. /* The 31's bit in the WSPI cmd is read bit */
  112. #define WSPI_CMD_READ 0x40000000
  113. #define WSPI_CMD_WRITE 0x00000000
  114. #define WSPI_CMD_FIXED 0x20000000
  115. #define WSPI_CMD_BYTE_LENGTH 0x1FFE0000
  116. #define WSPI_CMD_BYTE_LENGTH_OFFSET 17
  117. #define WSPI_CMD_BYTE_ADDR 0x0001FFFF
  118. #define WSPI_FIXED_BUSY_TIMEOUT 100
  119. #define WSPI_SYNC_OVER_ASYNC_TIMEOUT 100
  120. /* For FixedBusy Handle */
  121. #define NOT_IN_USE 0
  122. static UINT8 WSPI_GenerateCRC7 (UINT8* bits, UINT32 len);
  123. #ifndef USE_WRITE_READ_API
  124. static void WSPI_WriteCmdCb (TI_HANDLE hWSPI, int status);
  125. #endif
  126. static void WSPI_ReadDataCb (TI_HANDLE hWSPI, int status);
  127. #ifdef USE_SYNC_API
  128. #ifdef USE_SYNC_OVER_ASYNC
  129. static void WSPI_SyncOverAsyncCb (TI_HANDLE hWSPI, int status);
  130. #endif
  131. #endif
  132. static void WSPI_ReadAsyncCb (TI_HANDLE hWSPI, int status);
  133. static void WSPI_ConfigureResetCb (TI_HANDLE hWSPI, int status);
  134. #ifdef TI_DBG
  135. int DebugFixedBusy[10];
  136. #endif
  137. /*
  138. * ----------------------------------------------------------------------------
  139. * Function : WSPI_Open
  140. *
  141. * Input : none
  142. *
  143. * Output : void** phWSPI - a pointer to the handle of the WSPI
  144. *
  145. * ReturnVal: one of the error codes (zero is success)
  146. *
  147. * Note(s) : allocates the WSPI driver context and creates the SPI sublayer
  148. * -----------------------------------------------------------------------------
  149. */
  150. TI_HANDLE WSPI_Open (TI_HANDLE hOs)
  151. {
  152. WSPI_t* pWSPI;
  153. /* Allocate WSPI memory */
  154. pWSPI = (WSPI_t *) os_memoryAlloc (hOs, sizeof(WSPI_t));
  155. if (pWSPI == NULL)
  156. {
  157. return NULL;
  158. }
  159. pWSPI->hOs = hOs;
  160. pWSPI->pTempBuf = 0;
  161. pWSPI->pExtraFixedBusyBuf = 0;
  162. /* Call to SPI_Open */
  163. pWSPI->hSPI = SPI_Open ();
  164. return (TI_HANDLE)pWSPI;
  165. }
  166. /*
  167. * ----------------------------------------------------------------------------
  168. * Function : WSPI_Close
  169. *
  170. * Input : void* hWSPI - the WSPI handle
  171. *
  172. * Output : none
  173. *
  174. * ReturnVal: one of the error codes (zero is success)
  175. *
  176. * Note(s) : frees the WSPI driver context and closes the SPI sublayer
  177. * -----------------------------------------------------------------------------
  178. */
  179. int WSPI_Close (TI_HANDLE hWSPI)
  180. {
  181. WSPI_t* pWSPI = (WSPI_t*)hWSPI;
  182. /* Call SPI_Close */
  183. SPI_Close (pWSPI->hSPI);
  184. /* Free temporary buffer */
  185. if (pWSPI->pTempBuf)
  186. {
  187. os_memoryFree (pWSPI->hOs, pWSPI->pTempBuf, WSPI_NO_EXTRA_ALLOC_SIZE + pWSPI->uFixedBusyBytes);
  188. }
  189. if (pWSPI->pExtraFixedBusyBuf)
  190. {
  191. os_memoryFree (pWSPI->hOs, pWSPI->pExtraFixedBusyBuf, WSPI_EXTRA_BUFFER_ALLOC_SIZE);
  192. }
  193. /* Free allocated memory */
  194. os_memoryFree (pWSPI->hOs, hWSPI, sizeof(WSPI_t));
  195. return WSPI_OK;
  196. }
  197. /*
  198. * ----------------------------------------------------------------------------
  199. * Function : WSPI_Configure
  200. *
  201. * Input : void* hWSPI - the WSPI handle
  202. * const WSPIConfig_t* aConfig - a structure that holds the configuration data
  203. WSPI_CB_T* cb - callback
  204. *
  205. * Output :
  206. *
  207. * ReturnVal: one of the error codes (zero is success)
  208. *
  209. * Note(s) : 1. configures the SPI sublayer
  210. * 2. sends the WSPI init word
  211. * -----------------------------------------------------------------------------
  212. */
  213. int WSPI_Configure (TI_HANDLE hWSPI, TI_HANDLE hReport, const WSPIConfig_t* aConfig, WSPI_CB_T* cb)
  214. {
  215. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  216. int i;
  217. #ifdef TI_DBG
  218. for (i=0;i<10;i++)
  219. {
  220. DebugFixedBusy[i] = 0;
  221. }
  222. #endif
  223. /*
  224. * This function is called during initialization and recovery. In recovery,
  225. * The old values are used, so there's no need to re-configure everything again.
  226. */
  227. if (NULL != aConfig)
  228. {
  229. /* Set WSPI_t parameters */
  230. pWSPI->uConfigMask = aConfig->mask;
  231. pWSPI->bFixedAddr = aConfig->isFixedAddress;
  232. pWSPI->uFixedBusyLen = aConfig->fixedBusyLength;
  233. pWSPI->uFixedBusyBytes = pWSPI->uFixedBusyLen * 4 + 4;
  234. /* Will be set to TRUE only when no extra bytes were allocated */
  235. pWSPI->bUseTempBuf = FALSE;
  236. pWSPI->fErr = 0;
  237. pWSPI->hReport = hReport;
  238. /* Save CB for the WSPI_ConfigureResetCb() */
  239. pWSPI->fCb = cb->CBFunc;
  240. pWSPI->pCb = cb->CBArg;
  241. /* Allocate the temporary buffer that will hold buffers with no extra room */
  242. if (pWSPI->uFixedBusyLen != 0)
  243. {
  244. if ((pWSPI->pTempBuf = os_memoryAlloc (pWSPI->hOs, WSPI_NO_EXTRA_ALLOC_SIZE + pWSPI->uFixedBusyBytes)) == NULL)
  245. {
  246. return WSPI_ERR_ALLOC_MEM;
  247. }
  248. }
  249. }
  250. /* Allocate the temporary buffer that will hold buffers with no extra room */
  251. if ((pWSPI->pExtraFixedBusyBuf = os_memoryAlloc (pWSPI->hOs, WSPI_EXTRA_BUFFER_ALLOC_SIZE)) == NULL)
  252. {
  253. return WSPI_ERR_ALLOC_MEM;
  254. }
  255. pWSPI->ExtraBufLength = 0;
  256. /* This CMD is used to reset the HW SM */
  257. for (i = 0; i < WSPI_INIT_CMD_LEN; i++)
  258. {
  259. pWSPI->auInitCmd[i] = 0xff;
  260. }
  261. /* Write the reset CMD */
  262. pWSPI->returnStatus = SPI_Write (pWSPI->hSPI, pWSPI->auInitCmd, WSPI_INIT_CMD_LEN, (request_callback_t)WSPI_ConfigureResetCb, hWSPI, 1);
  263. if (pWSPI->returnStatus == SPI_TXN_COMPLETE)
  264. {
  265. /* Note that in the next function call, pWSPI->returnStatus is going to be changed */
  266. WSPI_ConfigureResetCb(hWSPI, OK);
  267. }
  268. return (pWSPI->returnStatus == SPI_TXN_COMPLETE ? WSPI_TXN_COMPLETE :
  269. (pWSPI->returnStatus == SPI_TXN_PENDING ? WSPI_TXN_PENDING : WSPI_ERR_UNKNOWN));
  270. }
  271. static void WSPI_ConfigureResetCb (TI_HANDLE hWSPI, int status)
  272. {
  273. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  274. UINT8 auCRCBuffer [WSPI_INIT_CMD_CRC_LEN];
  275. /*
  276. * Set WSPI_INIT_COMMAND
  277. * the data is being send from the MSB to LSB
  278. */
  279. pWSPI->auInitCmd[2] = 0xff;
  280. pWSPI->auInitCmd[3] = 0xff;
  281. pWSPI->auInitCmd[1] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX;
  282. pWSPI->auInitCmd[0] = 0;
  283. pWSPI->auInitCmd[7] = 0;
  284. pWSPI->auInitCmd[6] =
  285. (pWSPI->uConfigMask << 3) | (pWSPI->uFixedBusyLen & WSPI_INIT_CMD_FIXEDBUSY_LEN);
  286. pWSPI->auInitCmd[5] =
  287. ((pWSPI->uFixedBusyLen == 0) ?
  288. WSPI_INIT_CMD_DIS_FIXEDBUSY :
  289. WSPI_INIT_CMD_EN_FIXEDBUSY)
  290. | WSPI_INIT_CMD_IOD
  291. | WSPI_INIT_CMD_IP
  292. | WSPI_INIT_CMD_CS
  293. #ifndef SPI_16_BIT
  294. | WSPI_INIT_CMD_WS
  295. #endif
  296. | WSPI_INIT_CMD_WSPI;
  297. auCRCBuffer[0] = pWSPI->auInitCmd[1];
  298. auCRCBuffer[1] = pWSPI->auInitCmd[0];
  299. auCRCBuffer[2] = pWSPI->auInitCmd[7];
  300. auCRCBuffer[3] = pWSPI->auInitCmd[6];
  301. auCRCBuffer[4] = pWSPI->auInitCmd[5];
  302. pWSPI->auInitCmd[4] =
  303. (WSPI_GenerateCRC7 (auCRCBuffer, WSPI_INIT_CMD_CRC_INPUT_LEN) << 1)
  304. | WSPI_INIT_CMD_END;
  305. pWSPI->returnStatus = SPI_Write (pWSPI->hSPI, pWSPI->auInitCmd, WSPI_INIT_CMD_LEN, pWSPI->fCb, pWSPI->pCb, 1);
  306. }
  307. /*
  308. * ----------------------------------------------------------------------------
  309. * Function : WSPI_ReadSync
  310. *
  311. * Input : void* hWSPI - the WSPI handle
  312. * UINT32 address - the address (in bytes) in the firmware to read the data from
  313. * UINT32 length - the number of bytes to read
  314. * WSPI_CB_T cb - callback parameters
  315. * BOOL bMore - more read/write transaction will follow
  316. *
  317. * Output : UINT8* data - the buffer to put the read data
  318. *
  319. * ReturnVal: one of the error codes (zero is success)
  320. *
  321. * Note(s) : 1. set the WSPI cammand+address word
  322. * 2. send the WSPIcammand+address word
  323. * 3. read the fixed busy
  324. * 4. read the data
  325. * 5. check that the fixed busy was OK
  326. *
  327. * because of the TNET state machine the data is always sent and only after
  328. * we read it we validate that it's OK
  329. * -----------------------------------------------------------------------------
  330. */
  331. int WSPI_ReadSync (TI_HANDLE hWSPI, UINT32 address, UINT8* data, UINT32 length)
  332. {
  333. #ifdef USE_SYNC_OVER_ASYNC
  334. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  335. WSPI_CB_T cb = { (request_callback_t)WSPI_SyncOverAsyncCb, hWSPI };
  336. UINT32 i, timeout;
  337. if (length == 0)
  338. {
  339. return WSPI_ERR_WRONG_LENGTH;
  340. }
  341. /* Set the sync flag */
  342. pWSPI->bSyncFlag = 0;
  343. WSPI_ReadAsync (hWSPI, address, data, length, &cb, 1, 0);
  344. /* Wait to end of the asynchronous read */
  345. timeout = WSPI_SYNC_OVER_ASYNC_TIMEOUT * length;
  346. for (i = 0; i < timeout; i++)
  347. {
  348. if (pWSPI->bSyncFlag)
  349. {
  350. break;
  351. }
  352. }
  353. if (i == timeout)
  354. {
  355. /* Reached the timeout criteria without ending the asynchronous read */
  356. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG, ("WSPI ASYNC READ DIDN'T FINISH\n"));
  357. return WSPI_ERR_ASYNC_TIMEOUT;
  358. }
  359. return WSPI_OK;
  360. #else /* USE_SYNC_OVER_ASYNC */
  361. WSPI_t* pWSPI = (WSPI_t*)hWSPI;
  362. UINT32 i;
  363. UINT32 uFixedBusy;
  364. int ret = WSPI_OK;
  365. if (length == 0)
  366. {
  367. return WSPI_ERR_WRONG_LENGTH;
  368. }
  369. /*****************************/
  370. /* Write the command+address */
  371. /*****************************/
  372. pWSPI->uCmd = WSPI_CMD_READ;
  373. /* Set bFixedAddr */
  374. if (pWSPI->bFixedAddr)
  375. {
  376. pWSPI->uCmd |= WSPI_CMD_FIXED;
  377. }
  378. /* Set length */
  379. pWSPI->uCmd |= (length << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  380. /* Set address */
  381. pWSPI->uCmd |= address & WSPI_CMD_BYTE_ADDR;
  382. /* Write command+address */
  383. ret |= SPI_WriteSync (pWSPI->hSPI, (UINT8*)&pWSPI->uCmd, WSPI_SIZEOF_UINT32);
  384. if (pWSPI->uFixedBusyLen == 0)
  385. {
  386. /* 1150 */
  387. /* For 1150 read until we get the not-busy word */
  388. for (i = 0; i < WSPI_FIXED_BUSY_TIMEOUT; i++)
  389. {
  390. ret |= SPI_ReadSync (pWSPI->hSPI, (UINT8*)&uFixedBusy, WSPI_SIZEOF_UINT32);
  391. if ((uFixedBusy & 0x1) != 0)
  392. {
  393. break;
  394. }
  395. }
  396. if (i == WSPI_FIXED_BUSY_TIMEOUT)
  397. {
  398. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG, ("WSPI FIXED BUSY (SYNC)\n"));
  399. return WSPI_ERR_BUS_BUSY;
  400. }
  401. }
  402. else
  403. {
  404. /* 1251 */
  405. /* For 1251 read the predefined number of busy words and at the end the not-busy word */
  406. for (i = 0; i < pWSPI->uFixedBusyLen; i++)
  407. ret |= SPI_ReadSync (pWSPI->hSPI, (UINT8*)&uFixedBusy, WSPI_SIZEOF_UINT32);
  408. ret |= SPI_ReadSync (pWSPI->hSPI, (UINT8*)&uFixedBusy, WSPI_SIZEOF_UINT32);
  409. }
  410. /* Read data */
  411. ret |= SPI_ReadSync (pWSPI->hSPI, data, length);
  412. if (pWSPI->uFixedBusyLen)
  413. {
  414. /* 1251 */
  415. /* Check the fixed busy */
  416. if (!(uFixedBusy & 0x1))
  417. {
  418. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG, ("WSPI FIXED BUSY (SYNC)\n"));
  419. ret = WSPI_ERR_BUS_BUSY;
  420. }
  421. }
  422. return ret;
  423. #endif
  424. }
  425. /*
  426. * ----------------------------------------------------------------------------
  427. * Function : WSPI_ReadAsync
  428. *
  429. * Input : void* hWSPI - the WSPI handle
  430. * UINT32 address - the address (in bytes) in the firmware to read the data from
  431. * UINT32 length - the number of bytes to read
  432. * WSPI_CB_T cb - callback parameters
  433. * BOOL bMore - more read/write transaction will follow
  434. * BOOL bSpaceReserved
  435. * - extra space padding has been reserved by an upper layer
  436. *
  437. * Output : UINT8* data - the buffer to put the read data
  438. *
  439. * ReturnVal: one of the error codes (zero is success)
  440. *
  441. * -----------------------------------------------------------------------------
  442. */
  443. int WSPI_ReadAsyncOld (TI_HANDLE hWSPI, UINT32 address, UINT8* data, UINT32 length, WSPI_CB_T* cb, BOOL bMore, BOOL bSpaceReserved)
  444. {
  445. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  446. int ret = WSPI_OK;
  447. if (length == 0)
  448. {
  449. return WSPI_ERR_WRONG_LENGTH;
  450. }
  451. /*
  452. * Pass to the CB function of the read data also the fixed busy response so
  453. * to put all the required data in subsequent places in the buffer of the WSPI context
  454. * first the fixed busy, second the CBFunc, third the CBArg
  455. * here we guarantee that the data will be sequential
  456. */
  457. /*****************************/
  458. /* Write the command+address */
  459. /*****************************/
  460. pWSPI->uCmd = WSPI_CMD_READ;
  461. /* Set bFixedAddr */
  462. if (pWSPI->bFixedAddr)
  463. {
  464. pWSPI->uCmd |= WSPI_CMD_FIXED;
  465. }
  466. /* Set the length */
  467. pWSPI->uCmd |= (length << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  468. /* Set the address */
  469. pWSPI->uCmd |= address & WSPI_CMD_BYTE_ADDR;
  470. /* Write command+address */
  471. ret |= SPI_WriteSync (pWSPI->hSPI, (UINT8*)&pWSPI->uCmd, WSPI_SIZEOF_UINT32);
  472. if (pWSPI->uFixedBusyLen == 0)
  473. {
  474. UINT32 uFixedBusy, i;
  475. /* 1150 */
  476. /* For 1150 read until we get the not-busy word */
  477. for (i = 0; i < WSPI_FIXED_BUSY_TIMEOUT; i++)
  478. {
  479. ret |= SPI_ReadSync (pWSPI->hSPI, (UINT8*)&uFixedBusy, WSPI_SIZEOF_UINT32);
  480. if ((uFixedBusy & 0x1) != 0)
  481. {
  482. break;
  483. }
  484. }
  485. if (i == WSPI_FIXED_BUSY_TIMEOUT)
  486. {
  487. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG, ("WSPI FIXED BUSY (ASYNC)\n"));
  488. if (pWSPI->fErr)
  489. {
  490. (*pWSPI->fErr) ();
  491. }
  492. return WSPI_ERR_BUS_BUSY;
  493. }
  494. }
  495. else
  496. {
  497. UINT32 uFixedBusy, i;
  498. /* 1251 */
  499. /* For 1251 read the predefined number of busy words and at the end the not-busy word */
  500. for (i = 0; i < pWSPI->uFixedBusyLen; i++)
  501. ret |= SPI_ReadSync (pWSPI->hSPI, (UINT8*)&uFixedBusy, WSPI_SIZEOF_UINT32);
  502. ret |= SPI_ReadSync (pWSPI->hSPI, (UINT8*)&pWSPI->uFixedBusy, WSPI_SIZEOF_UINT32);
  503. }
  504. /* Read the data */
  505. pWSPI->fCb = cb->CBFunc;
  506. pWSPI->pCb = cb->CBArg;
  507. /* Tell the lower machine to start executing after this submission */
  508. ret |= SPI_Read (pWSPI->hSPI,
  509. data + bSpaceReserved * pWSPI->uFixedBusyBytes,
  510. length,
  511. WSPI_ReadAsyncCb,
  512. pWSPI,
  513. 1);
  514. return ret;
  515. }
  516. /*
  517. * ----------------------------------------------------------------------------
  518. * Function : WSPI_WriteSync
  519. *
  520. * Input : void* hWSPI - the WSPI handle
  521. * UINT32 address - the address (in bytes) in the firmware to read the data from
  522. * UINT8* data - the buffer that holds the data to write
  523. * UINT32 length - the number of bytes to read
  524. *
  525. * Output : none
  526. *
  527. * ReturnVal: one of the error codes (zero is success)
  528. *
  529. * Note(s) : 1. set the WSPI cammand+address word
  530. * 2. send the WSPIcammand+address word
  531. * 3. send the data
  532. *
  533. * -----------------------------------------------------------------------------
  534. */
  535. int WSPI_WriteSync (TI_HANDLE hWSPI, UINT32 address, UINT8* data, UINT32 length)
  536. {
  537. #ifdef USE_SYNC_OVER_ASYNC
  538. WSPI_t* pWSPI = (WSPI_t*)hWSPI;
  539. WSPI_CB_T cb = { (request_callback_t)WSPI_SyncOverAsyncCb, hWSPI };
  540. int i, timeout;
  541. if (length == 0)
  542. {
  543. return WSPI_ERR_WRONG_LENGTH;
  544. }
  545. /* Set the sync flag */
  546. pWSPI->bSyncFlag = 0;
  547. WSPI_WriteAsync (hWSPI, address, data, length, &cb, 1, 0);
  548. /* Wait to end of the asynchronous write */
  549. timeout = WSPI_SYNC_OVER_ASYNC_TIMEOUT * length;
  550. for (i = 0; i < timeout; i++)
  551. {
  552. if (pWSPI->bSyncFlag)
  553. {
  554. break;
  555. }
  556. }
  557. if (i == timeout)
  558. {
  559. /* Reached the timeout criteria without ending the asynchronous write */
  560. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG, ("WSPI ASYNC WRITE DIDN'T END\n"));
  561. return WSPI_ERR_ASYNC_TIMEOUT;
  562. }
  563. return WSPI_OK;
  564. #else
  565. WSPI_t* pWSPI = (WSPI_t*)hWSPI;
  566. int ret = WSPI_OK;
  567. if (length == 0)
  568. {
  569. return WSPI_ERR_WRONG_LENGTH;
  570. }
  571. /*****************************/
  572. /* Write the command+address */
  573. /*****************************/
  574. pWSPI->uCmd = WSPI_CMD_WRITE;
  575. /* Set bFixedAddr */
  576. if (pWSPI->bFixedAddr)
  577. {
  578. pWSPI->uCmd |= WSPI_CMD_FIXED;
  579. }
  580. /* Set length */
  581. pWSPI->uCmd |= ((UINT32)length << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  582. /* Set address */
  583. pWSPI->uCmd |= address & WSPI_CMD_BYTE_ADDR;
  584. /* Write */
  585. ret |= SPI_WriteSync (pWSPI->hSPI, (UINT8*)&pWSPI->uCmd, WSPI_SIZEOF_UINT32);
  586. /**************/
  587. /* Write data */
  588. /**************/
  589. ret |= SPI_WriteSync (pWSPI->hSPI, data, length);
  590. return ret;
  591. #endif
  592. }
  593. /*
  594. * ----------------------------------------------------------------------------
  595. * Function : WSPI_ReadAsync
  596. *
  597. * Input : void* hWSPI - the WSPI handle
  598. * UINT32 address - the address (in bytes) in the firmware to read the data from
  599. * UINT32 length - the number of bytes to read
  600. * WSPI_CB_T cb - callback parameters
  601. * BOOL bMore - more read/write transaction will follow
  602. * BOOL bSpaceReserved
  603. * - extra space padding has been reserved by an upper layer
  604. *
  605. * Output : UINT8* data - the buffer to put the read data
  606. *
  607. * ReturnVal: one of the error codes (zero is success)
  608. *
  609. * Note(s) : 1. set the WSPI cammand+address word
  610. * 2. set the command+address request struct
  611. * 3. submit the request
  612. * 4. set the read fixed busy request struct
  613. * 5. submit the request
  614. * 6. set the read data request struct
  615. * 7. submit the request with execute flag
  616. *
  617. * the fixed response is read into the buffer of the WSPI context
  618. * -----------------------------------------------------------------------------
  619. */
  620. int WSPI_ReadAsync (TI_HANDLE hWSPI, UINT32 address, UINT8* data, UINT32 length, WSPI_CB_T* cb, BOOL bMore, BOOL bSpaceReserved)
  621. {
  622. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  623. int status;
  624. if (length == 0)
  625. {
  626. return WSPI_ERR_WRONG_LENGTH;
  627. }
  628. /* Save parameters */
  629. pWSPI->length = (UINT32)length;
  630. pWSPI->data = data;
  631. pWSPI->bMore = bMore;
  632. pWSPI->bSpaceReserved = bSpaceReserved;
  633. pWSPI->fCb = cb->CBFunc;
  634. pWSPI->pCb = cb->CBArg;
  635. /**********************************/
  636. /* Prepare the CMD for the SM use */
  637. /**********************************/
  638. pWSPI->uCmd = WSPI_CMD_READ;
  639. /* Set bFixedAddr */
  640. if (pWSPI->bFixedAddr)
  641. {
  642. pWSPI->uCmd |= WSPI_CMD_FIXED;
  643. }
  644. /* Set length */
  645. pWSPI->uCmd |= ((UINT32)length << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  646. /* Set address */
  647. pWSPI->uCmd |= address & WSPI_CMD_BYTE_ADDR;
  648. #ifdef USE_WRITE_READ_API
  649. if (bSpaceReserved)
  650. {
  651. /* Indicate that that the temporary buffer is NOT used */
  652. pWSPI->bUseTempBuf = 0;
  653. }
  654. else
  655. {
  656. if (pWSPI->length <= WSPI_NO_EXTRA_ALLOC_SIZE)
  657. {
  658. /* Indicate that that the temporary buffer is used */
  659. data = pWSPI->pTempBuf;
  660. pWSPI->bUseTempBuf = 1;
  661. }
  662. else
  663. {
  664. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG, ("No space reserved for command\n"));
  665. return WSPI_ERR_UNKNOWN;
  666. }
  667. }
  668. status = SPI_WriteRead (pWSPI->hSPI,
  669. (UINT8*)&pWSPI->uCmd,
  670. WSPI_SIZEOF_CMD,
  671. data,
  672. length + pWSPI->uFixedBusyBytes,
  673. WSPI_ReadDataCb,
  674. pWSPI,
  675. bMore);
  676. /* In case of synchronous transaction completion call read callback explicitly */
  677. if (SPI_TXN_COMPLETE == status)
  678. {
  679. pWSPI->fCb = NULL;
  680. WSPI_ReadDataCb (hWSPI, status);
  681. }
  682. return status;
  683. #else
  684. /* Write command and indicate that more is ON */
  685. status = SPI_Write (pWSPI->hSPI,
  686. (UINT8*)&pWSPI->uCmd,
  687. WSPI_SIZEOF_CMD,
  688. WSPI_WriteCmdCb,
  689. hWSPI,
  690. 1);
  691. /* Don't pend, call directly to the callback */
  692. if (SPI_TXN_COMPLETE == status)
  693. {
  694. WSPI_WriteCmdCb (hWSPI, WSPI_OK);
  695. /* WSPI_WriteCmdCb updates the pWSPI->status */
  696. return pWSPI->status;
  697. }
  698. return status;
  699. #endif
  700. }
  701. #ifndef USE_WRITE_READ_API
  702. /*
  703. * ----------------------------------------------------------------------------
  704. * Function : WSPI_WriteCmdCb
  705. *
  706. * Input : void* hWSPI - the WSPI handle
  707. * int status - SPI request status
  708. *
  709. * Note(s) : CB from writing CMD in WSPI_ReadAsync().
  710. * Read the data according to bSpaceReserved (indicates whether extra bytes were allocated
  711. * in the buffer for the FixedBusyWord).
  712. * if (!bSpaceReserved) but the length is short (WSPI_NO_EXTRA_ALLOC_SIZE) than copy it to
  713. * temporary file and read the data
  714. * else - ERROR !
  715. * -----------------------------------------------------------------------------
  716. */
  717. void WSPI_WriteCmdCb (TI_HANDLE hWSPI, int status)
  718. {
  719. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  720. /* Extra room was saved - set the pointer as is */
  721. if (pWSPI->bSpaceReserved)
  722. {
  723. /* Indicate that that the temporary buffer is NOT used */
  724. pWSPI->bUseTempBuf = 0;
  725. /* Execute read with extra fixed busy bytes */
  726. pWSPI->status = SPI_Read (pWSPI->hSPI,
  727. pWSPI->data,
  728. pWSPI->length + pWSPI->uFixedBusyBytes,
  729. WSPI_ReadDataCb,
  730. hWSPI,
  731. pWSPI->bMore);
  732. }
  733. /*
  734. * This case is used for handling buffers which have no extra room for the fixed busy words.
  735. * Use a temporary buffer and than copy the results
  736. */
  737. else if (pWSPI->length <= WSPI_NO_EXTRA_ALLOC_SIZE)
  738. {
  739. /* Indicate that that the temporary buffer is used */
  740. pWSPI->bUseTempBuf = 1;
  741. /* Read fixed busy words and a data in one transaction */
  742. pWSPI->status = SPI_Read (pWSPI->hSPI,
  743. pWSPI->pTempBuf,
  744. pWSPI->length + pWSPI->uFixedBusyBytes,
  745. WSPI_ReadDataCb,
  746. hWSPI,
  747. pWSPI->bMore);
  748. }
  749. else
  750. {
  751. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG, ("No space reserved command\n"));
  752. }
  753. /* Check the return status; if not pending - call directly */
  754. if (SPI_TXN_COMPLETE == pWSPI->status)
  755. {
  756. WSPI_ReadDataCb (hWSPI, WSPI_OK);
  757. }
  758. }
  759. #endif
  760. /*
  761. * ----------------------------------------------------------------------------
  762. * Function : WSPI_ReadDataCb
  763. *
  764. * Input : void* hWSPI - the WSPI handle
  765. * int status - SPI request status
  766. *
  767. * Note(s) : CB from WSPI_WriteCmdCb().
  768. * Copy the data if needed and call original CB
  769. * -----------------------------------------------------------------------------
  770. */
  771. void WSPI_ReadDataCb (TI_HANDLE hWSPI, int status)
  772. {
  773. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  774. UINT32 *pRbuf;
  775. /* If we are using the temp buffer and its fixedBusyWord is OK */
  776. pRbuf = (pWSPI->bUseTempBuf) ? (UINT32 *)pWSPI->pTempBuf
  777. : (UINT32 *)pWSPI->data;
  778. /* No fixed busy */
  779. if ((pRbuf[pWSPI->uFixedBusyLen] & 0x1) != 0)
  780. {
  781. /* Copy data to the original buffer */
  782. if (pWSPI->bUseTempBuf)
  783. {
  784. #if WSPI_NO_EXTRA_ALLOC_SIZE == 4 /* used for optimization */
  785. /* In case the data size is 4 bytes copy it directly from the temp buffer */
  786. *((UINT32*)pWSPI->data) = pRbuf[pWSPI->uFixedBusyLen + 1];
  787. #else
  788. os_memoryCopy (pWSPI->hOs, pWSPI->data, &pRbuf[pWSPI->uFixedBusyLen + 1], pWSPI->length);
  789. #endif
  790. }
  791. /* Call user callback */
  792. if (pWSPI->fCb != NULL)
  793. {
  794. pWSPI->fCb (pWSPI->pCb, 0);
  795. }
  796. }
  797. /* Handle fixed busy */
  798. else
  799. {
  800. WLAN_REPORT_WARNING (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG,
  801. ("WSPI FIXED BUSY (READ CALLBACK) Cmd = 0x%x, data pointer = %p data = 0x%x length = %d\n",
  802. pWSPI->uCmd, pRbuf, pRbuf[pWSPI->uFixedBusyLen + 1], pWSPI->length));
  803. WSPI_HandleFixedBusy(hWSPI, pRbuf);
  804. }
  805. }
  806. /*
  807. * ----------------------------------------------------------------------------
  808. * Function : WSPI_ReadDataAfterNotBusyCb
  809. *
  810. * Input : void* hWSPI - the WSPI handle
  811. * int status - Not in use.
  812. *
  813. * Note(s) : Called from WSPI_HandleFixedBusy after the last read operation had the ~busy
  814. * word, but some of the data is missing
  815. * -----------------------------------------------------------------------------
  816. */
  817. void WSPI_ReadDataAfterNotBusyCb (TI_HANDLE hWSPI, int status)
  818. {
  819. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  820. UINT32 *pRbuf;
  821. UINT32 iExtraBufByteLength = pWSPI->ExtraBufLength*WSPI_SIZEOF_UINT32;
  822. UINT32 iTotalLength = pWSPI->length + pWSPI->uFixedBusyBytes;
  823. /* If we are using the temp buffer and its fixedBusyWord is OK */
  824. pRbuf = (pWSPI->bUseTempBuf) ? (UINT32 *)pWSPI->pTempBuf : (UINT32 *)pWSPI->data;
  825. if (pWSPI->bUseTempBuf)
  826. {
  827. #if WSPI_NO_EXTRA_ALLOC_SIZE == 4 /* used for optimization */
  828. /* In case the data size is 4 bytes copy it directly from the temp buffer */
  829. *((UINT32*)pWSPI->data) = *((UINT32*)pWSPI->pExtraFixedBusyBuf);
  830. #else
  831. os_memoryCopy (pWSPI->hOs, pWSPI->data, &(pRbuf[pWSPI->uFixedBusyLen + 1 + pWSPI->ExtraBufLength]), pWSPI->length - iExtraBufByteLength);
  832. os_memoryCopy (pWSPI->hOs, &(pWSPI->data[pWSPI->length - iExtraBufByteLength]), pWSPI->pExtraFixedBusyBuf, iExtraBufByteLength);
  833. #endif
  834. }
  835. else
  836. {
  837. os_memoryCopy(pWSPI->hOs, pRbuf, &(pRbuf[pWSPI->ExtraBufLength]),iTotalLength - iExtraBufByteLength);
  838. pWSPI->data = (UINT8*)pRbuf;
  839. os_memoryCopy (pWSPI->hOs, &(pWSPI->data[iTotalLength - iExtraBufByteLength]), pWSPI->pExtraFixedBusyBuf, iExtraBufByteLength);
  840. }
  841. /* Call user callback */
  842. if (pWSPI->fCb != NULL)
  843. {
  844. pWSPI->fCb (pWSPI->pCb, 0);
  845. }
  846. }
  847. /*
  848. * ----------------------------------------------------------------------------
  849. * Function : WSPI_ReadNotBusyAndDataCb
  850. *
  851. * Input : void* hWSPI - the WSPI handle
  852. * int status - Not in use.
  853. *
  854. * Note(s) : Called from WSPI_HandleFixedBusy after the last read operation had no response
  855. * from the CHIP. i.e. the ~busy word is missing too
  856. * -----------------------------------------------------------------------------
  857. */
  858. void WSPI_ReadNotBusyAndDataCb (TI_HANDLE hWSPI, int status)
  859. {
  860. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  861. int i = 0;
  862. if ( pWSPI->bUseTempBuf )
  863. {
  864. while (i < (WSPI_EXTRA_READ_AFTER_NO_RESPONSE) )
  865. {
  866. /* Check if this is the ~busy word */
  867. if ( (*(UINT32*)(pWSPI->pExtraFixedBusyBuf + i)) & 0x1 )
  868. {
  869. /* we have reached the fixed busy word */
  870. #if WSPI_NO_EXTRA_ALLOC_SIZE == 4 /* used for optimization */
  871. /* In case the data size is 4 bytes copy it directly from the temp buffer */
  872. *((UINT32*)pWSPI->data) = *((UINT32*)(pWSPI->pExtraFixedBusyBuf+i+4));
  873. #else
  874. os_memoryCopy (pWSPI->hOs, pWSPI->data, &(pWSPI->pTempBuf[pWSPI->uFixedBusyLen + 1 + pWSPI->ExtraBufLength]), pWSPI->length - iExtraBufByteLength);
  875. os_memoryCopy (pWSPI->hOs, &(pWSPI->data[pWSPI->length - iExtraBufByteLength]), pWSPI->pExtraFixedBusyBuf, iExtraBufByteLength);
  876. #endif
  877. if (pWSPI->fCb != NULL)
  878. {
  879. pWSPI->fCb (pWSPI->pCb, 0);
  880. }
  881. return;
  882. }
  883. i+=4;
  884. }
  885. }
  886. /* Oh boy, We couldn't find the ~Busy word */
  887. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG,
  888. ("WSPI FIXED BUSY (READ CALLBACK) Cmd = 0x%x, length = %d\n",
  889. pWSPI->uCmd,pWSPI->length));
  890. if (pWSPI->fErr)
  891. {
  892. (*pWSPI->fErr) ();
  893. }
  894. if (pWSPI->fCb != NULL)
  895. {
  896. pWSPI->fCb (pWSPI->pCb, WSPI_ERR_BUS_BUSY);
  897. }
  898. }
  899. /*
  900. * ----------------------------------------------------------------------------
  901. * Function : WSPI_HandleFixedBusy
  902. *
  903. * Input : void* hWSPI - the WSPI handle
  904. * UINT32 *pRbuf - The temp read buffer
  905. *
  906. * Note(s) : Called from WSPI_ReadDataCb() when a Fixed_Busy error accurse.
  907. * Shifting the data to the expected place and reading the missing data
  908. * -----------------------------------------------------------------------------
  909. */
  910. void WSPI_HandleFixedBusy(TI_HANDLE hWSPI, UINT32 *pRbuf)
  911. {
  912. WSPI_t *pWSPI = (WSPI_t*)hWSPI;
  913. UINT8 iTotalLength = pWSPI->length + pWSPI->uFixedBusyBytes;
  914. UINT8 iExtraBufByteLength = 0;
  915. int status;
  916. pWSPI->ExtraBufLength = 0;
  917. /* Find the Data beginning */
  918. while (((pRbuf[pWSPI->uFixedBusyLen + pWSPI->ExtraBufLength] & 0x1) == 0) &&
  919. ((pWSPI->uFixedBusyBytes + (pWSPI->ExtraBufLength * WSPI_SIZEOF_UINT32)) < iTotalLength) &&
  920. ((pWSPI->ExtraBufLength * WSPI_SIZEOF_UINT32 ) < WSPI_EXTRA_BUFFER_ALLOC_SIZE ))
  921. {
  922. pWSPI->ExtraBufLength++;
  923. }
  924. #ifdef TI_DBG
  925. if (pWSPI->ExtraBufLength > 0)
  926. {
  927. DebugFixedBusy[pWSPI->ExtraBufLength - 1]++;
  928. }
  929. #endif
  930. /* if we had less then WSPI_EXTRA_BUFFER_ALLOC_SIZE FixedBusy words */
  931. if ((pRbuf[pWSPI->uFixedBusyLen + pWSPI->ExtraBufLength] & 0x1) != 0)
  932. {
  933. iExtraBufByteLength = pWSPI->ExtraBufLength*WSPI_SIZEOF_UINT32;
  934. /* Execute read with extra fixed busy bytes and without CMD*/
  935. status = SPI_WriteRead(pWSPI->hSPI,
  936. NULL,
  937. 0,
  938. pWSPI->pExtraFixedBusyBuf,
  939. iExtraBufByteLength,
  940. WSPI_ReadDataAfterNotBusyCb,
  941. pWSPI,
  942. 1);
  943. /* In case of synchronous transaction call the handling function implicitly */
  944. if (SPI_TXN_COMPLETE == status)
  945. {
  946. WSPI_ReadDataAfterNotBusyCb(hWSPI, OK);
  947. }
  948. }
  949. /* In the next case we try to read again even though the SPI line doesn't indicate any response */
  950. else if ( pWSPI->bUseTempBuf )
  951. { /* This case is handled for TempBuf only */
  952. /* Execute read without CMD */
  953. status = SPI_WriteRead(pWSPI->hSPI,
  954. NULL,
  955. 0,
  956. pWSPI->pExtraFixedBusyBuf,
  957. WSPI_EXTRA_READ_AFTER_NO_RESPONSE,
  958. WSPI_ReadNotBusyAndDataCb,
  959. pWSPI,
  960. 1);
  961. /* In case of synchronous transaction call the handling function implicitly */
  962. if (SPI_TXN_COMPLETE == status)
  963. {
  964. WSPI_ReadNotBusyAndDataCb(hWSPI, OK);
  965. }
  966. }
  967. else /* Recovery from this one can be done by adjusting the length */
  968. {
  969. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG,
  970. ("WSPI FIXED BUSY (READ CALLBACK) Cmd = 0x%x, data pointer = %p data = 0x%x length = %d\n",
  971. pWSPI->uCmd, pRbuf, pRbuf[pWSPI->uFixedBusyLen + 1],pWSPI->length));
  972. if (pWSPI->fErr)
  973. {
  974. (*pWSPI->fErr) ();
  975. }
  976. if (pWSPI->fCb != NULL)
  977. {
  978. pWSPI->fCb (pWSPI->pCb, WSPI_ERR_BUS_BUSY);
  979. }
  980. }
  981. }
  982. /*
  983. * ----------------------------------------------------------------------------
  984. * Function : WSPI_WriteAsync
  985. *
  986. * Input : void* hWSPI - the WSPI handle
  987. * UINT32 address - the address (in bytes) in the firmware to read the data from
  988. * UINT8* data - the buffer that holds the data to write
  989. * UINT32 length - the number of bytes to read
  990. * WSPI_CB_T cb - callback parameters
  991. * BOOL bMore - more read/write transaction will follow
  992. * BOOL bSpaceReserved
  993. - extra space padding has been reserved by an upper layer
  994. *
  995. * Output : none
  996. *
  997. * ReturnVal: WSPI_Status_e
  998. *
  999. * Note(s) : 1. set the WSPI cammand+address word
  1000. * 2. set the command+address request struct
  1001. * 3. submit the request
  1002. * 4. set the write data request struct
  1003. * 5. submit the request with execute flag
  1004. *
  1005. * -----------------------------------------------------------------------------
  1006. */
  1007. int WSPI_WriteAsyncOld (TI_HANDLE hWSPI, UINT32 address, UINT8* data, UINT32 length, WSPI_CB_T* cb, BOOL bMore, BOOL bSpaceReserved)
  1008. {
  1009. WSPI_t *pWSPI = (WSPI_t*) hWSPI;
  1010. int ret = WSPI_OK;
  1011. if (length == 0)
  1012. {
  1013. return WSPI_ERR_WRONG_LENGTH;
  1014. }
  1015. /*****************************/
  1016. /* Write the command+address */
  1017. /*****************************/
  1018. pWSPI->uCmd = WSPI_CMD_WRITE;
  1019. /* Set bFixedAddr */
  1020. if (pWSPI->bFixedAddr)
  1021. {
  1022. pWSPI->uCmd |= WSPI_CMD_FIXED;
  1023. }
  1024. /* Set the length */
  1025. pWSPI->uCmd |= ((UINT32)length << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  1026. /* Set the address */
  1027. pWSPI->uCmd |= address & WSPI_CMD_BYTE_ADDR;
  1028. /* Write */
  1029. ret |= SPI_WriteSync (pWSPI->hSPI, (UINT8*)&pWSPI->uCmd, WSPI_SIZEOF_UINT32);
  1030. /******************/
  1031. /* Write the data */
  1032. /******************/
  1033. /* Tell the lower machine to start executing after this submission */
  1034. ret |= SPI_Write (pWSPI->hSPI,
  1035. data + bSpaceReserved * WSPI_SIZEOF_CMD,
  1036. length,
  1037. cb->CBFunc,
  1038. cb->CBArg,
  1039. 1);
  1040. return ret;
  1041. }
  1042. /*
  1043. * ----------------------------------------------------------------------------
  1044. * Function : WSPI_WriteAsync
  1045. *
  1046. * Input : void* hWSPI - the WSPI handle
  1047. * UINT32 address - the address (in bytes) in the firmware to read the data from
  1048. * UINT8* data - the buffer that holds the data to write
  1049. * UINT32 length - the number of bytes to read
  1050. * WSPI_CB_T cb - callback parameters
  1051. * BOOL bMore - more read/write transaction will follow
  1052. * BOOL bSpaceReserved
  1053. - extra space padding has been reserved by an upper layer
  1054. *
  1055. * Output : none
  1056. *
  1057. * ReturnVal: WSPI_Status_e
  1058. *
  1059. * Note(s) : 3 options are checked in this function:
  1060. * 1) (bSpaceReserved == TRUE)
  1061. * write the command and the data in one chunk
  1062. * 2) else (length <= WSPI_NO_EXTRA_ALLOC_SIZE)
  1063. * copy Command + data to tempBuffer and write it in one chunk
  1064. * 3) else - error !!!
  1065. *
  1066. * -----------------------------------------------------------------------------
  1067. */
  1068. int WSPI_WriteAsync (TI_HANDLE hWSPI, UINT32 address, UINT8* data, UINT32 length, WSPI_CB_T* cb, BOOL bMore, BOOL bSpaceReserved)
  1069. {
  1070. WSPI_t *pWSPI = (WSPI_t*) hWSPI;
  1071. int status;
  1072. if (length == 0)
  1073. {
  1074. return WSPI_ERR_WRONG_LENGTH;
  1075. }
  1076. /*****************************/
  1077. /* Write the command+address */
  1078. /*****************************/
  1079. pWSPI->uCmd = WSPI_CMD_WRITE;
  1080. /* Set bFixedAddr */
  1081. if (pWSPI->bFixedAddr)
  1082. {
  1083. pWSPI->uCmd |= WSPI_CMD_FIXED;
  1084. }
  1085. /* Set the length */
  1086. pWSPI->uCmd |= (length << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH;
  1087. /* Set the address */
  1088. pWSPI->uCmd |= address & WSPI_CMD_BYTE_ADDR;
  1089. if (bSpaceReserved)
  1090. {
  1091. /* If extra place was saved, transfer command and data in one transaction */
  1092. *(UINT32*)data = pWSPI->uCmd;
  1093. status = SPI_Write (pWSPI->hSPI,
  1094. data,
  1095. length + WSPI_SIZEOF_CMD,
  1096. cb->CBFunc,
  1097. cb->CBArg,
  1098. bMore);
  1099. }
  1100. /* If extra room was not saved for the command use temporary buffer */
  1101. else if (length <= WSPI_NO_EXTRA_ALLOC_SIZE)
  1102. {
  1103. #if WSPI_NO_EXTRA_ALLOC_SIZE == 4 /* used for optimization */
  1104. /* Copy data to the temporary buffer */
  1105. *((UINT32*)(pWSPI->pTempBuf + WSPI_SIZEOF_CMD)) = *((UINT32*)data);
  1106. #else
  1107. os_memoryCopy (pWSPI->hOs, pWSPI->pTempBuf + WSPI_SIZEOF_CMD, data, length);
  1108. #endif
  1109. /* Put the command at the beginning of the temporary buffer */
  1110. *((UINT32*)pWSPI->pTempBuf) = pWSPI->uCmd;
  1111. status = SPI_Write (pWSPI->hSPI,
  1112. pWSPI->pTempBuf,
  1113. length + WSPI_SIZEOF_CMD,
  1114. cb->CBFunc,
  1115. cb->CBArg,
  1116. bMore);
  1117. }
  1118. else
  1119. {
  1120. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG, ("No space reserved for command\n"));
  1121. return WSPI_ERR_UNKNOWN;
  1122. }
  1123. return status;
  1124. }
  1125. /*
  1126. * ----------------------------------------------------------------------------
  1127. * Function : WSPI_GenerateCRC7
  1128. *
  1129. * Input : UINT8* bits - a string that holds the bits, in the order from the first to last
  1130. * UINT32 len - the number of bits
  1131. *
  1132. * Output : none
  1133. *
  1134. * ReturnVal: UINT8 - the CRC word
  1135. *
  1136. * Note(s) : calculates the CRC7 for the WSPI init command
  1137. * -----------------------------------------------------------------------------
  1138. */
  1139. static UINT8 WSPI_GenerateCRC7 (UINT8* bits, UINT32 len)
  1140. {
  1141. UINT8 CRC, CRC0, CRC1, CRC2, CRC3, CRC4, CRC5, CRC6;
  1142. UINT8 bit, temp;
  1143. UINT32 i;
  1144. CRC0 = CRC1 = CRC2 = CRC3 = CRC4 = CRC5 = CRC6 = 0;
  1145. /* Calculate the CRC with the formula : G(x) = x^7 + x^3 + 1 */
  1146. for (i = 0; i < len; i++)
  1147. {
  1148. bit = (bits[i / 8] & (1 << (7 - (i % 8)))) >> (7 - (i % 8));
  1149. temp = CRC6;
  1150. CRC6 = CRC5;
  1151. CRC5 = CRC4;
  1152. CRC4 = CRC3;
  1153. CRC3 = CRC2;
  1154. CRC2 = CRC1;
  1155. CRC1 = CRC0;
  1156. CRC0 = temp ^ bit;
  1157. CRC3 = CRC0 ^ CRC3;
  1158. }
  1159. CRC = CRC0;
  1160. CRC |= CRC1 << 1;
  1161. CRC |= CRC2 << 2;
  1162. CRC |= CRC3 << 3;
  1163. CRC |= CRC4 << 4;
  1164. CRC |= CRC5 << 5;
  1165. CRC |= CRC6 << 6;
  1166. return CRC;
  1167. }
  1168. /*
  1169. * ----------------------------------------------------------------------------
  1170. * Function : WSPI_ReadAsyncCb
  1171. *
  1172. * Input : void* handle - a handle that was passed to the asynchronous request (usually the WSPI handle)
  1173. * int status - the status of the SPI request
  1174. *
  1175. * Output : none
  1176. *
  1177. * ReturnVal: none
  1178. *
  1179. * Note(s) : this is a temp function for passing as a CB function to the SPI layer for checking the async mechanism
  1180. * -----------------------------------------------------------------------------
  1181. */
  1182. static void WSPI_ReadAsyncCb (void* hWSPI, int status)
  1183. {
  1184. WSPI_t *pWSPI = (WSPI_t*) hWSPI;
  1185. /* Check the fixed busy word */
  1186. if ((pWSPI->uFixedBusy & 0x1) != 0)
  1187. {
  1188. pWSPI->fCb (pWSPI->pCb, 0);
  1189. }
  1190. else
  1191. {
  1192. WLAN_REPORT_ERROR (pWSPI->hReport, HAL_HW_CTRL_MODULE_LOG, ("WSPI FIXED BUSY (CALLBACK)\n"));
  1193. if (pWSPI->fErr)
  1194. {
  1195. (*pWSPI->fErr) ();
  1196. }
  1197. pWSPI->fCb (pWSPI->pCb, -1);
  1198. }
  1199. }
  1200. /*
  1201. * ----------------------------------------------------------------------------
  1202. * Function : WSPI_SyncOverAsyncCb
  1203. *
  1204. * Input : void* handle - a handle that was passed to the asynchronous request
  1205. * int status - the status that the SPI request ended
  1206. *
  1207. * Output : none
  1208. *
  1209. * ReturnVal: none
  1210. *
  1211. * Note(s) : this function just sets a flag so the sync SPI read/write function
  1212. * can return
  1213. * -----------------------------------------------------------------------------
  1214. */
  1215. #ifdef USE_SYNC_OVER_ASYNC
  1216. static void WSPI_SyncOverAsyncCb (void* hWSPI, int status)
  1217. {
  1218. WSPI_t* pWSPI = (WSPI_t*) hWSPI;
  1219. #ifdef USE_SPI_DEBUG
  1220. {
  1221. SPI_t *pSPI = (SPI_t*) pWSPI->hSPI;
  1222. pSPI->stat.uNumOfSyncOverAsync ++;
  1223. }
  1224. #endif
  1225. pWSPI->bSyncFlag = 1;
  1226. }
  1227. #endif
  1228. void WSPI_SetErrLog (void* hWSPI, void (*fErr)(void))
  1229. {
  1230. WSPI_t* pWSPI = (WSPI_t*) hWSPI;
  1231. pWSPI->fErr = fErr;
  1232. }