1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41#include "../rt_config.h"
42
43
44BUILD_TIMER_FUNCTION(MlmePeriodicExec);
45
46BUILD_TIMER_FUNCTION(AsicRxAntEvalTimeout);
47BUILD_TIMER_FUNCTION(APSDPeriodicExec);
48BUILD_TIMER_FUNCTION(AsicRfTuningExec);
49
50
51#ifdef CONFIG_STA_SUPPORT
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);
61#ifdef RTMP_MAC_PCI
62BUILD_TIMER_FUNCTION(PsPollWakeExec);
63BUILD_TIMER_FUNCTION(RadioOnExec);
64#endif
65#ifdef QOS_DLS_SUPPORT
66BUILD_TIMER_FUNCTION(DlsTimeoutAction);
67#endif
68
69
70#endif
71
72
73
74#if defined(AP_LED) || defined(STA_LED)
75extern void LedCtrlMain(
76 IN PVOID SystemSpecific1,
77 IN PVOID FunctionContext,
78 IN PVOID SystemSpecific2,
79 IN PVOID SystemSpecific3);
80BUILD_TIMER_FUNCTION(LedCtrlMain);
81#endif
82
83
84#ifdef RTMP_TIMER_TASK_SUPPORT
85static void RtmpTimerQHandle(RTMP_ADAPTER *pAd)
86{
87#ifndef KTHREAD_SUPPORT
88 int status;
89#endif
90 RALINK_TIMER_STRUCT *pTimer;
91 RTMP_TIMER_TASK_ENTRY *pEntry;
92 unsigned long irqFlag;
93 RTMP_OS_TASK *pTask;
94
95
96 pTask = &pAd->timerTask;
97 while(!pTask->task_killed)
98 {
99 pTimer = NULL;
100
101#ifdef KTHREAD_SUPPORT
102 RTMP_WAIT_EVENT_INTERRUPTIBLE(pAd, pTask);
103#else
104 RTMP_SEM_EVENT_WAIT(&(pTask->taskSema), status);
105#endif
106
107 if (pAd->TimerQ.status == RTMP_TASK_STAT_STOPED)
108 break;
109
110
111 while(pAd->TimerQ.pQHead)
112 {
113 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlag);
114 pEntry = pAd->TimerQ.pQHead;
115 if (pEntry)
116 {
117 pTimer = pEntry->pRaTimer;
118
119
120 pAd->TimerQ.pQHead = pEntry->pNext;
121 if (pEntry == pAd->TimerQ.pQTail)
122 pAd->TimerQ.pQTail = NULL;
123
124
125 pEntry->pNext = pAd->TimerQ.pQPollFreeList;
126 pAd->TimerQ.pQPollFreeList = pEntry;
127 }
128 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlag);
129
130 if (pTimer)
131 {
132 if ((pTimer->handle != NULL) && (!pAd->PM_FlgSuspend))
133 pTimer->handle(NULL, (PVOID) pTimer->cookie, NULL, pTimer);
134 if ((pTimer->Repeat) && (pTimer->State == FALSE))
135 RTMP_OS_Add_Timer(&pTimer->TimerObj, pTimer->TimerValue);
136 }
137 }
138
139#ifndef KTHREAD_SUPPORT
140 if (status != 0)
141 {
142 pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
143 RTMP_SET_FLAG(pAd, fRTMP_ADAPTER_HALT_IN_PROGRESS);
144 break;
145 }
146#endif
147 }
148}
149
150
151INT RtmpTimerQThread(
152 IN OUT PVOID Context)
153{
154 RTMP_OS_TASK *pTask;
155 PRTMP_ADAPTER pAd;
156
157
158 pTask = (RTMP_OS_TASK *)Context;
159 pAd = (PRTMP_ADAPTER)pTask->priv;
160
161 RtmpOSTaskCustomize(pTask);
162
163 RtmpTimerQHandle(pAd);
164
165 DBGPRINT(RT_DEBUG_TRACE,( "<---%s\n",__FUNCTION__));
166#ifndef KTHREAD_SUPPORT
167 pTask->taskPID = THREAD_PID_INIT_VALUE;
168#endif
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183 RtmpOSTaskNotifyToExit(pTask);
184
185 return 0;
186
187}
188
189
190RTMP_TIMER_TASK_ENTRY *RtmpTimerQInsert(
191 IN RTMP_ADAPTER *pAd,
192 IN RALINK_TIMER_STRUCT *pTimer)
193{
194 RTMP_TIMER_TASK_ENTRY *pQNode = NULL, *pQTail;
195 unsigned long irqFlags;
196 RTMP_OS_TASK *pTask = &pAd->timerTask;
197
198 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
199 if (pAd->TimerQ.status & RTMP_TASK_CAN_DO_INSERT)
200 {
201 if(pAd->TimerQ.pQPollFreeList)
202 {
203 pQNode = pAd->TimerQ.pQPollFreeList;
204 pAd->TimerQ.pQPollFreeList = pQNode->pNext;
205
206 pQNode->pRaTimer = pTimer;
207 pQNode->pNext = NULL;
208
209 pQTail = pAd->TimerQ.pQTail;
210 if (pAd->TimerQ.pQTail != NULL)
211 pQTail->pNext = pQNode;
212 pAd->TimerQ.pQTail = pQNode;
213 if (pAd->TimerQ.pQHead == NULL)
214 pAd->TimerQ.pQHead = pQNode;
215 }
216 }
217 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
218
219 if (pQNode)
220 {
221#ifdef KTHREAD_SUPPORT
222 WAKE_UP(pTask);
223#else
224 RTMP_SEM_EVENT_UP(&pTask->taskSema);
225#endif
226 }
227
228 return pQNode;
229}
230
231
232BOOLEAN RtmpTimerQRemove(
233 IN RTMP_ADAPTER *pAd,
234 IN RALINK_TIMER_STRUCT *pTimer)
235{
236 RTMP_TIMER_TASK_ENTRY *pNode, *pPrev = NULL;
237 unsigned long irqFlags;
238
239 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
240 if (pAd->TimerQ.status >= RTMP_TASK_STAT_INITED)
241 {
242 pNode = pAd->TimerQ.pQHead;
243 while (pNode)
244 {
245 if (pNode->pRaTimer == pTimer)
246 break;
247 pPrev = pNode;
248 pNode = pNode->pNext;
249 }
250
251
252 if (pNode)
253 {
254 if (pNode == pAd->TimerQ.pQHead)
255 pAd->TimerQ.pQHead = pNode->pNext;
256 if (pNode == pAd->TimerQ.pQTail)
257 pAd->TimerQ.pQTail = pPrev;
258 if (pPrev != NULL)
259 pPrev->pNext = pNode->pNext;
260
261
262 pNode->pNext = pAd->TimerQ.pQPollFreeList;
263 pAd->TimerQ.pQPollFreeList = pNode;
264 }
265 }
266 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
267
268 return TRUE;
269}
270
271
272void RtmpTimerQExit(RTMP_ADAPTER *pAd)
273{
274 RTMP_TIMER_TASK_ENTRY *pTimerQ;
275 unsigned long irqFlags;
276
277 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
278 while (pAd->TimerQ.pQHead)
279 {
280 pTimerQ = pAd->TimerQ.pQHead;
281 pAd->TimerQ.pQHead = pTimerQ->pNext;
282
283 }
284 pAd->TimerQ.pQPollFreeList = NULL;
285 os_free_mem(pAd, pAd->TimerQ.pTimerQPoll);
286 pAd->TimerQ.pQTail = NULL;
287 pAd->TimerQ.pQHead = NULL;
288#ifndef KTHREAD_SUPPORT
289 pAd->TimerQ.status = RTMP_TASK_STAT_STOPED;
290#endif
291 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
292
293}
294
295
296void RtmpTimerQInit(RTMP_ADAPTER *pAd)
297{
298 int i;
299 RTMP_TIMER_TASK_ENTRY *pQNode, *pEntry;
300 unsigned long irqFlags;
301
302 NdisAllocateSpinLock(&pAd->TimerQLock);
303
304 NdisZeroMemory(&pAd->TimerQ, sizeof(pAd->TimerQ));
305
306 os_alloc_mem(pAd, &pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
307 if (pAd->TimerQ.pTimerQPoll)
308 {
309 pEntry = NULL;
310 pQNode = (RTMP_TIMER_TASK_ENTRY *)pAd->TimerQ.pTimerQPoll;
311 NdisZeroMemory(pAd->TimerQ.pTimerQPoll, sizeof(RTMP_TIMER_TASK_ENTRY) * TIMER_QUEUE_SIZE_MAX);
312
313 RTMP_INT_LOCK(&pAd->TimerQLock, irqFlags);
314 for (i = 0 ;i <TIMER_QUEUE_SIZE_MAX; i++)
315 {
316 pQNode->pNext = pEntry;
317 pEntry = pQNode;
318 pQNode++;
319 }
320 pAd->TimerQ.pQPollFreeList = pEntry;
321 pAd->TimerQ.pQHead = NULL;
322 pAd->TimerQ.pQTail = NULL;
323 pAd->TimerQ.status = RTMP_TASK_STAT_INITED;
324 RTMP_INT_UNLOCK(&pAd->TimerQLock, irqFlags);
325 }
326}
327#endif
328