• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 *************************************************************************/
hwInit_Create(TI_HANDLE hOs)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 ***************************************************************************/
hwInit_Destroy(TI_HANDLE hHwInit)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 ***************************************************************************/
hwInit_Init(TI_HANDLE hHwInit,TI_HANDLE hReport,TI_HANDLE hTimer,TI_HANDLE hTWD,TI_HANDLE hFinalizeDownload,TFinalizeCb fFinalizeDownload,TEndOfHwInitCb fInitHwCb)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 
hwInit_SetNvsImage(TI_HANDLE hHwInit,TI_UINT8 * pbuf,TI_UINT32 length)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 
hwInit_SetFwImage(TI_HANDLE hHwInit,TFileInfo * pFileInfo)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  */
hwInit_SetPartition(THwInit * pHwInit,TPartition * pPartition)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  ****************************************************************************/
hwInit_Boot(TI_HANDLE hHwInit)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  ****************************************************************************/
hwInit_BootSm(TI_HANDLE hHwInit)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 << 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 
hwInit_LoadFw(TI_HANDLE hHwInit)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  ****************************************************************************/
hwInit_FinalizeDownloadSm(TI_HANDLE hHwInit)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  ****************************************************************************/
hwInit_ResetSm(TI_HANDLE hHwInit)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  ****************************************************************************/
hwInit_EepromlessStartBurstSm(TI_HANDLE hHwInit)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 
hwInit_LoadFwImageSm(TI_HANDLE hHwInit)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  ****************************************************************************/
hwInit_ReadRadioParamsSm(TI_HANDLE hHwInit)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 
hwInit_ReadRadioParams(TI_HANDLE hHwInit)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 
hwInit_InitPolarity(TI_HANDLE hHwInit)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  ****************************************************************************/
hwInit_WriteIRQPolarity(TI_HANDLE hHwInit)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 
hwInit_InitTopRegisterWrite(TI_HANDLE hHwInit,TI_UINT32 uAddress,TI_UINT32 uValue)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  ****************************************************************************/
hwInit_TopRegisterWrite(TI_HANDLE hHwInit)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 
hwInit_InitTopRegisterRead(TI_HANDLE hHwInit,TI_UINT32 uAddress)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  ****************************************************************************/
hwInit_TopRegisterRead(TI_HANDLE hHwInit)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
hwInit_StallTimerCb(TI_HANDLE hHwInit,TI_BOOL bTwdInitOccured)2356  static void hwInit_StallTimerCb (TI_HANDLE hHwInit, TI_BOOL bTwdInitOccured)
2357 {
2358 	hwInit_FinalizeDownloadSm (hHwInit);
2359 }
2360 #endif
2361