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