]> bbs.cooldavid.org Git - net-next-2.6.git/blame - drivers/staging/rt2860/common/rtmp_timer.c
Staging: rt28x0: remove typedefs (part one)
[net-next-2.6.git] / drivers / staging / rt2860 / common / rtmp_timer.c
CommitLineData
ca97b838
BZ
1/*
2 *************************************************************************
3 * Ralink Tech Inc.
4 * 5F., No.36, Taiyuan St., Jhubei City,
5 * Hsinchu County 302,
6 * Taiwan, R.O.C.
7 *
8 * (c) Copyright 2002-2007, Ralink Technology, Inc.
9 *
10 * This program is free software; you can redistribute it and/or modify *
11 * it under the terms of the GNU General Public License as published by *
12 * the Free Software Foundation; either version 2 of the License, or *
13 * (at your option) any later version. *
14 * *
15 * This program is distributed in the hope that it will be useful, *
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
18 * GNU General Public License for more details. *
19 * *
20 * You should have received a copy of the GNU General Public License *
21 * along with this program; if not, write to the *
22 * Free Software Foundation, Inc., *
23 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
24 * *
25 *************************************************************************
26
27 Module Name:
28 rtmp_timer.c
29
30 Abstract:
31 task for timer handling
32
33 Revision History:
34 Who When What
35 -------- ---------- ----------------------------------------------
36 Name Date Modification logs
37 Shiang Tu 08-28-2008 init version
38
39*/
40
41#include "../rt_config.h"
42
ca97b838 43BUILD_TIMER_FUNCTION(MlmePeriodicExec);
ec278fa2 44/*BUILD_TIMER_FUNCTION(MlmeRssiReportExec); */
ca97b838
BZ
45BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
46BUILD_TIMER_FUNCTION(APSDPeriodicExec);
47BUILD_TIMER_FUNCTION(AsicRfTuningExec);
48#ifdef RTMP_MAC_USB
49BUILD_TIMER_FUNCTION(BeaconUpdateExec);
ec278fa2 50#endif /* RTMP_MAC_USB // */
ca97b838
BZ
51
52BUILD_TIMER_FUNCTION(BeaconTimeout);
53BUILD_TIMER_FUNCTION(ScanTimeout);
54BUILD_TIMER_FUNCTION(AuthTimeout);
55BUILD_TIMER_FUNCTION(AssocTimeout);
56BUILD_TIMER_FUNCTION(ReassocTimeout);
57BUILD_TIMER_FUNCTION(DisassocTimeout);
58BUILD_TIMER_FUNCTION(LinkDownExec);
59BUILD_TIMER_FUNCTION(StaQuickResponeForRateUpExec);
60BUILD_TIMER_FUNCTION(WpaDisassocApAndBlockAssoc);
e44fd1cf 61#ifdef RTMP_MAC_PCI
ca97b838
BZ
62BUILD_TIMER_FUNCTION(PsPollWakeExec);
63BUILD_TIMER_FUNCTION(RadioOnExec);
ec278fa2 64#endif /* RTMP_MAC_PCI // */
ca97b838
BZ
65#ifdef RTMP_MAC_USB
66BUILD_TIMER_FUNCTION(RtmpUsbStaAsicForceWakeupTimeout);
ec278fa2 67#endif /* RTMP_MAC_USB // */
ca97b838
BZ
68
69#if defined(AP_LED) || defined(STA_LED)
51126deb
BZ
70extern void LedCtrlMain(void *SystemSpecific1,
71 void *FunctionContext,
72 void *SystemSpecific2, void *SystemSpecific3);
ca97b838
BZ
73BUILD_TIMER_FUNCTION(LedCtrlMain);
74#endif
75
ca97b838 76#ifdef RTMP_TIMER_TASK_SUPPORT
96b3c83d 77static void RtmpTimerQHandle(RTMP_ADAPTER * pAd)
ca97b838
BZ
78{
79#ifndef KTHREAD_SUPPORT
80 int status;
81#endif
96b3c83d
BZ
82 RALINK_TIMER_STRUCT *pTimer;
83 RTMP_TIMER_TASK_ENTRY *pEntry;
84 unsigned long irqFlag;
ca97b838
BZ
85 RTMP_OS_TASK *pTask;
86
ca97b838 87 pTask = &pAd->timerTask;
96b3c83d 88 while (!pTask->task_killed) {
ca97b838
BZ
89 pTimer = NULL;
90
91#ifdef KTHREAD_SUPPORT
92 RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
93#else
94 RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
95#endif
96
97 if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
98 break;
99
ec278fa2 100 /* event happened. */
96b3c83d 101 while (pAd->TimerQ.pQHead) {
ca97b838
BZ
102 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
103 pEntry = pAd->TimerQ.pQHead;
96b3c83d 104 if (pEntry) {
ca97b838
BZ
105 pTimer = pEntry->pRaTimer;
106
ec278fa2 107 /* update pQHead */
ca97b838
BZ
108 pAd->TimerQ.pQHead = pEntry->pNext;
109 if (pEntry == pAd->TimerQ.pQTail)
110 pAd->TimerQ.pQTail = NULL;
111
ec278fa2 112 /* return this queue entry to timerQFreeList. */
ca97b838
BZ
113 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
114 pAd->TimerQ.pQPollFreeList = pEntry;
115 }
116 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
117
96b3c83d
BZ
118 if (pTimer) {
119 if ((pTimer->handle != NULL)
120 && (!pAd->PM_FlgSuspend))
121 pTimer->handle(NULL,
51126deb 122 (void *)pTimer->cookie,
96b3c83d
BZ
123 NULL, pTimer);
124 if ((pTimer->Repeat)
125 && (pTimer->State == FALSE))
126 RTMP_OS_Add_Timer(&pTimer->TimerObj,
127 pTimer->TimerValue);
ca97b838
BZ
128 }
129 }
130
131#ifndef KTHREAD_SUPPORT
96b3c83d 132 if (status != 0) {
ca97b838
BZ
133 pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
134 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
135 break;
136 }
137#endif
138 }
139}
140
51126deb 141int RtmpTimerQThread(IN void *Context)
ca97b838 142{
96b3c83d
BZ
143 RTMP_OS_TASK *pTask;
144 PRTMP_ADAPTER pAd;
ca97b838 145
96b3c83d
BZ
146 pTask = (RTMP_OS_TASK *) Context;
147 pAd = (PRTMP_ADAPTER) pTask->priv;
ca97b838
BZ
148
149 RtmpOSTaskCustomize(pTask);
150
151 RtmpTimerQHandle(pAd);
152
96b3c83d 153 DBGPRINT(RT_DEBUG_TRACE, ("<---%s\n", __func__));
ca97b838
BZ
154#ifndef KTHREAD_SUPPORT
155 pTask->taskPID = THREAD_PID_INIT_VALUE;
156#endif
157 /* notify the exit routine that we're actually exiting now
158 *
159 * complete()/wait_for_completion() is similar to up()/down(),
160 * except that complete() is safe in the case where the structure
161 * is getting deleted in a parallel mode of execution (i.e. just
162 * after the down() -- that's necessary for the thread-shutdown
163 * case.
164 *
165 * complete_and_exit() goes even further than this -- it is safe in
166 * the case that the thread of the caller is going away (not just
167 * the structure) -- this is necessary for the module-remove case.
168 * This is important in preemption kernels, which transfer the flow
169 * of execution immediately upon a complete().
170 */
171 RtmpOSTaskNotifyToExit(pTask);
172
173 return 0;
174
175}
176
96b3c83d
BZ
177RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert(IN RTMP_ADAPTER * pAd,
178 IN RALINK_TIMER_STRUCT * pTimer)
ca97b838
BZ
179{
180 RTMP_TIMER_TASK_ENTRY *pQNode = NULL, *pQTail;
181 unsigned long irqFlags;
96b3c83d 182 RTMP_OS_TASK *pTask = &pAd->timerTask;
ca97b838
BZ
183
184 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
96b3c83d
BZ
185 if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT) {
186 if (pAd->TimerQ.pQPollFreeList) {
ca97b838
BZ
187 pQNode = pAd->TimerQ.pQPollFreeList;
188 pAd->TimerQ.pQPollFreeList = pQNode->pNext;
189
190 pQNode->pRaTimer = pTimer;
191 pQNode->pNext = NULL;
192
193 pQTail = pAd->TimerQ.pQTail;
194 if (pAd->TimerQ.pQTail != NULL)
195 pQTail->pNext = pQNode;
196 pAd->TimerQ.pQTail = pQNode;
197 if (pAd->TimerQ.pQHead == NULL)
198 pAd->TimerQ.pQHead = pQNode;
199 }
200 }
201 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
202
96b3c83d 203 if (pQNode) {
ca97b838
BZ
204#ifdef KTHREAD_SUPPORT
205 WAKE_UP(pTask);
206#else
207 RTMP_SEM_EVENT_UP(&pTask->taskSema);
208#endif
209 }
210
211 return pQNode;
212}
213
96b3c83d 214BOOLEAN RtmpTimerQRemove(IN RTMP_ADAPTER * pAd, IN RALINK_TIMER_STRUCT * pTimer)
ca97b838
BZ
215{
216 RTMP_TIMER_TASK_ENTRY *pNode, *pPrev = NULL;
217 unsigned long irqFlags;
218
219 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
96b3c83d 220 if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED) {
ca97b838 221 pNode = pAd->TimerQ.pQHead;
96b3c83d 222 while (pNode) {
ca97b838
BZ
223 if (pNode->pRaTimer == pTimer)
224 break;
225 pPrev = pNode;
226 pNode = pNode->pNext;
227 }
228
ec278fa2 229 /* Now move it to freeList queue. */
96b3c83d 230 if (pNode) {
ca97b838
BZ
231 if (pNode == pAd->TimerQ.pQHead)
232 pAd->TimerQ.pQHead = pNode->pNext;
233 if (pNode == pAd->TimerQ.pQTail)
234 pAd->TimerQ.pQTail = pPrev;
235 if (pPrev != NULL)
236 pPrev->pNext = pNode->pNext;
237
ec278fa2 238 /* return this queue entry to timerQFreeList. */
ca97b838
BZ
239 pNode->pNext = pAd->TimerQ.pQPollFreeList;
240 pAd->TimerQ.pQPollFreeList = pNode;
241 }
242 }
243 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
244
245 return TRUE;
246}
247
96b3c83d 248void RtmpTimerQExit(RTMP_ADAPTER * pAd)
ca97b838
BZ
249{
250 RTMP_TIMER_TASK_ENTRY *pTimerQ;
251 unsigned long irqFlags;
252
253 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
96b3c83d 254 while (pAd->TimerQ.pQHead) {
ca97b838
BZ
255 pTimerQ = pAd->TimerQ.pQHead;
256 pAd->TimerQ.pQHead = pTimerQ->pNext;
ec278fa2 257 /* remove the timeQ */
ca97b838
BZ
258 }
259 pAd->TimerQ.pQPollFreeList = NULL;
260 os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
261 pAd->TimerQ.pQTail = NULL;
262 pAd->TimerQ.pQHead = NULL;
263#ifndef KTHREAD_SUPPORT
264 pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
265#endif
266 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
267
268}
269
96b3c83d 270void RtmpTimerQInit(RTMP_ADAPTER * pAd)
ca97b838 271{
96b3c83d 272 int i;
ca97b838
BZ
273 RTMP_TIMER_TASK_ENTRY *pQNode, *pEntry;
274 unsigned long irqFlags;
275
276 NdisAllocateSpinLock(&pAd->TimerQLock);
277
278 NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
279
96b3c83d
BZ
280 os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll,
281 sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
282 if (pAd->TimerQ.pTimerQPoll) {
ca97b838 283 pEntry = NULL;
96b3c83d
BZ
284 pQNode = (RTMP_TIMER_TASK_ENTRY *) pAd->TimerQ.pTimerQPoll;
285 NdisZeroMemory(pAd->TimerQ.pTimerQPoll,
286 sizeof(RTMP_TIMER_TASK_ENTRY) *
287 TIMER_QUEUE_SIZE_MAX);
ca97b838
BZ
288
289 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
96b3c83d 290 for (i = 0; i < TIMER_QUEUE_SIZE_MAX; i++) {
ca97b838
BZ
291 pQNode->pNext = pEntry;
292 pEntry = pQNode;
293 pQNode++;
294 }
295 pAd->TimerQ.pQPollFreeList = pEntry;
296 pAd->TimerQ.pQHead = NULL;
297 pAd->TimerQ.pQTail = NULL;
298 pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
299 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
300 }
301}
ec278fa2 302#endif /* RTMP_TIMER_TASK_SUPPORT // */