Home | History | Annotate | Download | only in BusTxn
      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  */
    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  */
    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  */
    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 
    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  */
    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  */
    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  */
    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  */
    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  */
    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  */
    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 */
    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 */
   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  */
   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  */
   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  */
   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  */
   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  */
   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
   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 
   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