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 */
85 typedef 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 */
93 typedef 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 */
101 typedef 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 */
111 typedef 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 */
119 typedef 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 */
127 typedef 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 */
135 typedef 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 ************************************************************************/
182 static void twIf_WriteElpReg (TTwIfObj *pTwIf, TI_UINT32 uValue);
183 static void twIf_PartitionTxnDoneCb (TI_HANDLE hTwIf, void *hTxn);
184 static ETxnStatus twIf_SendTransaction (TTwIfObj *pTwIf, TTxnStruct *pTxn);
185 static void twIf_HandleSmEvent (TTwIfObj *pTwIf, ESmEvent eEvent);
186 static void twIf_TxnDoneCb (TI_HANDLE hTwIf, TTxnStruct *pTxn);
187 static void twIf_HandleTxnDone (TI_HANDLE hTwIf);
188 static 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 */
twIf_Create(TI_HANDLE hOs)207 TI_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 */
twIf_Destroy(TI_HANDLE hTwIf)237 TI_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 */
twIf_Init(TI_HANDLE hTwIf,TI_HANDLE hReport,TI_HANDLE hContext,TI_HANDLE hTxnQ,TRecoveryCb fRecoveryCb,TI_HANDLE hRecoveryCb)268 void 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 */
twIf_Restart(TI_HANDLE hTwIf)338 ETxnStatus 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 */
twIf_RegisterErrCb(TI_HANDLE hTwIf,void * fErrCb,TI_HANDLE hErrCb)368 void 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 */
twIf_WriteElpReg(TTwIfObj * pTwIf,TI_UINT32 uValue)388 static 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
twIf_SetPartition(TI_HANDLE hTwIf,TPartition * pPartition)427 void 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
twIf_PartitionTxnDoneCb(TI_HANDLE hTwIf,void * hTxn)515 static 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 */
twIf_Awake(TI_HANDLE hTwIf)539 void 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 */
twIf_Sleep(TI_HANDLE hTwIf)566 void 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 */
twIf_HwAvailable(TI_HANDLE hTwIf)601 void 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 */
twIf_Transact(TI_HANDLE hTwIf,TTxnStruct * pTxn)625 ETxnStatus 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
twIf_TransactReadFWStatus(TI_HANDLE hTwIf,TTxnStruct * pTxn)648 ETxnStatus 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 */
twIf_SendTransaction(TTwIfObj * pTwIf,TTxnStruct * pTxn)674 static 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 */
twIf_HandleSmEvent(TTwIfObj * pTwIf,ESmEvent eEvent)753 static 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 */
twIf_TxnDoneCb(TI_HANDLE hTwIf,TTxnStruct * pTxn)812 static 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 */
twIf_HandleTxnDone(TI_HANDLE hTwIf)877 static 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 */
twIf_ClearTxnDoneQueue(TI_HANDLE hTwIf)956 static 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 }
twIf_isValidMemoryAddr(TI_HANDLE hTwIf,TI_UINT32 Address,TI_UINT32 Length)990 TI_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
twIf_isValidRegAddr(TI_HANDLE hTwIf,TI_UINT32 Address,TI_UINT32 Length)1001 TI_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 */
twIf_PrintModuleInfo(TI_HANDLE hTwIf)1029 void 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
twIf_PrintQueues(TI_HANDLE hTwIf)1057 void twIf_PrintQueues (TI_HANDLE hTwIf)
1058 {
1059 TTwIfObj *pTwIf = (TTwIfObj*)hTwIf;
1060
1061 txnQ_PrintQueues(pTwIf->hTxnQ);
1062 }
1063
1064 #endif /* TI_DBG */
1065