• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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  */
fwEvent_Create(TI_HANDLE hOs)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  */
fwEvent_Destroy(TI_HANDLE hFwEvent)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  */
fwEvent_Init(TI_HANDLE hFwEvent,TI_HANDLE hTWD)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  */
fwEvent_CallHandler(TI_HANDLE hFwEvent)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  */
fwEvent_InterruptRequest(TI_HANDLE hFwEvent)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 
fwEvent_Handle(TI_HANDLE hFwEvent)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  */
fwEvent_ReadCompleteCb(TI_HANDLE hFwEvent)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  */
fwEvent_TranslateToFwTime(TI_HANDLE hFwEvent,TI_UINT32 uHostTime)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  */
fwEvent_GetInitMask(TI_HANDLE hFwEvent)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  */
fwEvent_Stop(TI_HANDLE hFwEvent)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  */
fwEvent_EnableExternalEvents(TI_HANDLE hFwEvent)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  */
fwEvent_DisableInterrupts(TI_HANDLE hFwEvent)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  */
fwEvent_EnableInterrupts(TI_HANDLE hFwEvent)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 
fwEvent_PrintStat(TI_HANDLE hFwEvent)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