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