Home | History | Annotate | Download | only in FW_Transfer
      1 /*
      2  * HwInit.c
      3  *
      4  * Copyright(c) 1998 - 2010 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 /*  MODULE:  HwInit.c                                                          */
     39 /*  PURPOSE: HwInit module manages the init process of the TNETW, included     */
     40 /*           firmware download process. It shall perform Hard Reset the chip   */
     41 /*           if possible (this will require a Reset line to be connected to    */
     42 /*           the host); Start InterfaceCtrl; Download NVS and FW               */
     43 /*                                                                             */
     44 /*                                                                             */
     45 /*******************************************************************************/
     46 
     47 #define __FILE_ID__  FILE_ID_105
     48 #include "tidef.h"
     49 #include "osApi.h"
     50 #include "report.h"
     51 #include "timer.h"
     52 #include "HwInit_api.h"
     53 #include "FwEvent_api.h"
     54 #include "TwIf.h"
     55 #include "TWDriver.h"
     56 #include "TWDriverInternal.h"
     57 #include "eventMbox_api.h"
     58 #include "CmdBld.h"
     59 #include "CmdMBox_api.h"
     60 #ifdef TI_RANDOM_DEFAULT_MAC
     61 #include <linux/random.h>
     62 #include <linux/jiffies.h>
     63 #endif
     64 
     65 
     66 extern void TWD_FinalizeOnFailure   (TI_HANDLE hTWD);
     67 extern void cmdBld_FinalizeDownload (TI_HANDLE hCmdBld, TBootAttr *pBootAttr, FwStaticData_t *pFwInfo);
     68 
     69 
     70 /************************************************************************
     71  * Defines
     72  ************************************************************************/
     73 
     74 /* Download phase partition */
     75 #define PARTITION_DOWN_MEM_ADDR       0
     76 #define PARTITION_DOWN_MEM_SIZE       0x177C0
     77 #define PARTITION_DOWN_REG_ADDR       REGISTERS_BASE
     78 #define PARTITION_DOWN_REG_SIZE       0x8800
     79 
     80 /* Working phase partition */
     81 #define PARTITION_WORK_MEM_ADDR1       0x40000
     82 #define PARTITION_WORK_MEM_SIZE1       0x14FC0
     83 #define PARTITION_WORK_MEM_ADDR2       REGISTERS_BASE
     84 #define PARTITION_WORK_MEM_SIZE2       0xA000
     85 #define PARTITION_WORK_MEM_ADDR3       0x3004F8
     86 #define PARTITION_WORK_MEM_SIZE3       0x4
     87 #define PARTITION_WORK_MEM_ADDR4       0x40404
     88 
     89 /* DRPW setting partition */
     90 #define PARTITION_DRPW_MEM_ADDR       0x40000
     91 #define PARTITION_DRPW_MEM_SIZE       0x14FC0
     92 #define PARTITION_DRPW_REG_ADDR       DRPW_BASE
     93 #define PARTITION_DRPW_REG_SIZE       0x6000
     94 
     95 /* Total range of bus addresses range */
     96 #define PARTITION_TOTAL_ADDR_RANGE    0x1FFC0
     97 
     98 /* Maximal block size in a single SDIO transfer --> Firmware image load chunk size */
     99 #ifdef _VLCT_
    100 #define MAX_SDIO_BLOCK					(4000)
    101 #else
    102 #define MAX_SDIO_BLOCK					(500)
    103 #endif
    104 
    105 #define ACX_EEPROMLESS_IND_REG        (SCR_PAD4)
    106 #define USE_EEPROM                    (0)
    107 #define SOFT_RESET_MAX_TIME           (1000000)
    108 #define SOFT_RESET_STALL_TIME         (1000)
    109 #define NVS_DATA_BUNDARY_ALIGNMENT    (4)
    110 
    111 #define MAX_HW_INIT_CONSECUTIVE_TXN     15
    112 
    113 #define WORD_SIZE                       4
    114 #define WORD_ALIGNMENT_MASK             0x3
    115 #define DEF_NVS_SIZE                    ((NVS_PRE_PARAMETERS_LENGTH) + (NVS_TX_TYPE_INDEX) + 4)
    116 
    117 #define RADIO_SM_WAIT_LOOP  32
    118 
    119 #define FREF_CLK_FREQ_MASK      0x7
    120 #define FREF_CLK_TYPE_MASK      BIT_3
    121 #define FREF_CLK_POLARITY_MASK  BIT_4
    122 
    123 #define FREF_CLK_TYPE_BITS      0xfffffe7f
    124 #define CLK_REQ_PRCM            0x100
    125 
    126 #define FREF_CLK_POLARITY_BITS  0xfffff8ff
    127 #define CLK_REQ_OUTN_SEL        0x700
    128 
    129 #define DRPw_MASK_CHECK  0xc0
    130 #define DRPw_MASK_SET    0x2000000
    131 
    132 /* time to wait till we check if fw is running */
    133 #define STALL_TIMEOUT   7
    134 
    135 #ifdef DOWNLOAD_TIMER_REQUIERD
    136 #define FIN_LOOP 10
    137 #endif
    138 
    139 
    140 #ifdef _VLCT_
    141 #define FIN_LOOP 10
    142 #else
    143 #define FIN_LOOP 20000
    144 #endif
    145 
    146 
    147 /************************************************************************
    148  * Macros
    149  ************************************************************************/
    150 
    151 #define SET_DEF_NVS(aNVS)     aNVS[0]=0x01; aNVS[1]=0x6d; aNVS[2]=0x54; aNVS[3]=0x56; aNVS[4]=0x34; \
    152                               aNVS[5]=0x12; aNVS[6]=0x28; aNVS[7]=0x01; aNVS[8]=0x71; aNVS[9]=0x54; \
    153                               aNVS[10]=0x00; aNVS[11]=0x08; aNVS[12]=0x00; aNVS[13]=0x00; aNVS[14]=0x00; \
    154                               aNVS[15]=0x00; aNVS[16]=0x00; aNVS[17]=0x00; aNVS[18]=0x00; aNVS[19]=0x00; \
    155                               aNVS[20]=0x00; aNVS[21]=0x00; aNVS[22]=0x00; aNVS[23]=0x00; aNVS[24]=eNVS_NON_FILE;\
    156 							  aNVS[25]=0x00; aNVS[26]=0x00; aNVS[27]=0x00;
    157 
    158 
    159 #define SET_PARTITION(pPartition,uAddr1,uMemSize1,uAddr2,uMemSize2,uAddr3,uMemSize3,uAddr4) \
    160                     ((TPartition*)pPartition)[0].uMemAdrr = uAddr1; \
    161                     ((TPartition*)pPartition)[0].uMemSize = uMemSize1; \
    162                     ((TPartition*)pPartition)[1].uMemAdrr = uAddr2; \
    163                     ((TPartition*)pPartition)[1].uMemSize = uMemSize2; \
    164                     ((TPartition*)pPartition)[2].uMemAdrr = uAddr3; \
    165                     ((TPartition*)pPartition)[2].uMemSize = uMemSize3; \
    166                     ((TPartition*)pPartition)[3].uMemAdrr = uAddr4;
    167 
    168 #define HW_INIT_PTXN_SET(pHwInit, pTxn)  pTxn = (TTxnStruct*)&(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].tTxnStruct);
    169 
    170 #define BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, uAddr, uVal, uSize, direction, fCB, hCB)     \
    171                               HW_INIT_PTXN_SET(pHwInit, pTxn) \
    172                               TXN_PARAM_SET_DIRECTION(pTxn, direction); \
    173                               pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData = (TI_UINT32)uVal; \
    174                               BUILD_TTxnStruct(pTxn, uAddr, &(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData), uSize, fCB, hCB)
    175 
    176 #define BUILD_HW_INIT_FW_STATIC_TXN(pHwInit, pTxn, uAddr, fCB, hCB)     \
    177                               HW_INIT_PTXN_SET(pHwInit, pTxn) \
    178                               TXN_PARAM_SET_DIRECTION(pTxn, TXN_DIRECTION_READ); \
    179                               BUILD_TTxnStruct(pTxn, uAddr, &(pHwInit->tFwStaticTxn.tFwStaticInfo), sizeof(FwStaticData_t), fCB, hCB)
    180 
    181 #define BUILD_HW_INIT_FW_DL_TXN(pHwInit, pTxn, uAddr, uVal, uSize, direction, fCB, hCB)     \
    182                               HW_INIT_PTXN_SET(pHwInit, pTxn) \
    183                               TXN_PARAM_SET_DIRECTION(pTxn, direction); \
    184                               BUILD_TTxnStruct(pTxn, uAddr, uVal, uSize, fCB, hCB)
    185 
    186 
    187 #define SET_DRP_PARTITION(pPartition)\
    188                         SET_PARTITION(pPartition, PARTITION_DRPW_MEM_ADDR, PARTITION_DRPW_MEM_SIZE, PARTITION_DRPW_REG_ADDR, PARTITION_DRPW_REG_SIZE, 0, 0, 0)
    189 
    190 #define SET_FW_LOAD_PARTITION(pPartition,uFwAddress)\
    191                             SET_PARTITION(pPartition,uFwAddress,PARTITION_DOWN_MEM_SIZE, PARTITION_DOWN_REG_ADDR, PARTITION_DOWN_REG_SIZE,0,0,0)
    192 
    193 #define SET_WORK_PARTITION(pPartition)\
    194                         SET_PARTITION(pPartition,PARTITION_WORK_MEM_ADDR1, PARTITION_WORK_MEM_SIZE1, PARTITION_WORK_MEM_ADDR2, PARTITION_WORK_MEM_SIZE2, PARTITION_WORK_MEM_ADDR3, PARTITION_WORK_MEM_SIZE3, PARTITION_WORK_MEM_ADDR4)
    195 
    196 /* Handle return status inside a state machine */
    197 #define EXCEPT(phwinit,status)                                   \
    198     switch (status) {                                           \
    199         case TI_OK:                                             \
    200         case TXN_STATUS_OK:                                     \
    201         case TXN_STATUS_COMPLETE:                               \
    202              break;                                             \
    203         case TXN_STATUS_PENDING:                                \
    204              return TXN_STATUS_PENDING;                         \
    205         default:                                                \
    206              TWD_FinalizeOnFailure (phwinit->hTWD);             \
    207              return TXN_STATUS_ERROR;                           \
    208     }
    209 
    210 
    211 /* Handle return status inside an init sequence state machine  */
    212 #define EXCEPT_I(phwinit,status)                                \
    213     switch (status) {                                           \
    214         case TI_OK:                                             \
    215         case TXN_STATUS_COMPLETE:                               \
    216              break;                                             \
    217         case TXN_STATUS_PENDING:                                \
    218              phwinit->uInitSeqStatus = status;                  \
    219              return TXN_STATUS_PENDING;                         \
    220         default:                                                \
    221              TWD_FinalizeOnFailure (phwinit->hTWD);             \
    222              return TXN_STATUS_ERROR;                           \
    223     }
    224 
    225 
    226 /* Handle return status inside a load image state machine */
    227 #define EXCEPT_L(phwinit,status)                                \
    228     switch (status) {                                           \
    229         case TXN_STATUS_OK:                                     \
    230         case TXN_STATUS_COMPLETE:                               \
    231              break;                                             \
    232         case TXN_STATUS_PENDING:                                \
    233              phwinit->DownloadStatus = status;                  \
    234              return TXN_STATUS_PENDING;                         \
    235         default:                                                \
    236              phwinit->DownloadStatus = status;                  \
    237              TWD_FinalizeOnFailure (phwinit->hTWD);             \
    238              return TXN_STATUS_ERROR;                           \
    239     }
    240 
    241 
    242 /************************************************************************
    243  * Types
    244  ************************************************************************/
    245 
    246 enum
    247 {
    248     REF_FREQ_19_2                   = 0,
    249     REF_FREQ_26_0                   = 1,
    250     REF_FREQ_38_4                   = 2,
    251     REF_FREQ_40_0                   = 3,
    252     REF_FREQ_33_6                   = 4,
    253     REF_FREQ_NUM                    = 5
    254 };
    255 
    256 enum
    257 {
    258     LUT_PARAM_INTEGER_DIVIDER       = 0,
    259     LUT_PARAM_FRACTIONAL_DIVIDER    = 1,
    260     LUT_PARAM_ATTN_BB               = 2,
    261     LUT_PARAM_ALPHA_BB              = 3,
    262     LUT_PARAM_STOP_TIME_BB          = 4,
    263     LUT_PARAM_BB_PLL_LOOP_FILTER    = 5,
    264     LUT_PARAM_NUM                   = 6
    265 };
    266 
    267 typedef struct
    268 {
    269     TTxnStruct              tTxnStruct;
    270     TI_UINT32               uData;
    271 
    272 } THwInitTxn;
    273 
    274 typedef struct
    275 {
    276     TTxnStruct              tTxnStruct;
    277     FwStaticData_t          tFwStaticInfo;
    278 
    279 } TFwStaticTxn;
    280 
    281 
    282 /* The HW Init module object */
    283 typedef struct
    284 {
    285     /* Handles */
    286     TI_HANDLE               hOs;
    287     TI_HANDLE               hReport;
    288     TI_HANDLE               hTWD;
    289     TI_HANDLE               hBusTxn;
    290     TI_HANDLE               hTwIf;
    291 
    292     TI_HANDLE 		    hFileInfo;	/* holds parameters of FW Image Portion - for DW Download */
    293     TEndOfHwInitCb          fInitHwCb;
    294 
    295     /* Firmware image ptr */
    296     TI_UINT8               *pFwBuf;
    297     /* Firmware image length */
    298     TI_UINT32               uFwLength;
    299     TI_UINT32               uFwAddress;
    300     TI_UINT32               bFwBufLast;
    301     TI_UINT32               uFwLastAddr;
    302     /* EEPROM image ptr */
    303     TI_UINT8               *pEEPROMBuf;
    304     /* EEPROM image length */
    305     TI_UINT32               uEEPROMLen;
    306 
    307     TI_UINT8               *pEEPROMCurPtr;
    308     TI_UINT32               uEEPROMCurLen;
    309     TBootAttr               tBootAttr;
    310     TI_HANDLE               hHwCtrl;
    311     ETxnStatus              DownloadStatus;
    312     /* Upper module callback for the init stage */
    313     fnotify_t               fCb;
    314     /* Upper module handle for the init stage */
    315     TI_HANDLE               hCb;
    316     /* Init stage */
    317     TI_UINT32               uInitStage;
    318     /* Reset statge */
    319     TI_UINT32               uResetStage;
    320     /* EEPROM burst stage */
    321     TI_UINT32               uEEPROMStage;
    322     /* Init state machine temporary data */
    323     TI_UINT32               uInitData;
    324     /* ELP command image */
    325     TI_UINT32               uElpCmd;
    326     /* Chip ID */
    327     TI_UINT32               uChipId;
    328     /* Boot state machine temporary data */
    329     TI_UINT32               uBootData;
    330     TI_UINT32               uSelfClearTime;
    331     TI_UINT8                uEEPROMBurstLen;
    332     TI_UINT8                uEEPROMBurstLoop;
    333     TI_UINT32               uEEPROMRegAddr;
    334     TI_STATUS               uEEPROMStatus;
    335     TI_UINT32               uNVSStartAddr;
    336     TI_UINT32               uNVSNumChar;
    337     TI_UINT32               uNVSNumByte;
    338     TI_STATUS               uNVSStatus;
    339     TI_UINT32               uScrPad6;
    340     TI_UINT32               uRefFreq;
    341     TI_UINT32               uInitSeqStage;
    342     TI_STATUS               uInitSeqStatus;
    343     TI_UINT32               uLoadStage;
    344     TI_UINT32               uBlockReadNum;
    345     TI_UINT32               uBlockWriteNum;
    346     TI_UINT32               uPartitionLimit;
    347     TI_UINT32               uFinStage;
    348     TI_UINT32               uFinData;
    349     TI_UINT32               uFinLoop;
    350      TI_UINT32               uRegStage;
    351     TI_UINT32               uRegLoop;
    352     TI_UINT32               uRegSeqStage;
    353     TI_UINT32               uRegData;
    354 	TI_HANDLE               hStallTimer;
    355 
    356     /* Top register Read/Write SM temporary data*/
    357     TI_UINT32               uTopRegAddr;
    358     TI_UINT32               uTopRegValue;
    359     TI_UINT32               uTopRegMask;
    360     TI_UINT32               uTopRegUpdateValue;
    361     TI_UINT32               uTopStage;
    362     TI_STATUS               uTopStatus;
    363 
    364     TI_UINT8                auFwTmpBuf [WSPI_PAD_LEN_WRITE + MAX_SDIO_BLOCK];
    365 
    366     TFinalizeCb             fFinalizeDownload;
    367     TI_HANDLE               hFinalizeDownload;
    368     /* Size of the Fw image, retrieved from the image itself */
    369     TI_UINT32               uFwDataLen;
    370     TI_UINT8                aDefaultNVS[DEF_NVS_SIZE];
    371     TI_UINT8                uTxnIndex;
    372     THwInitTxn              aHwInitTxn[MAX_HW_INIT_CONSECUTIVE_TXN];
    373     TFwStaticTxn            tFwStaticTxn;
    374 
    375     TI_UINT32               uSavedDataForWspiHdr;  /* For saving the 4 bytes before the NVS data for WSPI case
    376                                                         where they are overrun by the WSPI BusDrv */
    377     TPartition              aPartition[NUM_OF_PARTITION];
    378 } THwInit;
    379 
    380 
    381 /************************************************************************
    382  * Local Functions Prototypes
    383  ************************************************************************/
    384 static void      hwInit_SetPartition                (THwInit   *pHwInit,
    385                                                      TPartition *pPartition);
    386 static TI_STATUS hwInit_BootSm                      (TI_HANDLE hHwInit);
    387 static TI_STATUS hwInit_ResetSm                     (TI_HANDLE hHwInit);
    388 static TI_STATUS hwInit_EepromlessStartBurstSm      (TI_HANDLE hHwInit);
    389 static TI_STATUS hwInit_LoadFwImageSm               (TI_HANDLE hHwInit);
    390 static TI_STATUS hwInit_FinalizeDownloadSm          (TI_HANDLE hHwInit);
    391 static TI_STATUS hwInit_TopRegisterRead(TI_HANDLE hHwInit);
    392 static TI_STATUS hwInit_InitTopRegisterRead(TI_HANDLE hHwInit, TI_UINT32 uAddress);
    393 static TI_STATUS hwInit_TopRegisterWrite(TI_HANDLE hHwInit);
    394 static TI_STATUS hwInit_InitTopRegisterWrite(TI_HANDLE hHwInit, TI_UINT32 uAddress, TI_UINT32 uValue);
    395 #ifdef DOWNLOAD_TIMER_REQUIERD
    396 static void      hwInit_StallTimerCb                (TI_HANDLE hHwInit, TI_BOOL bTwdInitOccured);
    397 #endif
    398 
    399 
    400 /*******************************************************************************
    401 *                       PUBLIC  FUNCTIONS  IMPLEMENTATION                      *
    402 ********************************************************************************/
    403 
    404 
    405 /*************************************************************************
    406 *                        hwInit_Create                                   *
    407 **************************************************************************
    408 * DESCRIPTION:  This function initializes the HwInit module.
    409 *
    410 * INPUT:        hOs - handle to Os Abstraction Layer
    411 *
    412 * RETURN:       Handle to the allocated HwInit module
    413 *************************************************************************/
    414 TI_HANDLE hwInit_Create (TI_HANDLE hOs)
    415 {
    416     THwInit *pHwInit;
    417 
    418     /* Allocate HwInit module */
    419     pHwInit = os_memoryAlloc (hOs, sizeof(THwInit));
    420 
    421     if (pHwInit == NULL)
    422     {
    423         WLAN_OS_REPORT(("Error allocating the HwInit Module\n"));
    424         return NULL;
    425     }
    426 
    427     /* Reset HwInit module */
    428     os_memoryZero (hOs, pHwInit, sizeof(THwInit));
    429 
    430     pHwInit->hOs = hOs;
    431 
    432     return (TI_HANDLE)pHwInit;
    433 }
    434 
    435 
    436 /***************************************************************************
    437 *                           hwInit_Destroy                                 *
    438 ****************************************************************************
    439 * DESCRIPTION:  This function unload the HwInit module.
    440 *
    441 * INPUTS:       hHwInit - the object
    442 *
    443 * OUTPUT:
    444 *
    445 * RETURNS:      TI_OK - Unload succesfull
    446 *               TI_NOK - Unload unsuccesfull
    447 ***************************************************************************/
    448 TI_STATUS hwInit_Destroy (TI_HANDLE hHwInit)
    449 {
    450     THwInit *pHwInit = (THwInit *)hHwInit;
    451 
    452     if (pHwInit->hStallTimer)
    453     {
    454 #ifdef DOWNLOAD_TIMER_REQUIERD
    455 		tmr_DestroyTimer (pHwInit->hStallTimer);
    456 #endif
    457     }
    458 
    459     /* Free HwInit Module */
    460     os_memoryFree (pHwInit->hOs, pHwInit, sizeof(THwInit));
    461 
    462     return TI_OK;
    463 }
    464 
    465 
    466 /***************************************************************************
    467 *                           hwInit_Init                                    *
    468 ****************************************************************************
    469 * DESCRIPTION:  This function configures the hwInit module
    470 *
    471 * RETURNS:      TI_OK - Configuration successful
    472 *               TI_NOK - Configuration unsuccessful
    473 ***************************************************************************/
    474 TI_STATUS hwInit_Init (TI_HANDLE      hHwInit,
    475                        TI_HANDLE      hReport,
    476                        TI_HANDLE      hTimer,
    477                        TI_HANDLE      hTWD,
    478                        TI_HANDLE 	  hFinalizeDownload,
    479                        TFinalizeCb    fFinalizeDownload,
    480                        TEndOfHwInitCb fInitHwCb)
    481 {
    482     THwInit   *pHwInit = (THwInit *)hHwInit;
    483     TTxnStruct* pTxn;
    484 #ifdef TI_RANDOM_DEFAULT_MAC
    485     u32 rand_mac;
    486 #endif
    487 
    488     /* Configure modules handles */
    489     pHwInit->hReport    = hReport;
    490     pHwInit->hTWD       = hTWD;
    491     pHwInit->hTwIf      = ((TTwd *)hTWD)->hTwIf;
    492     pHwInit->hOs        = ((TTwd *)hTWD)->hOs;
    493     pHwInit->fInitHwCb  = fInitHwCb;
    494     pHwInit->fFinalizeDownload 	= fFinalizeDownload;
    495     pHwInit->hFinalizeDownload 	= hFinalizeDownload;
    496 
    497     SET_DEF_NVS(pHwInit->aDefaultNVS)
    498 #ifdef TI_RANDOM_DEFAULT_MAC
    499     /* Create random MAC address: offset 3, 4 and 5 */
    500     srandom32((u32)jiffies);
    501     rand_mac = random32();
    502     pHwInit->aDefaultNVS[3] = (u8)rand_mac;
    503     pHwInit->aDefaultNVS[4] = (u8)(rand_mac >> 8);
    504     pHwInit->aDefaultNVS[5] = (u8)(rand_mac >> 16);
    505 #endif
    506 
    507     for (pHwInit->uTxnIndex=0;pHwInit->uTxnIndex<MAX_HW_INIT_CONSECUTIVE_TXN;pHwInit->uTxnIndex++)
    508     {
    509         HW_INIT_PTXN_SET(pHwInit, pTxn)
    510         /* Setting write as default transaction */
    511         TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
    512     }
    513 
    514 #ifdef DOWNLOAD_TIMER_REQUIERD
    515 	pHwInit->hStallTimer = tmr_CreateTimer (hTimer);
    516 	if (pHwInit->hStallTimer == NULL)
    517 	{
    518 		return TI_NOK;
    519 	}
    520 #endif
    521 
    522     TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT, ".....HwInit configured successfully\n");
    523 
    524     return TI_OK;
    525 }
    526 
    527 
    528 TI_STATUS hwInit_SetNvsImage (TI_HANDLE hHwInit, TI_UINT8 *pbuf, TI_UINT32 length)
    529 {
    530     THwInit   *pHwInit = (THwInit *)hHwInit;
    531 
    532     pHwInit->pEEPROMBuf = pbuf;
    533     pHwInit->uEEPROMLen = length;
    534 
    535     return TI_OK;
    536 }
    537 
    538 
    539 TI_STATUS hwInit_SetFwImage (TI_HANDLE hHwInit, TFileInfo *pFileInfo)
    540 {
    541     THwInit   *pHwInit = (THwInit *)hHwInit;
    542 
    543     if ((hHwInit == NULL) || (pFileInfo == NULL))
    544     {
    545 	return TI_NOK;
    546     }
    547 
    548     pHwInit->pFwBuf 	= pFileInfo->pBuffer;
    549     pHwInit->uFwLength  = pFileInfo->uLength;
    550     pHwInit->uFwAddress = pFileInfo->uAddress;
    551     pHwInit->bFwBufLast = pFileInfo->bLast;
    552 
    553     return TI_OK;
    554 }
    555 
    556 
    557 /**
    558  * \fn     hwInit_SetPartition
    559  * \brief  Set HW addresses partition
    560  *
    561  * Set the HW address ranges for download or working memory and registers access.
    562  * Generate and configure the bus access address mapping table.
    563  * The partition is split between register (fixed partition of 24KB size, exists in all modes),
    564  *     and memory (dynamically changed during init and gets constant value in run-time, 104KB size).
    565  * The TwIf configures the memory mapping table on the device by issuing write transaction to
    566  *     table address (note that the TxnQ and bus driver see this as a regular transaction).
    567  *
    568  * \note In future versions, a specific bus may not support partitioning (as in wUART),
    569  *       In this case the HwInit module shall not call this function (will learn the bus
    570  *       configuration from the INI file).
    571  *
    572  * \param  pHwInit   - The module's object
    573  * \param  pPartition  - all partition base address
    574  * \return void
    575  * \sa
    576  */
    577 static void hwInit_SetPartition (THwInit   *pHwInit,
    578                                  TPartition *pPartition)
    579 {
    580    TRACE7(pHwInit->hReport, REPORT_SEVERITY_INFORMATION, "hwInit_SetPartition: uMemAddr1=0x%x, MemSize1=0x%x uMemAddr2=0x%x, MemSize2=0x%x, uMemAddr3=0x%x, MemSize3=0x%x, uMemAddr4=0x%x, MemSize4=0x%x\n",pPartition[0].uMemAdrr, pPartition[0].uMemSize,pPartition[1].uMemAdrr, pPartition[1].uMemSize,pPartition[2].uMemAdrr, pPartition[2].uMemSize,pPartition[3].uMemAdrr );
    581 
    582     /* Prepare partition Txn data and send to HW */
    583     twIf_SetPartition (pHwInit->hTwIf,pPartition);
    584 }
    585 
    586 
    587 /****************************************************************************
    588  *                      hwInit_Boot()
    589  ****************************************************************************
    590  * DESCRIPTION: Start HW init sequence which writes and reads some HW registers
    591  *                  that are needed prior to FW download.
    592  *
    593  * INPUTS:  None
    594  *
    595  * OUTPUT:  None
    596  *
    597  * RETURNS: TI_OK or TI_NOK
    598  ****************************************************************************/
    599 TI_STATUS hwInit_Boot (TI_HANDLE hHwInit)
    600 {
    601     THwInit      *pHwInit = (THwInit *)hHwInit;
    602     TTwd         *pTWD = (TTwd *)pHwInit->hTWD;
    603     TWlanParams  *pWlanParams = &DB_WLAN(pTWD->hCmdBld);
    604     TBootAttr     tBootAttr;
    605 
    606     tBootAttr.MacClock = pWlanParams->MacClock;
    607     tBootAttr.ArmClock = pWlanParams->ArmClock;
    608 
    609     /*
    610      * Initialize the status of download to  pending
    611      * It will be set to TXN_STATUS_COMPLETE at the FinalizeDownload function
    612      */
    613     pHwInit->DownloadStatus = TXN_STATUS_PENDING;
    614 
    615     /* Call the boot sequence state machine */
    616     pHwInit->uInitStage = 0;
    617 
    618     os_memoryCopy (pHwInit->hOs, &pHwInit->tBootAttr, &tBootAttr, sizeof(TBootAttr));
    619 
    620     hwInit_BootSm (hHwInit);
    621 
    622     /*
    623      * If it returns the status of the StartInstance only then we can here query for the download status
    624      * and then return the status up to the TNETW_Driver.
    625      * This return value will go back up to the TNETW Driver layer so that the init from OS will know
    626      * if to wait for the InitComplte or not in case of TXN_STATUS_ERROR.
    627      * This value will always be pending since the SPI is ASYNC
    628      * and in SDIOa timer is set so it will be ASync also in anyway.
    629      */
    630     return pHwInit->DownloadStatus;
    631 }
    632 
    633 
    634  /****************************************************************************
    635  * DESCRIPTION: Firmware boot state machine
    636  *
    637  * INPUTS:
    638  *
    639  * OUTPUT:  None
    640  *
    641  * RETURNS: TI_OK
    642  ****************************************************************************/
    643 static TI_STATUS hwInit_BootSm (TI_HANDLE hHwInit)
    644 {
    645     THwInit    *pHwInit = (THwInit *)hHwInit;
    646     TI_STATUS   status = 0;
    647     TTxnStruct  *pTxn;
    648     TI_UINT32   uData;
    649     TTwd        *pTWD        = (TTwd *) pHwInit->hTWD;
    650     IniFileGeneralParam  *pGenParams = &DB_GEN(pTWD->hCmdBld);
    651     TI_UINT32   clkVal = 0x3;
    652 
    653     switch (pHwInit->uInitStage)
    654     {
    655     case 0:
    656         pHwInit->uInitStage++;
    657         pHwInit->uTxnIndex = 0;
    658 
    659         /* Set the bus addresses partition to its "running" mode */
    660         SET_WORK_PARTITION(pHwInit->aPartition)
    661         hwInit_SetPartition (pHwInit,pHwInit->aPartition);
    662 
    663 #ifdef _VLCT_
    664          /* Set FW to test mode */
    665          BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, SCR_PAD8, 0xBABABABE,
    666                                 REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
    667          twIf_Transact(pHwInit->hTwIf, pTxn);
    668          pHwInit->uTxnIndex++;
    669 #endif
    670 
    671         if (( 0 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)) || (2 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK))
    672              || (4 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)))
    673         {/* ref clk: 19.2/38.4/38.4-XTAL */
    674             clkVal = 0x3;
    675         }
    676         if ((1 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)) || (3 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)))
    677         {/* ref clk: 26/52 */
    678             clkVal = 0x5;
    679         }
    680 
    681         WLAN_OS_REPORT(("CHIP VERSION... set 1273 chip top registers\n"));
    682 
    683         /* set the reference clock freq' to be used (pll_selinpfref field) */
    684         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, PLL_PARAMETERS, clkVal,
    685                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
    686         twIf_Transact(pHwInit->hTwIf, pTxn);
    687 
    688         pHwInit->uTxnIndex++;
    689 
    690         /* read the PAUSE value to highest threshold */
    691         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, PLL_PARAMETERS, 0,
    692                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_BootSm, hHwInit)
    693         status = twIf_Transact(pHwInit->hTwIf, pTxn);
    694 
    695         EXCEPT (pHwInit, status)
    696 
    697     case 1:
    698         pHwInit->uInitStage ++;
    699         /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
    700         uData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
    701         uData &= ~(0x3ff);
    702 
    703         /* Now we can zero the index */
    704         pHwInit->uTxnIndex = 0;
    705 
    706         /* set the the PAUSE value to highest threshold */
    707         uData |= WU_COUNTER_PAUSE_VAL;
    708         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, WU_COUNTER_PAUSE, uData,
    709                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
    710         twIf_Transact(pHwInit->hTwIf, pTxn);
    711 
    712         pHwInit->uTxnIndex++;
    713 
    714         /* Continue the ELP wake up sequence */
    715         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL,
    716                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
    717         twIf_Transact(pHwInit->hTwIf, pTxn);
    718 
    719         /* Wait 500uS */
    720         os_StalluSec (pHwInit->hOs, 500);
    721 
    722         /* Set the bus addresses partition to DRPw registers region */
    723         SET_DRP_PARTITION(pHwInit->aPartition)
    724         hwInit_SetPartition (pHwInit,pHwInit->aPartition);
    725 
    726         pHwInit->uTxnIndex++;
    727 
    728         /* Read-modify-write DRPW_SCRATCH_START register (see next state) to be used by DRPw FW.
    729            The RTRIM value will be added  by the FW before taking DRPw out of reset */
    730         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, DRPW_SCRATCH_START, 0,
    731                                REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
    732         status = twIf_Transact(pHwInit->hTwIf, pTxn);
    733 
    734         EXCEPT (pHwInit, status)
    735 
    736     case 2:
    737         pHwInit->uInitStage ++;
    738 
    739         /* multiply fref value by 2, so that {0,1,2,3} values will become {0,2,4,6} */
    740         /* Then, move it 4 places to the right, to alter Fref relevant bits in register 0x2c */
    741         clkVal = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
    742         pHwInit->uTxnIndex = 0; /* Reset index only after getting the last read value! */
    743         clkVal |= ((pGenParams->RefClk & 0x3)<< 1) << 4;
    744         if ((pGenParams->GeneralSettings & DRPw_MASK_CHECK) > 0)
    745         {
    746             clkVal |= DRPw_MASK_SET;
    747         }
    748         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, DRPW_SCRATCH_START, clkVal,
    749                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
    750         twIf_Transact(pHwInit->hTwIf, pTxn);
    751 
    752         pHwInit->uTxnIndex++;
    753 
    754 
    755         /* Set the bus addresses partition back to its "running" mode */
    756         SET_WORK_PARTITION(pHwInit->aPartition)
    757         hwInit_SetPartition (pHwInit,pHwInit->aPartition);
    758 
    759         /*
    760          * end of CHIP init seq.
    761          */
    762 
    763         /* Disable interrupts */
    764         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_MASK, ACX_INTR_ALL,
    765                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
    766         twIf_Transact(pHwInit->hTwIf, pTxn);
    767 
    768         pHwInit->uTxnIndex++;
    769 
    770         /* Read the CHIP ID to get an indication that the bus is TI_OK */
    771         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, CHIP_ID, 0,
    772                                REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
    773         status = twIf_Transact(pHwInit->hTwIf, pTxn);
    774 
    775         EXCEPT (pHwInit, status)
    776 
    777     case 3:
    778         pHwInit->uInitStage ++;
    779 
    780         /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
    781          pHwInit->uChipId = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
    782 
    783         /* This is only sanity check that the HW exists, we can continue and fail on FwLoad */
    784 		if (pHwInit->uChipId == CHIP_ID_1273_PG10)
    785         {
    786             WLAN_OS_REPORT(("Error!!  1273 PG 1.0 is not supported anymore!!.\n"));
    787         }
    788 		else if (pHwInit->uChipId == CHIP_ID_1273_PG20)
    789         {
    790             WLAN_OS_REPORT(("Working on a 1273 PG 2.0 board.\n"));
    791         }
    792         else
    793         {
    794             WLAN_OS_REPORT (("Error!! Found unknown Chip Id = 0x%x\n", pHwInit->uChipId));
    795 
    796             /*
    797              * NOTE: no exception because of forward compatibility
    798              */
    799         }
    800 
    801         /*
    802          * Soft reset
    803          */
    804         pHwInit->uResetStage = 0;
    805         pHwInit->uSelfClearTime = 0;
    806         pHwInit->uBootData = 0;
    807         status = hwInit_ResetSm (pHwInit);
    808 
    809         EXCEPT (pHwInit, status)
    810 
    811     case 4:
    812         pHwInit->uInitStage ++;
    813 
    814         TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "TNET SOFT-RESET\n");
    815 
    816         WLAN_OS_REPORT(("Starting to process NVS...\n"));
    817 
    818         /*
    819          * Start EEPROM/NVS burst
    820          */
    821 
    822         if (pHwInit->pEEPROMBuf)
    823         {
    824             /* NVS file exists (EEPROM-less support) */
    825             pHwInit->uEEPROMCurLen = pHwInit->uEEPROMLen;
    826 
    827             TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "EEPROM Image addr=0x%x, EEPROM Len=0x0x%x\n", pHwInit->pEEPROMBuf, pHwInit->uEEPROMLen);
    828             WLAN_OS_REPORT (("NVS found, EEPROM Image addr=0x%x, EEPROM Len=0x0x%x\n",
    829             pHwInit->pEEPROMBuf, pHwInit->uEEPROMLen));
    830         }
    831         else
    832         {
    833             WLAN_OS_REPORT (("No Nvs, Setting default MAC address\n"));
    834             pHwInit->uEEPROMCurLen = DEF_NVS_SIZE;
    835             pHwInit->pEEPROMBuf = (TI_UINT8*)(&pHwInit->aDefaultNVS[0]);
    836             WLAN_OS_REPORT (("pHwInit->uEEPROMCurLen: %x\n", pHwInit->uEEPROMCurLen));
    837             WLAN_OS_REPORT (("ERROR: If you are not calibating the device, you will soon get errors !!!\n"));
    838 
    839         }
    840 
    841         pHwInit->pEEPROMCurPtr = pHwInit->pEEPROMBuf;
    842         pHwInit->uEEPROMStage = 0;
    843         status = hwInit_EepromlessStartBurstSm (hHwInit);
    844 
    845         EXCEPT (pHwInit, status)
    846 
    847     case 5:
    848         pHwInit->uInitStage ++;
    849         pHwInit->uTxnIndex = 0;
    850 
    851         if (pHwInit->pEEPROMBuf)
    852         {
    853             /* Signal FW that we are eeprom less */
    854             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG,
    855                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
    856             twIf_Transact(pHwInit->hTwIf, pTxn);
    857 
    858             TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "DRIVER NVS BURST-READ\n");
    859         }
    860         else
    861         {
    862 	    /* 1273 - EEPROM is not support by FPGA yet */
    863             /*
    864              * Start ACX EEPROM
    865              */
    866             /*pHwInit->uRegister = START_EEPROM_MGR;
    867             TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
    868             BUILD_TTxnStruct(pTxn, ACX_REG_EE_START, &pHwInit->uRegister, REGISTER_SIZE, 0, NULL, NULL)
    869             twIf_Transact(pHwInit->hTwIf, pTxn);*/
    870 
    871             /*
    872              * The stall is needed so the EEPROM NVS burst read will complete
    873              */
    874             os_StalluSec (pHwInit->hOs, 40000);
    875 
    876             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_EEPROMLESS_IND_REG, USE_EEPROM,
    877                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
    878             twIf_Transact(pHwInit->hTwIf, pTxn);
    879 
    880             TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "STARTING EEPROM NVS BURST-READ\n");
    881         }
    882 
    883         pHwInit->uTxnIndex++;
    884 
    885         /* Read Chip ID */
    886         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn,  CHIP_ID, 0,
    887                                REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
    888         status = twIf_Transact(pHwInit->hTwIf, pTxn);
    889 
    890         EXCEPT (pHwInit, status)
    891 
    892     case 6:
    893         pHwInit->uInitStage ++;
    894         /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
    895         pHwInit->uBootData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
    896         /* Now we can zero the index */
    897         pHwInit->uTxnIndex = 0;
    898 
    899         WLAN_OS_REPORT(("Chip ID is 0x%X.\n", pHwInit->uBootData));
    900         /* if the WLAN_EN is ON but MainClock is problamtic the chip-id will be zero*/
    901         if (pHwInit->uBootData == 0)
    902         {
    903          WLAN_OS_REPORT(("Cannot read ChipID stopping\n", pHwInit->uBootData));
    904          TWD_FinalizeOnFailure (pHwInit->hTWD);
    905          return TXN_STATUS_ERROR;
    906         }
    907 
    908 
    909 
    910         /* Read Scr2 to verify that the HW is ready */
    911         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, SCR_PAD2, 0,
    912                                REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
    913         status = twIf_Transact(pHwInit->hTwIf, pTxn);
    914         EXCEPT (pHwInit, status)
    915 
    916     case 7:
    917         pHwInit->uInitStage ++;
    918         /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
    919         pHwInit->uBootData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
    920 
    921         if (pHwInit->uBootData == 0xffffffff)
    922         {
    923             TRACE0(pHwInit->hReport, REPORT_SEVERITY_FATAL_ERROR , "Error in SCR_PAD2 register\n");
    924             EXCEPT (pHwInit, TXN_STATUS_ERROR)
    925         }
    926 
    927         /* Call the restart sequence */
    928         pHwInit->uInitSeqStage = 0;
    929         pHwInit->uInitSeqStatus = TXN_STATUS_COMPLETE;
    930 
    931         EXCEPT (pHwInit, status)
    932 
    933     case 8:
    934         pHwInit->uInitStage++;
    935         if ((pGenParams->RefClk & FREF_CLK_TYPE_MASK) != 0x0)
    936         {
    937             status = hwInit_InitTopRegisterRead(hHwInit, 0x448);
    938             EXCEPT (pHwInit, status)
    939         }
    940 
    941     case 9:
    942         pHwInit->uInitStage++;
    943 
    944         if ((pGenParams->RefClk & FREF_CLK_TYPE_MASK) != 0x0)
    945         {
    946 			pHwInit->uTopRegValue &= FREF_CLK_TYPE_BITS;
    947             pHwInit->uTopRegValue |= CLK_REQ_PRCM;
    948 			status =  hwInit_InitTopRegisterWrite( hHwInit, 0x448, pHwInit->uTopRegValue);
    949             EXCEPT (pHwInit, status)
    950         }
    951 
    952     case 10:
    953         pHwInit->uInitStage++;
    954 		if ((pGenParams->RefClk & FREF_CLK_POLARITY_MASK) == 0x0)
    955         {
    956             status = hwInit_InitTopRegisterRead(hHwInit, 0xCB2);
    957             EXCEPT (pHwInit, status)
    958         }
    959 
    960     case 11:
    961         pHwInit->uInitStage++;
    962         if ((pGenParams->RefClk & FREF_CLK_POLARITY_MASK) == 0x0)
    963         {
    964             pHwInit->uTopRegValue &= FREF_CLK_POLARITY_BITS;
    965             pHwInit->uTopRegValue |= CLK_REQ_OUTN_SEL;
    966             status =  hwInit_InitTopRegisterWrite( hHwInit, 0xCB2, pHwInit->uTopRegValue);
    967             EXCEPT (pHwInit, status)
    968         }
    969 
    970     case 12:
    971         pHwInit->uInitStage = 0;
    972 
    973         /* Set the Download Status to COMPLETE */
    974         pHwInit->DownloadStatus = TXN_STATUS_COMPLETE;
    975 
    976         /* Call upper layer callback */
    977         if (pHwInit->fInitHwCb)
    978         {
    979             (*pHwInit->fInitHwCb) (pHwInit->hTWD);
    980         }
    981 
    982         return TI_OK;
    983     }
    984 
    985     return TI_OK;
    986 }
    987 
    988 
    989 TI_STATUS hwInit_LoadFw (TI_HANDLE hHwInit)
    990 {
    991     THwInit   *pHwInit = (THwInit *)hHwInit;
    992     TI_STATUS  status;
    993 
    994     /* check parameters */
    995     if (hHwInit == NULL)
    996     {
    997         EXCEPT (pHwInit, TXN_STATUS_ERROR)
    998     }
    999 
   1000     if (pHwInit->pFwBuf)
   1001     {
   1002         TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "CPU halt -> download code\n");
   1003 
   1004         /* Load firmware image */
   1005         pHwInit->uLoadStage = 0;
   1006         status = hwInit_LoadFwImageSm (pHwInit);
   1007 
   1008         switch (status)
   1009         {
   1010         case TI_OK:
   1011         case TXN_STATUS_OK:
   1012         case TXN_STATUS_COMPLETE:
   1013             WLAN_OS_REPORT (("Firmware successfully downloaded.\n"));
   1014             break;
   1015         case TXN_STATUS_PENDING:
   1016             WLAN_OS_REPORT (("Starting to download firmware...\n"));
   1017             break;
   1018         default:
   1019             TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Firmware download failed!\n");
   1020             break;
   1021         }
   1022 
   1023         EXCEPT (pHwInit, status);
   1024     }
   1025     else
   1026     {
   1027         TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Firmware not downloaded...\n");
   1028 
   1029         EXCEPT (pHwInit, TXN_STATUS_ERROR)
   1030     }
   1031 
   1032     WLAN_OS_REPORT (("FW download OK...\n"));
   1033     return TI_OK;
   1034 }
   1035 
   1036 
   1037 /****************************************************************************
   1038  *                      hwInit_FinalizeDownloadSm()
   1039  ****************************************************************************
   1040  * DESCRIPTION: Run the Hardware firmware
   1041  *              Wait for Init Complete
   1042  *              Configure the Bus Access with Addresses available on the scratch pad register
   1043  *              Change the SDIO/SPI partitions to be able to see all the memory addresses
   1044  *
   1045  * INPUTS:  None
   1046  *
   1047  * OUTPUT:  None
   1048  *
   1049  * RETURNS: None
   1050  ****************************************************************************/
   1051 static TI_STATUS hwInit_FinalizeDownloadSm (TI_HANDLE hHwInit)
   1052 {
   1053     THwInit  *pHwInit = (THwInit *)hHwInit;
   1054     TTwd     *pTWD = (TTwd *)pHwInit->hTWD;
   1055     TI_STATUS status = TI_OK;
   1056     TTxnStruct* pTxn;
   1057 
   1058 
   1059     while (TI_TRUE)
   1060     {
   1061         switch (pHwInit->uFinStage)
   1062         {
   1063         case 0:
   1064             pHwInit->uFinStage = 1;
   1065             pHwInit->uTxnIndex = 0;
   1066             /*
   1067              * Run the firmware (I) - Read current value from ECPU Control Reg.
   1068              */
   1069             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_ECPU_CONTROL, 0,
   1070                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
   1071             status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1072 
   1073             EXCEPT (pHwInit, status)
   1074 
   1075         case 1:
   1076             pHwInit->uFinStage ++;
   1077             /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
   1078             pHwInit->uFinData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
   1079             /* Now we can zero the index */
   1080             pHwInit->uTxnIndex = 0;
   1081 
   1082             /*
   1083              * Run the firmware (II) - Take HW out of reset (write ECPU_CONTROL_HALT to ECPU Control Reg.)
   1084              */
   1085             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_ECPU_CONTROL, (pHwInit->uFinData | ECPU_CONTROL_HALT),
   1086                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1087             twIf_Transact(pHwInit->hTwIf, pTxn);
   1088 
   1089             WLAN_OS_REPORT (("Firmware running.\n"));
   1090 
   1091             /*
   1092              * CHIP ID Debug
   1093              */
   1094 
   1095             pHwInit->uTxnIndex++;
   1096 
   1097             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, CHIP_ID, 0,
   1098                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
   1099             status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1100 
   1101             EXCEPT (pHwInit, status)
   1102 
   1103         case 2:
   1104             pHwInit->uFinStage ++;
   1105             pHwInit->uFinLoop = 0;
   1106 
   1107             /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
   1108             pHwInit->uFinData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
   1109 
   1110             TRACE1(pHwInit->hReport, REPORT_SEVERITY_INIT , "CHIP ID IS %x\n", pHwInit->uFinData);
   1111 
   1112             TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Wait init complete\n");
   1113 
   1114         case 3:
   1115             pHwInit->uTxnIndex = 0;
   1116 
   1117             /*
   1118              * Wait for init complete
   1119              */
   1120             if (pHwInit->uFinLoop < FIN_LOOP)
   1121             {
   1122                 pHwInit->uFinStage = 4;
   1123 
   1124 #ifndef DOWNLOAD_TIMER_REQUIERD
   1125 				os_StalluSec (pHwInit->hOs, 50);
   1126 #endif
   1127 
   1128                 /* Read interrupt status register */
   1129                 BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_NO_CLEAR, 0,
   1130                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
   1131                 status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1132 
   1133                 EXCEPT (pHwInit, status)
   1134             }
   1135             else
   1136 			{
   1137 				pHwInit->uFinStage = 5;
   1138 			}
   1139             continue;
   1140 
   1141         case 4:
   1142             /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
   1143             pHwInit->uFinData = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
   1144             /* Now we can zero the index */
   1145             pHwInit->uTxnIndex = 0;
   1146 
   1147             if (pHwInit->uFinData == 0xffffffff) /* error */
   1148             {
   1149                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Error reading hardware complete init indication\n");
   1150 
   1151                 pHwInit->DownloadStatus = TXN_STATUS_ERROR;
   1152                 EXCEPT (pHwInit, TXN_STATUS_ERROR)
   1153             }
   1154 
   1155             if (IS_MASK_ON (pHwInit->uFinData, ACX_INTR_INIT_COMPLETE))
   1156             {
   1157                 pHwInit->uFinStage = 5;
   1158 
   1159                 /* Interrupt ACK */
   1160                 BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_ACK, ACX_INTR_INIT_COMPLETE,
   1161                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1162                 twIf_Transact(pHwInit->hTwIf, pTxn);
   1163 
   1164                 break;
   1165             }
   1166             else
   1167             {
   1168                 pHwInit->uFinStage = 3;
   1169                 pHwInit->uFinLoop ++;
   1170 
   1171 #ifdef DOWNLOAD_TIMER_REQUIERD
   1172                 tmr_StartTimer (pHwInit->hStallTimer, hwInit_StallTimerCb, hHwInit, STALL_TIMEOUT, TI_FALSE);
   1173                 return TXN_STATUS_PENDING;
   1174 #endif
   1175             }
   1176 #ifndef DOWNLOAD_TIMER_REQUIERD
   1177             continue;
   1178 #endif
   1179 
   1180         case 5:
   1181             pHwInit->uFinStage++;
   1182 
   1183             if (pHwInit->uFinLoop >= FIN_LOOP)
   1184             {
   1185                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for the hardware to complete initialization\n");
   1186 
   1187                 pHwInit->DownloadStatus = TXN_STATUS_ERROR;
   1188                 EXCEPT (pHwInit, TXN_STATUS_ERROR);
   1189             }
   1190 
   1191             TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Firmware init complete...\n");
   1192 
   1193             /*
   1194              * There are valid addresses of the command and event mailbox
   1195              * on the scratch pad registers
   1196              */
   1197             /* Hardware config command mail box */
   1198             status = cmdMbox_ConfigHw (pTWD->hCmdMbox,
   1199                                        (fnotify_t)hwInit_FinalizeDownloadSm,
   1200                                        hHwInit);
   1201             EXCEPT (pHwInit, status)
   1202 
   1203         case 6:
   1204             pHwInit->uFinStage++;
   1205 
   1206             /* Hardware config event mail box */
   1207             status = eventMbox_InitMboxAddr (pTWD->hEventMbox,
   1208                                          (fnotify_t)hwInit_FinalizeDownloadSm,
   1209                                          hHwInit);
   1210             EXCEPT (pHwInit, status);
   1211 
   1212         case 7:
   1213             pHwInit->uFinStage++;
   1214             pHwInit->uTxnIndex = 0;
   1215 
   1216             SET_WORK_PARTITION(pHwInit->aPartition)
   1217             /* Set the bus addresses partition to its "running" mode */
   1218             SET_WORK_PARTITION(pHwInit->aPartition)
   1219             hwInit_SetPartition (pHwInit,pHwInit->aPartition);
   1220 
   1221             /* Unmask interrupts needed in the FW configuration phase */
   1222             fwEvent_SetInitMask (pTWD->hFwEvent);
   1223 
   1224             /* Get FW static information from mailbox area */
   1225             BUILD_HW_INIT_FW_STATIC_TXN(pHwInit, pTxn, cmdMbox_GetMboxAddress (pTWD->hCmdMbox),
   1226                                         (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
   1227             status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1228 
   1229             EXCEPT (pHwInit, status);
   1230             continue;
   1231 
   1232         case 8:
   1233 
   1234             pHwInit->uFinStage = 0;
   1235 
   1236             cmdBld_FinalizeDownload (pTWD->hCmdBld, &pHwInit->tBootAttr, &(pHwInit->tFwStaticTxn.tFwStaticInfo));
   1237 
   1238             /* Set the Download Status to COMPLETE */
   1239             pHwInit->DownloadStatus = TXN_STATUS_COMPLETE;
   1240 
   1241             return TXN_STATUS_COMPLETE;
   1242 
   1243         } /* End switch */
   1244 
   1245     } /* End while */
   1246 
   1247 }
   1248 
   1249 
   1250 /****************************************************************************
   1251  *                      hwInit_ResetSm()
   1252  ****************************************************************************
   1253  * DESCRIPTION: Reset hardware state machine
   1254  *
   1255  * INPUTS:  None
   1256  *
   1257  * OUTPUT:  None
   1258  *
   1259  * RETURNS: TI_OK or TI_NOK
   1260  ****************************************************************************/
   1261 static TI_STATUS hwInit_ResetSm (TI_HANDLE hHwInit)
   1262 {
   1263     THwInit *pHwInit = (THwInit *)hHwInit;
   1264     TI_STATUS status = TI_OK;
   1265     TTxnStruct* pTxn;
   1266 
   1267     pHwInit->uTxnIndex = 0;
   1268 
   1269         /* Disable Rx/Tx */
   1270     BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, REG_ENABLE_TX_RX, 0x0,
   1271                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1272     status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1273 	pHwInit->uTxnIndex++;
   1274 	return status;
   1275 }
   1276 
   1277 
   1278 /****************************************************************************
   1279  *                      hwInit_EepromlessStartBurstSm()
   1280  ****************************************************************************
   1281  * DESCRIPTION: prepare eepromless configuration before boot
   1282  *
   1283  * INPUTS:
   1284  *
   1285  * OUTPUT:
   1286  *
   1287  * RETURNS:
   1288  ****************************************************************************/
   1289 static TI_STATUS hwInit_EepromlessStartBurstSm (TI_HANDLE hHwInit)
   1290 {
   1291     THwInit   *pHwInit = (THwInit *)hHwInit;
   1292     TI_STATUS  status = TI_OK;
   1293     TI_UINT8   *uAddr;
   1294     TI_UINT32  uDeltaLength;
   1295     TTxnStruct* pTxn;
   1296 
   1297     pHwInit->uTxnIndex = 0;
   1298 
   1299     while (TI_TRUE)
   1300     {
   1301         switch (pHwInit->uEEPROMStage)
   1302         {
   1303         /*
   1304          * Stages 0, 1 handles the eeprom format parameters:
   1305          * ------------------------------------------------
   1306          * Length  - 8bit       --> The length is counted in 32bit words
   1307          * Address - 16bit
   1308          * Data    - (Length * 4) bytes
   1309          *
   1310          * Note: The nvs is in big endian format and we need to change it to little endian
   1311          */
   1312         case 0:
   1313             /* Check if address LSB = 1 --> Register address */
   1314             if ((pHwInit->uEEPROMRegAddr = pHwInit->pEEPROMCurPtr[1]) & 1)
   1315             {
   1316                 /* Mask the register's address LSB before writing to it */
   1317                 pHwInit->uEEPROMRegAddr &= 0xfe;
   1318                 /* Change the address's endian */
   1319                 pHwInit->uEEPROMRegAddr |= (TI_UINT32)pHwInit->pEEPROMCurPtr[2] << 8;
   1320                 /* Length of burst data */
   1321                 pHwInit->uEEPROMBurstLen = pHwInit->pEEPROMCurPtr[0];
   1322                 pHwInit->pEEPROMCurPtr += 3;
   1323                 pHwInit->uEEPROMBurstLoop = 0;
   1324                 /*
   1325                  * We've finished reading the burst information.
   1326                  * Go to stage 1 in order to write it
   1327                  */
   1328                 pHwInit->uEEPROMStage = 1;
   1329             }
   1330             /* If address LSB = 0 --> We're not in the burst section */
   1331             else
   1332             {
   1333                 /* End of Burst transaction: we should see 7 zeroed bytes */
   1334                 if (pHwInit->pEEPROMCurPtr[0] == 0)
   1335                 {
   1336                     pHwInit->pEEPROMCurPtr += 7;
   1337                 }
   1338                 pHwInit->uEEPROMCurLen -= (pHwInit->pEEPROMCurPtr - pHwInit->pEEPROMBuf + 1);
   1339                 pHwInit->uEEPROMCurLen = (pHwInit->uEEPROMCurLen + NVS_DATA_BUNDARY_ALIGNMENT - 1) & 0xfffffffc;
   1340                 /* End of Burst transaction, go to TLV section */
   1341                 pHwInit->uEEPROMStage = 2;
   1342             }
   1343             continue;
   1344 
   1345         case 1:
   1346             if (pHwInit->uEEPROMBurstLoop < pHwInit->uEEPROMBurstLen)
   1347             {
   1348                 /* Change the data's endian */
   1349                 TI_UINT32 val = (pHwInit->pEEPROMCurPtr[0] |
   1350                                 (pHwInit->pEEPROMCurPtr[1] << 8) |
   1351                                 (pHwInit->pEEPROMCurPtr[2] << 16) |
   1352                                 (pHwInit->pEEPROMCurPtr[3] << 24));
   1353 
   1354                 TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "NVS::BurstRead: *(%08x) = %x\n", pHwInit->uEEPROMRegAddr, val);
   1355 
   1356                 BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, (REGISTERS_BASE+pHwInit->uEEPROMRegAddr), val,
   1357                                REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_EepromlessStartBurstSm, hHwInit)
   1358                 status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1359 
   1360                 pHwInit->uEEPROMStatus = status;
   1361                 pHwInit->uEEPROMRegAddr += WORD_SIZE;
   1362                 pHwInit->pEEPROMCurPtr +=  WORD_SIZE;
   1363                 /* While not end of burst, we stay in stage 1 */
   1364                 pHwInit->uEEPROMStage = 1;
   1365                 pHwInit->uEEPROMBurstLoop ++;
   1366 
   1367                 EXCEPT (pHwInit, status);
   1368             }
   1369             else
   1370             {
   1371                 /* If end of burst return to stage 0 to read the next one */
   1372                 pHwInit->uEEPROMStage = 0;
   1373             }
   1374 
   1375             continue;
   1376 
   1377         case 2:
   1378 
   1379 
   1380             pHwInit->uEEPROMStage = 3;
   1381 
   1382             /* Set the bus addresses partition to its "running" mode */
   1383             SET_WORK_PARTITION(pHwInit->aPartition)
   1384             hwInit_SetPartition (pHwInit,pHwInit->aPartition);
   1385             continue;
   1386 
   1387         case 3:
   1388             TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Reached TLV section\n");
   1389 
   1390             /* Align the host address */
   1391             if (((TI_UINT32)pHwInit->pEEPROMCurPtr & WORD_ALIGNMENT_MASK) && (pHwInit->uEEPROMCurLen > 0) )
   1392             {
   1393                 uAddr = (TI_UINT8*)(((TI_UINT32)pHwInit->pEEPROMCurPtr & 0xFFFFFFFC)+WORD_SIZE);
   1394                 uDeltaLength = uAddr - pHwInit->pEEPROMCurPtr + 1;
   1395 
   1396                 pHwInit->pEEPROMCurPtr = uAddr;
   1397                 pHwInit->uEEPROMCurLen-= uDeltaLength;
   1398             }
   1399 
   1400             TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "NVS::WriteTLV: pEEPROMCurPtr= %x, Length=%d\n", pHwInit->pEEPROMCurPtr, pHwInit->uEEPROMCurLen);
   1401 
   1402             if (pHwInit->uEEPROMCurLen)
   1403             {
   1404                 /* Save the 4 bytes before the NVS data for WSPI case where they are overrun by the WSPI BusDrv */
   1405                 pHwInit->uSavedDataForWspiHdr = *(TI_UINT32 *)(pHwInit->pEEPROMCurPtr - WSPI_PAD_LEN_WRITE);
   1406 
   1407                 /* Prepare the Txn structure for the NVS transaction to the CMD_MBOX */
   1408                 HW_INIT_PTXN_SET(pHwInit, pTxn)
   1409                 TXN_PARAM_SET_DIRECTION(pTxn, TXN_DIRECTION_WRITE);
   1410                 BUILD_TTxnStruct(pTxn, CMD_MBOX_ADDRESS, pHwInit->pEEPROMCurPtr, pHwInit->uEEPROMCurLen,
   1411                                  (TTxnDoneCb)hwInit_EepromlessStartBurstSm, hHwInit)
   1412 
   1413                 /* Transact the NVS data to the CMD_MBOX */
   1414                 status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1415 
   1416                 pHwInit->uEEPROMCurLen = 0;
   1417                 pHwInit->uNVSStatus = status;
   1418 
   1419                 EXCEPT (pHwInit, status);
   1420             }
   1421             else
   1422             {
   1423                 /* Restore the 4 bytes before the NVS data for WSPI case were they are overrun by the WSPI BusDrv */
   1424                 *(TI_UINT32 *)(pHwInit->pEEPROMCurPtr - WSPI_PAD_LEN_WRITE) = pHwInit->uSavedDataForWspiHdr;
   1425 
   1426                 /* Call the upper level state machine */
   1427                 if (pHwInit->uEEPROMStatus == TXN_STATUS_PENDING ||
   1428                     pHwInit->uNVSStatus == TXN_STATUS_PENDING)
   1429                 {
   1430                     hwInit_BootSm (hHwInit);
   1431                 }
   1432 
   1433                 return TXN_STATUS_COMPLETE;
   1434             }
   1435         } /* End switch */
   1436 
   1437     } /* End while */
   1438 }
   1439 
   1440 /****************************************************************************
   1441  *                      hwInit_LoadFwImageSm()
   1442  ****************************************************************************
   1443  * DESCRIPTION: Load image from the host and download into the hardware
   1444  *
   1445  * INPUTS:  None
   1446  *
   1447  * OUTPUT:  None
   1448  *
   1449  * RETURNS: TI_OK or TI_NOK
   1450  ****************************************************************************/
   1451 
   1452 
   1453 #define ADDRESS_SIZE		(sizeof(TI_INT32))
   1454 
   1455 static TI_STATUS hwInit_LoadFwImageSm (TI_HANDLE hHwInit)
   1456 {
   1457     THwInit *pHwInit 			= (THwInit *)hHwInit;
   1458     TI_STATUS status 			= TI_OK;
   1459 	ETxnStatus	TxnStatus;
   1460 	TI_UINT32 uMaxPartitionSize	= PARTITION_DOWN_MEM_SIZE;
   1461     TTxnStruct* pTxn;
   1462 
   1463     pHwInit->uTxnIndex = 0;
   1464 
   1465     while (TI_TRUE)
   1466     {
   1467         switch (pHwInit->uLoadStage)
   1468         {
   1469 		case 0:
   1470             pHwInit->uLoadStage = 1;
   1471 
   1472 			/* Check the Downloaded FW alignment */
   1473 			if ((pHwInit->uFwLength % ADDRESS_SIZE) != 0)
   1474 			{
   1475 				TRACE1(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Length of downloaded Portion (%d) is not aligned\n",pHwInit->uFwLength);
   1476 				EXCEPT_L (pHwInit, TXN_STATUS_ERROR);
   1477 			}
   1478 
   1479 			TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "Image addr=0x%x, Len=0x%x\n", pHwInit->pFwBuf, pHwInit->uFwLength);
   1480 
   1481 			/* Set bus memory partition to current download area */
   1482            SET_FW_LOAD_PARTITION(pHwInit->aPartition,pHwInit->uFwAddress)
   1483            hwInit_SetPartition (pHwInit,pHwInit->aPartition);
   1484             status = TI_OK;
   1485 			break;
   1486 
   1487         case 1:
   1488 
   1489 			pHwInit->uLoadStage = 2;
   1490 			/* if initial size is smaller than MAX_SDIO_BLOCK - go strait to stage 4 to write partial block */
   1491 			if (pHwInit->uFwLength < MAX_SDIO_BLOCK)
   1492 			{
   1493 				pHwInit->uLoadStage = 4;
   1494 			}
   1495 
   1496 			pHwInit->uBlockReadNum 		= 0;
   1497 			pHwInit->uBlockWriteNum 	= 0;
   1498 			pHwInit->uPartitionLimit 	= pHwInit->uFwAddress + uMaxPartitionSize;
   1499 
   1500             continue;
   1501 
   1502         case 2:
   1503 
   1504             /* Load firmware by blocks */
   1505  			if (pHwInit->uBlockReadNum < (pHwInit->uFwLength / MAX_SDIO_BLOCK))
   1506             {
   1507                 pHwInit->uLoadStage = 3;
   1508 
   1509                 /* Change partition */
   1510 				/* The +2 is for the last block and the block remainder */
   1511 				if ( ((pHwInit->uBlockWriteNum + 2) * MAX_SDIO_BLOCK + pHwInit->uFwAddress) > pHwInit->uPartitionLimit)
   1512                 {
   1513 					pHwInit->uFwAddress += pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK;
   1514 					/* update uPartitionLimit */
   1515 					pHwInit->uPartitionLimit = pHwInit->uFwAddress + uMaxPartitionSize;
   1516                     /* Set bus memory partition to current download area */
   1517                     SET_FW_LOAD_PARTITION(pHwInit->aPartition,pHwInit->uFwAddress)
   1518                     hwInit_SetPartition (pHwInit,pHwInit->aPartition);
   1519                     TxnStatus = TXN_STATUS_OK;
   1520 					pHwInit->uBlockWriteNum = 0;
   1521                     TRACE1(pHwInit->hReport, REPORT_SEVERITY_INIT , "Change partition to address offset = 0x%x\n", 									   pHwInit->uFwAddress + pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK);
   1522                     EXCEPT_L (pHwInit, TxnStatus);
   1523                 }
   1524             }
   1525             else
   1526             {
   1527                 pHwInit->uLoadStage = 4;
   1528                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Load firmware with Portions\n");
   1529             }
   1530             continue;
   1531 
   1532         case 3:
   1533             pHwInit->uLoadStage = 2;
   1534 
   1535             pHwInit->uTxnIndex = 0;
   1536 
   1537             /* Copy image block to temporary buffer */
   1538             os_memoryCopy (pHwInit->hOs,
   1539                            (void *)&pHwInit->auFwTmpBuf[WSPI_PAD_LEN_WRITE],
   1540 						   (void *)(pHwInit->pFwBuf + pHwInit->uBlockReadNum * MAX_SDIO_BLOCK),
   1541 						   MAX_SDIO_BLOCK);
   1542 
   1543             /* Load the block. Save WSPI_PAD_LEN_WRITE space for WSPI bus command */
   1544              BUILD_HW_INIT_FW_DL_TXN(pHwInit, pTxn, (pHwInit->uFwAddress + pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK),
   1545                                      (pHwInit->auFwTmpBuf + WSPI_PAD_LEN_WRITE), MAX_SDIO_BLOCK, TXN_DIRECTION_WRITE,
   1546                                      (TTxnDoneCb)hwInit_LoadFwImageSm, hHwInit)
   1547             TxnStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
   1548 
   1549             /* Log ERROR if the transaction returned ERROR */
   1550             if (TxnStatus == TXN_STATUS_ERROR)
   1551             {
   1552                 TRACE1(pHwInit->hReport, REPORT_SEVERITY_ERROR , "hwInit_LoadFwImageSm: twIf_Transact retruned status=0x%x\n", TxnStatus);
   1553             }
   1554 
   1555 			pHwInit->uBlockWriteNum ++;
   1556 			pHwInit->uBlockReadNum ++;
   1557             EXCEPT_L (pHwInit, TxnStatus);
   1558             continue;
   1559 
   1560         case 4:
   1561 			pHwInit->uLoadStage 	= 5;
   1562 
   1563             pHwInit->uTxnIndex = 0;
   1564 
   1565 			/* If No Last block to write */
   1566 			if ( pHwInit->uFwLength % MAX_SDIO_BLOCK == 0 )
   1567 			{
   1568 				continue;
   1569 			}
   1570 
   1571 
   1572             /* Copy the last image block */
   1573              os_memoryCopy (pHwInit->hOs,
   1574                            (void *)&pHwInit->auFwTmpBuf[WSPI_PAD_LEN_WRITE],
   1575 						   (void *)(pHwInit->pFwBuf + pHwInit->uBlockReadNum * MAX_SDIO_BLOCK),
   1576 						   pHwInit->uFwLength % MAX_SDIO_BLOCK);
   1577 
   1578             /* Load the last block */
   1579              BUILD_HW_INIT_FW_DL_TXN(pHwInit, pTxn, (pHwInit->uFwAddress + pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK),
   1580                                      (pHwInit->auFwTmpBuf + WSPI_PAD_LEN_WRITE), (pHwInit->uFwLength % MAX_SDIO_BLOCK), TXN_DIRECTION_WRITE,
   1581                                      (TTxnDoneCb)hwInit_LoadFwImageSm, hHwInit)
   1582             TxnStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
   1583 
   1584             if (TxnStatus == TXN_STATUS_ERROR)
   1585 			{
   1586                 TRACE1(pHwInit->hReport, REPORT_SEVERITY_ERROR , "hwInit_LoadFwImageSm: last block retruned status=0x%x\n", TxnStatus);
   1587 			}
   1588 
   1589             EXCEPT_L (pHwInit, TxnStatus);
   1590             continue;
   1591 
   1592         case 5:
   1593             pHwInit->uLoadStage = 0;
   1594 
   1595 			/*If end of overall FW Download Process: Finalize download (run firmware)*/
   1596 			if ( pHwInit->bFwBufLast == TI_TRUE )
   1597 			{
   1598 				/* The download has completed */
   1599 				WLAN_OS_REPORT (("Finished downloading firmware.\n"));
   1600 				status = hwInit_FinalizeDownloadSm (hHwInit);
   1601 			}
   1602 			/* Have to wait to more FW Portions */
   1603 			else
   1604 			{
   1605 				/* Call the upper layer callback */
   1606 				if ( pHwInit->fFinalizeDownload != NULL )
   1607 				{
   1608 					(pHwInit->fFinalizeDownload) (pHwInit->hFinalizeDownload);
   1609 				}
   1610 
   1611 				status = TI_OK;
   1612 			}
   1613             return status;
   1614 
   1615         } /* End switch */
   1616 
   1617     } /* End while */
   1618 
   1619 } /* hwInit_LoadFwImageSm() */
   1620 
   1621 #define READ_TOP_REG_LOOP  32
   1622 
   1623 /****************************************************************************
   1624  *                      hwInit_ReadRadioParamsSm ()
   1625  ****************************************************************************
   1626  * DESCRIPTION: hwInit_ReadRadioParamsSm
   1627  * INPUTS:  None
   1628  *
   1629  * OUTPUT:  None
   1630  *
   1631  * RETURNS: TI_OK or TI_NOK
   1632  ****************************************************************************/
   1633 TI_STATUS hwInit_ReadRadioParamsSm (TI_HANDLE hHwInit)
   1634 {
   1635     THwInit      *pHwInit = (THwInit *)hHwInit;
   1636     TTwd         *pTWD = (TTwd *)pHwInit->hTWD;
   1637    IniFileGeneralParam *pGenParams = &DB_GEN(pTWD->hCmdBld);
   1638     TI_UINT32  val= 0, value;
   1639     TI_UINT32  add = FUNC7_SEL;
   1640 	TI_UINT32  retAddress;
   1641     TTxnStruct  *pTxn;
   1642     TI_STATUS   status = 0;
   1643 
   1644 
   1645     while (TI_TRUE)
   1646     {
   1647        switch (pHwInit->uRegStage)
   1648         {
   1649         case 0:
   1650             pHwInit->uRegStage = 1;
   1651             pHwInit->uTxnIndex++;
   1652 
   1653             /*
   1654              * Select GPIO over Debug for BT_FUNC7 clear bit 17
   1655              */
   1656             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_SELECT, 0,
   1657                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
   1658             status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1659 
   1660             EXCEPT (pHwInit, status)
   1661 
   1662         case 1:
   1663             pHwInit->uRegStage ++;
   1664             pHwInit->uRegLoop = 0;
   1665 
   1666             /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
   1667             val = (pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData);
   1668             val &= 0xFFFDFFFF; /*clear bit 17*/
   1669             /* Now we can zero the index */
   1670             pHwInit->uTxnIndex = 0;
   1671 
   1672             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_SELECT, val,
   1673                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1674 
   1675             twIf_Transact(pHwInit->hTwIf, pTxn);
   1676 
   1677             pHwInit->uTxnIndex++;
   1678 
   1679             pHwInit->uRegData = FUNC7_SEL;
   1680 
   1681             continue;
   1682 
   1683         case 2:
   1684 
   1685             pHwInit->uRegStage ++;
   1686             add = pHwInit->uRegData;
   1687 
   1688 
   1689             /* Select GPIO over Debug for BT_FUNC7*/
   1690             retAddress = (TI_UINT32)(add / 2);
   1691 	        val = (retAddress & 0x7FF);
   1692         	val |= BIT_16 | BIT_17;
   1693 
   1694             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, val,
   1695                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1696             twIf_Transact(pHwInit->hTwIf, pTxn);
   1697 
   1698             pHwInit->uTxnIndex++;
   1699 
   1700             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x2,
   1701                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1702             twIf_Transact(pHwInit->hTwIf, pTxn);
   1703 
   1704             continue;
   1705 
   1706         case 3:
   1707 
   1708             pHwInit->uRegStage ++;
   1709             pHwInit->uTxnIndex++;
   1710 
   1711             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_DATA_RD, 0,
   1712                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
   1713             status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1714 
   1715             EXCEPT (pHwInit, status)
   1716 
   1717 
   1718         case 4:
   1719 
   1720             val = (pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData);
   1721 
   1722             pHwInit->uTxnIndex = 0;
   1723             if (val & BIT_18)
   1724             {
   1725               if ((val & BIT_16) && (!(val & BIT_17)))
   1726               {
   1727                   pHwInit->uRegStage ++;
   1728                   pHwInit->uRegLoop = 0;
   1729 
   1730               }
   1731               else
   1732               {
   1733                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "can't writing bt_func7_sel\n");
   1734 
   1735                 TWD_FinalizeFEMRead(pHwInit->hTWD);
   1736 
   1737                 return TI_NOK;
   1738               }
   1739             }
   1740             else
   1741             {
   1742               if (pHwInit->uRegLoop < READ_TOP_REG_LOOP)
   1743               {
   1744                  pHwInit->uRegStage = 3;
   1745                  pHwInit->uRegLoop++;
   1746               }
   1747               else
   1748               {
   1749 
   1750                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for writing bt_func7_sel\n");
   1751 
   1752                 TWD_FinalizeFEMRead(pHwInit->hTWD);
   1753 
   1754                 return TI_NOK;
   1755 
   1756               }
   1757             }
   1758 
   1759             continue;
   1760 
   1761         case 5:
   1762                pHwInit->uRegStage ++;
   1763                add = pHwInit->uRegData;
   1764                retAddress = (TI_UINT32)(add / 2);
   1765 	           value = (retAddress & 0x7FF);
   1766                value |= BIT_16 | BIT_17;
   1767 
   1768                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, value,
   1769                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1770                twIf_Transact(pHwInit->hTwIf, pTxn);
   1771 
   1772                pHwInit->uTxnIndex++;
   1773 
   1774               if (pHwInit->uRegSeqStage == 0)
   1775               {
   1776                   if (pHwInit->uRegData == FUNC7_SEL)
   1777                     value = (val | 0x600);
   1778                   else
   1779                     value = (val | 0x1000);
   1780               }
   1781               else
   1782               {
   1783                   if (pHwInit->uRegData == FUNC7_SEL)
   1784                     value = (val & 0xF8FF);
   1785                   else
   1786                     value = (val & 0xCFFF);
   1787 
   1788               }
   1789 
   1790 	      value &= 0xFFFF;
   1791 
   1792                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_WDATA, value,
   1793                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1794                twIf_Transact(pHwInit->hTwIf, pTxn);
   1795 
   1796                pHwInit->uTxnIndex++;
   1797 
   1798                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x1,
   1799                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
   1800 
   1801                /*BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, INDIRECT_REG5, 0x1,
   1802                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL) */
   1803 
   1804                status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1805 
   1806                pHwInit->uTxnIndex++;
   1807 
   1808                if ((pHwInit->uRegData == FUNC7_SEL)&& (pHwInit->uRegSeqStage == 0))
   1809                {
   1810                  pHwInit->uRegData = FUNC7_PULL;
   1811                  pHwInit->uRegStage = 2;
   1812                }
   1813                else
   1814                {
   1815                   if ((pHwInit->uRegData == FUNC7_PULL)&& (pHwInit->uRegSeqStage == 1))
   1816                    {
   1817                      pHwInit->uRegData = FUNC7_SEL;
   1818                      pHwInit->uRegStage = 2;
   1819                    }
   1820                }
   1821 
   1822                EXCEPT (pHwInit, status)
   1823                continue;
   1824 
   1825         case 6:
   1826 
   1827               if (pHwInit->uRegSeqStage == 1)
   1828               {
   1829                   pHwInit->uRegStage = 8;
   1830               }
   1831               else
   1832               {
   1833                 pHwInit->uRegStage ++;
   1834                 pHwInit->uTxnIndex++;
   1835 
   1836                 BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_OE_RADIO, 0,
   1837                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
   1838                 status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1839                 EXCEPT (pHwInit, status)
   1840               }
   1841               continue;
   1842 
   1843         case 7:
   1844             pHwInit->uRegStage ++;
   1845 
   1846             /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
   1847             val = (pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData);
   1848             val |= 0x00020000;
   1849 
   1850             pHwInit->uTxnIndex = 0;
   1851             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_OE_RADIO, val,
   1852                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1853             twIf_Transact(pHwInit->hTwIf, pTxn);
   1854 
   1855             pHwInit->uTxnIndex++;
   1856 
   1857             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_IN, 0,
   1858                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
   1859             status = twIf_Transact(pHwInit->hTwIf, pTxn);
   1860 
   1861             EXCEPT (pHwInit, status)
   1862 
   1863 
   1864         case 8:
   1865             if (pHwInit->uRegSeqStage == 0)
   1866              {
   1867 	       val = (pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData);
   1868 	       val &= 0x20000;
   1869 	       if(val)
   1870 	      {
   1871 		   pGenParams->TXBiPFEMManufacturer = FEM_TRIQUINT_TYPE_E;
   1872 	      }
   1873 	      else
   1874 	      {
   1875 	  	   pGenParams->TXBiPFEMManufacturer = FEM_RFMD_TYPE_E;
   1876 	      }
   1877                WLAN_OS_REPORT (("FEM Type %d \n",pGenParams->TXBiPFEMManufacturer));
   1878 			   pHwInit->uTxnIndex = 0;
   1879                pHwInit->uRegSeqStage = 1;
   1880                pHwInit->uRegStage = 2;
   1881                pHwInit->uRegData = FUNC7_PULL;
   1882                continue;
   1883              }
   1884              else
   1885              {
   1886               TRACE0(pHwInit->hReport, REPORT_SEVERITY_INFORMATION, "hwInit_ReadRadioParamsSm Ended Successfully\n");
   1887 
   1888               TWD_FinalizeFEMRead(pHwInit->hTWD);
   1889 
   1890               return TI_OK;
   1891 
   1892              }
   1893 
   1894         } /* End switch */
   1895 
   1896     } /* End while */
   1897 
   1898 }
   1899 
   1900 
   1901 /****************************************************************************
   1902  *                      hwInit_ReadRadioParams()
   1903  ****************************************************************************
   1904  * DESCRIPTION: hwInit_ReadRadioParamsSm
   1905  * initalizie hwInit_ReadRadioParamsSm parmaeters
   1906   ****************************************************************************/
   1907 
   1908 TI_STATUS hwInit_ReadRadioParams (TI_HANDLE hHwInit)
   1909 {
   1910   THwInit      *pHwInit = (THwInit *)hHwInit;
   1911 
   1912   pHwInit->uRegStage = 0;
   1913   pHwInit->uRegSeqStage = 0;
   1914 
   1915   return hwInit_ReadRadioParamsSm (hHwInit);
   1916 }
   1917 
   1918 /****************************************************************************
   1919  *                      hwInit_InitPoalrity()
   1920  ****************************************************************************
   1921  * DESCRIPTION: hwInit_ReadRadioParamsSm
   1922  * initalizie hwInit_ReadRadioParamsSm parmaeters
   1923   ****************************************************************************/
   1924 
   1925 TI_STATUS hwInit_InitPolarity(TI_HANDLE hHwInit)
   1926 {
   1927   THwInit      *pHwInit = (THwInit *)hHwInit;
   1928 
   1929   pHwInit->uRegStage = 0;
   1930   pHwInit->uRegSeqStage = 0;
   1931 
   1932   return hwInit_WriteIRQPolarity (hHwInit);
   1933 }
   1934 
   1935 
   1936 
   1937 /****************************************************************************
   1938  *                      hwInit_WriteIRQPolarity ()
   1939  ****************************************************************************
   1940  * DESCRIPTION: hwInit_WriteIRQPolarity
   1941   * INPUTS:  None
   1942  *
   1943  * OUTPUT:  None
   1944  *
   1945  * RETURNS: TI_OK or TI_NOK
   1946  ****************************************************************************/
   1947  TI_STATUS hwInit_WriteIRQPolarity(TI_HANDLE hHwInit)
   1948  {
   1949      THwInit     *pHwInit = (THwInit *)hHwInit;
   1950      TI_UINT32   Address,value;
   1951      TI_UINT32   val=0;
   1952      TTxnStruct  *pTxn;
   1953      TI_STATUS   status = 0;
   1954 
   1955    /*  To write to a top level address from the WLAN IP:
   1956        Write the top level address to the OCP_POR_CTR register.
   1957        Divide the top address by 2, and add 0x30000 to the result  for example for top address 0xC00, write to the OCP_POR_CTR 0x30600
   1958        Write the data to the OCP_POR_WDATA register
   1959        Write 0x1 to the OCP_CMD register.
   1960 
   1961       To read from a top level address:
   1962       Write the top level address to the OCP_POR_CTR register.
   1963       Divide the top address by 2, and add 0x30000 to the result  for example for top address 0xC00, write to the OCP_POR_CTR 0x30600
   1964       Write 0x2 to the OCP_CMD register.
   1965       Poll bit [18] of OCP_DATA_RD for data valid indication
   1966       Check bits 17:16 of OCP_DATA_RD:
   1967       00  no response
   1968       01  data valid / accept
   1969       10  request failed
   1970       11  response error
   1971       Read the data from the OCP_DATA_RD register
   1972    */
   1973 
   1974      while (TI_TRUE)
   1975      {
   1976          switch (pHwInit->uRegStage)
   1977          {
   1978          case 0:
   1979 
   1980              pHwInit->uRegStage = 1;
   1981              pHwInit->uTxnIndex++;
   1982              pHwInit->uRegLoop = 0;
   1983 
   1984              /* first read the IRQ Polarity register*/
   1985              Address = (TI_UINT32)(FN0_CCCR_REG_32 / 2);
   1986              val = (Address & 0x7FF);
   1987              val |= BIT_16 | BIT_17;
   1988 
   1989              /* Write IRQ Polarity address register to OCP_POR_CTR*/
   1990              BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, val,
   1991                                 REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   1992 
   1993              twIf_Transact(pHwInit->hTwIf, pTxn);
   1994 
   1995              pHwInit->uTxnIndex++;
   1996 
   1997              /* Write read (2)command to the OCP_CMD register. */
   1998 
   1999              BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x2,
   2000                                 REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   2001              twIf_Transact(pHwInit->hTwIf, pTxn);
   2002 
   2003              continue;
   2004 
   2005          case 1:
   2006 
   2007              pHwInit->uRegStage ++;
   2008              pHwInit->uTxnIndex++;
   2009 
   2010              BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_DATA_RD, 0,
   2011                                 REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_WriteIRQPolarity, hHwInit)
   2012              status = twIf_Transact(pHwInit->hTwIf, pTxn);
   2013 
   2014              EXCEPT (pHwInit, status)
   2015 
   2016 
   2017          case 2:
   2018              /* get the value from  IRQ Polarity register*/
   2019              val = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
   2020 
   2021              pHwInit->uTxnIndex = 0;
   2022 
   2023              /*Poll bit 18 of OCP_DATA_RD for data valid indication*/
   2024              if (val & BIT_18)
   2025              {
   2026                if ((val & BIT_16) && (!(val & BIT_17)))
   2027                {
   2028                    pHwInit->uRegStage ++;
   2029                    pHwInit->uRegLoop = 0;
   2030 
   2031                }
   2032                else
   2033                {
   2034                  TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "can't writing bt_func7_sel\n");
   2035                  TWD_FinalizePolarityRead(pHwInit->hTWD);
   2036 
   2037                 return TI_NOK;
   2038                }
   2039              }
   2040              else
   2041              {
   2042                if (pHwInit->uRegLoop < READ_TOP_REG_LOOP)
   2043                {
   2044                   pHwInit->uRegStage = 1;
   2045                   pHwInit->uRegLoop++;
   2046                }
   2047                else
   2048                {
   2049 
   2050                  TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for writing bt_func7_sel\n");
   2051                  TWD_FinalizePolarityRead(pHwInit->hTWD);
   2052 
   2053                 return TI_NOK;
   2054 
   2055                }
   2056              }
   2057 
   2058              continue;
   2059 
   2060 
   2061          case 3:
   2062                /* second, write new value of IRQ polarity due to complation flag 1 - active low, 0 - active high*/
   2063                 pHwInit->uRegStage ++;
   2064                 Address = (TI_UINT32)(FN0_CCCR_REG_32 / 2);
   2065                 value = (Address & 0x7FF);
   2066                 value |= BIT_16 | BIT_17;
   2067 
   2068                 /* Write IRQ Polarity address register to OCP_POR_CTR*/
   2069 
   2070                 BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, value,
   2071                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   2072 
   2073                 twIf_Transact(pHwInit->hTwIf, pTxn);
   2074 
   2075                 pHwInit->uTxnIndex++;
   2076 
   2077 #ifdef USE_IRQ_ACTIVE_HIGH
   2078                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_INFORMATION , "Hwinit IRQ polarity active high\n");
   2079                 val |= 0x0<<1;
   2080 
   2081 #else
   2082                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_INFORMATION , "Hwinit IRQ polarity active low\n");
   2083                 val |= 0x01<<1;
   2084 #endif
   2085 
   2086               /* Write the new IRQ polarity value to the OCP_POR_WDATA register */
   2087                 BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_WDATA, val,
   2088                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   2089                 twIf_Transact(pHwInit->hTwIf, pTxn);
   2090 
   2091                 pHwInit->uTxnIndex++;
   2092 
   2093                /* Write write (1)command to the OCP_CMD register. */
   2094                 BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x1,
   2095                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_WriteIRQPolarity, hHwInit)
   2096                 status = twIf_Transact(pHwInit->hTwIf, pTxn);
   2097 
   2098                 pHwInit->uTxnIndex++;
   2099 
   2100                 EXCEPT (pHwInit, status)
   2101                 continue;
   2102 
   2103          case 4:
   2104 
   2105                TWD_FinalizePolarityRead(pHwInit->hTWD);
   2106 
   2107               return TI_OK;
   2108 
   2109 
   2110          } /* End switch */
   2111 
   2112      } /* End while */
   2113 
   2114  }
   2115 
   2116 
   2117 /****************************************************************************
   2118  *                      hwInit_InitTopRegisterWrite()
   2119  ****************************************************************************
   2120  * DESCRIPTION: hwInit_InitTopRegisterWrite
   2121  * initalizie hwInit_TopRegisterWrite SM parmaeters
   2122   ****************************************************************************/
   2123 
   2124 TI_STATUS hwInit_InitTopRegisterWrite(TI_HANDLE hHwInit, TI_UINT32 uAddress, TI_UINT32 uValue)
   2125 {
   2126   THwInit      *pHwInit = (THwInit *)hHwInit;
   2127 
   2128   pHwInit->uTopStage = 0;
   2129   uAddress = (TI_UINT32)(uAddress / 2);
   2130   uAddress = (uAddress & 0x7FF);
   2131   uAddress|= BIT_16 | BIT_17;
   2132   pHwInit->uTopRegAddr = uAddress;
   2133   pHwInit->uTopRegValue = uValue & 0xffff;
   2134   return hwInit_TopRegisterWrite (hHwInit);
   2135 }
   2136 
   2137 
   2138 /****************************************************************************
   2139  *                      hwInit_TopRegisterWrite ()
   2140  ****************************************************************************
   2141  * DESCRIPTION: Generic function that writes to the top registers area
   2142   * INPUTS:  None
   2143  *
   2144  * OUTPUT:  None
   2145  *
   2146  * RETURNS: TI_OK or TI_NOK
   2147  ****************************************************************************/
   2148  TI_STATUS hwInit_TopRegisterWrite(TI_HANDLE hHwInit)
   2149  {
   2150      /*  To write to a top level address from the WLAN IP:
   2151          Write the top level address to the OCP_POR_CTR register.
   2152          Divide the top address by 2, and add 0x30000 to the result  for example for top address 0xC00, write to the OCP_POR_CTR 0x30600
   2153          Write the data to the OCP_POR_WDATA register
   2154          Write 0x1 to the OCP_CMD register.
   2155      */
   2156      THwInit *pHwInit = (THwInit *)hHwInit;
   2157      TTxnStruct *pTxn;
   2158 
   2159      while (TI_TRUE)
   2160      {
   2161          switch (pHwInit->uTopStage)
   2162          {
   2163          case 0:
   2164              pHwInit->uTopStage = 1;
   2165 
   2166              pHwInit->uTxnIndex++;
   2167              /* Write the address to OCP_POR_CTR*/
   2168              BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, pHwInit->uTopRegAddr,
   2169                                     REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   2170              twIf_Transact(pHwInit->hTwIf, pTxn);
   2171 
   2172              pHwInit->uTxnIndex++;
   2173              /* Write the new value to the OCP_POR_WDATA register */
   2174              BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_WDATA, pHwInit->uTopRegValue,
   2175                                     REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   2176              twIf_Transact(pHwInit->hTwIf, pTxn);
   2177 
   2178              pHwInit->uTxnIndex++;
   2179              /* Write write (1)command to the OCP_CMD register. */
   2180              BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x1,
   2181                                     REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_TopRegisterWrite, hHwInit)
   2182              pHwInit->uTopStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
   2183 
   2184              pHwInit->uTxnIndex++;
   2185 
   2186              EXCEPT (pHwInit, pHwInit->uTopStatus)
   2187              continue;
   2188 
   2189          case 1:
   2190 
   2191              pHwInit->uTxnIndex = 0;
   2192 
   2193              if (pHwInit->uTopStatus == TXN_STATUS_PENDING)
   2194              {
   2195                  hwInit_BootSm (hHwInit);
   2196              }
   2197 
   2198              return TI_OK;
   2199 
   2200          } /* End switch */
   2201 
   2202      } /* End while */
   2203 
   2204  }
   2205 
   2206 
   2207  /****************************************************************************
   2208  *                      hwInit_InitTopRegisterRead()
   2209  ****************************************************************************
   2210  * DESCRIPTION: hwInit_InitTopRegisterRead
   2211  * initalizie hwInit_InitTopRegisterRead SM parmaeters
   2212   ****************************************************************************/
   2213 
   2214 TI_STATUS hwInit_InitTopRegisterRead(TI_HANDLE hHwInit, TI_UINT32 uAddress)
   2215 {
   2216   THwInit      *pHwInit = (THwInit *)hHwInit;
   2217 
   2218   pHwInit->uTopStage = 0;
   2219   uAddress = (TI_UINT32)(uAddress / 2);
   2220   uAddress = (uAddress & 0x7FF);
   2221   uAddress|= BIT_16 | BIT_17;
   2222   pHwInit->uTopRegAddr = uAddress;
   2223 
   2224   return hwInit_TopRegisterRead (hHwInit);
   2225 }
   2226 
   2227 
   2228 /****************************************************************************
   2229  *                      hwInit_TopRegisterRead ()
   2230  ****************************************************************************
   2231  * DESCRIPTION: Generic function that reads the top registers area
   2232   * INPUTS:  None
   2233  *
   2234  * OUTPUT:  None
   2235  *
   2236  * RETURNS: TI_OK or TI_NOK
   2237  ****************************************************************************/
   2238  TI_STATUS hwInit_TopRegisterRead(TI_HANDLE hHwInit)
   2239  {
   2240      /*
   2241         To read from a top level address:
   2242         Write the top level address to the OCP_POR_CTR register.
   2243         Divide the top address by 2, and add 0x30000 to the result  for example for top address 0xC00, write to the OCP_POR_CTR 0x30600
   2244         Write 0x2 to the OCP_CMD register.
   2245         Poll bit [18] of OCP_DATA_RD for data valid indication
   2246         Check bits 17:16 of OCP_DATA_RD:
   2247         00  no response
   2248         01  data valid / accept
   2249         10  request failed
   2250         11  response error
   2251         Read the data from the OCP_DATA_RD register
   2252      */
   2253 
   2254      THwInit *pHwInit = (THwInit *)hHwInit;
   2255      TTxnStruct *pTxn;
   2256 
   2257      while (TI_TRUE)
   2258      {
   2259          switch (pHwInit->uTopStage)
   2260          {
   2261          case 0:
   2262              pHwInit->uTopStage = 1;
   2263              pHwInit->uTxnIndex++;
   2264              pHwInit->uRegLoop = 0;
   2265 
   2266              /* Write the address to OCP_POR_CTR*/
   2267              BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, pHwInit->uTopRegAddr,
   2268                                     REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   2269              twIf_Transact(pHwInit->hTwIf, pTxn);
   2270 
   2271              pHwInit->uTxnIndex++;
   2272              BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x2,
   2273                                     REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
   2274              twIf_Transact(pHwInit->hTwIf, pTxn);
   2275 
   2276              continue;
   2277 
   2278          case 1:
   2279              pHwInit->uTopStage ++;
   2280              pHwInit->uTxnIndex++;
   2281 
   2282              BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_DATA_RD, 0,
   2283                                     REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_TopRegisterRead, hHwInit)
   2284              pHwInit->uTopStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
   2285 
   2286              EXCEPT (pHwInit, pHwInit->uTopStatus)
   2287 
   2288          case 2:
   2289              /* get the value from  IRQ Polarity register*/
   2290              pHwInit->uTopRegValue = pHwInit->aHwInitTxn[pHwInit->uTxnIndex].uData;
   2291 
   2292              pHwInit->uTxnIndex = 0;
   2293 
   2294              /*Poll bit 18 of OCP_DATA_RD for data valid indication*/
   2295              if (pHwInit->uTopRegValue & BIT_18)
   2296              {
   2297                if ((pHwInit->uTopRegValue & BIT_16) && (!(pHwInit->uTopRegValue & BIT_17)))
   2298                {
   2299                    pHwInit->uTopRegValue &= 0xffff;
   2300                    pHwInit->uTxnIndex = 0;
   2301                    pHwInit->uRegLoop = 0;
   2302                    if (pHwInit->uTopStatus == TXN_STATUS_PENDING)
   2303                    {
   2304                        hwInit_BootSm (hHwInit);
   2305                    }
   2306                    return TI_OK;
   2307                }
   2308                else
   2309                {
   2310                  TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "can't write bt_func7_sel\n");
   2311                  if (pHwInit->uTopStatus == TXN_STATUS_PENDING)
   2312                  {
   2313                        hwInit_BootSm (hHwInit);
   2314                  }
   2315                  return TI_NOK;
   2316                }
   2317              }
   2318              else
   2319              {
   2320                if (pHwInit->uRegLoop < READ_TOP_REG_LOOP)
   2321                {
   2322                   pHwInit->uTopStage = 1;
   2323                   pHwInit->uRegLoop++;
   2324                }
   2325                else
   2326                {
   2327                  TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for writing bt_func7_sel\n");
   2328                  if (pHwInit->uTopStatus == TXN_STATUS_PENDING)
   2329                  {
   2330                        hwInit_BootSm (hHwInit);
   2331                  }
   2332                  return TI_NOK;
   2333                }
   2334               }
   2335 
   2336              continue;
   2337 
   2338          } /* End switch */
   2339 
   2340      } /* End while */
   2341 
   2342  }
   2343 
   2344 
   2345 /****************************************************************************
   2346 *                      hwInit_StallTimerCb ()
   2347 ****************************************************************************
   2348 * DESCRIPTION: CB timer function in fTimerFunction format that calls hwInit_StallTimerCb
   2349 * INPUTS:  TI_HANDLE hHwInit
   2350 *
   2351 * OUTPUT:  None
   2352 *
   2353 * RETURNS: None
   2354 ****************************************************************************/
   2355 #ifdef DOWNLOAD_TIMER_REQUIERD
   2356  static void hwInit_StallTimerCb (TI_HANDLE hHwInit, TI_BOOL bTwdInitOccured)
   2357 {
   2358 	hwInit_FinalizeDownloadSm (hHwInit);
   2359 }
   2360 #endif
   2361