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