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) */
53typedef 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 */
67typedef 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 */
94TI_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 */
124TI_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 */
165TI_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 */
193void 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
205void 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 */
233void 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 */
290void 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 */
355TI_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 */
405TI_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 */
452void 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 */
493void 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 */
525void 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 */
580void 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
651void 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
675void 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