TWD/FW_Transfer/HwInit.c
changeset 0 10c42ec6c05f
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/TWD/FW_Transfer/HwInit.c	Tue Jun 29 12:34:26 2010 +0100
@@ -0,0 +1,2422 @@
+/*
+ * HwInit.c
+ *
+ * Copyright(c) 1998 - 2010 Texas Instruments. All rights reserved.      
+ * All rights reserved.      
+ * 
+ * This program and the accompanying materials are made available under the 
+ * terms of the Eclipse Public License v1.0 or BSD License which accompanies
+ * this distribution. The Eclipse Public License is available at
+ * http://www.eclipse.org/legal/epl-v10.html and the BSD License is as below.                                   
+ *                                                                       
+ * Redistribution and use in source and binary forms, with or without    
+ * modification, are permitted provided that the following conditions    
+ * are met:                                                              
+ *                                                                       
+ *  * Redistributions of source code must retain the above copyright     
+ *    notice, this list of conditions and the following disclaimer.      
+ *  * Redistributions in binary form must reproduce the above copyright  
+ *    notice, this list of conditions and the following disclaimer in    
+ *    the documentation and/or other materials provided with the         
+ *    distribution.                                                      
+ *  * Neither the name Texas Instruments nor the names of its            
+ *    contributors may be used to endorse or promote products derived    
+ *    from this software without specific prior written permission.      
+ *                                                                       
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+
+
+/*******************************************************************************/
+/*                                                                             */
+/*  MODULE:  HwInit.c                                                          */
+/*  PURPOSE: HwInit module manages the init process of the TNETW, included     */
+/*           firmware download process. It shall perform Hard Reset the chip   */
+/*           if possible (this will require a Reset line to be connected to    */
+/*           the host); Start InterfaceCtrl; Download NVS and FW               */
+/*                                                                             */
+/*                                                                             */
+/*******************************************************************************/
+
+#define __FILE_ID__  FILE_ID_105
+#include "tidef.h"
+#include "osApi.h"
+#include "report.h"
+#include "HwInit_api.h"
+#include "FwEvent_api.h"
+#include "TwIf.h"
+#include "TWDriver.h"
+#include "TWDriverInternal.h"
+#include "eventMbox_api.h"
+#include "CmdBld.h"
+#include "CmdMBox_api.h"
+
+
+
+extern void TWD_FinalizeOnFailure   (TI_HANDLE hTWD);
+extern void cmdBld_FinalizeDownload (TI_HANDLE hCmdBld, TBootAttr *pBootAttr, FwStaticData_t *pFwInfo);
+
+
+/************************************************************************
+ * Defines
+ ************************************************************************/
+
+/* Download phase partition */
+#define PARTITION_DOWN_MEM_ADDR       0                 
+#define PARTITION_DOWN_MEM_SIZE       0x177C0           
+#define PARTITION_DOWN_REG_ADDR       REGISTERS_BASE	
+#define PARTITION_DOWN_REG_SIZE       0x8800            
+
+/* Working phase partition */
+#define PARTITION_WORK_MEM_ADDR1       0x40000
+#define PARTITION_WORK_MEM_SIZE1       0x14FC0
+#define PARTITION_WORK_MEM_ADDR2       REGISTERS_BASE    
+#define PARTITION_WORK_MEM_SIZE2       0xA000   
+#define PARTITION_WORK_MEM_ADDR3       0x3004F8     
+#define PARTITION_WORK_MEM_SIZE3       0x4   
+#define PARTITION_WORK_MEM_ADDR4       0x40404   
+
+/* DRPW setting partition */
+#define PARTITION_DRPW_MEM_ADDR       0x40000
+#define PARTITION_DRPW_MEM_SIZE       0x14FC0
+#define PARTITION_DRPW_REG_ADDR       DRPW_BASE         
+#define PARTITION_DRPW_REG_SIZE       0x6000	        
+
+/* Total range of bus addresses range */
+#define PARTITION_TOTAL_ADDR_RANGE    0x1FFC0
+
+/* Maximal block size in a single SDIO transfer --> Firmware image load chunk size */
+#ifdef _VLCT_
+#define MAX_SDIO_BLOCK					(4000)	
+#else
+#define MAX_SDIO_BLOCK					(500)	
+#endif
+
+#define ACX_EEPROMLESS_IND_REG        (SCR_PAD4)
+#define USE_EEPROM                    (0)
+#define SOFT_RESET_MAX_TIME           (1000000)
+#define SOFT_RESET_STALL_TIME         (1000)
+#define NVS_DATA_BUNDARY_ALIGNMENT    (4)
+
+#define MAX_HW_INIT_CONSECUTIVE_TXN     15
+
+#define WORD_SIZE                       4
+#define WORD_ALIGNMENT_MASK             0x3
+#define DEF_NVS_SIZE                    (NVS_TOTAL_LENGTH)
+
+#define RADIO_SM_WAIT_LOOP  32
+
+#define FREF_CLK_FREQ_MASK      0x7
+#define FREF_CLK_TYPE_MASK      BIT_3
+#define FREF_CLK_POLARITY_MASK  BIT_4
+
+#define FREF_CLK_TYPE_BITS      0xfffffe7f
+#define CLK_REQ_PRCM            0x100
+
+#define FREF_CLK_POLARITY_BITS  0xfffff8ff
+#define CLK_REQ_OUTN_SEL        0x700
+
+/* time to wait till we check if fw is running */
+#define STALL_TIMEOUT   10
+#define FIN_LOOP 10
+
+/************************************************************************
+ * Macros
+ ************************************************************************/
+
+#define SET_DEF_NVS(aNVS)     aNVS[0]=0x01; aNVS[1]=0x6d; aNVS[2]=0x54; aNVS[3]=0x56; aNVS[4]=0x34; \
+                              aNVS[5]=0x12; aNVS[6]=0x28; aNVS[7]=0x01; aNVS[8]=0x71; aNVS[9]=0x54; \
+                              aNVS[10]=0x00; aNVS[11]=0x08; aNVS[12]=0x00; aNVS[13]=0x00; aNVS[14]=0x00; \
+                              aNVS[15]=0x00; aNVS[16]=0x00; aNVS[17]=0x00; aNVS[18]=0x00; aNVS[19]=0x00; \
+                              aNVS[20]=0x00; aNVS[21]=0x00; aNVS[22]=0x00; aNVS[23]=0x00; aNVS[24]=eNVS_NON_FILE;\
+							  aNVS[25]=0x00; aNVS[26]=0x00; aNVS[27]=0x00;
+
+
+#define SET_PARTITION(pPartition,uAddr1,uMemSize1,uAddr2,uMemSize2,uAddr3,uMemSize3,uAddr4) \
+                    ((TPartition*)pPartition)[0].uMemAdrr = uAddr1; \
+                    ((TPartition*)pPartition)[0].uMemSize = uMemSize1; \
+                    ((TPartition*)pPartition)[1].uMemAdrr = uAddr2; \
+                    ((TPartition*)pPartition)[1].uMemSize = uMemSize2; \
+                    ((TPartition*)pPartition)[2].uMemAdrr = uAddr3; \
+                    ((TPartition*)pPartition)[2].uMemSize = uMemSize3; \
+                    ((TPartition*)pPartition)[3].uMemAdrr = uAddr4; 
+
+#define HW_INIT_PTXN_SET(pHwInit, pTxn)  pTxn = (TTxnStruct*)&(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].tTxnStruct);
+
+#define BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, uAddr, uVal, uSize, direction, fCB, hCB)     \
+                              HW_INIT_PTXN_SET(pHwInit, pTxn) \
+                              TXN_PARAM_SET_DIRECTION(pTxn, direction); \
+                              *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData)) = (TI_UINT32)uVal; \
+                              BUILD_TTxnStruct(pTxn, uAddr, pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData, uSize, fCB, hCB)
+
+#define BUILD_HW_INIT_FW_STATIC_TXN(pHwInit, pTxn, uAddr, fCB, hCB)     \
+                              HW_INIT_PTXN_SET(pHwInit, pTxn) \
+                              TXN_PARAM_SET_DIRECTION(pTxn, TXN_DIRECTION_READ); \
+                              BUILD_TTxnStruct(pTxn, uAddr, pHwInit->tFwStaticTxn.pFwStaticInfo, sizeof(FwStaticData_t), fCB, hCB)
+
+#define BUILD_HW_INIT_FW_DL_TXN(pHwInit, pTxn, uAddr, uVal, uSize, direction, fCB, hCB)     \
+                              HW_INIT_PTXN_SET(pHwInit, pTxn) \
+                              TXN_PARAM_SET_DIRECTION(pTxn, direction); \
+                              BUILD_TTxnStruct(pTxn, uAddr, uVal, uSize, fCB, hCB)
+
+
+#define SET_DRP_PARTITION(pPartition)\
+                        SET_PARTITION(pPartition, PARTITION_DRPW_MEM_ADDR, PARTITION_DRPW_MEM_SIZE, PARTITION_DRPW_REG_ADDR, PARTITION_DRPW_REG_SIZE, 0, 0, 0)
+
+#define SET_FW_LOAD_PARTITION(pPartition,uFwAddress)\
+                            SET_PARTITION(pPartition,uFwAddress,PARTITION_DOWN_MEM_SIZE, PARTITION_DOWN_REG_ADDR, PARTITION_DOWN_REG_SIZE,0,0,0)
+
+#define SET_WORK_PARTITION(pPartition)\
+                        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)
+
+/* Handle return status inside a state machine */
+#define EXCEPT(phwinit,status)                                   \
+    switch (status) {                                           \
+        case TI_OK:                                             \
+        case TXN_STATUS_OK:                                     \
+        case TXN_STATUS_COMPLETE:                               \
+             break;                                             \
+        case TXN_STATUS_PENDING:                                \
+             return TXN_STATUS_PENDING;                         \
+        default:                                                \
+             phwinit->DownloadStatus = TXN_STATUS_ERROR;        \
+             TWD_FinalizeOnFailure (phwinit->hTWD);             \
+             return TXN_STATUS_ERROR;                           \
+    }
+
+
+/* Handle return status inside an init sequence state machine  */
+#define EXCEPT_I(phwinit,status)                                \
+    switch (status) {                                           \
+        case TI_OK:                                             \
+        case TXN_STATUS_COMPLETE:                               \
+             break;                                             \
+        case TXN_STATUS_PENDING:                                \
+             phwinit->uInitSeqStatus = status;                  \
+             return TXN_STATUS_PENDING;                         \
+        default:                                                \
+             TWD_FinalizeOnFailure (phwinit->hTWD);             \
+             return TXN_STATUS_ERROR;                           \
+    }
+
+
+/* Handle return status inside a load image state machine */
+#define EXCEPT_L(phwinit,status)                                \
+    switch (status) {                                           \
+        case TXN_STATUS_OK:                                     \
+        case TXN_STATUS_COMPLETE:                               \
+             break;                                             \
+        case TXN_STATUS_PENDING:                                \
+             phwinit->DownloadStatus = status;                  \
+             return TXN_STATUS_PENDING;                         \
+        default:                                                \
+             phwinit->DownloadStatus = status;                  \
+             TWD_FinalizeOnFailure (phwinit->hTWD);             \
+             return TXN_STATUS_ERROR;                           \
+    }
+
+
+/************************************************************************
+ * Types
+ ************************************************************************/
+
+enum
+{
+    REF_FREQ_19_2                   = 0,
+    REF_FREQ_26_0                   = 1,
+    REF_FREQ_38_4                   = 2,
+    REF_FREQ_40_0                   = 3,
+    REF_FREQ_33_6                   = 4,
+    REF_FREQ_NUM                    = 5
+};
+
+enum
+{
+    LUT_PARAM_INTEGER_DIVIDER       = 0,
+    LUT_PARAM_FRACTIONAL_DIVIDER    = 1,
+    LUT_PARAM_ATTN_BB               = 2,
+    LUT_PARAM_ALPHA_BB              = 3,
+    LUT_PARAM_STOP_TIME_BB          = 4,
+    LUT_PARAM_BB_PLL_LOOP_FILTER    = 5,
+    LUT_PARAM_NUM                   = 6
+};
+
+typedef struct 
+{
+    TTxnStruct              tTxnStruct;
+    TI_UINT8                *pData; 
+
+} THwInitTxn;
+
+typedef struct 
+{
+    TTxnStruct              tTxnStruct;
+    TI_UINT8                *pFwStaticInfo; 
+
+} TFwStaticTxn;
+
+
+/* The HW Init module object */
+typedef struct 
+{
+    /* Handles */
+    TI_HANDLE               hOs;
+    TI_HANDLE               hReport;
+    TI_HANDLE               hTWD;
+    TI_HANDLE               hBusTxn;
+    TI_HANDLE               hTwIf;
+
+    TI_HANDLE 		    hFileInfo;	/* holds parameters of FW Image Portion - for DW Download */
+    TEndOfHwInitCb          fInitHwCb;
+
+    /* Firmware image ptr */
+    TI_UINT8               *pFwBuf;       
+    /* Firmware image length */
+    TI_UINT32               uFwLength;
+    TI_UINT32               uFwAddress;
+    TI_UINT32               bFwBufLast;  
+    TI_UINT32               uFwLastAddr;  
+    /* EEPROM image ptr */
+    TI_UINT8               *pEEPROMBuf;   
+    /* EEPROM image length */
+    TI_UINT32               uEEPROMLen;   
+
+    TI_UINT8               *pEEPROMCurPtr;
+    TI_UINT32               uEEPROMCurLen;
+    TBootAttr               tBootAttr;
+    TI_HANDLE               hHwCtrl;
+    ETxnStatus              DownloadStatus;
+    /* Upper module callback for the init stage */
+    fnotify_t               fCb;          
+    /* Upper module handle for the init stage */
+    TI_HANDLE               hCb;          
+    /* Init stage */
+    TI_UINT32               uInitStage;   
+    /* Reset statge */ 
+    TI_UINT32               uResetStage;  
+    /* EEPROM burst stage */
+    TI_UINT32               uEEPROMStage; 
+    /* Init state machine temporary data */
+    TI_UINT32               uInitData;    
+    /* ELP command image */
+    TI_UINT32               uElpCmd;      
+    /* Chip ID */
+    TI_UINT32               uChipId;      
+    /* Boot state machine temporary data */
+    TI_UINT32               uBootData;    
+    TI_UINT32               uSelfClearTime;
+    TI_UINT8                uEEPROMBurstLen;
+    TI_UINT8                uEEPROMBurstLoop;
+    TI_UINT32               uEEPROMRegAddr;
+    TI_STATUS               uEEPROMStatus;
+    TI_UINT32               uNVSStartAddr;
+    TI_UINT32               uNVSNumChar;
+    TI_UINT32               uNVSNumByte;
+    TI_STATUS               uNVSStatus;
+    TI_UINT32               uScrPad6;
+    TI_UINT32               uRefFreq; 
+    TI_UINT32               uInitSeqStage;
+    TI_STATUS               uInitSeqStatus;
+    TI_UINT32               uLoadStage;
+    TI_UINT32               uBlockReadNum;
+    TI_UINT32               uBlockWriteNum;
+    TI_UINT32               uPartitionLimit;
+    TI_UINT32               uFinStage;
+    TI_UINT32               uFinData;
+    TI_UINT32               uFinLoop; 
+    TI_UINT32               uRegStage;
+    TI_UINT32               uRegLoop;
+    TI_UINT32               uRegSeqStage;
+    TI_UINT32               uRegData;  
+    #ifndef _VLCT_   
+        TI_HANDLE               hStallTimer;
+    #endif
+
+    /* Top register Read/Write SM temporary data*/
+    TI_UINT32               uTopRegAddr;
+    TI_UINT32               uTopRegValue;
+    TI_UINT32               uTopRegMask;
+    TI_UINT32               uTopRegUpdateValue;
+    TI_UINT32               uTopStage;
+    TI_STATUS               uTopStatus;
+
+    TI_UINT8                *puFwTmpBuf;
+
+    TFinalizeCb             fFinalizeDownload;
+    TI_HANDLE               hFinalizeDownload;
+    /* Size of the Fw image, retrieved from the image itself */         
+    TI_UINT32               uFwDataLen; 
+    TI_UINT8                aDefaultNVS[DEF_NVS_SIZE];
+    TI_UINT8                uTxnIndex;
+    THwInitTxn              aHwInitTxn[MAX_HW_INIT_CONSECUTIVE_TXN];
+    TFwStaticTxn            tFwStaticTxn;
+
+    TI_UINT32               uSavedDataForWspiHdr;  /* For saving the 4 bytes before the NVS data for WSPI case 
+                                                        where they are overrun by the WSPI BusDrv */
+    TPartition              aPartition[NUM_OF_PARTITION];
+} THwInit;
+
+
+/************************************************************************
+ * Local Functions Prototypes
+ ************************************************************************/
+static void      hwInit_SetPartition                (THwInit   *pHwInit, 
+                                                     TPartition *pPartition);
+static TI_STATUS hwInit_BootSm                      (TI_HANDLE hHwInit);
+static TI_STATUS hwInit_ResetSm                     (TI_HANDLE hHwInit);
+static TI_STATUS hwInit_EepromlessStartBurstSm      (TI_HANDLE hHwInit);                                                   
+static TI_STATUS hwInit_LoadFwImageSm               (TI_HANDLE hHwInit);
+static TI_STATUS hwInit_FinalizeDownloadSm          (TI_HANDLE hHwInit);                                             
+static TI_STATUS hwInit_TopRegisterRead(TI_HANDLE hHwInit);
+static TI_STATUS hwInit_InitTopRegisterRead(TI_HANDLE hHwInit, TI_UINT32 uAddress);
+static TI_STATUS hwInit_TopRegisterWrite(TI_HANDLE hHwInit);
+static TI_STATUS hwInit_InitTopRegisterWrite(TI_HANDLE hHwInit, TI_UINT32 uAddress, TI_UINT32 uValue);
+#ifndef _VLCT_  
+    static void      hwInit_StallTimerCb                (TI_HANDLE hHwInit);
+#endif
+
+
+/*******************************************************************************
+*                       PUBLIC  FUNCTIONS  IMPLEMENTATION                      *
+********************************************************************************/
+
+
+/*************************************************************************
+*                        hwInit_Create                                   *
+**************************************************************************
+* DESCRIPTION:  This function initializes the HwInit module.
+*
+* INPUT:        hOs - handle to Os Abstraction Layer
+*               
+* RETURN:       Handle to the allocated HwInit module
+*************************************************************************/
+TI_HANDLE hwInit_Create (TI_HANDLE hOs)
+{
+    THwInit *pHwInit;
+    int i;
+
+    /* Allocate HwInit module */
+    pHwInit = os_memoryAlloc (hOs, sizeof(THwInit),MemoryNormal);
+
+    if (pHwInit == NULL)
+    {
+        WLAN_OS_REPORT(("Error allocating the HwInit Module\n"));
+        return NULL;
+    }
+
+    /* Reset HwInit module */
+    os_memoryZero (hOs, pHwInit, sizeof(THwInit));
+
+    /* Allocate Register buffer */
+    for (i = 0; i < MAX_HW_INIT_CONSECUTIVE_TXN; i++) 
+    {
+        pHwInit->aHwInitTxn[i].pData = os_memoryAlloc (hOs, sizeof(TI_UINT32) + WSPI_PAD_LEN_READ,MemoryDMA);
+        if (pHwInit->aHwInitTxn[i].pData == NULL) 
+        {
+            return NULL;
+        }
+        os_memoryZero (hOs, pHwInit->aHwInitTxn[i].pData, sizeof(TI_UINT32) + WSPI_PAD_LEN_READ);
+        pHwInit->aHwInitTxn[i].pData += WSPI_PAD_LEN_READ;
+    }
+    
+    pHwInit->tFwStaticTxn.pFwStaticInfo = os_memoryAlloc (hOs, sizeof (FwStaticData_t) + WSPI_PAD_LEN_READ,MemoryDMA);
+    if (pHwInit->tFwStaticTxn.pFwStaticInfo == NULL) 
+    {
+        return NULL;
+    }
+    os_memoryZero (hOs, pHwInit->tFwStaticTxn.pFwStaticInfo, sizeof (FwStaticData_t) + WSPI_PAD_LEN_READ);
+    pHwInit->tFwStaticTxn.pFwStaticInfo += WSPI_PAD_LEN_READ;
+
+
+
+    pHwInit->puFwTmpBuf = os_memoryAlloc (hOs, WSPI_PAD_LEN_READ + MAX_SDIO_BLOCK,MemoryDMA);
+    if (pHwInit->puFwTmpBuf == NULL) 
+    {
+     return NULL;
+    }
+    os_memoryZero (hOs, pHwInit->puFwTmpBuf, WSPI_PAD_LEN_READ + MAX_SDIO_BLOCK);
+    pHwInit->puFwTmpBuf += WSPI_PAD_LEN_READ;
+
+    pHwInit->hOs = hOs;
+
+    return (TI_HANDLE)pHwInit;
+}
+
+
+/***************************************************************************
+*                           hwInit_Destroy                                 *
+****************************************************************************
+* DESCRIPTION:  This function unload the HwInit module. 
+*
+* INPUTS:       hHwInit - the object
+*
+* OUTPUT:
+*
+* RETURNS:      TI_OK - Unload succesfull
+*               TI_NOK - Unload unsuccesfull
+***************************************************************************/
+TI_STATUS hwInit_Destroy (TI_HANDLE hHwInit)
+{
+    THwInit *pHwInit = (THwInit *)hHwInit;
+    int i;
+
+    for (i = 0; i < MAX_HW_INIT_CONSECUTIVE_TXN; i++) 
+    {
+        if (pHwInit->aHwInitTxn[i].pData) 
+        {
+            os_memoryFree (pHwInit->hOs, pHwInit->aHwInitTxn[i].pData - WSPI_PAD_LEN_READ, sizeof(TI_UINT32) + WSPI_PAD_LEN_READ);
+        }
+    }
+
+    if (pHwInit->puFwTmpBuf) 
+     {
+
+         os_memoryFree (pHwInit->hOs, pHwInit->puFwTmpBuf - WSPI_PAD_LEN_READ, WSPI_PAD_LEN_READ + MAX_SDIO_BLOCK);
+     }
+
+    if (pHwInit->pEEPROMBuf) 
+     {
+         os_memoryFree (pHwInit->hOs, pHwInit->pEEPROMBuf, pHwInit->uEEPROMLen);
+     }
+
+    if (pHwInit->tFwStaticTxn.pFwStaticInfo)
+    {
+        os_memoryFree (pHwInit->hOs, pHwInit->tFwStaticTxn.pFwStaticInfo - WSPI_PAD_LEN_READ, sizeof (FwStaticData_t) + WSPI_PAD_LEN_READ);
+    }
+
+    #ifndef _VLCT_   
+        if (pHwInit->hStallTimer)
+        {
+            os_timerDestroy(pHwInit->hOs, pHwInit->hStallTimer);
+        }        
+    #endif
+
+    /* Free HwInit Module */
+    os_memoryFree (pHwInit->hOs, pHwInit, sizeof(THwInit));
+
+    return TI_OK;
+}
+
+
+/***************************************************************************
+*                           hwInit_Init                                    *
+****************************************************************************
+* DESCRIPTION:  This function configures the hwInit module
+*
+* RETURNS:      TI_OK - Configuration successful
+*               TI_NOK - Configuration unsuccessful
+***************************************************************************/
+TI_STATUS hwInit_Init (TI_HANDLE      hHwInit,
+                         TI_HANDLE      hReport,
+                         TI_HANDLE      hTWD,
+                         TI_HANDLE 	hFinalizeDownload, 
+			 TFinalizeCb    fFinalizeDownload, 
+                         TEndOfHwInitCb fInitHwCb)
+{
+    THwInit   *pHwInit = (THwInit *)hHwInit;
+    TTxnStruct* pTxn;
+
+    /* Configure modules handles */
+    pHwInit->hReport    = hReport;
+    pHwInit->hTWD       = hTWD;
+    pHwInit->hTwIf      = ((TTwd *)hTWD)->hTwIf;
+    pHwInit->hOs        = ((TTwd *)hTWD)->hOs;
+    pHwInit->fInitHwCb  = fInitHwCb;
+    pHwInit->fFinalizeDownload 	= fFinalizeDownload;
+    pHwInit->hFinalizeDownload 	= hFinalizeDownload;
+
+    SET_DEF_NVS(pHwInit->aDefaultNVS)
+
+    for (pHwInit->uTxnIndex=0;pHwInit->uTxnIndex<MAX_HW_INIT_CONSECUTIVE_TXN;pHwInit->uTxnIndex++)
+    {
+        HW_INIT_PTXN_SET(pHwInit, pTxn)
+        /* Setting write as default transaction */
+        TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
+    }
+
+    #ifndef _VLCT_   
+        pHwInit->hStallTimer = os_timerCreate (pHwInit->hOs, hwInit_StallTimerCb, hHwInit);
+        if (pHwInit->hStallTimer == NULL) 
+        {
+            return TI_NOK;
+        }
+    #endif
+
+    TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT, ".....HwInit configured successfully\n");
+    
+    return TI_OK;
+}
+
+
+TI_STATUS hwInit_SetNvsImage (TI_HANDLE hHwInit, TI_UINT8 *pbuf, TI_UINT32 length)
+{
+    THwInit   *pHwInit = (THwInit *)hHwInit;
+
+    if (length == 0) {
+        TRACE0 (pHwInit->hReport, REPORT_SEVERITY_WARNING,"NVS File Length iz zero");
+        pHwInit->pEEPROMBuf = NULL;
+        return TI_OK;
+    }
+    /* We need to guarantee that the NVS buffer will be DMA'ble (physically continous) */
+    pHwInit->pEEPROMBuf = os_memoryAlloc (pHwInit->hOs, length, MemoryDMA);
+
+    if (pHwInit->pEEPROMBuf == NULL) 
+    {
+        return TI_NOK;
+    }
+
+    os_memoryCopy(pHwInit->hOs, pHwInit->pEEPROMBuf, pbuf, length);
+
+    pHwInit->uEEPROMLen = length; 
+
+    return TI_OK;
+}
+
+
+TI_STATUS hwInit_SetFwImage (TI_HANDLE hHwInit, TFileInfo *pFileInfo)
+{
+    THwInit   *pHwInit = (THwInit *)hHwInit;
+
+    if ((hHwInit == NULL) || (pFileInfo == NULL))
+    {
+	return TI_NOK;
+    }
+
+    pHwInit->pFwBuf 	= pFileInfo->pBuffer;
+    pHwInit->uFwLength  = pFileInfo->uLength;
+    pHwInit->uFwAddress = pFileInfo->uAddress;
+    pHwInit->bFwBufLast = pFileInfo->bLast;
+
+    return TI_OK;
+}
+
+
+/** 
+ * \fn     hwInit_SetPartition
+ * \brief  Set HW addresses partition
+ * 
+ * Set the HW address ranges for download or working memory and registers access.
+ * Generate and configure the bus access address mapping table.
+ * The partition is split between register (fixed partition of 24KB size, exists in all modes), 
+ *     and memory (dynamically changed during init and gets constant value in run-time, 104KB size).
+ * The TwIf configures the memory mapping table on the device by issuing write transaction to 
+ *     table address (note that the TxnQ and bus driver see this as a regular transaction). 
+ * 
+ * \note In future versions, a specific bus may not support partitioning (as in wUART), 
+ *       In this case the HwInit module shall not call this function (will learn the bus 
+ *       configuration from the INI file).
+ *
+ * \param  pHwInit   - The module's object
+ * \param  uMemAddr  - The memory partition base address
+ * \param  uMemSize  - The memory partition size
+ * \param  uRegAddr  - The registers partition base address
+ * \param  uRegSize  - The register partition size
+ * \return void
+ * \sa     
+ */ 
+static void hwInit_SetPartition (THwInit   *pHwInit, 
+                                 TPartition *pPartition)
+{
+    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 );
+
+    /* Prepare partition Txn data and send to HW */
+    twIf_SetPartition (pHwInit->hTwIf,pPartition);
+}
+
+
+/****************************************************************************
+ *                      hwInit_Boot()
+ ****************************************************************************
+ * DESCRIPTION: Start HW init sequence which writes and reads some HW registers
+ *                  that are needed prior to FW download.
+ * 
+ * INPUTS:  None    
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: TI_OK or TI_NOK
+ ****************************************************************************/
+TI_STATUS hwInit_Boot (TI_HANDLE hHwInit)
+{ 
+    THwInit      *pHwInit = (THwInit *)hHwInit;
+    TTwd         *pTWD = (TTwd *)pHwInit->hTWD;
+    TWlanParams  *pWlanParams = &DB_WLAN(pTWD->hCmdBld);
+    TBootAttr     tBootAttr;
+
+    tBootAttr.MacClock = pWlanParams->MacClock;
+    tBootAttr.ArmClock = pWlanParams->ArmClock;
+
+    /*
+     * Initialize the status of download to  pending 
+     * It will be set to TXN_STATUS_COMPLETE at the FinalizeDownload function 
+     */
+    pHwInit->DownloadStatus = TXN_STATUS_PENDING;
+
+    /* Call the boot sequence state machine */
+    pHwInit->uInitStage = 0;
+
+    os_memoryCopy (pHwInit->hOs, &pHwInit->tBootAttr, &tBootAttr, sizeof(TBootAttr));
+
+    hwInit_BootSm (hHwInit);
+
+    /*
+     * If it returns the status of the StartInstance only then we can here query for the download status 
+     * and then return the status up to the TNETW_Driver.
+     * This return value will go back up to the TNETW Driver layer so that the init from OS will know
+     * if to wait for the InitComplte or not in case of TXN_STATUS_ERROR.
+     * This value will always be pending since the SPI is ASYNC 
+     * and in SDIOa timer is set so it will be ASync also in anyway.
+     */
+    return pHwInit->DownloadStatus;
+}
+
+
+ /****************************************************************************
+ * DESCRIPTION: Firmware boot state machine
+ * 
+ * INPUTS:  
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: TI_OK 
+ ****************************************************************************/
+static TI_STATUS hwInit_BootSm (TI_HANDLE hHwInit)
+{
+    THwInit    *pHwInit = (THwInit *)hHwInit;
+    TI_STATUS   status = 0;
+    TTxnStruct  *pTxn;
+    TI_UINT32   uData;
+    TTwd        *pTWD        = (TTwd *) pHwInit->hTWD;
+    IniFileGeneralParam  *pGenParams = &DB_GEN(pTWD->hCmdBld);
+    TI_UINT32   clkVal = 0x3;
+
+    switch (pHwInit->uInitStage)
+    {
+    case 0:
+        pHwInit->uInitStage++;
+        pHwInit->uTxnIndex = 0;
+        SET_WORK_PARTITION(pHwInit->aPartition)
+
+        /* Set the bus addresses partition to its "running" mode */
+        hwInit_SetPartition (pHwInit,pHwInit->aPartition);
+
+#ifdef _VLCT_
+         /* Set FW to test mode */    
+         BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, SCR_PAD8, 0xBABABABE, 
+                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+         twIf_Transact(pHwInit->hTwIf, pTxn);
+         pHwInit->uTxnIndex++;
+#endif
+
+        if (( 0 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)) || (2 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK))
+             || (4 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)))
+        {/* ref clk: 19.2/38.4/38.4-XTAL */
+            clkVal = 0x3;
+        }
+        if ((1 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)) || (3 == (pGenParams->RefClk & FREF_CLK_FREQ_MASK)))
+        {/* ref clk: 26/52 */
+            clkVal = 0x5;
+        }
+
+        WLAN_OS_REPORT(("CHIP VERSION... set 1273 chip top registers\n"));
+
+        /* set the reference clock freq' to be used (pll_selinpfref field) */        
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, PLL_PARAMETERS, clkVal,
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+        twIf_Transact(pHwInit->hTwIf, pTxn);
+
+        pHwInit->uTxnIndex++;
+
+        /* read the PAUSE value to highest threshold */        
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, PLL_PARAMETERS, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_BootSm, hHwInit)
+        status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+        EXCEPT (pHwInit, status)
+
+    case 1:
+        pHwInit->uInitStage ++;
+        /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
+        uData = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+        if (uData == 0xFFFFFFFF)                     
+        {            
+            TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "hwInit_BootSm: Failed to read PLL parameters\n");
+            pHwInit->DownloadStatus = TXN_STATUS_ERROR;
+            TWD_FinalizeOnFailure (pHwInit->hTWD);
+            return TXN_STATUS_ERROR;
+        }
+        else
+        {
+            uData &= ~(0x3ff);
+        }
+
+        /* Now we can zero the index */
+        pHwInit->uTxnIndex = 0;
+
+        /* set the the PAUSE value to highest threshold */        
+        uData |= WU_COUNTER_PAUSE_VAL;
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, WU_COUNTER_PAUSE, uData, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+        twIf_Transact(pHwInit->hTwIf, pTxn);
+
+        pHwInit->uTxnIndex++;
+
+        /* Continue the ELP wake up sequence */
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, WELP_ARM_COMMAND, WELP_ARM_COMMAND_VAL, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+        twIf_Transact(pHwInit->hTwIf, pTxn);
+
+        /* Wait 500uS */
+        os_StalluSec (pHwInit->hOs, 500);
+
+        SET_DRP_PARTITION(pHwInit->aPartition)
+        /* Set the bus addresses partition to DRPw registers region */
+        hwInit_SetPartition (pHwInit,pHwInit->aPartition);
+
+        pHwInit->uTxnIndex++;
+
+        /* Read-modify-write DRPW_SCRATCH_START register (see next state) to be used by DRPw FW. 
+           The RTRIM value will be added  by the FW before taking DRPw out of reset */
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, DRPW_SCRATCH_START, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
+        status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+        EXCEPT (pHwInit, status)
+
+    case 2:
+        pHwInit->uInitStage ++;
+
+        /* multiply fref value by 2, so that {0,1,2,3} values will become {0,2,4,6} */
+        /* Then, move it 4 places to the right, to alter Fref relevant bits in register 0x2c */
+        clkVal = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+        pHwInit->uTxnIndex = 0; /* Reset index only after getting the last read value! */
+        clkVal |= (pGenParams->RefClk << 1) << 4;
+        
+        /* Disable LPD mode */
+        clkVal &= 0xf9ffffff;
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, DRPW_SCRATCH_START, clkVal, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+        twIf_Transact(pHwInit->hTwIf, pTxn);
+
+        pHwInit->uTxnIndex++;
+
+        SET_WORK_PARTITION(pHwInit->aPartition)
+        /* Set the bus addresses partition back to its "running" mode */
+        hwInit_SetPartition (pHwInit,pHwInit->aPartition);
+
+        /* 
+         * end of CHIP init seq.
+         */
+
+        /* Disable interrupts */
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_MASK, ACX_INTR_ALL, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+        twIf_Transact(pHwInit->hTwIf, pTxn);
+
+        pHwInit->uTxnIndex++;
+
+        /* Read the CHIP ID to get an indication that the bus is TI_OK */
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, CHIP_ID, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
+        status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+        EXCEPT (pHwInit, status)
+        
+    case 3:
+        pHwInit->uInitStage ++;
+         
+        /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
+         pHwInit->uChipId = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+
+        /* This is only sanity check that the HW exists, we can continue and fail on FwLoad */
+		if (pHwInit->uChipId == CHIP_ID_1273_PG10)
+        {
+            WLAN_OS_REPORT(("Working on a 1273 PG 1.0 board.\n"));
+        }
+		else if (pHwInit->uChipId == CHIP_ID_1273_PG20)
+        {
+            WLAN_OS_REPORT(("Working on a 1273 PG 2.0 board.\n"));
+        }
+        else 
+        {
+            WLAN_OS_REPORT (("Error!! Found unknown Chip Id = 0x%x\n", pHwInit->uChipId));
+
+            /*
+             * NOTE: no exception because of forward compatibility
+             */
+        }
+    
+        /*
+         * Soft reset 
+         */
+        pHwInit->uResetStage = 0;
+        pHwInit->uSelfClearTime = 0;
+        pHwInit->uBootData = 0;
+        status = hwInit_ResetSm (pHwInit);    
+
+        EXCEPT (pHwInit, status)
+    
+    case 4:
+        pHwInit->uInitStage ++;
+
+        TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "TNET SOFT-RESET\n");
+
+        WLAN_OS_REPORT(("Starting to process NVS...\n"));
+
+        /*
+         * Start EEPROM/NVS burst
+         */
+
+        if (pHwInit->pEEPROMBuf) 
+        {
+            /* NVS file exists (EEPROM-less support) */
+            pHwInit->uEEPROMCurLen = pHwInit->uEEPROMLen;
+
+            TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "EEPROM Image addr=0x%x, EEPROM Len=0x0x%x\n", pHwInit->pEEPROMBuf, pHwInit->uEEPROMLen);
+            WLAN_OS_REPORT (("NVS found, EEPROM Image addr=0x%x, EEPROM Len=0x0x%x\n", 
+                              pHwInit->pEEPROMBuf, pHwInit->uEEPROMLen));
+        }
+        else
+        {
+            WLAN_OS_REPORT (("No Nvs, Setting default MAC address\n"));
+            pHwInit->uEEPROMCurLen = DEF_NVS_SIZE;
+            pHwInit->pEEPROMBuf = (TI_UINT8*)(&pHwInit->aDefaultNVS[0]);
+            WLAN_OS_REPORT (("pHwInit->uEEPROMCurLen: %x\n", pHwInit->uEEPROMCurLen));
+            WLAN_OS_REPORT (("ERROR: If you are not calibating the device, you will soon get errors !!!\n"));
+
+        }
+
+        pHwInit->pEEPROMCurPtr = pHwInit->pEEPROMBuf;
+        pHwInit->uEEPROMStage = 0;
+        status = hwInit_EepromlessStartBurstSm (hHwInit);
+
+        EXCEPT (pHwInit, status)
+        
+    case 5: 
+        pHwInit->uInitStage ++;
+        pHwInit->uTxnIndex = 0;
+
+        if (pHwInit->pEEPROMBuf) 
+        {
+            /* Signal FW that we are eeprom less */
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_EEPROMLESS_IND_REG, ACX_EEPROMLESS_IND_REG, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+            twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "DRIVER NVS BURST-READ\n");
+        }
+        else
+        {
+	    /* 1273 - EEPROM is not support by FPGA yet */ 
+            /*
+             * Start ACX EEPROM
+             */     
+            /*pHwInit->uRegister = START_EEPROM_MGR;
+            TXN_PARAM_SET(pTxn, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
+            BUILD_TTxnStruct(pTxn, ACX_REG_EE_START, &pHwInit->uRegister, REGISTER_SIZE, 0, NULL, NULL)
+            twIf_Transact(pHwInit->hTwIf, pTxn);*/
+
+            /*
+             * The stall is needed so the EEPROM NVS burst read will complete
+             */     
+            os_StalluSec (pHwInit->hOs, 40000);
+
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_EEPROMLESS_IND_REG, USE_EEPROM, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+            twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "STARTING EEPROM NVS BURST-READ\n");
+        }
+
+        pHwInit->uTxnIndex++;
+
+        /* Read Chip ID */
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn,  CHIP_ID, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
+        status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+        EXCEPT (pHwInit, status)
+
+    case 6:
+        pHwInit->uInitStage ++;
+        /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
+        pHwInit->uBootData = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+        /* Now we can zero the index */
+        pHwInit->uTxnIndex = 0;
+
+        WLAN_OS_REPORT(("Chip ID is 0x%X.\n", pHwInit->uBootData));
+		
+        /* Read Scr2 to verify that the HW is ready */
+        BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, SCR_PAD2, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ,(TTxnDoneCb)hwInit_BootSm, hHwInit)
+        status = twIf_Transact(pHwInit->hTwIf, pTxn);
+        EXCEPT (pHwInit, status)
+
+    case 7:
+        pHwInit->uInitStage ++;        
+
+        /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
+        pHwInit->uBootData = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+
+        if (pHwInit->uBootData == 0xffffffff)
+        {
+            TRACE0(pHwInit->hReport, REPORT_SEVERITY_FATAL_ERROR , "Error in SCR_PAD2 register\n");
+            EXCEPT (pHwInit, TXN_STATUS_ERROR)
+        }
+
+        /* Call the restart sequence */
+        pHwInit->uInitSeqStage = 0;
+        pHwInit->uInitSeqStatus = TXN_STATUS_COMPLETE;
+
+        EXCEPT (pHwInit, status)
+
+
+    case 8:
+        pHwInit->uInitStage++;
+        
+        if ((pGenParams->RefClk & FREF_CLK_TYPE_MASK) != 0x0)
+        {            
+            status = hwInit_InitTopRegisterRead(hHwInit, 0x448);            
+            EXCEPT (pHwInit, status)
+        }
+
+    case 9:
+        pHwInit->uInitStage++;
+
+        if ((pGenParams->RefClk & FREF_CLK_TYPE_MASK) != 0x0)
+        {            
+            pHwInit->uTopRegValue &= FREF_CLK_TYPE_BITS;
+            pHwInit->uTopRegValue |= CLK_REQ_PRCM;
+         
+            status =  hwInit_InitTopRegisterWrite( hHwInit, 0x448, pHwInit->uTopRegValue);
+            EXCEPT (pHwInit, status)
+        }
+
+    case 10:
+        pHwInit->uInitStage++; 
+
+        if ((pGenParams->RefClk & FREF_CLK_POLARITY_MASK) == 0x0)
+        {            
+            status = hwInit_InitTopRegisterRead(hHwInit, 0xCB2);            
+            EXCEPT (pHwInit, status)
+        }
+
+    case 11:
+        pHwInit->uInitStage++;        
+        if ((pGenParams->RefClk & FREF_CLK_POLARITY_MASK) == 0x0)
+        {            
+            pHwInit->uTopRegValue &= FREF_CLK_POLARITY_BITS;
+            pHwInit->uTopRegValue |= CLK_REQ_OUTN_SEL;            
+
+            status =  hwInit_InitTopRegisterWrite( hHwInit, 0xCB2, pHwInit->uTopRegValue);
+            EXCEPT (pHwInit, status)
+        }
+
+    case 12:
+        pHwInit->uInitStage = 0;
+        
+        /* Set the Download Status to COMPLETE */
+        pHwInit->DownloadStatus = TXN_STATUS_COMPLETE;
+
+        /* Call upper layer callback */
+        if (pHwInit->fInitHwCb)
+        {
+            (*pHwInit->fInitHwCb) (pHwInit->hTWD);
+        }
+
+        return TI_OK;
+    }
+
+    return TI_OK;
+}
+
+
+TI_STATUS hwInit_LoadFw (TI_HANDLE hHwInit)
+{
+    THwInit   *pHwInit = (THwInit *)hHwInit;
+    TI_STATUS  status;
+
+    /* check parameters */
+    if (hHwInit == NULL)
+    {
+        EXCEPT (pHwInit, TXN_STATUS_ERROR)
+    }
+
+    if (pHwInit->pFwBuf)
+    {
+        TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "CPU halt -> download code\n");
+
+        /* Load firmware image */ 
+        pHwInit->uLoadStage = 0;
+        status = hwInit_LoadFwImageSm (pHwInit);
+
+        switch (status)
+        {
+        case TI_OK:
+        case TXN_STATUS_OK:
+        case TXN_STATUS_COMPLETE:
+            WLAN_OS_REPORT (("Firmware successfully downloaded.\n"));
+            break;
+        case TXN_STATUS_PENDING:
+            WLAN_OS_REPORT (("Starting to download firmware...\n"));
+            break;
+        default:
+            TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Firmware download failed!\n");
+            break;
+        }
+
+        EXCEPT (pHwInit, status);
+    }   
+    else
+    {
+        TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Firmware not downloaded...\n");
+
+        EXCEPT (pHwInit, TXN_STATUS_ERROR)
+    }
+            
+    WLAN_OS_REPORT (("FW download OK...\n"));
+    return TI_OK;
+}                                                  
+    
+
+/****************************************************************************
+ *                      hwInit_FinalizeDownloadSm()
+ ****************************************************************************
+ * DESCRIPTION: Run the Hardware firmware
+ *              Wait for Init Complete
+ *              Configure the Bus Access with Addresses available on the scratch pad register 
+ *              Change the SDIO/SPI partitions to be able to see all the memory addresses
+ * 
+ * INPUTS:  None    
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: None
+ ****************************************************************************/
+static TI_STATUS hwInit_FinalizeDownloadSm (TI_HANDLE hHwInit)
+{
+    THwInit  *pHwInit = (THwInit *)hHwInit;
+    TTwd     *pTWD = (TTwd *)pHwInit->hTWD;
+    TI_STATUS status = TI_OK;
+    TI_UINT32   uIntVect;
+    TTxnStruct* pTxn;
+
+    while (TI_TRUE)
+    {
+        switch (pHwInit->uFinStage)
+        {
+        case 0:
+            pHwInit->uFinStage = 1;
+            pHwInit->uTxnIndex = 0;
+            /*
+             * Run the firmware (I) - Read current value from ECPU Control Reg.
+             */
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_ECPU_CONTROL, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
+            status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            EXCEPT (pHwInit, status)
+
+        case 1:
+            pHwInit->uFinStage ++;
+            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
+            pHwInit->uFinData = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+            /* Now we can zero the index */
+            pHwInit->uTxnIndex = 0;
+
+            /*
+             * Run the firmware (II) - Take HW out of reset (write ECPU_CONTROL_HALT to ECPU Control Reg.)
+             */
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_ECPU_CONTROL, (pHwInit->uFinData | ECPU_CONTROL_HALT), 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+            twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            WLAN_OS_REPORT (("Firmware running.\n"));
+
+            /* 
+             * CHIP ID Debug
+             */     
+
+            pHwInit->uTxnIndex++;                  
+
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, CHIP_ID, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
+            status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            EXCEPT (pHwInit, status)
+
+        case 2:
+            pHwInit->uFinStage ++;
+            pHwInit->uFinLoop = 0;
+
+            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
+            pHwInit->uFinData = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+                               
+            TRACE1(pHwInit->hReport, REPORT_SEVERITY_INIT , "CHIP ID IS %x\n", pHwInit->uFinData);
+
+            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Wait init complete\n");
+
+        case 3:
+            pHwInit->uTxnIndex = 0;
+
+            /* 
+             * Wait for init complete 
+             */
+            if (pHwInit->uFinLoop < FIN_LOOP)
+            {           
+                pHwInit->uFinStage = 4;
+
+                #ifdef _VLCT_
+                    os_StalluSec (pHwInit->hOs, 50);*/
+                #endif
+                
+                /* Read interrupt status register */
+                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_NO_CLEAR, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
+                status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+                EXCEPT (pHwInit, status)
+            }
+            else
+			{
+				pHwInit->uFinStage = 5;
+			}                
+            continue;
+
+        case 4:
+            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
+            pHwInit->uFinData = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+            /* Now we can zero the index */
+            pHwInit->uTxnIndex = 0;
+            
+            if (pHwInit->uFinData == 0xffffffff) /* error */
+            {
+                TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Error reading hardware complete init indication\n");
+
+                pHwInit->DownloadStatus = TXN_STATUS_ERROR;
+                EXCEPT (pHwInit, TXN_STATUS_ERROR)
+            }
+
+            if (IS_MASK_ON (pHwInit->uFinData, ACX_INTR_INIT_COMPLETE))
+            {
+                pHwInit->uFinStage = 5;
+
+                /* Interrupt ACK */
+                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_ACK, ACX_INTR_INIT_COMPLETE, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+                twIf_Transact(pHwInit->hTwIf, pTxn);
+
+                break;
+            }
+            else
+            {
+                pHwInit->uFinStage = 3;
+                pHwInit->uFinLoop ++;
+
+                #ifndef _VLCT_                
+                    os_timerStart (pHwInit->hOs, pHwInit->hStallTimer, STALL_TIMEOUT);
+                    return TI_PENDING;
+                #endif
+            }
+            #ifdef _VLCT_     
+                continue;
+            #endif
+
+        case 5:  
+            pHwInit->uFinStage++;
+
+            if (pHwInit->uFinLoop >= FIN_LOOP)
+            {
+                TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for the hardware to complete initialization\n");
+
+                pHwInit->DownloadStatus = TXN_STATUS_ERROR;
+                EXCEPT (pHwInit, TXN_STATUS_ERROR);
+            }
+        
+            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Firmware init complete...\n");
+
+            /* 
+             * There are valid addresses of the command and event mailbox 
+             * on the scratch pad registers 
+             */
+            /* Hardware config command mail box */
+            status = cmdMbox_ConfigHw (pTWD->hCmdMbox,
+                                       (fnotify_t)hwInit_FinalizeDownloadSm, 
+                                       hHwInit);
+            EXCEPT (pHwInit, status)
+            
+        case 6:  
+            pHwInit->uFinStage++;
+
+            /* Hardware config event mail box */
+            status = eventMbox_InitMboxAddr (pTWD->hEventMbox,
+                                         (fnotify_t)hwInit_FinalizeDownloadSm, 
+                                         hHwInit);
+            EXCEPT (pHwInit, status);
+            
+        case 7: 
+            pHwInit->uFinStage++;
+            pHwInit->uTxnIndex = 0;
+
+            SET_WORK_PARTITION(pHwInit->aPartition)
+            /* Set the bus addresses partition to its "running" mode */
+            hwInit_SetPartition (pHwInit,pHwInit->aPartition);
+
+            /* 
+             * In case of full asynchronous mode the firmware event must be ready 
+             * to receive event from the command mailbox
+             */
+
+            uIntVect = fwEvent_GetInitMask (pTWD->hFwEvent);
+
+                /* Clearing all the interrupt status register sources */
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, ACX_REG_INTERRUPT_MASK, (~uIntVect), 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+            twIf_Transact(pHwInit->hTwIf, pTxn);
+
+
+            pHwInit->uTxnIndex++;
+
+            BUILD_HW_INIT_FW_STATIC_TXN(pHwInit, pTxn, cmdMbox_GetMboxAddress (pTWD->hCmdMbox),
+                                        (TTxnDoneCb)hwInit_FinalizeDownloadSm, hHwInit)
+            status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            EXCEPT (pHwInit, status);
+            continue;
+
+        case 8:
+            
+            pHwInit->uFinStage = 0;
+
+            cmdBld_FinalizeDownload (pTWD->hCmdBld, &pHwInit->tBootAttr, (FwStaticData_t *)(pHwInit->tFwStaticTxn.pFwStaticInfo));
+
+            /* Set the Download Status to COMPLETE */
+            pHwInit->DownloadStatus = TXN_STATUS_COMPLETE;
+
+            return TXN_STATUS_COMPLETE;
+
+        } /* End switch */
+
+    } /* End while */
+
+}
+
+
+/****************************************************************************
+ *                      hwInit_ResetSm()
+ ****************************************************************************
+ * DESCRIPTION: Reset hardware state machine
+ * 
+ * INPUTS:  None    
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: TI_OK or TI_NOK
+ ****************************************************************************/
+static TI_STATUS hwInit_ResetSm (TI_HANDLE hHwInit)
+{
+    THwInit *pHwInit = (THwInit *)hHwInit;
+    TI_STATUS status = TI_OK;
+    TTxnStruct* pTxn;
+
+    pHwInit->uTxnIndex = 0;
+
+        /* Disable Rx/Tx */
+    BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, REG_ENABLE_TX_RX, 0x0, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+    twIf_Transact(pHwInit->hTwIf, pTxn);
+
+    pHwInit->uTxnIndex++;
+
+        /* Disable auto calibration on start */
+    BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, SPARE_A2, 0xFFFF, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE,(TTxnDoneCb)hwInit_BootSm, hHwInit)
+    status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+    return status;
+}
+
+
+/****************************************************************************
+ *                      hwInit_EepromlessStartBurstSm()
+ ****************************************************************************
+ * DESCRIPTION: prepare eepromless configuration before boot
+ * 
+ * INPUTS:  
+ * 
+ * OUTPUT:  
+ * 
+ * RETURNS: 
+ ****************************************************************************/
+static TI_STATUS hwInit_EepromlessStartBurstSm (TI_HANDLE hHwInit)
+{
+    THwInit   *pHwInit = (THwInit *)hHwInit;
+    TI_STATUS  status = TI_OK;
+    TI_UINT8   *uAddr;
+    TI_UINT32  uDeltaLength;
+    TTxnStruct* pTxn;
+
+    pHwInit->uTxnIndex = 0;
+
+    while (TI_TRUE)
+    {
+        switch (pHwInit->uEEPROMStage)
+        {
+        /* 
+         * Stages 0, 1 handles the eeprom format parameters: 
+         * ------------------------------------------------
+         * Length  - 8bit       --> The length is counted in 32bit words
+         * Address - 16bit
+         * Data    - (Length * 4) bytes
+         * 
+         * Note: The nvs is in big endian format and we need to change it to little endian
+         */
+        case 0: 
+            /* Check if address LSB = 1 --> Register address */
+            if ((pHwInit->uEEPROMRegAddr = pHwInit->pEEPROMCurPtr[1]) & 1)
+            {
+                /* Mask the register's address LSB before writing to it */
+                pHwInit->uEEPROMRegAddr &= 0xfe;
+                /* Change the address's endian */
+                pHwInit->uEEPROMRegAddr |= (TI_UINT32)pHwInit->pEEPROMCurPtr[2] << 8;
+                /* Length of burst data */
+                pHwInit->uEEPROMBurstLen = pHwInit->pEEPROMCurPtr[0];
+                pHwInit->pEEPROMCurPtr += 3;
+                pHwInit->uEEPROMBurstLoop = 0; 
+                /* 
+                 * We've finished reading the burst information.
+                 * Go to stage 1 in order to write it 
+                 */
+                pHwInit->uEEPROMStage = 1;
+            }
+            /* If address LSB = 0 --> We're not in the burst section */
+            else
+            {
+                /* End of Burst transaction: we should see 7 zeroed bytes */
+                if (pHwInit->pEEPROMCurPtr[0] == 0)
+                {
+                    pHwInit->pEEPROMCurPtr += 7;
+                }
+                pHwInit->uEEPROMCurLen -= (pHwInit->pEEPROMCurPtr - pHwInit->pEEPROMBuf + 1);
+                pHwInit->uEEPROMCurLen = (pHwInit->uEEPROMCurLen + NVS_DATA_BUNDARY_ALIGNMENT - 1) & 0xfffffffc;
+                /* End of Burst transaction, go to TLV section */
+                pHwInit->uEEPROMStage = 2;
+            }
+            continue;            
+
+        case 1: 
+            if (pHwInit->uEEPROMBurstLoop < pHwInit->uEEPROMBurstLen)
+            {
+                /* Change the data's endian */
+                TI_UINT32 val = (pHwInit->pEEPROMCurPtr[0] | 
+                                (pHwInit->pEEPROMCurPtr[1] << 8) | 
+                                (pHwInit->pEEPROMCurPtr[2] << 16) | 
+                                (pHwInit->pEEPROMCurPtr[3] << 24));
+
+                TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "NVS::BurstRead: *(%08x) = %x\n", pHwInit->uEEPROMRegAddr, val);
+
+                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, (REGISTERS_BASE+pHwInit->uEEPROMRegAddr), val, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_EepromlessStartBurstSm, hHwInit)
+                status = twIf_Transact(pHwInit->hTwIf, pTxn);
+ 
+                pHwInit->uEEPROMStatus = status;
+                pHwInit->uEEPROMRegAddr += WORD_SIZE;
+                pHwInit->pEEPROMCurPtr +=  WORD_SIZE;
+                /* While not end of burst, we stay in stage 1 */
+                pHwInit->uEEPROMStage = 1;
+                pHwInit->uEEPROMBurstLoop ++;
+
+                EXCEPT (pHwInit, status);
+            }
+            else
+            {
+                /* If end of burst return to stage 0 to read the next one */
+                pHwInit->uEEPROMStage = 0;
+            }
+             
+            continue;
+
+        case 2:
+
+
+            pHwInit->uEEPROMStage = 3;
+    
+            SET_WORK_PARTITION(pHwInit->aPartition)
+            /* Set the bus addresses partition to its "running" mode */
+            hwInit_SetPartition (pHwInit,pHwInit->aPartition);
+            continue;
+ 
+        case 3:
+            TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Reached TLV section\n");
+
+            /* Align the host address */
+            if (((TI_UINT32)pHwInit->pEEPROMCurPtr & WORD_ALIGNMENT_MASK) && (pHwInit->uEEPROMCurLen > 0) )
+            {
+                uAddr = (TI_UINT8*)(((TI_UINT32)pHwInit->pEEPROMCurPtr & 0xFFFFFFFC)+WORD_SIZE);
+                uDeltaLength = uAddr - pHwInit->pEEPROMCurPtr + 1;
+
+                pHwInit->pEEPROMCurPtr = uAddr;
+                pHwInit->uEEPROMCurLen-= uDeltaLength;
+            }
+
+            TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "NVS::WriteTLV: pEEPROMCurPtr= %x, Length=%d\n", pHwInit->pEEPROMCurPtr, pHwInit->uEEPROMCurLen);
+
+            if (pHwInit->uEEPROMCurLen)
+            {
+                /* Save the 4 bytes before the NVS data for WSPI case where they are overrun by the WSPI BusDrv */
+                pHwInit->uSavedDataForWspiHdr = *(TI_UINT32 *)(pHwInit->pEEPROMCurPtr - WSPI_PAD_LEN_WRITE);
+
+                /* Prepare the Txn structure for the NVS transaction to the CMD_MBOX */
+                HW_INIT_PTXN_SET(pHwInit, pTxn)
+                TXN_PARAM_SET_DIRECTION(pTxn, TXN_DIRECTION_WRITE);
+                BUILD_TTxnStruct(pTxn, CMD_MBOX_ADDRESS, pHwInit->pEEPROMCurPtr, pHwInit->uEEPROMCurLen, 
+                                 (TTxnDoneCb)hwInit_EepromlessStartBurstSm, hHwInit)
+
+                /* Transact the NVS data to the CMD_MBOX */
+                status = twIf_Transact(pHwInit->hTwIf, pTxn);
+                
+                pHwInit->uEEPROMCurLen = 0;
+                pHwInit->uNVSStatus = status;
+
+                EXCEPT (pHwInit, status); 
+            }
+            else
+            {
+                /* Restore the 4 bytes before the NVS data for WSPI case were they are overrun by the WSPI BusDrv */
+                *(TI_UINT32 *)(pHwInit->pEEPROMCurPtr - WSPI_PAD_LEN_WRITE) = pHwInit->uSavedDataForWspiHdr;
+
+                /* Call the upper level state machine */
+                if (pHwInit->uEEPROMStatus == TXN_STATUS_PENDING || 
+                    pHwInit->uNVSStatus == TXN_STATUS_PENDING)
+                {
+                    hwInit_BootSm (hHwInit);
+                }
+
+                return TXN_STATUS_COMPLETE;
+            }
+        } /* End switch */
+ 
+    } /* End while */
+}
+
+/****************************************************************************
+ *                      hwInit_LoadFwImageSm()
+ ****************************************************************************
+ * DESCRIPTION: Load image from the host and download into the hardware 
+ * 
+ * INPUTS:  None    
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: TI_OK or TI_NOK
+ ****************************************************************************/
+
+
+#define ADDRESS_SIZE		(sizeof(TI_INT32))
+
+static TI_STATUS hwInit_LoadFwImageSm (TI_HANDLE hHwInit)
+{
+    THwInit *pHwInit 			= (THwInit *)hHwInit;
+    TI_STATUS status 			= TI_OK;
+	ETxnStatus	TxnStatus;
+	TI_UINT32 uMaxPartitionSize	= PARTITION_DOWN_MEM_SIZE;
+    TTxnStruct* pTxn;
+
+    pHwInit->uTxnIndex = 0;
+
+    while (TI_TRUE)
+    {
+        switch (pHwInit->uLoadStage)
+        {
+		case 0:
+            pHwInit->uLoadStage = 1; 
+
+			/* Check the Downloaded FW alignment */
+			if ((pHwInit->uFwLength % ADDRESS_SIZE) != 0)
+			{
+                TRACE1(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Length of downloaded Portion (%d) is not aligned\n",pHwInit->uFwLength);
+				EXCEPT_L (pHwInit, TXN_STATUS_ERROR);
+			}
+
+            TRACE2(pHwInit->hReport, REPORT_SEVERITY_INIT , "Image addr=0x%x, Len=0x%x\n", pHwInit->pFwBuf, pHwInit->uFwLength);
+
+            SET_FW_LOAD_PARTITION(pHwInit->aPartition,pHwInit->uFwAddress)
+			/* Set bus memory partition to current download area */
+            hwInit_SetPartition (pHwInit,pHwInit->aPartition);
+            status = TI_OK;
+			break;
+
+        case 1:
+
+			pHwInit->uLoadStage = 2;
+			/* if initial size is smaller than MAX_SDIO_BLOCK - go strait to stage 4 to write partial block */
+			if (pHwInit->uFwLength < MAX_SDIO_BLOCK)
+			{
+				pHwInit->uLoadStage = 4; 
+			}
+
+			pHwInit->uBlockReadNum 		= 0;
+			pHwInit->uBlockWriteNum 	= 0;
+			pHwInit->uPartitionLimit 	= pHwInit->uFwAddress + uMaxPartitionSize;
+
+            break;
+                    
+        case 2:
+
+            /* Load firmware by blocks */
+ 			if (pHwInit->uBlockReadNum < (pHwInit->uFwLength / MAX_SDIO_BLOCK))
+            {            
+                pHwInit->uLoadStage = 3;
+
+                /* Change partition */
+				/* The +2 is for the last block and the block remainder */  
+				if ( ((pHwInit->uBlockWriteNum + 2) * MAX_SDIO_BLOCK + pHwInit->uFwAddress) > pHwInit->uPartitionLimit)
+                {                					
+					pHwInit->uFwAddress += pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK;
+					/* update uPartitionLimit */
+					pHwInit->uPartitionLimit = pHwInit->uFwAddress + uMaxPartitionSize;
+                    SET_FW_LOAD_PARTITION(pHwInit->aPartition,pHwInit->uFwAddress)
+                    /* Set bus memory partition to current download area */
+                    hwInit_SetPartition (pHwInit,pHwInit->aPartition);
+                    TxnStatus = TXN_STATUS_OK;
+					pHwInit->uBlockWriteNum = 0;
+                    TRACE1(pHwInit->hReport, REPORT_SEVERITY_INIT , "Change partition to address offset = 0x%x\n", 									   pHwInit->uFwAddress + pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK);
+                    EXCEPT_L (pHwInit, TxnStatus);                                                     
+                }
+            }
+            else
+            {
+                pHwInit->uLoadStage = 4;
+                TRACE0(pHwInit->hReport, REPORT_SEVERITY_INIT , "Load firmware with Portions\n");
+            }
+            break;
+
+        case 3:        
+            pHwInit->uLoadStage = 2;
+
+            pHwInit->uTxnIndex = 0;
+
+            /* Copy image block to temporary buffer */
+            
+            os_memoryCopy (pHwInit->hOs,
+                           (void *)pHwInit->puFwTmpBuf,
+						   (void *)(pHwInit->pFwBuf + pHwInit->uBlockReadNum * MAX_SDIO_BLOCK),
+						   MAX_SDIO_BLOCK);
+
+            /* Load the block. Save WSPI_PAD_LEN_WRITE space for WSPI bus command */
+             BUILD_HW_INIT_FW_DL_TXN(pHwInit, pTxn, (pHwInit->uFwAddress + pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK),
+                                     pHwInit->puFwTmpBuf, MAX_SDIO_BLOCK, TXN_DIRECTION_WRITE,
+                                     (TTxnDoneCb)hwInit_LoadFwImageSm, hHwInit)
+            TxnStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            /* Log ERROR if the transaction returned ERROR */
+            if (TxnStatus == TXN_STATUS_ERROR)
+            {
+                TRACE1(pHwInit->hReport, REPORT_SEVERITY_ERROR , "hwInit_LoadFwImageSm: twIf_Transact retruned status=0x%x\n", TxnStatus);
+            } 
+
+			pHwInit->uBlockWriteNum ++;
+			pHwInit->uBlockReadNum ++;
+            EXCEPT_L (pHwInit, TxnStatus);
+            break;
+
+        case 4:    
+			pHwInit->uLoadStage 	= 5;
+
+            pHwInit->uTxnIndex = 0;
+
+			/* If No Last block to write */
+			if ( pHwInit->uFwLength % MAX_SDIO_BLOCK == 0 )
+			{
+				break;
+			}
+
+
+            /* Copy the last image block */
+            
+            os_memoryCopy (pHwInit->hOs,
+                           (void *)pHwInit->puFwTmpBuf,
+						   (void *)(pHwInit->pFwBuf + pHwInit->uBlockReadNum * MAX_SDIO_BLOCK),
+						   pHwInit->uFwLength % MAX_SDIO_BLOCK);
+
+            /* Load the last block */
+             BUILD_HW_INIT_FW_DL_TXN(pHwInit, pTxn, (pHwInit->uFwAddress + pHwInit->uBlockWriteNum * MAX_SDIO_BLOCK),
+                                     pHwInit->puFwTmpBuf, (pHwInit->uFwLength % MAX_SDIO_BLOCK), TXN_DIRECTION_WRITE,
+                                     (TTxnDoneCb)hwInit_LoadFwImageSm, hHwInit)
+            TxnStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            if (TxnStatus == TXN_STATUS_ERROR)
+			{
+                TRACE1(pHwInit->hReport, REPORT_SEVERITY_ERROR , "hwInit_LoadFwImageSm: last block retruned status=0x%x\n", TxnStatus);
+			}
+
+            EXCEPT_L (pHwInit, TxnStatus);
+            break;
+
+        case 5:
+            pHwInit->uLoadStage = 0;
+
+			/*If end of overall FW Download Process: Finalize download (run firmware)*/
+			if ( pHwInit->bFwBufLast == TI_TRUE )
+			{			
+				/* The download has completed */ 
+				WLAN_OS_REPORT (("Finished downloading firmware.\n"));
+				status = hwInit_FinalizeDownloadSm (hHwInit);
+			}
+			/* Have to wait to more FW Portions */
+			else
+			{
+				/* Call the upper layer callback */
+				if ( pHwInit->fFinalizeDownload != NULL )
+				{
+					(pHwInit->fFinalizeDownload) (pHwInit->hFinalizeDownload);
+				}
+
+				status = TI_OK;
+			}
+            return status;
+
+        } /* End switch */
+
+    } /* End while */
+
+} /* hwInit_LoadFwImageSm() */
+
+#define READ_TOP_REG_LOOP  32
+
+/****************************************************************************
+ *                      hwInit_ReadRadioParamsSm ()
+ ****************************************************************************
+ * DESCRIPTION: hwInit_ReadRadioParamsSm 
+ * INPUTS:  None    
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: TI_OK or TI_NOK
+ ****************************************************************************/
+TI_STATUS hwInit_ReadRadioParamsSm (TI_HANDLE hHwInit)
+{ 
+    THwInit      *pHwInit = (THwInit *)hHwInit;
+    TTwd         *pTWD = (TTwd *)pHwInit->hTWD;
+   IniFileGeneralParam *pGenParams = &DB_GEN(pTWD->hCmdBld);
+    TI_UINT32  val= 0, value;
+    TI_UINT32  add = FUNC7_SEL;
+	TI_UINT32  retAddress;
+    TTxnStruct  *pTxn;
+    TI_STATUS   status = 0;
+    
+    while (TI_TRUE)
+    {
+        switch (pHwInit->uRegStage)
+        {
+        case 0:
+            pHwInit->uRegStage = 1;
+            pHwInit->uTxnIndex++;
+
+            /*
+             * Select GPIO over Debug for BT_FUNC7 clear bit 17
+             */
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_SELECT, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
+            status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            EXCEPT (pHwInit, status)
+
+        case 1:
+            pHwInit->uRegStage ++;
+            pHwInit->uRegLoop = 0;
+
+            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
+            val = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));                
+            val &= 0xFFFDFFFF; /*clear bit 17*/
+            /* Now we can zero the index */
+            pHwInit->uTxnIndex = 0;
+
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_SELECT, val, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+
+            twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            pHwInit->uTxnIndex++; 
+
+            pHwInit->uRegData = FUNC7_SEL;
+
+            continue;
+
+        case 2:
+            pHwInit->uRegStage ++;
+            add = pHwInit->uRegData;
+
+            /* Select GPIO over Debug for BT_FUNC7*/
+            retAddress = (TI_UINT32)(add / 2);
+	        val = (retAddress & 0x7FF);
+        	val |= BIT_16 | BIT_17;
+
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, val, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+            twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            pHwInit->uTxnIndex++;  
+
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x2, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+            twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            continue;
+
+        case 3:
+            pHwInit->uRegStage ++;
+            pHwInit->uTxnIndex++; 
+
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_DATA_RD, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
+            status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            EXCEPT (pHwInit, status)
+
+           
+        case 4:
+            val = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+            pHwInit->uTxnIndex = 0;
+            if (val & BIT_18)
+            {
+              if ((val & BIT_16) && (!(val & BIT_17)))
+              {
+                  pHwInit->uRegStage ++;
+                  pHwInit->uRegLoop = 0;
+
+              }
+              else 
+              {
+                TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "hwInit_ReadRadioParamsSm: can't writing bt_func7_sel\n");
+                TWD_FinalizeFEMRead(pHwInit->hTWD);
+
+                return TI_NOK;
+              }
+            }
+            else
+            {
+              if (pHwInit->uRegLoop < READ_TOP_REG_LOOP)
+              {
+                 pHwInit->uRegStage = 3;
+                 pHwInit->uRegLoop++;
+              }
+              else 
+              {
+
+                TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for writing bt_func7_sel\n");
+                TWD_FinalizeFEMRead(pHwInit->hTWD);
+
+                return TI_NOK;
+
+              }
+            }
+
+            continue;
+
+        case 5:
+               
+               pHwInit->uRegStage ++;
+               add = pHwInit->uRegData;
+               retAddress = (TI_UINT32)(add / 2);
+	       value = (retAddress & 0x7FF);
+               value |= BIT_16 | BIT_17;
+
+               BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, value, 
+                                  REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+               twIf_Transact(pHwInit->hTwIf, pTxn);
+
+               pHwInit->uTxnIndex++;  
+
+              if (pHwInit->uRegSeqStage == 0)
+              {
+                  if (pHwInit->uRegData == FUNC7_SEL)
+                    value = (val | 0x600);
+                  else
+                    value = (val | 0x1000);
+              }
+              else
+              {
+                  if (pHwInit->uRegData == FUNC7_SEL)
+                    value = (val & 0xF8FF);
+                  else
+                    value = (val & 0xCFFF);
+
+              }
+
+	      value &= 0xFFFF;
+          
+               BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_WDATA, value, 
+                                  REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+               twIf_Transact(pHwInit->hTwIf, pTxn);
+
+               pHwInit->uTxnIndex++; 
+
+               BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x1, 
+                                  REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
+               status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+               pHwInit->uTxnIndex++; 
+
+               if ((pHwInit->uRegData == FUNC7_SEL)&& (pHwInit->uRegSeqStage == 0))
+               {
+                 pHwInit->uRegData = FUNC7_PULL;
+                 pHwInit->uRegStage = 2;
+               }
+               else
+               {
+                  if ((pHwInit->uRegData == FUNC7_PULL)&& (pHwInit->uRegSeqStage == 1))
+                   {
+                     pHwInit->uRegData = FUNC7_SEL;
+                     pHwInit->uRegStage = 2;
+                   }
+               }
+
+               EXCEPT (pHwInit, status)              
+               continue;
+
+        case 6:
+
+              if (pHwInit->uRegSeqStage == 1)
+              {
+                  pHwInit->uRegStage = 8;
+              }
+              else
+              {
+                pHwInit->uRegStage ++;
+                pHwInit->uTxnIndex++; 
+
+                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_OE_RADIO, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
+                status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+                EXCEPT (pHwInit, status)
+              }
+              continue;
+
+        case 7:
+            
+            pHwInit->uRegStage ++;
+
+            /* We don't zero pHwInit->uTxnIndex at the begining because we need it's value to the next transaction */
+            val = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));                
+            val |= 0x00020000;
+
+            pHwInit->uTxnIndex = 0; 
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_OE_RADIO, val, 
+                               REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+            twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            pHwInit->uTxnIndex++;  
+
+            BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, GPIO_IN, 0, 
+                               REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_ReadRadioParamsSm, hHwInit)
+            status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+            EXCEPT (pHwInit, status)
+
+            
+        case 8:
+            
+             if (pHwInit->uRegSeqStage == 0)
+             {
+	       val = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));                  
+	       val &= 0x20000;
+	       if(val)
+	      {
+		   pGenParams->TXBiPFEMManufacturer = FEM_TRIQUINT_TYPE_E;
+	      }
+	      else
+	      {
+	  	   pGenParams->TXBiPFEMManufacturer = FEM_RFMD_TYPE_E;
+	      }
+               WLAN_OS_REPORT (("hwInit_ReadRadioParamsSm FEM Type %d \n",pGenParams->TXBiPFEMManufacturer));
+			   pHwInit->uTxnIndex = 0;
+               pHwInit->uRegSeqStage = 1;
+               pHwInit->uRegStage = 2;
+               pHwInit->uRegData = FUNC7_PULL;
+               continue;
+             }
+             else
+             {
+              
+			  WLAN_OS_REPORT (("hwInit_ReadRadioParamsSm Ended Successfully\n"));
+
+              TWD_FinalizeFEMRead(pHwInit->hTWD);
+
+                return TI_OK;
+
+             }
+
+        } /* End switch */
+
+    } /* End while */
+
+}
+
+
+/****************************************************************************
+ *                      hwInit_ReadRadioParams()
+ ****************************************************************************
+ * DESCRIPTION: hwInit_ReadRadioParamsSm 
+ * initalizie hwInit_ReadRadioParamsSm parmaeters
+  ****************************************************************************/
+   
+TI_STATUS hwInit_ReadRadioParams (TI_HANDLE hHwInit)
+{
+  THwInit      *pHwInit = (THwInit *)hHwInit;
+
+  pHwInit->uRegStage = 0;
+  pHwInit->uRegSeqStage = 0;
+ 
+  return hwInit_ReadRadioParamsSm (hHwInit);
+}
+
+/****************************************************************************
+ *                      hwInit_InitPoalrity()
+ ****************************************************************************
+ * DESCRIPTION: hwInit_ReadRadioParamsSm 
+ * initalizie hwInit_ReadRadioParamsSm parmaeters
+  ****************************************************************************/
+   
+TI_STATUS hwInit_InitPolarity(TI_HANDLE hHwInit)
+{
+  THwInit      *pHwInit = (THwInit *)hHwInit;
+
+  pHwInit->uRegStage = 0;
+  pHwInit->uRegSeqStage = 0;
+ 
+  return hwInit_WriteIRQPolarity (hHwInit);
+}
+
+
+
+/****************************************************************************
+ *                      hwInit_WriteIRQPolarity ()
+ ****************************************************************************
+ * DESCRIPTION: hwInit_WriteIRQPolarity
+  * INPUTS:  None    
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: TI_OK or TI_NOK
+ ****************************************************************************/
+ TI_STATUS hwInit_WriteIRQPolarity(TI_HANDLE hHwInit)
+ {
+     THwInit      *pHwInit = (THwInit *)hHwInit;
+     TI_UINT32    Address = 0,val = 0,value = 0;
+     TTxnStruct  *pTxn;
+     TI_STATUS   status = 0;
+
+   /*  To write to a top level address from the WLAN IP:
+       Write the top level address to the OCP_POR_CTR register. 
+       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
+       Write the data to the OCP_POR_WDATA register
+       Write 0x1 to the OCP_CMD register. 
+
+      To read from a top level address:
+      Write the top level address to the OCP_POR_CTR register.
+      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 
+      Write 0x2 to the OCP_CMD register. 
+      Poll bit [18] of OCP_DATA_RD for data valid indication
+      Check bits 17:16 of OCP_DATA_RD:
+      00 – no response
+      01 – data valid / accept
+      10 – request failed
+      11 – response error
+      Read the data from the OCP_DATA_RD register
+   */
+      
+     while (TI_TRUE)
+     {
+         switch (pHwInit->uRegStage)
+         {
+         case 0:
+             pHwInit->uRegStage = 1;
+             pHwInit->uTxnIndex++;
+             pHwInit->uRegLoop = 0;
+
+             /* first read the IRQ Polarity register*/
+             Address = (TI_UINT32)(FN0_CCCR_REG_32 / 2);
+             val = (Address & 0x7FF);
+             val |= BIT_16 | BIT_17;
+
+             /* Write IRQ Polarity address register to OCP_POR_CTR*/
+             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, val, 
+                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+
+             twIf_Transact(pHwInit->hTwIf, pTxn);
+
+             pHwInit->uTxnIndex++;  
+
+             /* Write read (2)command to the OCP_CMD register. */
+
+             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x2, 
+                                REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+             twIf_Transact(pHwInit->hTwIf, pTxn);
+
+             continue;
+
+         case 1:
+             pHwInit->uRegStage ++;
+             pHwInit->uTxnIndex++; 
+
+             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_DATA_RD, 0, 
+                                REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_WriteIRQPolarity, hHwInit)
+             status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+             EXCEPT (pHwInit, status)
+
+
+         case 2:
+             /* get the value from  IRQ Polarity register*/
+             val = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+            
+             pHwInit->uTxnIndex = 0;
+
+             /*Poll bit 18 of OCP_DATA_RD for data valid indication*/
+             if (val & BIT_18)
+             {
+               if ((val & BIT_16) && (!(val & BIT_17)))
+               {
+                   pHwInit->uRegStage ++;
+                   pHwInit->uRegLoop = 0;
+
+               }
+               else 
+               {
+                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "can't writing bt_func7_sel\n");
+                 TWD_FinalizePolarityRead(pHwInit->hTWD);
+
+                 return TI_NOK;
+               }
+             }
+             else
+             {
+               if (pHwInit->uRegLoop < READ_TOP_REG_LOOP)
+               {
+                  pHwInit->uRegStage = 1;
+                  pHwInit->uRegLoop++;
+               }
+               else 
+               {
+
+                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for writing bt_func7_sel\n");
+                 TWD_FinalizePolarityRead(pHwInit->hTWD);
+
+                 return TI_NOK;
+
+               }
+             }
+
+             continue;
+
+
+         case 3:
+               /* second, write new value of IRQ polarity due to complation flag 1 - active low, 0 - active high*/
+                pHwInit->uRegStage ++;
+                Address = (TI_UINT32)(FN0_CCCR_REG_32 / 2);
+                value = (Address & 0x7FF);
+                value |= BIT_16 | BIT_17;
+
+                /* Write IRQ Polarity address register to OCP_POR_CTR*/
+
+                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, value, 
+                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+
+                twIf_Transact(pHwInit->hTwIf, pTxn);
+
+                pHwInit->uTxnIndex++;  
+
+#ifdef USE_IRQ_ACTIVE_HIGH
+                val |= 0x0<<1;
+              
+#else
+                val |= 0x01<<1;
+#endif
+
+                /* Write the new IRQ polarity value to the OCP_POR_WDATA register */
+                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_WDATA, val, 
+                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+                twIf_Transact(pHwInit->hTwIf, pTxn);
+
+                pHwInit->uTxnIndex++; 
+
+               /* Write write (1)command to the OCP_CMD register. */
+                BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x1, 
+                                   REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_WriteIRQPolarity, hHwInit)
+                status = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+                pHwInit->uTxnIndex++; 
+
+                EXCEPT (pHwInit, status)              
+                continue;
+
+         case 4:
+
+             TWD_FinalizePolarityRead(pHwInit->hTWD);
+
+             return TI_OK;
+
+
+         
+         } /* End switch */
+
+     } /* End while */
+
+ }
+
+
+/****************************************************************************
+ *                      hwInit_InitTopRegisterWrite()
+ ****************************************************************************
+ * DESCRIPTION: hwInit_InitTopRegisterWrite 
+ * initalizie hwInit_TopRegisterWrite SM parmaeters
+  ****************************************************************************/
+   
+TI_STATUS hwInit_InitTopRegisterWrite(TI_HANDLE hHwInit, TI_UINT32 uAddress, TI_UINT32 uValue)
+{
+  THwInit      *pHwInit = (THwInit *)hHwInit;
+
+  pHwInit->uTopStage = 0;
+  uAddress = (TI_UINT32)(uAddress / 2);
+  uAddress = (uAddress & 0x7FF);  
+  uAddress|= BIT_16 | BIT_17;
+  pHwInit->uTopRegAddr = uAddress;
+  pHwInit->uTopRegValue = uValue & 0xffff;  
+ 
+  return hwInit_TopRegisterWrite (hHwInit);
+}
+
+
+/****************************************************************************
+ *                      hwInit_WriteTopRegister ()
+ ****************************************************************************
+ * DESCRIPTION: Generic function that writes to the top registers area
+  * INPUTS:  None    
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: TI_OK or TI_NOK
+ ****************************************************************************/
+ TI_STATUS hwInit_TopRegisterWrite(TI_HANDLE hHwInit)
+ {
+     /*  To write to a top level address from the WLAN IP:
+         Write the top level address to the OCP_POR_CTR register. 
+         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
+         Write the data to the OCP_POR_WDATA register
+         Write 0x1 to the OCP_CMD register. 
+     */ 
+     THwInit *pHwInit = (THwInit *)hHwInit;
+     TTxnStruct *pTxn;
+        
+     while (TI_TRUE)
+     {
+         switch (pHwInit->uTopStage)
+         {
+         case 0:
+             pHwInit->uTopStage = 1;
+
+             pHwInit->uTxnIndex++;
+             /* Write the address to OCP_POR_CTR*/
+             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, pHwInit->uTopRegAddr,
+                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+             twIf_Transact(pHwInit->hTwIf, pTxn);
+
+             pHwInit->uTxnIndex++;
+             /* Write the new value to the OCP_POR_WDATA register */
+             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_WDATA, pHwInit->uTopRegValue, 
+                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+             twIf_Transact(pHwInit->hTwIf, pTxn);
+
+             pHwInit->uTxnIndex++; 
+             /* Write write (1)command to the OCP_CMD register. */
+             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x1, 
+                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, (TTxnDoneCb)hwInit_TopRegisterWrite, hHwInit)
+             pHwInit->uTopStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
+
+             pHwInit->uTxnIndex++;
+
+             EXCEPT (pHwInit, pHwInit->uTopStatus)              
+             continue;
+
+         case 1:
+
+             pHwInit->uTxnIndex = 0;
+             
+             if (pHwInit->uTopStatus == TXN_STATUS_PENDING) {
+                 hwInit_BootSm (hHwInit);
+             }
+             
+             return TI_OK;
+         
+         } /* End switch */
+
+     } /* End while */
+
+ }
+
+
+ /****************************************************************************
+ *                      hwInit_InitTopRegisterRead()
+ ****************************************************************************
+ * DESCRIPTION: hwInit_InitTopRegisterRead 
+ * initalizie hwInit_InitTopRegisterRead SM parmaeters
+  ****************************************************************************/
+   
+TI_STATUS hwInit_InitTopRegisterRead(TI_HANDLE hHwInit, TI_UINT32 uAddress)
+{
+  THwInit      *pHwInit = (THwInit *)hHwInit;
+
+  pHwInit->uTopStage = 0;
+  uAddress = (TI_UINT32)(uAddress / 2);
+  uAddress = (uAddress & 0x7FF);  
+  uAddress|= BIT_16 | BIT_17;
+  pHwInit->uTopRegAddr = uAddress;
+
+  return hwInit_TopRegisterRead (hHwInit);
+}
+
+
+/****************************************************************************
+ *                      hwInit_TopRegisterRead ()
+ ****************************************************************************
+ * DESCRIPTION: Generic function that reads to the top registers area
+  * INPUTS:  None    
+ * 
+ * OUTPUT:  None
+ * 
+ * RETURNS: TI_OK or TI_NOK
+ ****************************************************************************/
+ TI_STATUS hwInit_TopRegisterRead(TI_HANDLE hHwInit)
+ {
+     /*  
+        To read from a top level address:
+        Write the top level address to the OCP_POR_CTR register.
+        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 
+        Write 0x2 to the OCP_CMD register. 
+        Poll bit [18] of OCP_DATA_RD for data valid indication
+        Check bits 17:16 of OCP_DATA_RD:
+        00 – no response
+        01 – data valid / accept
+        10 – request failed
+        11 – response error
+        Read the data from the OCP_DATA_RD register
+     */
+
+     THwInit *pHwInit = (THwInit *)hHwInit;
+     TTxnStruct *pTxn;
+        
+     while (TI_TRUE)
+     {
+         switch (pHwInit->uTopStage)
+         {
+         case 0:
+             pHwInit->uTopStage = 1;
+             pHwInit->uTxnIndex++;
+             pHwInit->uRegLoop = 0;
+
+             /* Write the address to OCP_POR_CTR*/
+             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_POR_CTR, pHwInit->uTopRegAddr,
+                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+             twIf_Transact(pHwInit->hTwIf, pTxn);
+
+             pHwInit->uTxnIndex++;  
+             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_CMD, 0x2, 
+                                    REGISTER_SIZE, TXN_DIRECTION_WRITE, NULL, NULL)
+             twIf_Transact(pHwInit->hTwIf, pTxn);
+
+             continue;
+
+         case 1:
+             pHwInit->uTopStage ++;
+             pHwInit->uTxnIndex++; 
+
+             BUILD_HW_INIT_TXN_DATA(pHwInit, pTxn, OCP_DATA_RD, 0, 
+                                    REGISTER_SIZE, TXN_DIRECTION_READ, (TTxnDoneCb)hwInit_TopRegisterRead, hHwInit)
+             pHwInit->uTopStatus = twIf_Transact(pHwInit->hTwIf, pTxn);
+             
+             EXCEPT (pHwInit, pHwInit->uTopStatus)
+
+         case 2:
+             /* get the value from  IRQ Polarity register*/
+             pHwInit->uTopRegValue = *((TI_UINT32*)(pHwInit->aHwInitTxn[pHwInit->uTxnIndex].pData));
+            
+             pHwInit->uTxnIndex = 0;
+
+             /*Poll bit 18 of OCP_DATA_RD for data valid indication*/
+             if (pHwInit->uTopRegValue & BIT_18)
+             {
+               if ((pHwInit->uTopRegValue & BIT_16) && (!(pHwInit->uTopRegValue & BIT_17)))
+               {                   
+                   pHwInit->uTopRegValue &= 0xffff;
+                   
+                   pHwInit->uTxnIndex = 0;
+                   pHwInit->uRegLoop = 0;
+                   if (pHwInit->uTopStatus == TXN_STATUS_PENDING) {
+                       hwInit_BootSm (hHwInit);
+                   }
+                   return TI_OK;
+               }
+               else 
+               {
+                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "can't writing bt_func7_sel\n");                 
+                 if (pHwInit->uTopStatus == TXN_STATUS_PENDING) {
+                       hwInit_BootSm (hHwInit);
+                 }
+                 return TI_NOK;
+               }
+             }
+             else
+             {
+               if (pHwInit->uRegLoop < READ_TOP_REG_LOOP)
+               {
+                  pHwInit->uTopStage = 1;
+                  pHwInit->uRegLoop++;
+               }
+               else 
+               {
+                 TRACE0(pHwInit->hReport, REPORT_SEVERITY_ERROR , "Timeout waiting for writing bt_func7_sel\n");                 
+                 if (pHwInit->uTopStatus == TXN_STATUS_PENDING) {
+                       hwInit_BootSm (hHwInit);
+                 }
+                 return TI_NOK;
+               }
+              }
+
+             continue;
+         
+         } /* End switch */
+
+     } /* End while */
+
+ }
+
+
+#ifndef _VLCT_
+    /****************************************************************************
+    *                      hwInit_StallTimerCb ()
+    ****************************************************************************
+    * DESCRIPTION: CB timer function in fTimerFunction format that calls hwInit_StallTimerCb
+     * INPUTS:  TI_HANDLE hHwInit    
+    * 
+    * OUTPUT:  None
+    * 
+    * RETURNS: None
+    ****************************************************************************/
+    static void hwInit_StallTimerCb (TI_HANDLE hHwInit)
+    {
+        hwInit_FinalizeDownloadSm(hHwInit);
+    }
+#endif