Home | History | Annotate | Download | only in FW_Transfer
      1 /*
      2  * FwEvent.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  FwEvent.c
     36  *  \brief Handle firmware events
     37  *
     38  *
     39  * \par Description
     40  *      Call the appropriate event handler.
     41  *
     42  *  \see FwEvent.h
     43  */
     44 
     45 #define __FILE_ID__  FILE_ID_104
     46 #include "tidef.h"
     47 #include "report.h"
     48 #include "context.h"
     49 #include "osApi.h"
     50 #include "TWDriver.h"
     51 #include "TWDriverInternal.h"
     52 #include "txResult_api.h"
     53 #include "CmdMBox_api.h"
     54 #include "rxXfer_api.h"
     55 #include "txXfer_api.h"
     56 #include "txHwQueue_api.h"
     57 #include "eventMbox_api.h"
     58 #include "TwIf.h"
     59 #include "public_host_int.h"
     60 #include "FwEvent_api.h"
     61 #ifdef TI_DBG
     62     #include "tracebuf_api.h"
     63 #endif
     64 #include "bmtrace_api.h"
     65 
     66 
     67 #ifdef _VLCT_
     68 extern int trigger_another_read;
     69 #endif
     70 
     71 
     72 #define FW_STATUS_ADDR (0x14FC0 + 0xA000)
     73 
     74 #define ALL_EVENTS_VECTOR        ACX_INTR_WATCHDOG | ACX_INTR_INIT_COMPLETE | ACX_INTR_EVENT_A |\
     75                                  ACX_INTR_EVENT_B | ACX_INTR_CMD_COMPLETE |ACX_INTR_HW_AVAILABLE |\
     76                                  ACX_INTR_DATA
     77 
     78 #define ALL_EVENTS_VECTOR_NEGATE 0xFFFFFFC0
     79 
     80 
     81 #define TXN_FW_EVENT_SET_MASK_ADDR(pFwEvent)      pFwEvent->tMaskTxn.tTxnStruct.uHwAddr = HINT_MASK;
     82 #define TXN_FW_EVENT_SET_UNMASK_ADDR(pFwEvent)    pFwEvent->tUnMaskTxn.tTxnStruct.uHwAddr = HINT_MASK;
     83 #define TXN_FW_EVENT_SET_FW_STAT_ADDR(pFwEvent)   pFwEvent->tFwStatusTxn.tTxnStruct.uHwAddr = FW_STATUS_ADDR;
     84 
     85 
     86 typedef enum
     87 {
     88     FW_EVENT_STATE_IDLE,
     89     FW_EVENT_STATE_READING
     90 
     91 } EFwEventState;
     92 
     93 typedef struct
     94 {
     95     TTxnStruct              tTxnStruct;
     96     TI_UINT32               uData;
     97 
     98 } TRegisterTxn;
     99 
    100 typedef struct
    101 {
    102     TTxnStruct     tTxnStruct;
    103     FwStatus_t     tFwStatus;
    104 
    105 } TFwStatusTxn;
    106 
    107 /* The FwEvent module's main structure */
    108 typedef struct
    109 {
    110     EFwEventState       eFwEventState;           	/* State machine state */
    111     TI_UINT32           uEventMask;              	/* Static interrupt event mask */
    112     TI_UINT32           uEventVector;               /* Saves the current active FW interrupts */
    113     TI_BOOL             bIsActualFwInterrupt;       /* Indicates that we are working on a real interrupt from the FW */
    114     TRegisterTxn        tMaskTxn;
    115     TRegisterTxn        tUnMaskTxn;
    116     TFwStatusTxn        tFwStatusTxn;               /* The FW status structure transaction (read from FW memory) */
    117 
    118     TI_UINT32           uFwTimeOffset;              /* Offset in microseconds between driver and FW clocks */
    119     TI_BOOL             bEmulateRxIntr;             /* Indicate to call Rx interrupt handler even if not issued */
    120 
    121     /* Other modules handles */
    122     TI_HANDLE           hOs;
    123     TI_HANDLE           hTWD;
    124     TI_HANDLE           hReport;
    125     TI_HANDLE           hContext;
    126     TI_UINT32           uContextId;
    127     TI_HANDLE           hTwIf;
    128     TI_HANDLE           hHealthMonitor;
    129     TI_HANDLE           hEventMbox;
    130     TI_HANDLE           hCmdMbox;
    131     TI_HANDLE           hRxXfer;
    132     TI_HANDLE           hTxXfer;
    133     TI_HANDLE           hTxHwQueue;
    134     TI_HANDLE           hTxResult;
    135 
    136 } TfwEvent;
    137 
    138 
    139 static void fwEvent_CallHandler     (TI_HANDLE hFwEvent);
    140 static void fwEvent_Handle          (TI_HANDLE hFwEvent);
    141 static void fwEvent_ReadCompleteCb  (TI_HANDLE hFwEvent);
    142 
    143 
    144 
    145 
    146 /*
    147  * \brief	Create the FwEvent module object
    148  *
    149  * \param  hOs  - OS module object handle
    150  * \return Handle to the created object
    151  *
    152  * \par Description
    153  * Calling this function creates a FwEvent object
    154  *
    155  * \sa fwEvent_Destroy
    156  */
    157 TI_HANDLE fwEvent_Create (TI_HANDLE hOs)
    158 {
    159     TfwEvent *pFwEvent;
    160 
    161     pFwEvent = os_memoryAlloc (hOs, sizeof(TfwEvent));
    162     if (pFwEvent == NULL)
    163     {
    164         return NULL;
    165     }
    166 
    167     os_memoryZero (hOs, pFwEvent, sizeof(TfwEvent));
    168 
    169     pFwEvent->hOs = hOs;
    170 
    171     return (TI_HANDLE)pFwEvent;
    172 }
    173 
    174 
    175 /*
    176  * \brief	Destroys the FwEvent object
    177  *
    178  * \param  hFwEvent  - The object to free
    179  * \return TI_OK
    180  *
    181  * \par Description
    182  * Calling this function destroys a FwEvent object
    183  *
    184  * \sa fwEvent_Create
    185  */
    186 TI_STATUS fwEvent_Destroy (TI_HANDLE hFwEvent)
    187 {
    188     TfwEvent *pFwEvent = (TfwEvent *)hFwEvent;
    189 
    190     if (pFwEvent)
    191     {
    192         os_memoryFree (pFwEvent->hOs, pFwEvent, sizeof(TfwEvent));
    193     }
    194 
    195     return TI_OK;
    196 }
    197 
    198 
    199 /*
    200  * \brief	Config the FwEvent module object
    201  *
    202  * \param  hFwEvent  - FwEvent Driver handle
    203  * \param  hTWD  - Handle to TWD module
    204  * \return TI_OK
    205  *
    206  * \par Description
    207  * From hTWD we extract : hOs, hReport, hTwIf, hContext,
    208  *      hHealthMonitor, hEventMbox, hCmdMbox, hRxXfer,
    209  *      hTxHwQueue, hTxResult
    210  * In this function we also register the FwEvent to the context engine
    211  *
    212  * \sa
    213  */
    214 TI_STATUS fwEvent_Init (TI_HANDLE hFwEvent, TI_HANDLE hTWD)
    215 {
    216     TfwEvent  *pFwEvent = (TfwEvent *)hFwEvent;
    217     TTwd      *pTWD = (TTwd *)hTWD;
    218     TTxnStruct* pTxn;
    219 
    220     pFwEvent->hTWD              = hTWD;
    221     pFwEvent->hOs               = pTWD->hOs;
    222     pFwEvent->hReport           = pTWD->hReport;
    223     pFwEvent->hContext          = pTWD->hContext;
    224     pFwEvent->hTwIf             = pTWD->hTwIf;
    225     pFwEvent->hHealthMonitor    = pTWD->hHealthMonitor;
    226     pFwEvent->hEventMbox        = pTWD->hEventMbox;
    227     pFwEvent->hCmdMbox          = pTWD->hCmdMbox;
    228     pFwEvent->hRxXfer           = pTWD->hRxXfer;
    229     pFwEvent->hTxHwQueue        = pTWD->hTxHwQueue;
    230     pFwEvent->hTxXfer           = pTWD->hTxXfer;
    231     pFwEvent->hTxResult         = pTWD->hTxResult;
    232 
    233     pFwEvent->eFwEventState       = FW_EVENT_STATE_IDLE;
    234     pFwEvent->uEventMask          = 0;
    235     pFwEvent->uEventVector        = 0;
    236     pFwEvent->bIsActualFwInterrupt = TI_FALSE;
    237     pFwEvent->bEmulateRxIntr      = TI_FALSE;
    238 
    239     pTxn = (TTxnStruct*)&pFwEvent->tMaskTxn.tTxnStruct;
    240     TXN_PARAM_SET(pTxn, TXN_HIGH_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
    241     BUILD_TTxnStruct(pTxn, HINT_MASK, &pFwEvent->tMaskTxn.uData, REGISTER_SIZE, NULL, NULL)
    242 
    243     pTxn = (TTxnStruct*)&pFwEvent->tUnMaskTxn.tTxnStruct;
    244     TXN_PARAM_SET(pTxn, TXN_HIGH_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_WRITE, TXN_INC_ADDR)
    245     BUILD_TTxnStruct(pTxn, HINT_MASK, &pFwEvent->tUnMaskTxn.uData, REGISTER_SIZE, NULL, NULL)
    246 
    247 
    248     pTxn = (TTxnStruct*)&pFwEvent->tFwStatusTxn.tTxnStruct;
    249     TXN_PARAM_SET(pTxn, TXN_HIGH_PRIORITY, TXN_FUNC_ID_WLAN, TXN_DIRECTION_READ, TXN_INC_ADDR)
    250     BUILD_TTxnStruct(pTxn, FW_STATUS_ADDR, &pFwEvent->tFwStatusTxn.tFwStatus, sizeof(FwStatus_t), (TTxnDoneCb)fwEvent_ReadCompleteCb, hFwEvent)
    251 
    252     /*
    253      *  Register the FwEvent to the context engine and get the client ID.
    254      *  The FwEvent() will be called from the context_DriverTask() after scheduled
    255      *    by a FW-Interrupt (see fwEvent_InterruptRequest()).
    256      */
    257     pFwEvent->uContextId = context_RegisterClient (pFwEvent->hContext,
    258                                                    fwEvent_Handle,
    259                                                    hFwEvent,
    260                                                    TI_FALSE,
    261                                                    "FW_EVENT",
    262                                                    sizeof("FW_EVENT"));
    263 
    264     return TI_OK;
    265 }
    266 
    267 
    268 /*
    269  * \brief	Call FwEvent client's event handler
    270  *
    271  * \param  hFwEvent  - FwEvent Driver handle
    272  * \return void
    273  *
    274  * \par Description
    275  *
    276  * \sa fwEvent_ReadCompleteCb
    277  */
    278 static void fwEvent_CallHandler (TI_HANDLE hFwEvent)
    279 {
    280     TfwEvent   *pFwEvent = (TfwEvent *)hFwEvent;
    281 
    282     if (pFwEvent->uEventVector & ACX_INTR_WATCHDOG)
    283     {
    284         /* Fw watchdog timeout has occured */
    285         TWD_WdExpireEvent (pFwEvent->hTWD);
    286     }
    287 
    288     if (pFwEvent->uEventVector & ACX_INTR_INIT_COMPLETE)
    289     {
    290         TRACE0(pFwEvent->hReport, REPORT_SEVERITY_INFORMATION, "fwEvent_CallHandler: INIT_COMPLETE\n");
    291     }
    292 	/* Change to handle the command MBOX before the event MBOX to maintain order for WHA command response
    293 	 * and follow command complete
    294 	 */
    295     if (pFwEvent->uEventVector & ACX_INTR_CMD_COMPLETE)
    296     {
    297         /* Command Mbox completed */
    298         cmdMbox_CommandComplete(pFwEvent->hCmdMbox);
    299     }
    300     if (pFwEvent->uEventVector & ACX_INTR_EVENT_A)
    301     {
    302         eventMbox_Handle(pFwEvent->hEventMbox,&pFwEvent->tFwStatusTxn.tFwStatus);
    303     }
    304     if (pFwEvent->uEventVector & ACX_INTR_EVENT_B)
    305     {
    306         eventMbox_Handle(pFwEvent->hEventMbox,&pFwEvent->tFwStatusTxn.tFwStatus);
    307     }
    308 
    309 
    310     /* The DATA interrupt is shared by all data path events, so call all Tx and Rx clients */
    311     if (pFwEvent->uEventVector & ACX_INTR_DATA)
    312     {
    313         rxXfer_RxEvent (pFwEvent->hRxXfer, &pFwEvent->tFwStatusTxn.tFwStatus);
    314 
    315         txHwQueue_UpdateFreeResources (pFwEvent->hTxHwQueue, &pFwEvent->tFwStatusTxn.tFwStatus);
    316 
    317         txResult_TxCmpltIntrCb (pFwEvent->hTxResult, &pFwEvent->tFwStatusTxn.tFwStatus);
    318     }
    319     else if (pFwEvent->bEmulateRxIntr)
    320     {
    321         pFwEvent->bEmulateRxIntr = TI_FALSE;
    322         rxXfer_RxEvent (pFwEvent->hRxXfer, &pFwEvent->tFwStatusTxn.tFwStatus);
    323     }
    324 
    325     /* After handling all raised bits, we can negate them */
    326     pFwEvent->tFwStatusTxn.tFwStatus.intrStatus &= pFwEvent->uEventMask;
    327 }
    328 
    329 
    330 /*
    331  * \brief	Requests the context engine to schedule the driver task
    332  *
    333  * \param  hFwEvent  - FwEvent Driver handle
    334  * \return void
    335  *
    336  * \par Description
    337  * Called by the FW-Interrupt ISR.
    338  * Requests the context engine to schedule the driver task
    339  * for handling the FW-Events (FwEvent callback).
    340  *
    341  * \sa
    342  */
    343 void fwEvent_InterruptRequest (TI_HANDLE hFwEvent)
    344 {
    345     TfwEvent *pFwEvent = (TfwEvent *)hFwEvent;
    346     CL_TRACE_START_L1();
    347 
    348     /* Indicate that we are handling an actual FW interrupt (for FW time setting) */
    349     pFwEvent->bIsActualFwInterrupt = TI_TRUE;
    350 
    351     /* Request switch to driver context for handling the FW-Interrupt event */
    352     context_RequestSchedule (pFwEvent->hContext, pFwEvent->uContextId);
    353 
    354     CL_TRACE_END_L1("tiwlan_drv.ko", "FwEvent", "IRQ", "");
    355 }
    356 
    357 
    358 /*
    359  * \brief	Handle the FW interrupts
    360  *
    361  * \param  hFwEvent  - FwEvent Driver handle
    362  * \return void
    363  *
    364  * \par Description
    365  * Called from context module upon receiving FW interrupt
    366  * The function mask the interrupts and reads the FW status
    367  *
    368  * \sa
    369  */
    370 
    371 static void fwEvent_Handle (TI_HANDLE hFwEvent)
    372 {
    373     TfwEvent   *pFwEvent = (TfwEvent *)hFwEvent;
    374     ETxnStatus rc;
    375     CL_TRACE_START_L2();
    376 
    377     if (pFwEvent->eFwEventState != FW_EVENT_STATE_IDLE)
    378     {
    379         if (pFwEvent->bIsActualFwInterrupt)
    380         {
    381             os_InterruptServiced (pFwEvent->hOs);
    382             twIf_HwAvailable(pFwEvent->hTwIf);
    383         }
    384         CL_TRACE_END_L2("tiwlan_drv.ko", "FwEvent", "Handle", "");
    385         return;
    386     }
    387 
    388     pFwEvent->eFwEventState = FW_EVENT_STATE_READING;
    389 
    390     twIf_Awake(pFwEvent->hTwIf);
    391 	if (pFwEvent->bIsActualFwInterrupt)
    392     {
    393         twIf_HwAvailable(pFwEvent->hTwIf);
    394     }
    395 
    396     /* Write HINT mask */
    397     pFwEvent->tMaskTxn.uData = ACX_INTR_ALL;
    398     TXN_FW_EVENT_SET_MASK_ADDR(pFwEvent)
    399     twIf_Transact(pFwEvent->hTwIf, &(pFwEvent->tMaskTxn.tTxnStruct));
    400 
    401 
    402     /*
    403      * Read the Fw status
    404      */
    405     TXN_FW_EVENT_SET_FW_STAT_ADDR(pFwEvent)
    406     rc = twIf_TransactReadFWStatus(pFwEvent->hTwIf, &(pFwEvent->tFwStatusTxn.tTxnStruct));
    407 
    408     if (rc == TXN_STATUS_COMPLETE)
    409     {
    410         fwEvent_ReadCompleteCb(hFwEvent);
    411     }
    412 
    413     CL_TRACE_END_L2("tiwlan_drv.ko", "FwEvent", "Handle", "");
    414 }
    415 
    416 
    417 /*
    418  * \brief	Handle the Fw Status information
    419  *
    420  * \param  hFwEvent  - FwEvent Driver handle
    421  * \return void
    422  *
    423  * \par Description
    424  * This function is called from fwEvent_Handle on a sync read, or from TwIf as a CB on an async read.
    425  * It calls fwEvent_CallHandler to handle the triggered interrupts.
    426  *
    427  * \sa fwEvent_Handle
    428  */
    429 static void fwEvent_ReadCompleteCb (TI_HANDLE hFwEvent)
    430 {
    431     TfwEvent *pFwEvent = (TfwEvent *)hFwEvent;
    432 
    433     os_InterruptServiced (pFwEvent->hOs);
    434 
    435     /* If we were called because of an interrupt */
    436 	if (pFwEvent->bIsActualFwInterrupt)
    437     {
    438         /* In case of level interrupt we need to clear the line */
    439         /*os_InterruptServiced(pFwEvent->hOs);*/
    440 
    441         /*
    442          * Sync to fw time so we can update the tx packets
    443          * on the delta time that they spent in the driver
    444          */
    445         pFwEvent->uFwTimeOffset = (os_timeStampMs (pFwEvent->hOs) * 1000) -
    446                                   ENDIAN_HANDLE_LONG (pFwEvent->tFwStatusTxn.tFwStatus.fwLocalTime);
    447 
    448         pFwEvent->bIsActualFwInterrupt = TI_FALSE;
    449     }
    450 
    451     /* Save the interrupts status retreived from the FW */
    452     pFwEvent->uEventVector = pFwEvent->tFwStatusTxn.tFwStatus.intrStatus;
    453 
    454     /* Mask unwanted interrupts */
    455     pFwEvent->uEventVector &= pFwEvent->uEventMask;
    456 
    457     /* Call the interrupts handlers */
    458     fwEvent_CallHandler(hFwEvent);
    459 
    460     /* Check if the state is changed in the context of the event callbacks */
    461     if (pFwEvent->eFwEventState == FW_EVENT_STATE_IDLE)
    462     {
    463         /*
    464          * When fwEvent_stop is called state is changed to IDLE
    465          * This is done in the context of the above events callbacks
    466          * Don't send the UNMASK transaction because the driver stop process includes power off
    467          */
    468         TRACE0(pFwEvent->hReport, REPORT_SEVERITY_WARNING, "fwEvent_ReadCompleteCb : State is IDLE ! don't send the UNMASK");
    469         return;
    470     }
    471 
    472     /* Write HINT unmask */
    473     pFwEvent->tUnMaskTxn.uData = ~pFwEvent->uEventMask;
    474     TXN_FW_EVENT_SET_UNMASK_ADDR(pFwEvent)
    475     twIf_Transact(pFwEvent->hTwIf, &(pFwEvent->tUnMaskTxn.tTxnStruct));
    476 
    477     twIf_Sleep(pFwEvent->hTwIf);
    478     pFwEvent->eFwEventState = FW_EVENT_STATE_IDLE;
    479 }
    480 
    481 
    482 /*
    483  * \brief	Translate host to FW time (Usec)
    484  *
    485  * \param  hFwEvent  - FwEvent Driver handle
    486  * \param  uHostTime - The host time in MS to translate
    487  *
    488  * \return FW Time in Usec
    489  *
    490  * \par Description
    491  *
    492  * \sa
    493  */
    494 TI_UINT32 fwEvent_TranslateToFwTime (TI_HANDLE hFwEvent, TI_UINT32 uHostTime)
    495 {
    496     TfwEvent *pFwEvent = (TfwEvent *)hFwEvent;
    497 
    498     return ((uHostTime * 1000) - pFwEvent->uFwTimeOffset);
    499 }
    500 
    501 
    502 /*
    503  * \brief	Unmask only cmd-cmplt and events interrupts (needed for init phase)
    504  *
    505  * \param  hFwEvent  - FwEvent Driver handle
    506  * \return Event mask
    507  *
    508  * \par Description
    509  * Unmask only cmd-cmplt and events interrupts (needed for init phase)
    510  *                  and return interrupt enabled bit mask.
    511  *
    512  * \sa
    513  */
    514 TI_UINT32 fwEvent_GetInitMask (TI_HANDLE hFwEvent)
    515 {
    516     TfwEvent *pFwEvent = (TfwEvent *)hFwEvent;
    517 
    518     /* Unmask only the interrupts needed for the FW configuration process. */
    519     pFwEvent->uEventMask = ACX_INTR_CMD_COMPLETE | ACX_INTR_EVENT_A | ACX_INTR_EVENT_B;
    520 
    521     return pFwEvent->uEventMask;
    522 }
    523 
    524 
    525 /*
    526  * \brief	Stop & reset FwEvent (called by the driver stop process)
    527  *
    528  * \param  hFwEvent  - FwEvent Driver handle
    529  * \return TI_OK
    530  *
    531  * \par Description
    532  *
    533  * \sa
    534  */
    535 TI_STATUS fwEvent_Stop (TI_HANDLE hFwEvent)
    536 {
    537     TfwEvent *pFwEvent = (TfwEvent *)hFwEvent;
    538 
    539     pFwEvent->eFwEventState = FW_EVENT_STATE_IDLE;
    540     pFwEvent->uEventMask = 0;
    541     pFwEvent->bIsActualFwInterrupt = TI_FALSE;
    542     pFwEvent->uEventVector = 0;
    543     pFwEvent->bEmulateRxIntr = TI_FALSE;
    544 
    545     return TI_OK;
    546 }
    547 
    548 
    549 /*
    550  * \brief	Unmask all interrupts, set Rx interrupt bit and call FwEvent_Handle
    551  *
    552  * \param  hFwEvent  - FwEvent Driver handle
    553  * \return void
    554  *
    555  * \par Description
    556  * Called when driver Start or recovery process is completed.
    557  *              Unmask all interrupts, set Rx interrupt bit and call FwEvent_Handle
    558  *                  (in case we missed an Rx interrupt in a recovery process).
    559  *
    560  * \sa
    561  */
    562 void fwEvent_EnableExternalEvents (TI_HANDLE hFwEvent)
    563 {
    564     TfwEvent *pFwEvent = (TfwEvent *)hFwEvent;
    565 
    566     /* Unmask all interrupts */
    567     pFwEvent->uEventMask = ALL_EVENTS_VECTOR;
    568 
    569     /* Set flag to invoke Rx interrupt handler in case we missed it in a recovery/start process */
    570     pFwEvent->bEmulateRxIntr = TI_TRUE;
    571 
    572     /* Handle interrupts including the Rx we've just set manually */
    573     fwEvent_Handle (hFwEvent);
    574 }
    575 
    576 
    577 /*
    578  * \brief	Disable the FwEvent client of the context thread handler
    579  *
    580  * \param  hFwEvent  - FwEvent Driver handle
    581  * \return void
    582  *
    583  * \par Description
    584  *
    585  * \sa
    586  */
    587 void fwEvent_DisableInterrupts(TI_HANDLE hFwEvent)
    588 {
    589     TfwEvent  *pFwEvent = (TfwEvent *)hFwEvent;
    590 
    591     context_DisableClient (pFwEvent->hContext,pFwEvent->uContextId);
    592 
    593 }
    594 
    595 
    596 /*
    597  * \brief	Enable the FwEvent client of the context thread handler
    598  *
    599  * \param  hFwEvent  - FwEvent Driver handle
    600  * \return void
    601  *
    602  * \par Description
    603  *
    604  * \sa
    605  */
    606 void fwEvent_EnableInterrupts(TI_HANDLE hFwEvent)
    607 {
    608     TfwEvent  *pFwEvent = (TfwEvent *)hFwEvent;
    609 
    610     context_EnableClient (pFwEvent->hContext,pFwEvent->uContextId);
    611 
    612 }
    613 
    614 
    615 
    616 #ifdef TI_DBG
    617 
    618 void fwEvent_PrintStat (TI_HANDLE hFwEvent)
    619 {
    620 #ifdef REPORT_LOG
    621     TfwEvent *pFwEvent = (TfwEvent *)hFwEvent;
    622     FwStatus_t *fwStat = &pFwEvent->tFwStatusTxn.tFwStatus;
    623     int i;
    624 
    625     WLAN_OS_REPORT(("Print FW event module info\n"));
    626     WLAN_OS_REPORT(("==========================\n"));
    627     WLAN_OS_REPORT(("intrStatus = 0x%08x\n", pFwEvent->uEventVector));
    628     WLAN_OS_REPORT(("intrMask   = 0x%08x\n", pFwEvent->uEventMask));
    629     WLAN_OS_REPORT(("counters   = 0x%08x\n", fwStat->counters));
    630 	for (i = 0; i < NUM_RX_PKT_DESC; i++)
    631     {
    632 		WLAN_OS_REPORT(("rxPktsDesc[%1d] = 0x%08x\n", i, fwStat->rxPktsDesc[i]));
    633     }
    634 	for (i = 0; i < NUM_TX_QUEUES; i++)
    635     {
    636 		WLAN_OS_REPORT(("txReleasedBlks[%1d] = 0x%08x\n", i, fwStat->txReleasedBlks[i]));
    637     }
    638     WLAN_OS_REPORT(("fwLocalTime = 0x%08x\n", fwStat->fwLocalTime));
    639 #endif
    640 }
    641 
    642 #endif  /* TI_DBG */
    643 
    644 
    645 
    646