1/*
2 * TwIf.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/** \file   TwIf.c
36 *  \brief  The TWD bottom API towards the Txn-Queue.
37 *
38 * The TwIf module is the lowest WLAN-specific layer and presents a common interface to all Xfer modules.
39 * As such, it is responsible for the common functionalities related to device access, which includes:
40 *    - transactions submission
41 *    - interface power control
42 *    - address translation (paging) when needed (depends on bus attributes).
43 * The TwIf has no OS, platform or bus type dependencies.
44 *
45 *  \see    TwIf.h, TxnQueue.c, TxnQueue.h
46 */
47
48#define __FILE_ID__  FILE_ID_121
49#include "tidef.h"
50#include "report.h"
51#include "context.h"
52#include "timer.h"
53#include "TxnDefs.h"
54#include "TxnQueue.h"
55#include "TwIf.h"
56#include "TWDriver.h"
57
58
59/************************************************************************
60 * Defines
61 ************************************************************************/
62#define TXN_DONE_QUE_SIZE       QUE_UNLIMITED_SIZE
63#define PEND_RESTART_TIMEOUT    100   /* timeout in msec for completion of last DMA transaction during restart */
64
65/* Values to write to the ELP register for sleep/awake */
66#define ELP_CTRL_REG_SLEEP      0
67#define ELP_CTRL_REG_AWAKE      1
68
69/*
70 * Device interface-control registers addresses (at the end ot the 17-bit address space):
71 */
72#define PARTITION_REGISTERS_ADDR        (0x1FFC0)   /* Four 32 bit register:                      */
73                                                    /*    Memory region size            (0x1FFC0) */
74                                                    /*    Memory region base address    (0x1FFC4) */
75                                                    /*    Registers region size         (0x1FFC8) */
76                                                    /*    Registers region base address (0x1FFCC) */
77
78#define ELP_CTRL_REG_ADDR		        (0x1FFFC)   /* ELP control register address */
79
80
81
82/************************************************************************
83 * Types
84 ************************************************************************/
85
86/* TwIf SM States */
87typedef enum
88{
89	SM_STATE_AWAKE,           /* HW is awake and Txn-Queue is running */
90	SM_STATE_SLEEP,           /* HW is asleep and Txn-Queue is stopped */
91	SM_STATE_WAIT_HW          /* Waiting for HW to wake up (after triggering it), Txn-Queue is stopped */
92} ESmState;
93
94/* TwIf SM Events */
95typedef enum
96{
97	SM_EVENT_START,           /* Need to wake up the device to handle transactions */
98	SM_EVENT_HW_AVAILABLE,    /* The device woke up */
99	SM_EVENT_SLEEP            /* Need to let the device go to sleep */
100} ESmEvent;
101
102/* The addresses partitioning configuration Txn data */
103typedef struct
104{
105    TI_UINT32       uMemSize;        /* The HW memory region size. */
106    TI_UINT32       uMemAddr;        /* The HW memory region address. */
107    TI_UINT32       uRegSize;        /* The HW registers region size. */
108    TI_UINT32       uRegAddr;        /* The HW registers region address. */
109
110} TPartitionTxnData;
111
112/* The addresses partitioning configuration Txn */
113typedef struct
114{
115    TTxnStruct          tHdr;        /* The generic transaction structure */
116    TPartitionTxnData   tData;       /* The addresses partitioning configuration data */
117
118} TPartitionTxn;
119
120/* The addresses partitioning configuration Txn */
121typedef struct
122{
123    TTxnStruct      tHdr;           /* The generic transaction structure */
124    TI_UINT32   tData;       /* The addresses partitioning configuration data for one register */
125
126} TPartitionRegTxn;
127
128/* The addresses partitioning configuration Txn */
129typedef struct
130{
131    TTxnStruct      tHdr;           /* The generic transaction structure */
132    TI_UINT8        uElpData;       /* The value to write to the ELP register */
133
134} TElpTxn;
135
136/* The TwIf module Object */
137typedef struct _TTwIfObj
138{
139    /* Other modules handles */
140    TI_HANDLE	    hOs;
141    TI_HANDLE	    hReport;
142	TI_HANDLE       hContext;
143	TI_HANDLE       hTimer;
144	TI_HANDLE	    hTxnQ;
145
146    ESmState        eState;          /* SM current state */
147    TI_HANDLE       hTxnDoneQueue;   /* Queue for completed transactions not reported yet to the upper layer */
148    TI_UINT32       uContextId;      /* The ID allocated to this module on registration to context module */
149    TFailureEventCb fErrCb;          /* The upper layer CB function for error handling */
150    TI_HANDLE       hErrCb;          /* The CB function handle */
151    TRecoveryCb     fRecoveryCb;     /* The upper layer CB for restart complete */
152    TI_HANDLE       hRecoveryCb;     /* The CB function handle */
153    TI_UINT32       uAwakeReqCount;  /* Increment on awake requests and decrement on sleep requests */
154    TI_UINT32       uPendingTxnCount;/* Count pending transactions (sent to TxnQ and not completed yet) */
155    TElpTxn         tElpTxnSleep;    /* Transaction structure for writing sleep to ELP register  */
156    TElpTxn         tElpTxnAwake;    /* Transaction structure for writing awake to ELP register  */
157
158    /* HW Addresses partitioning */
159    TI_UINT32       uMemAddr1;        /* The HW memory region start address. */
160    TI_UINT32       uMemSize1;        /* The HW memory region end address. */
161    TI_UINT32       uMemAddr2;        /* The HW registers region start address. */
162    TI_UINT32       uMemSize2;        /* The HW registers region end address. */
163    TI_UINT32       uMemAddr3;        /* The INT Status registers region start address. */
164    TI_UINT32       uMemSize3;        /* The INT Status registers region end address. */
165    TI_UINT32       uMemAddr4;        /* The FW Status mem registers region start address. */
166
167
168#ifdef TI_DBG
169    /* Debug counters */
170    TI_UINT32       uDbgCountAwake;      /* Count calls to twIf_Awake */
171    TI_UINT32       uDbgCountSleep;      /* Count calls to twIf_Sleep */
172    TI_UINT32       uDbgCountTxn;        /* Count calls to twIf_SendTransaction (including TwIf internal Txns) */
173    TI_UINT32       uDbgCountTxnPending; /* Count transactions that returned PENDING */
174    TI_UINT32       uDbgCountTxnComplete;/* Count transactions that returned COMPLETE */
175    TI_UINT32       uDbgCountTxnDoneCb;  /* Count calls to twIf_TxnDoneCb */
176#endif
177
178    TI_BOOL         bTxnDoneInRecovery;      /* Indicate that current TxnDone is within recovery process */
179    TI_BOOL         bPendRestartTimerRunning;/* Indicate that the restart guard timer is running */
180    TI_HANDLE       hPendRestartTimer;       /* The restart process guard timer */
181
182} TTwIfObj;
183
184
185/************************************************************************
186 * Internal functions prototypes
187 ************************************************************************/
188static void        twIf_WriteElpReg        (TTwIfObj *pTwIf, TI_UINT32 uValue);
189static void        twIf_PartitionTxnDoneCb (TI_HANDLE hTwIf, void *hTxn);
190static ETxnStatus  twIf_SendTransaction    (TTwIfObj *pTwIf, TTxnStruct *pTxn);
191static void        twIf_HandleSmEvent      (TTwIfObj *pTwIf, ESmEvent eEvent);
192static void        twIf_TxnDoneCb          (TI_HANDLE hTwIf, TTxnStruct *pTxn);
193static void        twIf_HandleTxnDone      (TI_HANDLE hTwIf);
194static void        twIf_ClearTxnDoneQueue  (TI_HANDLE hTwIf);
195static void        twIf_PendRestratTimeout (TI_HANDLE hTwIf, TI_BOOL bTwdInitOccured);
196
197
198/************************************************************************
199 *
200 *   Module functions implementation
201 *
202 ************************************************************************/
203
204/**
205 * \fn     twIf_Create
206 * \brief  Create the module
207 *
208 * Allocate and clear the module's object.
209 *
210 * \note
211 * \param  hOs - Handle to Os Abstraction Layer
212 * \return Handle of the allocated object, NULL if allocation failed
213 * \sa     twIf_Destroy
214 */
215TI_HANDLE twIf_Create (TI_HANDLE hOs)
216{
217    TI_HANDLE  hTwIf;
218    TTwIfObj  *pTwIf;
219
220    hTwIf = os_memoryAlloc (hOs, sizeof(TTwIfObj));
221    if (hTwIf == NULL)
222        return NULL;
223
224    pTwIf = (TTwIfObj *)hTwIf;
225
226    os_memoryZero (hOs, hTwIf, sizeof(TTwIfObj));
227
228    pTwIf->hOs = hOs;
229
230    return pTwIf;
231}
232
233
234/**
235 * \fn     twIf_Destroy
236 * \brief  Destroy the module.
237 *
238 * Unregister from TxnQ and free the TxnDone-queue and the module's object.
239 *
240 * \note
241 * \param  The module's object
242 * \return TI_OK on success or TI_NOK on failure
243 * \sa     twIf_Create
244 */
245TI_STATUS twIf_Destroy (TI_HANDLE hTwIf)
246{
247    TTwIfObj *pTwIf = (TTwIfObj*)hTwIf;
248
249    if (pTwIf)
250    {
251        txnQ_Close (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN);
252        if (pTwIf->hTxnDoneQueue)
253        {
254            que_Destroy (pTwIf->hTxnDoneQueue);
255        }
256        if (pTwIf->hPendRestartTimer)
257        {
258            tmr_DestroyTimer (pTwIf->hPendRestartTimer);
259        }
260        os_memoryFree (pTwIf->hOs, pTwIf, sizeof(TTwIfObj));
261    }
262    return TI_OK;
263}
264
265
266/**
267 * \fn     twIf_Init
268 * \brief  Init module
269 *
270 * - Init required handles and module variables
271 * - Create the TxnDone-queue
272 * - Register to TxnQ
273 * - Register to context module
274 *
275 * \note
276 * \param  hTwIf       - The module's object
277 * \param  hXxx        - Handles to other modules
278 * \param  fRecoveryCb - Callback function for recovery completed after TxnDone
279 * \param  hRecoveryCb - Handle for fRecoveryCb
280 * \return void
281 * \sa
282 */
283void twIf_Init (TI_HANDLE hTwIf,
284                TI_HANDLE hReport,
285                TI_HANDLE hContext,
286                TI_HANDLE hTimer,
287                TI_HANDLE hTxnQ,
288                TRecoveryCb fRecoveryCb,
289                TI_HANDLE hRecoveryCb)
290{
291    TTwIfObj   *pTwIf = (TTwIfObj*)hTwIf;
292    TI_UINT32   uNodeHeaderOffset;
293    TTxnStruct *pTxnHdr;   /* The ELP transactions header (as used in the TxnQ API) */
294
295    pTwIf->hReport          = hReport;
296    pTwIf->hContext         = hContext;
297    pTwIf->hTimer           = hTimer;
298    pTwIf->hTxnQ            = hTxnQ;
299    pTwIf->fRecoveryCb      = fRecoveryCb;
300    pTwIf->hRecoveryCb      = hRecoveryCb;
301
302    /* Prepare ELP sleep transaction */
303    pTwIf->tElpTxnSleep.uElpData = ELP_CTRL_REG_SLEEP;
304    pTxnHdr = &(pTwIf->tElpTxnSleep.tHdr);
305    TXN_PARAM_SET(pTxnHdr, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
306    TXN_PARAM_SET_MORE(pTxnHdr, 0);         /* Sleep is the last transaction! */
307    /* NOTE: Function id for single step will be replaced to 0 by the bus driver */
308    TXN_PARAM_SET_SINGLE_STEP(pTxnHdr, 1);  /* ELP write is always single step (TxnQ is topped)! */
309    BUILD_TTxnStruct(pTxnHdr, ELP_CTRL_REG_ADDR, &(pTwIf->tElpTxnSleep.uElpData), sizeof(TI_UINT8), NULL, NULL)
310
311    /* Prepare ELP awake transaction */
312    pTwIf->tElpTxnAwake.uElpData = ELP_CTRL_REG_AWAKE;
313    pTxnHdr = &(pTwIf->tElpTxnAwake.tHdr);
314    TXN_PARAM_SET(pTxnHdr, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
315    TXN_PARAM_SET_MORE(pTxnHdr, 1);
316    /* NOTE: Function id for single step will be replaced to 0 by the bus driver */
317    TXN_PARAM_SET_SINGLE_STEP(pTxnHdr, 1);  /* ELP write is always single step (TxnQ is topped)! */
318    BUILD_TTxnStruct(pTxnHdr, ELP_CTRL_REG_ADDR, &(pTwIf->tElpTxnAwake.uElpData), sizeof(TI_UINT8), NULL, NULL)
319
320    /* Create the TxnDone queue. */
321    uNodeHeaderOffset = TI_FIELD_OFFSET(TTxnStruct, tTxnQNode);
322    pTwIf->hTxnDoneQueue = que_Create (pTwIf->hOs, pTwIf->hReport, TXN_DONE_QUE_SIZE, uNodeHeaderOffset);
323    if (pTwIf->hTxnDoneQueue == NULL)
324    {
325        TRACE0(pTwIf->hReport, REPORT_SEVERITY_ERROR, "twIf_Init: TxnDone queue creation failed!\n");
326    }
327
328    /* Register to the context engine and get the client ID */
329    pTwIf->uContextId = context_RegisterClient (pTwIf->hContext,
330                                                twIf_HandleTxnDone,
331                                                hTwIf,
332                                                TI_TRUE,
333                                                "TWIF",
334                                                sizeof("TWIF"));
335
336	/* Allocate timer */
337	pTwIf->hPendRestartTimer = tmr_CreateTimer (hTimer);
338	if (pTwIf->hPendRestartTimer == NULL)
339	{
340        TRACE0(pTwIf->hReport, REPORT_SEVERITY_ERROR, "twIf_Init: Failed to create PendRestartTimer!\n");
341        return;
342	}
343    pTwIf->bPendRestartTimerRunning = TI_FALSE;
344
345    /* Register to TxnQ */
346    txnQ_Open (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN, TXN_NUM_PRIORITYS, (TTxnQueueDoneCb)twIf_TxnDoneCb, hTwIf);
347
348    /* Restart TwIf and TxnQ modules */
349    twIf_Restart (hTwIf);
350}
351
352
353/**
354 * \fn     twIf_Restart
355 * \brief  Restart module upon driver stop or recovery
356 *
357 * Called upon driver stop command or upon recovery.
358 * Calls txnQ_Restart to clear the WLAN queues and call the TxnDone CB on each tansaction.
359 * If no transaction in progress, the queues are cleared immediately.
360 * If a transaction is in progress, it is done upon TxnDone.
361 * The status in transactions that were dropped due to restart is TXN_STATUS_RECOVERY,
362 *     and its originator (Xfer module) handles it if required (if its CB was written in the Txn).
363 *
364 * \note
365 * \param  hTwIf - The module's object
366 * \return COMPLETE if the WLAN queues were restarted, PENDING if waiting for TxnDone to restart queues
367 * \sa
368 */
369ETxnStatus twIf_Restart (TI_HANDLE hTwIf)
370{
371    TTwIfObj    *pTwIf = (TTwIfObj*)hTwIf;
372    ETxnStatus  eStatus;
373
374    pTwIf->eState           = SM_STATE_SLEEP;
375    pTwIf->uAwakeReqCount   = 0;
376
377    pTwIf->uPendingTxnCount = 0;
378
379    /* Clear done queue */
380    twIf_ClearTxnDoneQueue(hTwIf);
381
382    /* Restart WLAN queues */
383    eStatus = txnQ_Restart (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN);
384
385    /* If pending upon ongoing transaction, start guard timer in case SDIO does not call us back */
386    if (eStatus == TXN_STATUS_PENDING)
387    {
388        pTwIf->bPendRestartTimerRunning = TI_TRUE;
389		tmr_StartTimer (pTwIf->hPendRestartTimer, twIf_PendRestratTimeout, hTwIf, PEND_RESTART_TIMEOUT, TI_FALSE);
390    }
391
392    /* Return result (COMPLETE if completed or PENDING if will be completed in TxnDone context) */
393    return eStatus;
394}
395
396
397/**
398 * \fn     twIf_RegisterErrCb
399 * \brief  Register Error CB
400 *
401 * Register upper layer (health monitor) CB for bus error
402 *
403 * \note
404 * \param  hTwIf  - The module's object
405 * \param  fErrCb - The upper layer CB function for error handling
406 * \param  hErrCb - The CB function handle
407 * \return void
408 * \sa
409 */
410void twIf_RegisterErrCb (TI_HANDLE hTwIf, void *fErrCb, TI_HANDLE hErrCb)
411{
412    TTwIfObj *pTwIf = (TTwIfObj*) hTwIf;
413
414    /* Save upper layer (health monitor) CB for bus error */
415    pTwIf->fErrCb = (TFailureEventCb)fErrCb;
416    pTwIf->hErrCb = hErrCb;
417}
418
419
420/**
421 * \fn     twIf_WriteElpReg
422 * \brief  write ELP register
423 *
424 * \note
425 * \param  pTwIf   - The module's object
426 * \param  uValue  - ELP_CTRL_REG_SLEEP or ELP_CTRL_REG_AWAKE
427 * \return void
428 * \sa
429 */
430static void twIf_WriteElpReg (TTwIfObj *pTwIf, TI_UINT32 uValue)
431{
432    TRACE1(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_WriteElpReg:  ELP Txn data = 0x%x\n", uValue);
433    /* Send ELP (awake or sleep) transaction to TxnQ */
434    if (uValue == ELP_CTRL_REG_AWAKE)
435    {
436        txnQ_Transact (pTwIf->hTxnQ, &(pTwIf->tElpTxnAwake.tHdr));
437    }
438    else
439    {
440        txnQ_Transact (pTwIf->hTxnQ, &(pTwIf->tElpTxnSleep.tHdr));
441    }
442}
443
444
445/**
446 * \fn     twIf_SetPartition
447 * \brief  Set HW addresses partition
448 *
449 * Called by the HwInit module to set the HW address ranges for download or working access.
450 * Generate and configure the bus access address mapping table.
451 * The partition is split between register (fixed partition of 24KB size, exists in all modes),
452 *     and memory (dynamically changed during init and gets constant value in run-time, 104KB size).
453 * The TwIf configures the memory mapping table on the device by issuing write transaction to
454 *     table address (note that the TxnQ and bus driver see this as a regular transaction).
455 *
456 * \note In future versions, a specific bus may not support partitioning (as in wUART),
457 *       In this case the HwInit module shall not call this function (will learn the bus
458 *       configuration from the INI file).
459 *
460 * \param  hTwIf          - The module's object
461 * \param  uMemAddr  - The memory partition base address
462 * \param  uMemSize  - The memory partition size
463 * \param  uRegAddr  - The registers partition base address
464 * \param  uRegSize  - The register partition size
465 * \return void
466 * \sa
467 */
468
469void twIf_SetPartition (TI_HANDLE hTwIf,
470                        TPartition *pPartition)
471{
472    TTwIfObj          *pTwIf = (TTwIfObj*) hTwIf;
473    TPartitionRegTxn  *pPartitionRegTxn;/* The partition transaction structure for one register */
474    TTxnStruct        *pTxnHdr;         /* The partition transaction header (as used in the TxnQ API) */
475    ETxnStatus         eStatus;
476    int i;
477
478    /* Save partition information for translation and validation. */
479    pTwIf->uMemAddr1 = pPartition[0].uMemAdrr;
480    pTwIf->uMemSize1 = pPartition[0].uMemSize;
481    pTwIf->uMemAddr2 = pPartition[1].uMemAdrr;
482    pTwIf->uMemSize2 = pPartition[1].uMemSize;
483    pTwIf->uMemAddr3 = pPartition[2].uMemAdrr;
484    pTwIf->uMemSize3 = pPartition[2].uMemSize;
485    pTwIf->uMemAddr4 = pPartition[3].uMemAdrr;
486
487    /* Allocate memory for the current 4 partition transactions */
488    pPartitionRegTxn = (TPartitionRegTxn *) os_memoryAlloc (pTwIf->hOs, 7*sizeof(TPartitionRegTxn));
489    pTxnHdr       = &(pPartitionRegTxn->tHdr);
490
491    /* Zero the allocated memory to be certain that unused fields will be initialized */
492    os_memoryZero(pTwIf->hOs, pPartitionRegTxn, 7*sizeof(TPartitionRegTxn));
493
494    /* Prepare partition transaction data */
495    pPartitionRegTxn[0].tData  = ENDIAN_HANDLE_LONG(pTwIf->uMemAddr1);
496    pPartitionRegTxn[1].tData  = ENDIAN_HANDLE_LONG(pTwIf->uMemSize1);
497    pPartitionRegTxn[2].tData  = ENDIAN_HANDLE_LONG(pTwIf->uMemAddr2);
498    pPartitionRegTxn[3].tData  = ENDIAN_HANDLE_LONG(pTwIf->uMemSize2);
499    pPartitionRegTxn[4].tData  = ENDIAN_HANDLE_LONG(pTwIf->uMemAddr3);
500    pPartitionRegTxn[5].tData  = ENDIAN_HANDLE_LONG(pTwIf->uMemSize3);
501    pPartitionRegTxn[6].tData  = ENDIAN_HANDLE_LONG(pTwIf->uMemAddr4);
502
503
504    /* Prepare partition Txn header */
505    for (i=0; i<7; i++)
506    {
507        pTxnHdr = &(pPartitionRegTxn[i].tHdr);
508        TXN_PARAM_SET(pTxnHdr, TXN_LOW_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
509        TXN_PARAM_SET_MORE(pTxnHdr, 1);
510        TXN_PARAM_SET_SINGLE_STEP(pTxnHdr, 0);
511    }
512
513
514    /* Memory address */
515    pTxnHdr = &(pPartitionRegTxn[0].tHdr);
516    BUILD_TTxnStruct(pTxnHdr, PARTITION_REGISTERS_ADDR+4,  &(pPartitionRegTxn[0].tData), REGISTER_SIZE, 0, 0)
517    twIf_SendTransaction (pTwIf, pTxnHdr);
518
519    /* Memory size */
520    pTxnHdr = &(pPartitionRegTxn[1].tHdr);
521    BUILD_TTxnStruct(pTxnHdr, PARTITION_REGISTERS_ADDR+0,  &(pPartitionRegTxn[1].tData), REGISTER_SIZE, 0, 0)
522    twIf_SendTransaction (pTwIf, pTxnHdr);
523
524    /* Registers address */
525    pTxnHdr = &(pPartitionRegTxn[2].tHdr);
526    BUILD_TTxnStruct(pTxnHdr, PARTITION_REGISTERS_ADDR+12, &(pPartitionRegTxn[2].tData), REGISTER_SIZE, 0, 0)
527    twIf_SendTransaction (pTwIf, pTxnHdr);
528
529    /* Registers size */
530    pTxnHdr = &(pPartitionRegTxn[3].tHdr);
531    BUILD_TTxnStruct(pTxnHdr, PARTITION_REGISTERS_ADDR+8,  &(pPartitionRegTxn[3].tData), REGISTER_SIZE, 0, 0)
532    eStatus = twIf_SendTransaction (pTwIf, pTxnHdr);
533
534 /* Registers address */
535    pTxnHdr = &(pPartitionRegTxn[4].tHdr);
536    BUILD_TTxnStruct(pTxnHdr, PARTITION_REGISTERS_ADDR+20,  &(pPartitionRegTxn[4].tData), REGISTER_SIZE, 0, 0)
537    twIf_SendTransaction (pTwIf, pTxnHdr);
538
539 /* Registers size */
540    pTxnHdr = &(pPartitionRegTxn[5].tHdr);
541    BUILD_TTxnStruct(pTxnHdr, PARTITION_REGISTERS_ADDR+16,  &(pPartitionRegTxn[5].tData), REGISTER_SIZE, 0, 0)
542    eStatus = twIf_SendTransaction (pTwIf, pTxnHdr);
543
544 /* Registers address */
545    pTxnHdr = &(pPartitionRegTxn[6].tHdr);
546    BUILD_TTxnStruct(pTxnHdr, PARTITION_REGISTERS_ADDR+24,  &(pPartitionRegTxn[6].tData), REGISTER_SIZE, twIf_PartitionTxnDoneCb, pTwIf)
547    twIf_SendTransaction (pTwIf, pTxnHdr);
548
549    /* If the transaction is done, free the allocated memory (otherwise freed in the partition CB) */
550    if (eStatus != TXN_STATUS_PENDING)
551    {
552        os_memoryFree (pTwIf->hOs, pPartitionRegTxn,7*sizeof(TPartitionRegTxn));
553    }
554}
555
556
557static void twIf_PartitionTxnDoneCb (TI_HANDLE hTwIf, void *hTxn)
558{
559    TTwIfObj *pTwIf = (TTwIfObj*) hTwIf;
560
561    /* Free the partition transaction buffer after completed (see transaction above) */
562    os_memoryFree (pTwIf->hOs,
563                   (char *)hTxn - (6 * sizeof(TPartitionRegTxn)),  /* Move back to the first Txn start */
564                   7 * sizeof(TPartitionRegTxn));
565}
566
567
568/**
569 * \fn     twIf_Awake
570 * \brief  Request to keep the device awake
571 *
572 * Used by the Xfer modules to request to keep the device awake until twIf_Sleep() is called.
573 * Each call to this function increments AwakeReq counter. Once the device is awake (upon transaction),
574 *     the TwIf SM keeps it awake as long as this counter is not zero.
575 *
576 * \note
577 * \param  hTwIf - The module's object
578 * \return void
579 * \sa     twIf_Sleep
580 */
581void twIf_Awake (TI_HANDLE hTwIf)
582{
583    TTwIfObj *pTwIf = (TTwIfObj*) hTwIf;
584
585    /* Increment awake requests counter */
586    pTwIf->uAwakeReqCount++;
587
588#ifdef TI_DBG
589    pTwIf->uDbgCountAwake++;
590    TRACE1(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_Awake: uAwakeReqCount = %d\n", pTwIf->uAwakeReqCount);
591#endif
592}
593
594
595/**
596 * \fn     twIf_Sleep
597 * \brief  Remove request to keep the device awake
598 *
599 * Each call to this function decrements AwakeReq counter.
600 * Once this counter is zeroed, if the TxnQ is empty (no WLAN transactions), the TwIf SM is
601 *     invoked to stop the TxnQ and enable the device to sleep (write 0 to ELP register).
602 *
603 * \note
604 * \param  hTwIf - The module's object
605 * \return void
606 * \sa     twIf_Awake
607 */
608void twIf_Sleep (TI_HANDLE hTwIf)
609{
610    TTwIfObj *pTwIf = (TTwIfObj*) hTwIf;
611
612    /* Decrement awake requests counter */
613    if (pTwIf->uAwakeReqCount > 0) /* in case of redundant call after recovery */
614    {
615    pTwIf->uAwakeReqCount--;
616    }
617
618#ifdef TI_DBG
619    pTwIf->uDbgCountSleep++;
620    TRACE1(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_Sleep: uAwakeReqCount = %d\n", pTwIf->uAwakeReqCount);
621#endif
622
623    /* If Awake not required and no pending transactions in TxnQ, issue Sleep event to SM */
624    if ((pTwIf->uAwakeReqCount == 0) && (pTwIf->uPendingTxnCount == 0))
625    {
626        twIf_HandleSmEvent (pTwIf, SM_EVENT_SLEEP);
627    }
628}
629
630
631/**
632 * \fn     twIf_HwAvailable
633 * \brief  The device is awake
634 *
635 * This is an indication from the FwEvent that the device is awake.
636 * Issue HW_AVAILABLE event to the SM.
637 *
638 * \note
639 * \param  hTwIf - The module's object
640 * \return void
641 * \sa
642 */
643void twIf_HwAvailable (TI_HANDLE hTwIf)
644{
645    TTwIfObj *pTwIf = (TTwIfObj*) hTwIf;
646
647    TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_HwAvailable: HW is Available\n");
648
649    /* Issue HW_AVAILABLE event to the SM */
650    twIf_HandleSmEvent (pTwIf, SM_EVENT_HW_AVAILABLE);
651}
652
653
654/**
655 * \fn     twIf_Transact
656 * \brief  Issue a transaction
657 *
658 * This method is used by the Xfer modules to issue all transaction types.
659 * Translate HW address according to bus partition and call twIf_SendTransaction().
660 *
661 * \note
662 * \param  hTwIf - The module's object
663 * \param  pTxn  - The transaction object
664 * \return COMPLETE if the transaction was completed in this context, PENDING if not, ERROR if failed
665 * \sa     twIf_SendTransaction
666 */
667ETxnStatus twIf_Transact (TI_HANDLE hTwIf, TTxnStruct *pTxn)
668{
669    TTwIfObj  *pTwIf   = (TTwIfObj*)hTwIf;
670
671    /* Translate HW address for registers region */
672    if ((pTxn->uHwAddr >= pTwIf->uMemAddr2) && (pTxn->uHwAddr <= pTwIf->uMemAddr2 + pTwIf->uMemSize2))
673    {
674        pTxn->uHwAddr = pTxn->uHwAddr - pTwIf->uMemAddr2 + pTwIf->uMemSize1;
675    }
676    /* Translate HW address for memory region */
677    else
678    {
679        pTxn->uHwAddr = pTxn->uHwAddr - pTwIf->uMemAddr1;
680    }
681
682    /* Regular transaction are not the last and are not single step (only ELP write is) */
683    TXN_PARAM_SET_MORE(pTxn, 1);
684    TXN_PARAM_SET_SINGLE_STEP(pTxn, 0);
685
686    /* Send the transaction to the TxnQ and update the SM if needed. */
687    return twIf_SendTransaction (pTwIf, pTxn);
688}
689
690ETxnStatus twIf_TransactReadFWStatus (TI_HANDLE hTwIf, TTxnStruct *pTxn)
691{
692    TTwIfObj  *pTwIf   = (TTwIfObj*)hTwIf;
693
694    /* Regular transaction are not the last and are not single step (only ELP write is) */
695    TXN_PARAM_SET_MORE(pTxn, 1);
696    TXN_PARAM_SET_SINGLE_STEP(pTxn, 0);
697
698    /* Send the transaction to the TxnQ and update the SM if needed. */
699    return twIf_SendTransaction (pTwIf, pTxn);
700}
701
702
703/**
704 * \fn     twIf_SendTransaction
705 * \brief  Send a transaction to the device
706 *
707 * This method is used by the Xfer modules and the TwIf to send all transaction types to the device.
708 * Send the transaction to the TxnQ and update the SM if needed.
709 *
710 * \note
711 * \param  pTwIf - The module's object
712 * \param  pTxn  - The transaction object
713 * \return COMPLETE if the transaction was completed in this context, PENDING if not, ERROR if failed
714 * \sa
715 */
716static ETxnStatus twIf_SendTransaction (TTwIfObj *pTwIf, TTxnStruct *pTxn)
717{
718    ETxnStatus eStatus;
719#ifdef TI_DBG
720    TI_UINT32  data = 0;
721
722    /* Verify that the Txn HW-Address is 4-bytes aligned */
723    if (pTxn->uHwAddr & 0x3)
724    {
725        TRACE2(pTwIf->hReport, REPORT_SEVERITY_ERROR, "twIf_SendTransaction: Unaligned HwAddr! HwAddr=0x%x, Params=0x%x\n", pTxn->uHwAddr, pTxn->uTxnParams);
726		return TXN_STATUS_ERROR;
727    }
728#endif
729
730    context_EnterCriticalSection (pTwIf->hContext);
731    /* increment pending Txn counter */
732    pTwIf->uPendingTxnCount++;
733    context_LeaveCriticalSection (pTwIf->hContext);
734
735    /* Send transaction to TxnQ */
736    eStatus = txnQ_Transact(pTwIf->hTxnQ, pTxn);
737
738#ifdef TI_DBG
739    pTwIf->uDbgCountTxn++;
740    if      (eStatus == TXN_STATUS_COMPLETE) { pTwIf->uDbgCountTxnComplete++; }
741    else if (eStatus == TXN_STATUS_PENDING ) { pTwIf->uDbgCountTxnPending++;  }
742
743	COPY_WLAN_LONG(&data,&(pTxn->aBuf[0]));
744    TRACE8(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_SendTransaction: Status = %d, Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d, Data=0x%x \n", eStatus, pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0], pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3],data);
745#endif
746
747    /* If Txn status is PENDING issue Start event to the SM */
748    if (eStatus == TXN_STATUS_PENDING)
749    {
750        twIf_HandleSmEvent (pTwIf, SM_EVENT_START);
751    }
752
753    /* Else (COMPLETE or ERROR) */
754    else
755    {
756        context_EnterCriticalSection (pTwIf->hContext);
757        /* decrement pending Txn counter in case of sync transact*/
758        pTwIf->uPendingTxnCount--;
759        context_LeaveCriticalSection (pTwIf->hContext);
760
761        /* If Awake not required and no pending transactions in TxnQ, issue Sleep event to SM */
762        if ((pTwIf->uAwakeReqCount == 0) && (pTwIf->uPendingTxnCount == 0))
763        {
764            twIf_HandleSmEvent (pTwIf, SM_EVENT_SLEEP);
765        }
766
767        /* If Txn failed and error CB available, call it to initiate recovery */
768        if (eStatus == TXN_STATUS_ERROR)
769        {
770            TRACE6(pTwIf->hReport, REPORT_SEVERITY_ERROR, "twIf_SendTransaction: Txn failed!!  Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n", pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0], pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3]);
771
772            if (pTwIf->fErrCb)
773            {
774                pTwIf->fErrCb (pTwIf->hErrCb, BUS_FAILURE);
775            }
776        }
777    }
778
779    /* Return the Txn status (COMPLETE if completed in this context, PENDING if not, ERROR if failed) */
780    return eStatus;
781}
782
783/**
784 * \fn     twIf_HandleSmEvent
785 * \brief  The TwIf SM implementation
786 *
787 * Handle SM event.
788 * Control the device awake/sleep states and the TxnQ run/stop states according to the event.
789 *
790 * \note
791 * \param  hTwIf - The module's object
792 * \return void
793 * \sa
794 */
795static void twIf_HandleSmEvent (TTwIfObj *pTwIf, ESmEvent eEvent)
796{
797	ESmState eState = pTwIf->eState;  /* The state before handling the event */
798
799    /* Switch by current state and handle event */
800    switch (eState)
801    {
802    case SM_STATE_AWAKE:
803        /* SLEEP event:  AWAKE ==> SLEEP,  stop TxnQ and set ELP reg to sleep */
804        if (eEvent == SM_EVENT_SLEEP)
805        {
806            pTwIf->eState = SM_STATE_SLEEP;
807            txnQ_Stop (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN);
808            twIf_WriteElpReg (pTwIf, ELP_CTRL_REG_SLEEP);
809        }
810        break;
811    case SM_STATE_SLEEP:
812        /* START event:  SLEEP ==> WAIT_HW,  set ELP reg to wake-up */
813        if (eEvent == SM_EVENT_START)
814        {
815            pTwIf->eState = SM_STATE_WAIT_HW;
816            twIf_WriteElpReg (pTwIf, ELP_CTRL_REG_AWAKE);
817        }
818        /* HW_AVAILABLE event:  SLEEP ==> AWAKE,  set ELP reg to wake-up and run TxnQ */
819        else if (eEvent == SM_EVENT_HW_AVAILABLE)
820        {
821            pTwIf->eState = SM_STATE_AWAKE;
822            twIf_WriteElpReg (pTwIf, ELP_CTRL_REG_AWAKE);
823            txnQ_Run (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN);
824        }
825        break;
826    case SM_STATE_WAIT_HW:
827        /* HW_AVAILABLE event:  WAIT_HW ==> AWAKE,  run TxnQ */
828        if (eEvent == SM_EVENT_HW_AVAILABLE)
829        {
830            pTwIf->eState = SM_STATE_AWAKE;
831            txnQ_Run (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN);
832        }
833        break;
834    }
835
836	TRACE3(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_HandleSmEvent: <currentState = %d, event = %d> --> nextState = %d\n", eState, eEvent, pTwIf->eState);
837}
838
839
840/**
841 * \fn     twIf_TxnDoneCb
842 * \brief  Transaction completion CB
843 *
844 * This callback is called by the TxnQ upon transaction completion, unless is was completed in
845 *     the original context where it was issued.
846 * It may be called from bus driver external context (TxnDone ISR) or from WLAN driver context.
847 *
848 * \note
849 * \param  hTwIf - The module's object
850 * \param  pTxn  - The completed transaction object
851 * \return void
852 * \sa     twIf_HandleTxnDone
853 */
854static void twIf_TxnDoneCb (TI_HANDLE hTwIf, TTxnStruct *pTxn)
855{
856    TTwIfObj *pTwIf = (TTwIfObj*)hTwIf;
857
858#ifdef TI_DBG
859    pTwIf->uDbgCountTxnDoneCb++;
860    TRACE6(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_TxnDoneCb: Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n", pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0], pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3]);
861#endif
862
863    /* In case of recovery flag, Call directly restart callback */
864    if (TXN_PARAM_GET_STATUS(pTxn) == TXN_PARAM_STATUS_RECOVERY)
865    {
866        if (pTwIf->fRecoveryCb)
867        {
868            TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_TxnDoneCb: During Recovery\n");
869            pTwIf->bTxnDoneInRecovery = TI_TRUE;
870            /* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
871            context_RequestSchedule (pTwIf->hContext, pTwIf->uContextId);
872            return;
873        }
874    }
875
876    /* If the completed Txn is ELP, nothing to do (not counted) so exit */
877    if (TXN_PARAM_GET_SINGLE_STEP(pTxn))
878    {
879        return;
880    }
881
882    if (pTxn->fTxnDoneCb)
883    {
884        TI_STATUS eStatus;
885
886        /* In critical section, enqueue the completed transaction in the TxnDoneQ. */
887        context_EnterCriticalSection (pTwIf->hContext);
888        eStatus = que_Enqueue (pTwIf->hTxnDoneQueue, (TI_HANDLE)pTxn);
889        if (eStatus != TI_OK)
890        {
891            TRACE3(pTwIf->hReport, REPORT_SEVERITY_ERROR, "twIf_TxnDoneCb(): Enqueue failed, pTxn=0x%x, HwAddr=0x%x, Len0=%d\n", pTxn, pTxn->uHwAddr, pTxn->aLen[0]);
892        }
893        context_LeaveCriticalSection (pTwIf->hContext);
894    }
895    else
896    {
897        context_EnterCriticalSection (pTwIf->hContext);
898         /* Decrement pending Txn counter, It's value will be checked in twIf_HandleTxnDone() */
899        if (pTwIf->uPendingTxnCount > 0) /* in case of callback on recovery after restart */
900        {
901            pTwIf->uPendingTxnCount--;
902        }
903        context_LeaveCriticalSection (pTwIf->hContext);
904
905    }
906
907    /* Request schedule to continue handling in driver context (will call twIf_HandleTxnDone()) */
908    context_RequestSchedule (pTwIf->hContext, pTwIf->uContextId);
909}
910
911/**
912 * \fn     twIf_HandleTxnDone
913 * \brief  Completed transactions handler
914 *
915 * The completed transactions handler, called upon TxnDone event, either from the context engine
916 *     or directly from twIf_TxnDoneCb() if we are already in the WLAN driver's context.
917 * Dequeue all completed transactions in critical section, and call their callbacks if available.
918 * If awake is not required and no pending transactions in TxnQ, issue Sleep event to SM.
919 *
920 * \note
921 * \param  hTwIf - The module's object
922 * \return void
923 * \sa
924 */
925static void twIf_HandleTxnDone (TI_HANDLE hTwIf)
926{
927    TTwIfObj   *pTwIf = (TTwIfObj*)hTwIf;
928    TTxnStruct *pTxn;
929
930    /* In case of recovery, call the recovery callback and exit */
931    if (pTwIf->bTxnDoneInRecovery)
932    {
933        TRACE0(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_HandleTxnDone: call RecoveryCb\n");
934        pTwIf->bTxnDoneInRecovery = TI_FALSE;
935        if (pTwIf->bPendRestartTimerRunning)
936        {
937            tmr_StopTimer (pTwIf->hPendRestartTimer);
938            pTwIf->bPendRestartTimerRunning = TI_FALSE;
939        }
940        pTwIf->fRecoveryCb(pTwIf->hRecoveryCb);
941        return;
942    }
943
944    /* Loop while there are completed transactions to handle */
945    while (1)
946    {
947        /* In critical section, dequeue completed transaction from the TxnDoneQ. */
948        context_EnterCriticalSection (pTwIf->hContext);
949        pTxn = (TTxnStruct *) que_Dequeue (pTwIf->hTxnDoneQueue);
950        context_LeaveCriticalSection (pTwIf->hContext);
951
952        /* If no more transactions to handle, exit */
953        if (pTxn != NULL)
954        {
955            context_EnterCriticalSection (pTwIf->hContext);
956            /* Decrement pending Txn counter */
957            if (pTwIf->uPendingTxnCount > 0) /* in case of callback on recovery after restart */
958            {
959                pTwIf->uPendingTxnCount--;
960            }
961            context_LeaveCriticalSection (pTwIf->hContext);
962
963            TRACE4(pTwIf->hReport, REPORT_SEVERITY_INFORMATION, "twIf_HandleTxnDone: Completed-Txn: Params=0x%x, HwAddr=0x%x, Len0=%d, fTxnDoneCb=0x%x\n", pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0], pTxn->fTxnDoneCb);
964
965            /* If Txn failed and error CB available, call it to initiate recovery */
966            if (TXN_PARAM_GET_STATUS(pTxn) == TXN_PARAM_STATUS_ERROR)
967            {
968                TRACE6(pTwIf->hReport, REPORT_SEVERITY_ERROR, "twIf_HandleTxnDone: Txn failed!!  Params=0x%x, HwAddr=0x%x, Len0=%d, Len1=%d, Len2=%d, Len3=%d\n", pTxn->uTxnParams, pTxn->uHwAddr, pTxn->aLen[0], pTxn->aLen[1], pTxn->aLen[2], pTxn->aLen[3]);
969
970                if (pTwIf->fErrCb)
971                {
972                    pTwIf->fErrCb (pTwIf->hErrCb, BUS_FAILURE);
973                }
974                /* in error do not continue */
975		return;
976            }
977
978            /* If Txn specific CB available, call it (may free Txn resources and issue new Txns) */
979            if (pTxn->fTxnDoneCb != NULL)
980            {
981                ((TTxnDoneCb)(pTxn->fTxnDoneCb)) (pTxn->hCbHandle, pTxn);
982            }
983        }
984
985        /*If uPendingTxnCount == 0 and awake not required, issue Sleep event to SM */
986        if ((pTwIf->uAwakeReqCount == 0) && (pTwIf->uPendingTxnCount == 0))
987        {
988            twIf_HandleSmEvent (pTwIf, SM_EVENT_SLEEP);
989        }
990
991        if (pTxn == NULL)
992        {
993            return;
994        }
995    }
996}
997
998/**
999 * \fn     twIf_ClearTxnDoneQueue
1000 * \brief  Clean the DoneQueue
1001 *
1002 * Clear the specified done queue - don't call the callbacks.
1003 *
1004 * \note
1005 * \param  hTwIf - The module's object
1006 * \return void
1007 * \sa
1008 */
1009static void twIf_ClearTxnDoneQueue (TI_HANDLE hTwIf)
1010{
1011    TTwIfObj   *pTwIf = (TTwIfObj*)hTwIf;
1012    TTxnStruct *pTxn;
1013
1014    /* Loop while there are completed transactions to handle */
1015    while (1)
1016    {
1017        /* In critical section, dequeue completed transaction from the TxnDoneQ. */
1018        context_EnterCriticalSection (pTwIf->hContext);
1019        pTxn = (TTxnStruct *) que_Dequeue (pTwIf->hTxnDoneQueue);
1020        context_LeaveCriticalSection (pTwIf->hContext);
1021
1022        /* If no more transactions to handle, exit */
1023        if (pTxn != NULL)
1024        {
1025            /* Decrement pending Txn counter */
1026            if (pTwIf->uPendingTxnCount > 0) /* in case of callback on recovery after restart */
1027            {
1028                pTwIf->uPendingTxnCount--;
1029            }
1030
1031            /*
1032             * Drop on Recovery
1033             * do not call pTxn->fTxnDoneCb (pTxn->hCbHandle, pTxn) callback
1034             */
1035        }
1036
1037        if (pTxn == NULL)
1038        {
1039            return;
1040        }
1041    }
1042}
1043
1044
1045/**
1046 * \fn     twIf_PendRestratTimeout
1047 * \brief  Pending restart process timeout handler
1048 *
1049 * Called if timer expires upon fail to complete the last bus transaction that was
1050 *   pending during restart process.
1051 * Calls the recovery callback to continue the restart process.
1052 *
1053 * \note
1054 * \param  hTwIf - The module's object
1055 * \return void
1056 * \sa
1057 */
1058static void twIf_PendRestratTimeout (TI_HANDLE hTwIf, TI_BOOL bTwdInitOccured)
1059{
1060    TTwIfObj *pTwIf = (TTwIfObj*)hTwIf;
1061
1062    TRACE0(pTwIf->hReport, REPORT_SEVERITY_ERROR, "twIf_PendRestratTimeout: restart timer expired!\n");
1063
1064    pTwIf->bPendRestartTimerRunning = TI_FALSE;
1065
1066    /* Clear the Txn queues since TxnDone wasn't called so it wasn't done by the TxnQ module */
1067    txnQ_ClearQueues (pTwIf->hTxnQ, TXN_FUNC_ID_WLAN);
1068
1069    /* Call the recovery callback to continue the restart process */
1070    pTwIf->fRecoveryCb(pTwIf->hRecoveryCb);
1071}
1072
1073
1074TI_BOOL	twIf_isValidMemoryAddr(TI_HANDLE hTwIf, TI_UINT32 Address, TI_UINT32 Length)
1075{
1076    TTwIfObj   *pTwIf = (TTwIfObj*)hTwIf;
1077
1078	if ((Address >= pTwIf->uMemAddr1) &&
1079			(Address + Length < pTwIf->uMemAddr1 + pTwIf->uMemSize1 ))
1080	return TI_TRUE;
1081
1082	return TI_FALSE;
1083}
1084
1085TI_BOOL	twIf_isValidRegAddr(TI_HANDLE hTwIf, TI_UINT32 Address, TI_UINT32 Length)
1086{
1087    TTwIfObj   *pTwIf = (TTwIfObj*)hTwIf;
1088
1089	if ((Address >= pTwIf->uMemAddr2 ) &&
1090		( Address < pTwIf->uMemAddr2 + pTwIf->uMemSize2 ))
1091	return TI_TRUE;
1092
1093	return TI_FALSE;
1094}
1095
1096/*******************************************************************************
1097*                       DEBUG  FUNCTIONS  IMPLEMENTATION					   *
1098********************************************************************************/
1099
1100#ifdef TI_DBG
1101
1102/**
1103 * \fn     twIf_PrintModuleInfo
1104 * \brief  Print module's parameters (debug)
1105 *
1106 * This function prints the module's parameters.
1107 *
1108 * \note
1109 * \param  hTwIf - The module's object
1110 * \return void
1111 * \sa
1112 */
1113void twIf_PrintModuleInfo (TI_HANDLE hTwIf)
1114{
1115#ifdef REPORT_LOG
1116	TTwIfObj *pTwIf = (TTwIfObj*)hTwIf;
1117
1118	WLAN_OS_REPORT(("-------------- TwIf Module Info-- ------------------------\n"));
1119	WLAN_OS_REPORT(("==========================================================\n"));
1120	WLAN_OS_REPORT(("eSmState             = %d\n",   pTwIf->eState					));
1121	WLAN_OS_REPORT(("uContextId           = %d\n",   pTwIf->uContextId              ));
1122	WLAN_OS_REPORT(("fErrCb               = %d\n",   pTwIf->fErrCb                  ));
1123	WLAN_OS_REPORT(("hErrCb               = %d\n",   pTwIf->hErrCb                  ));
1124	WLAN_OS_REPORT(("uAwakeReqCount       = %d\n",   pTwIf->uAwakeReqCount          ));
1125	WLAN_OS_REPORT(("uPendingTxnCount     = %d\n",   pTwIf->uPendingTxnCount        ));
1126	WLAN_OS_REPORT(("uMemAddr             = 0x%x\n", pTwIf->uMemAddr1               ));
1127	WLAN_OS_REPORT(("uMemSize             = 0x%x\n", pTwIf->uMemSize1               ));
1128	WLAN_OS_REPORT(("uRegAddr             = 0x%x\n", pTwIf->uMemAddr2               ));
1129	WLAN_OS_REPORT(("uRegSize             = 0x%x\n", pTwIf->uMemSize2               ));
1130	WLAN_OS_REPORT(("uDbgCountAwake       = %d\n",   pTwIf->uDbgCountAwake          ));
1131	WLAN_OS_REPORT(("uDbgCountSleep       = %d\n",   pTwIf->uDbgCountSleep          ));
1132	WLAN_OS_REPORT(("uDbgCountTxn         = %d\n",   pTwIf->uDbgCountTxn            ));
1133	WLAN_OS_REPORT(("uDbgCountTxnPending  = %d\n",   pTwIf->uDbgCountTxnPending     ));
1134	WLAN_OS_REPORT(("uDbgCountTxnComplete = %d\n",   pTwIf->uDbgCountTxnComplete    ));
1135	WLAN_OS_REPORT(("uDbgCountTxnDone     = %d\n",   pTwIf->uDbgCountTxnDoneCb      ));
1136	WLAN_OS_REPORT(("==========================================================\n\n"));
1137#endif
1138}
1139
1140
1141void twIf_PrintQueues (TI_HANDLE hTwIf)
1142{
1143    TTwIfObj *pTwIf = (TTwIfObj*)hTwIf;
1144
1145    txnQ_PrintQueues(pTwIf->hTxnQ);
1146}
1147
1148#endif /* TI_DBG */
1149