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