1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17#include <drv_types.h>
18#include "rtw_led.h"
19
20
21
22
23
24
25static void BlinkTimerCallback(struct timer_list *t)
26{
27 struct LED_871x *pLed = from_timer(pLed, t, BlinkTimer);
28 struct adapter *padapter = pLed->padapter;
29
30 if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped))
31 return;
32
33 schedule_work(&pLed->BlinkWorkItem);
34}
35
36
37
38
39
40void BlinkWorkItemCallback(struct work_struct *work)
41{
42 struct LED_871x *pLed = container_of(work, struct LED_871x,
43 BlinkWorkItem);
44
45 BlinkHandler(pLed);
46}
47
48
49
50
51
52void ResetLedStatus(struct LED_871x *pLed)
53{
54 pLed->CurrLedState = RTW_LED_OFF;
55 pLed->bLedOn = false;
56
57 pLed->bLedBlinkInProgress = false;
58 pLed->bLedWPSBlinkInProgress = false;
59
60 pLed->BlinkTimes = 0;
61 pLed->BlinkingLedState = LED_UNKNOWN;
62
63 pLed->bLedNoLinkBlinkInProgress = false;
64 pLed->bLedLinkBlinkInProgress = false;
65 pLed->bLedScanBlinkInProgress = false;
66}
67
68
69
70void InitLed871x(struct adapter *padapter, struct LED_871x *pLed)
71{
72 pLed->padapter = padapter;
73
74 ResetLedStatus(pLed);
75
76 timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0);
77
78 INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback);
79}
80
81
82
83
84
85
86void DeInitLed871x(struct LED_871x *pLed)
87{
88 cancel_work_sync(&pLed->BlinkWorkItem);
89 del_timer_sync(&pLed->BlinkTimer);
90 ResetLedStatus(pLed);
91}
92
93
94
95
96
97
98
99static void SwLedBlink1(struct LED_871x *pLed)
100{
101 struct adapter *padapter = pLed->padapter;
102 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
103 u8 bStopBlinking = false;
104
105
106 if (pLed->BlinkingLedState == RTW_LED_ON) {
107 SwLedOn(padapter, pLed);
108 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
109 } else {
110 SwLedOff(padapter, pLed);
111 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
112 }
113
114 if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
115 SwLedOff(padapter, pLed);
116 ResetLedStatus(pLed);
117 return;
118 }
119
120 switch (pLed->CurrLedState) {
121 case LED_BLINK_SLOWLY:
122 if (pLed->bLedOn)
123 pLed->BlinkingLedState = RTW_LED_OFF;
124 else
125 pLed->BlinkingLedState = RTW_LED_ON;
126 mod_timer(&pLed->BlinkTimer, jiffies +
127 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
128 break;
129 case LED_BLINK_NORMAL:
130 if (pLed->bLedOn)
131 pLed->BlinkingLedState = RTW_LED_OFF;
132 else
133 pLed->BlinkingLedState = RTW_LED_ON;
134 mod_timer(&pLed->BlinkTimer, jiffies +
135 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
136 break;
137 case LED_BLINK_SCAN:
138 pLed->BlinkTimes--;
139 if (pLed->BlinkTimes == 0)
140 bStopBlinking = true;
141 if (bStopBlinking) {
142 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
143 pLed->bLedLinkBlinkInProgress = true;
144 pLed->CurrLedState = LED_BLINK_NORMAL;
145 if (pLed->bLedOn)
146 pLed->BlinkingLedState = RTW_LED_OFF;
147 else
148 pLed->BlinkingLedState = RTW_LED_ON;
149 mod_timer(&pLed->BlinkTimer, jiffies +
150 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
151 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
152 } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
153 pLed->bLedNoLinkBlinkInProgress = true;
154 pLed->CurrLedState = LED_BLINK_SLOWLY;
155 if (pLed->bLedOn)
156 pLed->BlinkingLedState = RTW_LED_OFF;
157 else
158 pLed->BlinkingLedState = RTW_LED_ON;
159 mod_timer(&pLed->BlinkTimer, jiffies +
160 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
161 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
162 }
163 pLed->bLedScanBlinkInProgress = false;
164 } else {
165 if (pLed->bLedOn)
166 pLed->BlinkingLedState = RTW_LED_OFF;
167 else
168 pLed->BlinkingLedState = RTW_LED_ON;
169 mod_timer(&pLed->BlinkTimer, jiffies +
170 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
171 }
172 break;
173 case LED_BLINK_TXRX:
174 pLed->BlinkTimes--;
175 if (pLed->BlinkTimes == 0)
176 bStopBlinking = true;
177 if (bStopBlinking) {
178 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
179 pLed->bLedLinkBlinkInProgress = true;
180 pLed->CurrLedState = LED_BLINK_NORMAL;
181 if (pLed->bLedOn)
182 pLed->BlinkingLedState = RTW_LED_OFF;
183 else
184 pLed->BlinkingLedState = RTW_LED_ON;
185 mod_timer(&pLed->BlinkTimer, jiffies +
186 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
187 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
188 } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
189 pLed->bLedNoLinkBlinkInProgress = true;
190 pLed->CurrLedState = LED_BLINK_SLOWLY;
191 if (pLed->bLedOn)
192 pLed->BlinkingLedState = RTW_LED_OFF;
193 else
194 pLed->BlinkingLedState = RTW_LED_ON;
195 mod_timer(&pLed->BlinkTimer, jiffies +
196 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
197 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
198 }
199 pLed->BlinkTimes = 0;
200 pLed->bLedBlinkInProgress = false;
201 } else {
202 if (pLed->bLedOn)
203 pLed->BlinkingLedState = RTW_LED_OFF;
204 else
205 pLed->BlinkingLedState = RTW_LED_ON;
206 mod_timer(&pLed->BlinkTimer, jiffies +
207 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
208 }
209 break;
210 case LED_BLINK_WPS:
211 if (pLed->bLedOn)
212 pLed->BlinkingLedState = RTW_LED_OFF;
213 else
214 pLed->BlinkingLedState = RTW_LED_ON;
215 mod_timer(&pLed->BlinkTimer, jiffies +
216 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
217 break;
218 case LED_BLINK_WPS_STOP:
219 if (pLed->BlinkingLedState == RTW_LED_ON)
220 bStopBlinking = false;
221 else
222 bStopBlinking = true;
223
224 if (bStopBlinking) {
225 pLed->bLedLinkBlinkInProgress = true;
226 pLed->CurrLedState = LED_BLINK_NORMAL;
227 if (pLed->bLedOn)
228 pLed->BlinkingLedState = RTW_LED_OFF;
229 else
230 pLed->BlinkingLedState = RTW_LED_ON;
231 mod_timer(&pLed->BlinkTimer, jiffies +
232 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
233 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
234
235 pLed->bLedWPSBlinkInProgress = false;
236 } else {
237 pLed->BlinkingLedState = RTW_LED_OFF;
238 mod_timer(&pLed->BlinkTimer, jiffies +
239 msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
240 }
241 break;
242 default:
243 break;
244 }
245}
246
247
248static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAction)
249{
250 struct led_priv *ledpriv = &padapter->ledpriv;
251 struct LED_871x *pLed = &ledpriv->SwLed0;
252 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
253
254 switch (LedAction) {
255 case LED_CTL_POWER_ON:
256 case LED_CTL_START_TO_LINK:
257 case LED_CTL_NO_LINK:
258 if (!pLed->bLedNoLinkBlinkInProgress) {
259 if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
260 return;
261 if (pLed->bLedLinkBlinkInProgress) {
262 del_timer_sync(&pLed->BlinkTimer);
263 pLed->bLedLinkBlinkInProgress = false;
264 }
265 if (pLed->bLedBlinkInProgress) {
266 del_timer_sync(&pLed->BlinkTimer);
267 pLed->bLedBlinkInProgress = false;
268 }
269
270 pLed->bLedNoLinkBlinkInProgress = true;
271 pLed->CurrLedState = LED_BLINK_SLOWLY;
272 if (pLed->bLedOn)
273 pLed->BlinkingLedState = RTW_LED_OFF;
274 else
275 pLed->BlinkingLedState = RTW_LED_ON;
276 mod_timer(&pLed->BlinkTimer, jiffies +
277 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
278 }
279 break;
280 case LED_CTL_LINK:
281 if (!pLed->bLedLinkBlinkInProgress) {
282 if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
283 return;
284 if (pLed->bLedNoLinkBlinkInProgress) {
285 del_timer_sync(&pLed->BlinkTimer);
286 pLed->bLedNoLinkBlinkInProgress = false;
287 }
288 if (pLed->bLedBlinkInProgress) {
289 del_timer_sync(&pLed->BlinkTimer);
290 pLed->bLedBlinkInProgress = false;
291 }
292 pLed->bLedLinkBlinkInProgress = true;
293 pLed->CurrLedState = LED_BLINK_NORMAL;
294 if (pLed->bLedOn)
295 pLed->BlinkingLedState = RTW_LED_OFF;
296 else
297 pLed->BlinkingLedState = RTW_LED_ON;
298 mod_timer(&pLed->BlinkTimer, jiffies +
299 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
300 }
301 break;
302 case LED_CTL_SITE_SURVEY:
303 if ((pmlmepriv->LinkDetectInfo.bBusyTraffic) && (check_fwstate(pmlmepriv, _FW_LINKED))) {
304 ;
305 } else if (!pLed->bLedScanBlinkInProgress) {
306 if (IS_LED_WPS_BLINKING(pLed))
307 return;
308 if (pLed->bLedNoLinkBlinkInProgress) {
309 del_timer_sync(&pLed->BlinkTimer);
310 pLed->bLedNoLinkBlinkInProgress = false;
311 }
312 if (pLed->bLedLinkBlinkInProgress) {
313 del_timer_sync(&pLed->BlinkTimer);
314 pLed->bLedLinkBlinkInProgress = false;
315 }
316 if (pLed->bLedBlinkInProgress) {
317 del_timer_sync(&pLed->BlinkTimer);
318 pLed->bLedBlinkInProgress = false;
319 }
320 pLed->bLedScanBlinkInProgress = true;
321 pLed->CurrLedState = LED_BLINK_SCAN;
322 pLed->BlinkTimes = 24;
323 if (pLed->bLedOn)
324 pLed->BlinkingLedState = RTW_LED_OFF;
325 else
326 pLed->BlinkingLedState = RTW_LED_ON;
327 mod_timer(&pLed->BlinkTimer, jiffies +
328 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
329 }
330 break;
331 case LED_CTL_TX:
332 case LED_CTL_RX:
333 if (!pLed->bLedBlinkInProgress) {
334 if (pLed->CurrLedState == LED_BLINK_SCAN || IS_LED_WPS_BLINKING(pLed))
335 return;
336 if (pLed->bLedNoLinkBlinkInProgress) {
337 del_timer_sync(&pLed->BlinkTimer);
338 pLed->bLedNoLinkBlinkInProgress = false;
339 }
340 if (pLed->bLedLinkBlinkInProgress) {
341 del_timer_sync(&pLed->BlinkTimer);
342 pLed->bLedLinkBlinkInProgress = false;
343 }
344 pLed->bLedBlinkInProgress = true;
345 pLed->CurrLedState = LED_BLINK_TXRX;
346 pLed->BlinkTimes = 2;
347 if (pLed->bLedOn)
348 pLed->BlinkingLedState = RTW_LED_OFF;
349 else
350 pLed->BlinkingLedState = RTW_LED_ON;
351 mod_timer(&pLed->BlinkTimer, jiffies +
352 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
353 }
354 break;
355 case LED_CTL_START_WPS:
356 case LED_CTL_START_WPS_BOTTON:
357 if (!pLed->bLedWPSBlinkInProgress) {
358 if (pLed->bLedNoLinkBlinkInProgress) {
359 del_timer_sync(&pLed->BlinkTimer);
360 pLed->bLedNoLinkBlinkInProgress = false;
361 }
362 if (pLed->bLedLinkBlinkInProgress) {
363 del_timer_sync(&pLed->BlinkTimer);
364 pLed->bLedLinkBlinkInProgress = false;
365 }
366 if (pLed->bLedBlinkInProgress) {
367 del_timer_sync(&pLed->BlinkTimer);
368 pLed->bLedBlinkInProgress = false;
369 }
370 if (pLed->bLedScanBlinkInProgress) {
371 del_timer_sync(&pLed->BlinkTimer);
372 pLed->bLedScanBlinkInProgress = false;
373 }
374 pLed->bLedWPSBlinkInProgress = true;
375 pLed->CurrLedState = LED_BLINK_WPS;
376 if (pLed->bLedOn)
377 pLed->BlinkingLedState = RTW_LED_OFF;
378 else
379 pLed->BlinkingLedState = RTW_LED_ON;
380 mod_timer(&pLed->BlinkTimer, jiffies +
381 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
382 }
383 break;
384 case LED_CTL_STOP_WPS:
385 if (pLed->bLedNoLinkBlinkInProgress) {
386 del_timer_sync(&pLed->BlinkTimer);
387 pLed->bLedNoLinkBlinkInProgress = false;
388 }
389 if (pLed->bLedLinkBlinkInProgress) {
390 del_timer_sync(&pLed->BlinkTimer);
391 pLed->bLedLinkBlinkInProgress = false;
392 }
393 if (pLed->bLedBlinkInProgress) {
394 del_timer_sync(&pLed->BlinkTimer);
395 pLed->bLedBlinkInProgress = false;
396 }
397 if (pLed->bLedScanBlinkInProgress) {
398 del_timer_sync(&pLed->BlinkTimer);
399 pLed->bLedScanBlinkInProgress = false;
400 }
401 if (pLed->bLedWPSBlinkInProgress)
402 del_timer_sync(&pLed->BlinkTimer);
403 else
404 pLed->bLedWPSBlinkInProgress = true;
405 pLed->CurrLedState = LED_BLINK_WPS_STOP;
406 if (pLed->bLedOn) {
407 pLed->BlinkingLedState = RTW_LED_OFF;
408 mod_timer(&pLed->BlinkTimer, jiffies +
409 msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
410 } else {
411 pLed->BlinkingLedState = RTW_LED_ON;
412 mod_timer(&pLed->BlinkTimer,
413 jiffies + msecs_to_jiffies(0));
414 }
415 break;
416 case LED_CTL_STOP_WPS_FAIL:
417 if (pLed->bLedWPSBlinkInProgress) {
418 del_timer_sync(&pLed->BlinkTimer);
419 pLed->bLedWPSBlinkInProgress = false;
420 }
421 pLed->bLedNoLinkBlinkInProgress = true;
422 pLed->CurrLedState = LED_BLINK_SLOWLY;
423 if (pLed->bLedOn)
424 pLed->BlinkingLedState = RTW_LED_OFF;
425 else
426 pLed->BlinkingLedState = RTW_LED_ON;
427 mod_timer(&pLed->BlinkTimer, jiffies +
428 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
429 break;
430 case LED_CTL_POWER_OFF:
431 pLed->CurrLedState = RTW_LED_OFF;
432 pLed->BlinkingLedState = RTW_LED_OFF;
433 if (pLed->bLedNoLinkBlinkInProgress) {
434 del_timer_sync(&pLed->BlinkTimer);
435 pLed->bLedNoLinkBlinkInProgress = false;
436 }
437 if (pLed->bLedLinkBlinkInProgress) {
438 del_timer_sync(&pLed->BlinkTimer);
439 pLed->bLedLinkBlinkInProgress = false;
440 }
441 if (pLed->bLedBlinkInProgress) {
442 del_timer_sync(&pLed->BlinkTimer);
443 pLed->bLedBlinkInProgress = false;
444 }
445 if (pLed->bLedWPSBlinkInProgress) {
446 del_timer_sync(&pLed->BlinkTimer);
447 pLed->bLedWPSBlinkInProgress = false;
448 }
449 if (pLed->bLedScanBlinkInProgress) {
450 del_timer_sync(&pLed->BlinkTimer);
451 pLed->bLedScanBlinkInProgress = false;
452 }
453 SwLedOff(padapter, pLed);
454 break;
455 default:
456 break;
457 }
458
459 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("Led %d\n", pLed->CurrLedState));
460}
461
462
463
464
465
466void BlinkHandler(struct LED_871x *pLed)
467{
468 struct adapter *padapter = pLed->padapter;
469
470 if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped))
471 return;
472
473 SwLedBlink1(pLed);
474}
475
476void LedControl8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction)
477{
478 if ((padapter->bSurpriseRemoved) || (padapter->bDriverStopped) ||
479 (!padapter->hw_init_completed))
480 return;
481
482 if ((padapter->pwrctrlpriv.rf_pwrstate != rf_on &&
483 padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) &&
484 (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
485 LedAction == LED_CTL_SITE_SURVEY ||
486 LedAction == LED_CTL_LINK ||
487 LedAction == LED_CTL_NO_LINK ||
488 LedAction == LED_CTL_POWER_ON))
489 return;
490
491 SwLedControlMode1(padapter, LedAction);
492}
493