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