• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * timer.c
3  *
4  * Copyright(c) 1998 - 2010 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   timer.c
36  *  \brief  The timers services OS-Independent layer over the OS-API timer services which are OS-Dependent.
37  *
38  *  \see    timer.h, osapi.c
39  */
40 
41 #define __FILE_ID__  FILE_ID_0
42 #include "osApi.h"
43 #include "report.h"
44 #include "queue.h"
45 #include "context.h"
46 #include "timer.h"
47 
48 
49 #define EXPIRY_QUE_SIZE  QUE_UNLIMITED_SIZE
50 
51 /* The timer module structure (common to all timers) */
52 typedef struct
53 {
54     TI_HANDLE   hOs;
55     TI_HANDLE   hReport;
56     TI_HANDLE   hContext;
57     TI_UINT32   uContextId;     /* The ID allocated to this module on registration to context module */
58     TI_HANDLE   hInitQueue;     /* Handle of the Init-Queue */
59     TI_HANDLE   hOperQueue;     /* Handle of the Operational-Queue */
60     TI_BOOL     bOperState;     /* TRUE when the driver is in operational state (not init or recovery) */
61     TI_UINT32   uTwdInitCount;  /* Increments on each TWD init (i.e. recovery) */
62     TI_UINT32   uTimersCount;   /* Number of created timers */
63 } TTimerModule;
64 
65 /* Per timer structure */
66 typedef struct
67 {
68     TI_HANDLE    hTimerModule;             /* The timer module handle (see TTimerModule, needed on expiry) */
69     TI_HANDLE    hOsTimerObj;              /* The OS-API timer object handle */
70     TQueNodeHdr  tQueNodeHdr;              /* The header used for queueing the timer */
71     TTimerCbFunc fExpiryCbFunc;            /* The CB-function provided by the timer user for expiration */
72     TI_HANDLE    hExpiryCbHndl;            /* The CB-function handle */
73     TI_UINT32    uIntervalMsec;            /* The timer duration in Msec */
74     TI_BOOL      bPeriodic;                /* If TRUE, restarted after each expiry */
75     TI_BOOL      bOperStateWhenStarted;    /* The bOperState value when the timer was started */
76     TI_UINT32    uTwdInitCountWhenStarted; /* The uTwdInitCount value when the timer was started */
77 } TTimerInfo;
78 
79 
80 
81 
82 /**
83  * \fn     tmr_Create
84  * \brief  Create the timer module
85  *
86  * Allocate and clear the timer module object.
87  *
88  * \note   This is NOT a specific timer creation! (see tmr_CreateTimer)
89  * \param  hOs - Handle to Os Abstraction Layer
90  * \return Handle of the allocated object
91  * \sa     tmr_Destroy
92  */
tmr_Create(TI_HANDLE hOs)93 TI_HANDLE tmr_Create (TI_HANDLE hOs)
94 {
95     TI_HANDLE hTimerModule;
96 
97     /* allocate module object */
98     hTimerModule = os_memoryAlloc (hOs, sizeof(TTimerModule));
99 
100     if (!hTimerModule)
101     {
102         WLAN_OS_REPORT (("tmr_Create():  Allocation failed!!\n"));
103         return NULL;
104     }
105 
106     os_memoryZero (hOs, hTimerModule, (sizeof(TTimerModule)));
107 
108     return (hTimerModule);
109 }
110 
111 
112 /**
113  * \fn     tmr_Destroy
114  * \brief  Destroy the module.
115  *
116  * Free the module's queues and object.
117  *
118  * \note   This is NOT a specific timer destruction! (see tmr_DestroyTimer)
119  * \param  hTimerModule - The module object
120  * \return TI_OK on success or TI_NOK on failure
121  * \sa     tmr_Create
122  */
tmr_Destroy(TI_HANDLE hTimerModule)123 TI_STATUS tmr_Destroy (TI_HANDLE hTimerModule)
124 {
125     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
126 
127     if (!pTimerModule)
128     {
129         WLAN_OS_REPORT (("tmr_Destroy(): ERROR - NULL timer!\n"));
130         return TI_NOK;
131     }
132 
133     /* Alert if there are still timers that were not destroyed */
134     if (pTimerModule->uTimersCount)
135     {
136         WLAN_OS_REPORT (("tmr_Destroy():  ERROR - Destroying Timer module but not all timers were destroyed!!\n"));
137     }
138 
139     /* Destroy the module's queues (protect in critical section)) */
140     context_EnterCriticalSection (pTimerModule->hContext);
141     que_Destroy (pTimerModule->hInitQueue);
142     que_Destroy (pTimerModule->hOperQueue);
143     context_LeaveCriticalSection (pTimerModule->hContext);
144 
145     /* free module object */
146     os_memoryFree (pTimerModule->hOs, pTimerModule, sizeof(TTimerModule));
147 
148     return TI_OK;
149 }
150 /**
151  * \fn     tmr_Free
152  * \brief  Free the memory.
153  *
154  * Free the module's queues and object.
155  *
156  * \param  hTimerModule - The module object
157  * \return TI_OK on success or TI_NOK on failure
158  * \sa     tmr_Create
159  */
tmr_Free(TI_HANDLE hTimerModule)160 TI_STATUS tmr_Free(TI_HANDLE hTimerModule)
161 {
162     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
163 
164     if (!pTimerModule)
165     {
166         WLAN_OS_REPORT (("tmr_Free(): ERROR - NULL timer!\n"));
167         return TI_NOK;
168     }
169 
170     /* free module object */
171     os_memoryFree (pTimerModule->hOs, pTimerModule, sizeof(TTimerModule));
172 
173     return TI_OK;
174 }
175 
176 
177 /**
178  * \fn     tmr_ClearInitQueue & tmr_ClearOperQueue
179  * \brief  Clear Init/Operationsl queue
180  *
181  * Dequeue all queued timers.
182  *
183  * \note
184  * \param  hTimerModule - The object
185  * \return void
186  * \sa
187  */
tmr_ClearInitQueue(TI_HANDLE hTimerModule)188 void tmr_ClearInitQueue (TI_HANDLE hTimerModule)
189 {
190     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
191 
192     context_EnterCriticalSection (pTimerModule->hContext);
193     while (que_Dequeue (pTimerModule->hInitQueue) != NULL) {}
194     context_LeaveCriticalSection (pTimerModule->hContext);
195 }
196 
tmr_ClearOperQueue(TI_HANDLE hTimerModule)197 void tmr_ClearOperQueue (TI_HANDLE hTimerModule)
198 {
199     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
200 
201     context_EnterCriticalSection (pTimerModule->hContext);
202     while (que_Dequeue (pTimerModule->hOperQueue) != NULL) {}
203     context_LeaveCriticalSection (pTimerModule->hContext);
204 }
205 
206 
207 /**
208  * \fn     tmr_Init
209  * \brief  Init required handles
210  *
211  * Init required handles and module variables, create the init-queue and
212  *     operational-queue, and register as the context-engine client.
213  *
214  * \note
215  * \param  hTimerModule  - The queue object
216  * \param  hOs       - Handle to Os Abstraction Layer
217  * \param  hReport   - Handle to report module
218  * \param  hContext  - Handle to context module
219  * \return void
220  * \sa
221  */
tmr_Init(TI_HANDLE hTimerModule,TI_HANDLE hOs,TI_HANDLE hReport,TI_HANDLE hContext)222 void tmr_Init (TI_HANDLE hTimerModule, TI_HANDLE hOs, TI_HANDLE hReport, TI_HANDLE hContext)
223 {
224     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
225     TI_UINT32     uNodeHeaderOffset;
226 
227     if (!pTimerModule)
228     {
229         WLAN_OS_REPORT (("tmr_Init(): ERROR - NULL timer!\n"));
230         return;
231     }
232 
233     pTimerModule->hOs           = hOs;
234     pTimerModule->hReport       = hReport;
235     pTimerModule->hContext      = hContext;
236 
237     pTimerModule->bOperState    = TI_FALSE;
238     pTimerModule->uTimersCount  = 0;
239     pTimerModule->uTwdInitCount = 0;
240 
241     /* The offset of the queue-node-header from timer structure entry is needed by the queue */
242     uNodeHeaderOffset = TI_FIELD_OFFSET(TTimerInfo, tQueNodeHdr);
243 
244     /* Create and initialize the Init and Operational queues (for timers expiry events) */
245     pTimerModule->hInitQueue = que_Create (pTimerModule->hOs,
246                                            pTimerModule->hReport,
247                                            EXPIRY_QUE_SIZE,
248                                            uNodeHeaderOffset);
249     pTimerModule->hOperQueue = que_Create (pTimerModule->hOs,
250                                            pTimerModule->hReport,
251                                            EXPIRY_QUE_SIZE,
252                                            uNodeHeaderOffset);
253 
254     /* Register to the context engine and get the client ID */
255     pTimerModule->uContextId = context_RegisterClient (pTimerModule->hContext,
256                                                        tmr_HandleExpiry,
257                                                        hTimerModule,
258                                                        TI_TRUE,
259                                                        "TIMER",
260                                                        sizeof("TIMER"));
261 }
262 
263 
264 /**
265  * \fn     tmr_UpdateDriverState
266  * \brief  Update driver state
267  *
268  * Under critical section, update driver state (operational or not),
269  *   and if opertional, clear init queue.
270  * Leave critical section and if operational state, request schedule for handling
271  *   timer events in driver context (if any).
272  *
273  * \note
274  * \param  hTimerModule - The timer module object
275  * \param  bOperState   - TRUE if driver state is now operational, FALSE if not.
276  * \return void
277  * \sa
278  */
tmr_UpdateDriverState(TI_HANDLE hTimerModule,TI_BOOL bOperState)279 void tmr_UpdateDriverState (TI_HANDLE hTimerModule, TI_BOOL bOperState)
280 {
281     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
282 
283     if (!pTimerModule)
284     {
285         WLAN_OS_REPORT (("tmr_UpdateDriverState(): ERROR - NULL timer!\n"));
286         return;
287     }
288 
289     /* Enter critical section */
290     context_EnterCriticalSection (pTimerModule->hContext);
291 
292     if (bOperState == pTimerModule->bOperState)
293     {
294         context_LeaveCriticalSection (pTimerModule->hContext);
295         TRACE1(pTimerModule->hReport, REPORT_SEVERITY_ERROR, "tmr_UpdateDriverState(): New bOperState (%d) is as current!\n", bOperState);
296         return;
297     }
298 
299     /* Save new state (TRUE means operational). */
300     pTimerModule->bOperState = bOperState;
301 
302     /* If new state is operational */
303     if (bOperState)
304     {
305         /* Increment the TWD initializations counter (for detecting recovery events). */
306         pTimerModule->uTwdInitCount++;
307 
308         /* Empty the init queue (obsolete). */
309         while (que_Dequeue (pTimerModule->hInitQueue) != NULL) {}
310     }
311 
312     /* Leave critical section */
313     context_LeaveCriticalSection (pTimerModule->hContext);
314 
315     /* If new state is operational, request switch to driver context for handling timer events */
316     if (bOperState)
317     {
318         context_RequestSchedule (pTimerModule->hContext, pTimerModule->uContextId);
319     }
320 }
321 
322 
323 
324 /**
325  * \fn     tmr_CreateTimer
326  * \brief  Create a new timer
327  *
328  * Create a new timer object, icluding creating a timer in the OS-API.
329  *
330  * \note   This timer creation may be used only after tmr_Create() and tmr_Init() were executed!!
331  * \param  hTimerModule - The module handle
332  * \return TI_HANDLE    - The created timer handle
333  * \sa     tmr_DestroyTimer
334  */
tmr_CreateTimer(TI_HANDLE hTimerModule)335 TI_HANDLE tmr_CreateTimer (TI_HANDLE hTimerModule)
336 {
337     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule; /* The timer module handle */
338     TTimerInfo   *pTimerInfo;  /* The created timer handle */
339 
340     if (!pTimerModule)
341     {
342         WLAN_OS_REPORT (("tmr_CreateTimer(): ERROR - NULL timer!\n"));
343         return NULL;
344     }
345 
346     /* Allocate timer object */
347     pTimerInfo = os_memoryAlloc (pTimerModule->hOs, sizeof(TTimerInfo));
348     if (!pTimerInfo)
349     {
350         WLAN_OS_REPORT (("tmr_CreateTimer():  Timer allocation failed!!\n"));
351         return NULL;
352     }
353     os_memoryZero (pTimerModule->hOs, pTimerInfo, (sizeof(TTimerInfo)));
354 
355     /* Allocate OS-API timer, providing the common expiry callback with the current timer handle */
356     pTimerInfo->hOsTimerObj = os_timerCreate(pTimerModule->hOs, tmr_GetExpiry, (TI_HANDLE)pTimerInfo);
357     if (!pTimerInfo->hOsTimerObj)
358     {
359         TRACE0(pTimerModule->hReport, REPORT_SEVERITY_CONSOLE ,"tmr_CreateTimer():  OS-API Timer allocation failed!!\n");
360         os_memoryFree (pTimerModule->hOs, pTimerInfo, sizeof(TTimerInfo));
361         WLAN_OS_REPORT (("tmr_CreateTimer():  OS-API Timer allocation failed!!\n"));
362         return NULL;
363     }
364 
365     /* Save the timer module handle in the created timer object (needed for the expiry callback) */
366     pTimerInfo->hTimerModule = hTimerModule;
367     pTimerModule->uTimersCount++;  /* count created timers */
368 
369     /* Return the created timer handle */
370     return (TI_HANDLE)pTimerInfo;
371 }
372 
373 
374 /**
375  * \fn     tmr_DestroyTimer
376  * \brief  Destroy the specified timer
377  *
378  * Destroy the specified timer object, icluding the timer in the OS-API.
379  *
380  * \note   This timer destruction function should be used before tmr_Destroy() is executed!!
381  * \param  hTimerInfo - The timer handle
382  * \return TI_OK on success or TI_NOK on failure
383  * \sa     tmr_CreateTimer
384  */
tmr_DestroyTimer(TI_HANDLE hTimerInfo)385 TI_STATUS tmr_DestroyTimer (TI_HANDLE hTimerInfo)
386 {
387     TTimerInfo *pTimerInfo = (TTimerInfo *)hTimerInfo;  /* The timer handle */
388     TTimerModule *pTimerModule;                  /* The timer module handle */
389 
390     if (!pTimerInfo)
391     {
392         return TI_NOK;
393     }
394     pTimerModule = (TTimerModule *)pTimerInfo->hTimerModule;
395     if (!pTimerModule)
396     {
397         WLAN_OS_REPORT (("tmr_DestroyTimer(): ERROR - NULL timer!\n"));
398         return TI_NOK;
399     }
400 
401     /* Free the OS-API timer */
402     if (pTimerInfo->hOsTimerObj) {
403         os_timerDestroy (pTimerModule->hOs, pTimerInfo->hOsTimerObj);
404         pTimerModule->uTimersCount--;  /* update created timers number */
405     }
406     /* Free the timer object */
407     os_memoryFree (pTimerModule->hOs, hTimerInfo, sizeof(TTimerInfo));
408     return TI_OK;
409 }
410 
411 
412 /**
413  * \fn     tmr_StartTimer
414  * \brief  Start a timer
415  *
416  * Start the specified timer running.
417  *
418  * \note   Periodic-Timer may be used by applications that serve the timer expiry
419  *           in a single context.
420  *         If an application can't finish serving the timer expiry in a single context,
421  *           e.g. periodic scan, then it isn't recommended to use the periodic timer service.
422  *         If such an application uses the periodic timer then it should protect itself from cases
423  *            where the timer expires again before the previous timer expiry processing is finished!!
424  * \param  hTimerInfo    - The specific timer handle
425  * \param  fExpiryCbFunc - The timer's expiry callback function.
426  * \param  hExpiryCbHndl - The client's expiry callback function handle.
427  * \param  uIntervalMsec - The timer's duration in Msec.
428  * \param  bPeriodic     - If TRUE, the timer is restarted after expiry.
429  * \return void
430  * \sa     tmr_StopTimer, tmr_GetExpiry
431  */
tmr_StartTimer(TI_HANDLE hTimerInfo,TTimerCbFunc fExpiryCbFunc,TI_HANDLE hExpiryCbHndl,TI_UINT32 uIntervalMsec,TI_BOOL bPeriodic)432 void tmr_StartTimer (TI_HANDLE     hTimerInfo,
433                      TTimerCbFunc  fExpiryCbFunc,
434                      TI_HANDLE     hExpiryCbHndl,
435                      TI_UINT32     uIntervalMsec,
436                      TI_BOOL       bPeriodic)
437 {
438     TTimerInfo   *pTimerInfo   = (TTimerInfo *)hTimerInfo;                 /* The timer handle */
439     TTimerModule *pTimerModule = (TTimerModule *)pTimerInfo->hTimerModule; /* The timer module handle */
440 
441     if (!pTimerModule)
442     {
443         WLAN_OS_REPORT (("tmr_StartTimer(): ERROR - NULL timer!\n"));
444         return;
445     }
446 
447     /* Save the timer parameters. */
448     pTimerInfo->fExpiryCbFunc            = fExpiryCbFunc;
449     pTimerInfo->hExpiryCbHndl            = hExpiryCbHndl;
450     pTimerInfo->uIntervalMsec            = uIntervalMsec;
451     pTimerInfo->bPeriodic                = bPeriodic;
452     pTimerInfo->bOperStateWhenStarted    = pTimerModule->bOperState;
453     pTimerInfo->uTwdInitCountWhenStarted = pTimerModule->uTwdInitCount;
454 
455     /* Start OS-API timer running */
456     os_timerStart(pTimerModule->hOs, pTimerInfo->hOsTimerObj, uIntervalMsec);
457 }
458 
459 
460 /**
461  * \fn     tmr_StopTimer
462  * \brief  Stop a running timer
463  *
464  * Stop the specified timer.
465  *
466  * \note   When using this function, it must be considered that timer expiry may happen
467  *           right before the timer is stopped, so it can't be assumed that this completely
468  *           prevents the timer expiry event!
469  * \param  hTimerInfo - The specific timer handle
470  * \return void
471  * \sa     tmr_StartTimer
472  */
tmr_StopTimer(TI_HANDLE hTimerInfo)473 void tmr_StopTimer (TI_HANDLE hTimerInfo)
474 {
475     TTimerInfo   *pTimerInfo   = (TTimerInfo *)hTimerInfo;                 /* The timer handle */
476     TTimerModule *pTimerModule = (TTimerModule *)pTimerInfo->hTimerModule; /* The timer module handle */
477 
478     if (!pTimerModule)
479     {
480         WLAN_OS_REPORT (("tmr_StopTimer(): ERROR - NULL timer!\n"));
481         return;
482     }
483 
484     /* Stop OS-API timer running */
485     os_timerStop(pTimerModule->hOs, pTimerInfo->hOsTimerObj);
486 
487     /* Clear periodic flag to prevent timer restart if we are in tmr_HandleExpiry context. */
488     pTimerInfo->bPeriodic = TI_FALSE;
489 }
490 
491 
492 /**
493  * \fn     tmr_GetExpiry
494  * \brief  Called by OS-API upon any timer expiry
495  *
496  * This is the common callback function called upon expiartion of any timer.
497  * It is called by the OS-API in timer expiry context and handles the transition
498  *   to the driver's context for handling the expiry event.
499  *
500  * \note
501  * \param  hTimerInfo - The specific timer handle
502  * \return void
503  * \sa     tmr_HandleExpiry
504  */
tmr_GetExpiry(TI_HANDLE hTimerInfo)505 void tmr_GetExpiry (TI_HANDLE hTimerInfo)
506 {
507     TTimerInfo   *pTimerInfo   = (TTimerInfo *)hTimerInfo;                 /* The timer handle */
508     TTimerModule *pTimerModule = (TTimerModule *)pTimerInfo->hTimerModule; /* The timer module handle */
509 
510     if (!pTimerModule)
511     {
512         WLAN_OS_REPORT (("tmr_GetExpiry(): ERROR - NULL timer!\n"));
513         return;
514     }
515 
516     /* Enter critical section */
517     context_EnterCriticalSection (pTimerModule->hContext);
518 
519     /*
520      * If the expired timer was started when the driver's state was Operational,
521      *   insert it to the Operational-queue
522      */
523     if (pTimerInfo->bOperStateWhenStarted)
524     {
525         que_Enqueue (pTimerModule->hOperQueue, hTimerInfo);
526     }
527 
528     /*
529      * Else (started when driver's state was NOT-Operational), if now the state is still
530      *   NOT Operational insert it to the Init-queue.
531      *   (If state changed from non-operational to operational the event is ignored)
532      */
533     else if (!pTimerModule->bOperState)
534     {
535         que_Enqueue (pTimerModule->hInitQueue, hTimerInfo);
536     }
537 
538     /* Leave critical section */
539     context_LeaveCriticalSection (pTimerModule->hContext);
540 
541     /* Request switch to driver context for handling timer events */
542     context_RequestSchedule (pTimerModule->hContext, pTimerModule->uContextId);
543 }
544 
545 
546 /**
547  * \fn     tmr_HandleExpiry
548  * \brief  Handles queued expiry events in driver context
549  *
550  * This is the Timer module's callback that is registered to the ContextEngine module to be invoked
551  *   from the driver task (after requested by tmr_GetExpiry through context_RequestSchedule ()).
552  * It dequeues all expiry events from the queue that correlates to the current driver state,
553  *   and calls their users callbacks.
554  *
555  * \note
556  * \param  hTimerModule - The module object
557  * \return void
558  * \sa     tmr_GetExpiry
559  */
tmr_HandleExpiry(TI_HANDLE hTimerModule)560 void tmr_HandleExpiry (TI_HANDLE hTimerModule)
561 {
562     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule; /* The timer module handle */
563     TTimerInfo   *pTimerInfo;      /* The timer handle */
564     TI_BOOL       bTwdInitOccured; /* Indicates if TWD init occured since timer start */
565 
566     if (!pTimerModule)
567     {
568         WLAN_OS_REPORT (("tmr_HandleExpiry(): ERROR - NULL timer!\n"));
569         return;
570     }
571 
572     while (1)
573     {
574         /* Enter critical section */
575         context_EnterCriticalSection (pTimerModule->hContext);
576 
577         /* If current driver state is Operational, dequeue timer object from Operational-queue */
578         if (pTimerModule->bOperState)
579         {
580             pTimerInfo = (TTimerInfo *) que_Dequeue (pTimerModule->hOperQueue);
581         }
582 
583         /* Else (driver state is NOT-Operational), dequeue timer object from Init-queue */
584         else
585         {
586             pTimerInfo = (TTimerInfo *) que_Dequeue (pTimerModule->hInitQueue);
587         }
588 
589         /* Leave critical section */
590         context_LeaveCriticalSection (pTimerModule->hContext);
591 
592         /* If no more objects in queue, exit */
593         if (!pTimerInfo)
594         {
595             return;  /** EXIT Point **/
596         }
597 
598         /* If current TWD-Init-Count is different than when the timer was started, Init occured. */
599         bTwdInitOccured = (pTimerModule->uTwdInitCount != pTimerInfo->uTwdInitCountWhenStarted);
600 
601         /* Call specific timer callback function */
602         pTimerInfo->fExpiryCbFunc (pTimerInfo->hExpiryCbHndl, bTwdInitOccured);
603 
604         /* If the expired timer is periodic, start it again. */
605         if (pTimerInfo->bPeriodic)
606         {
607             tmr_StartTimer ((TI_HANDLE)pTimerInfo,
608                             pTimerInfo->fExpiryCbFunc,
609                             pTimerInfo->hExpiryCbHndl,
610                             pTimerInfo->uIntervalMsec,
611                             pTimerInfo->bPeriodic);
612         }
613     }
614 }
615 
616 
617 /**
618  * \fn     tmr_PrintModule / tmr_PrintTimer
619  * \brief  Print module / timer information
620  *
621  * Print the module's information / a specific timer information.
622  *
623  * \note
624  * \param  The module / timer handle
625  * \return void
626  * \sa
627  */
628 
629 #ifdef TI_DBG
630 
tmr_PrintModule(TI_HANDLE hTimerModule)631 void tmr_PrintModule (TI_HANDLE hTimerModule)
632 {
633     TTimerModule *pTimerModule = (TTimerModule *)hTimerModule;
634 
635     if (!pTimerModule)
636     {
637         WLAN_OS_REPORT (("tmr_PrintModule(): ERROR - NULL timer!\n"));
638         return;
639     }
640 
641     /* Print module parameters */
642     WLAN_OS_REPORT(("tmr_PrintModule(): uContextId=%d, bOperState=%d, uTwdInitCount=%d, uTimersCount=%d\n",
643     pTimerModule->uContextId, pTimerModule->bOperState,
644     pTimerModule->uTwdInitCount, pTimerModule->uTimersCount));
645 
646     /* Print Init Queue Info */
647     WLAN_OS_REPORT(("tmr_PrintModule(): Init-Queue:\n"));
648     que_Print(pTimerModule->hInitQueue);
649 
650     /* Print Operational Queue Info */
651     WLAN_OS_REPORT(("tmr_PrintModule(): Operational-Queue:\n"));
652     que_Print(pTimerModule->hOperQueue);
653 }
654 
tmr_PrintTimer(TI_HANDLE hTimerInfo)655 void tmr_PrintTimer (TI_HANDLE hTimerInfo)
656 {
657 #ifdef REPORT_LOG
658     TTimerInfo   *pTimerInfo   = (TTimerInfo *)hTimerInfo;                 /* The timer handle */
659 
660     WLAN_OS_REPORT(("tmr_PrintTimer(): uIntervalMs=%d, bPeriodic=%d, bOperStateWhenStarted=%d, uTwdInitCountWhenStarted=%d, hOsTimerObj=0x%x, fExpiryCbFunc=0x%x\n",
661     pTimerInfo->uIntervalMsec, pTimerInfo->bPeriodic, pTimerInfo->bOperStateWhenStarted,
662     pTimerInfo->uTwdInitCountWhenStarted, pTimerInfo->hOsTimerObj, pTimerInfo->fExpiryCbFunc));
663 #endif
664 }
665 
666 #endif /* TI_DBG */
667