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