1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
5 * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved.
6 * Linux device driver for RTL8192SU
8 * Modifications for inclusion into the Linux staging tree are
9 * Copyright(c) 2010 Larry Finger. All rights reserved.
11 * Contact information:
15 ******************************************************************************/
17 #include "drv_types.h"
19 /*===========================================================================
21 *===========================================================================
24 * Default LED behavior.
26 #define LED_BLINK_NORMAL_INTERVAL 100
27 #define LED_BLINK_SLOWLY_INTERVAL 200
28 #define LED_BLINK_LONG_INTERVAL 400
30 #define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000
31 #define LED_BLINK_LINK_INTERVAL_ALPHA 500
32 #define LED_BLINK_SCAN_INTERVAL_ALPHA 180
33 #define LED_BLINK_FASTER_INTERVAL_ALPHA 50
34 #define LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA 5000
36 /*===========================================================================
38 *===========================================================================
40 enum _LED_STATE_871x {
46 LED_POWER_ON_BLINK = 5,
47 LED_SCAN_BLINK = 6, /* LED is blinking during scanning period,
48 * the # of times to blink is depend on time
51 LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */
52 LED_BLINK_StartToBlink = 8,/* Customized for Sercomm Printer
55 LED_BLINK_WPS = 9, /* LED is blinkg during WPS communication */
57 LED_BLINK_WPS_STOP = 11, /*for ALPHA */
58 LED_BLINK_WPS_STOP_OVERLAP = 12, /*for BELKIN */
61 /*===========================================================================
62 * Prototype of protected function.
63 *===========================================================================
65 static void BlinkTimerCallback(struct timer_list *t);
67 static void BlinkWorkItemCallback(struct work_struct *work);
68 /*===========================================================================
69 * LED_819xUsb routines.
70 *===========================================================================
75 * Initialize an LED_871x object.
77 static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed,
78 enum LED_PIN_871x LedPin)
80 pLed->padapter = padapter;
81 pLed->LedPin = LedPin;
82 pLed->CurrLedState = LED_STATE_OFF;
84 pLed->bLedBlinkInProgress = false;
86 pLed->BlinkingLedState = LED_UNKNOWN;
87 timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0);
88 INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback);
93 * DeInitialize an LED_871x object.
95 static void DeInitLed871x(struct LED_871x *pLed)
97 del_timer_sync(&pLed->BlinkTimer);
98 /* We should reset bLedBlinkInProgress if we cancel
99 * the LedControlTimer,
101 pLed->bLedBlinkInProgress = false;
106 * Turn on LED according to LedPin specified.
108 static void SwLedOn(struct _adapter *padapter, struct LED_871x *pLed)
112 if (padapter->surprise_removed || padapter->driver_stopped)
114 LedCfg = r8712_read8(padapter, LEDCFG);
115 switch (pLed->LedPin) {
119 /* SW control led0 on.*/
120 r8712_write8(padapter, LEDCFG, LedCfg & 0xf0);
123 /* SW control led1 on.*/
124 r8712_write8(padapter, LEDCFG, LedCfg & 0x0f);
134 * Turn off LED according to LedPin specified.
136 static void SwLedOff(struct _adapter *padapter, struct LED_871x *pLed)
140 if (padapter->surprise_removed || padapter->driver_stopped)
142 LedCfg = r8712_read8(padapter, LEDCFG);
143 switch (pLed->LedPin) {
147 LedCfg &= 0xf0; /* Set to software control.*/
148 r8712_write8(padapter, LEDCFG, (LedCfg | BIT(3)));
151 LedCfg &= 0x0f; /* Set to software control.*/
152 r8712_write8(padapter, LEDCFG, (LedCfg | BIT(7)));
157 pLed->bLedOn = false;
160 /*===========================================================================
161 * Interface to manipulate LED objects.
162 *===========================================================================
165 * Initialize all LED_871x objects.
167 void r8712_InitSwLeds(struct _adapter *padapter)
169 struct led_priv *pledpriv = &padapter->ledpriv;
171 pledpriv->LedControlHandler = LedControl871x;
172 InitLed871x(padapter, &pledpriv->SwLed0, LED_PIN_LED0);
173 InitLed871x(padapter, &pledpriv->SwLed1, LED_PIN_LED1);
177 * DeInitialize all LED_819xUsb objects.
179 void r8712_DeInitSwLeds(struct _adapter *padapter)
181 struct led_priv *ledpriv = &padapter->ledpriv;
183 DeInitLed871x(&ledpriv->SwLed0);
184 DeInitLed871x(&ledpriv->SwLed1);
188 * Implementation of LED blinking behavior.
189 * It toggle off LED and schedule corresponding timer if necessary.
191 static void SwLedBlink(struct LED_871x *pLed)
193 struct _adapter *padapter = pLed->padapter;
194 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
195 u8 bStopBlinking = false;
197 /* Change LED according to BlinkingLedState specified. */
198 if (pLed->BlinkingLedState == LED_STATE_ON)
199 SwLedOn(padapter, pLed);
201 SwLedOff(padapter, pLed);
202 /* Determine if we shall change LED state again. */
204 switch (pLed->CurrLedState) {
205 case LED_BLINK_NORMAL:
206 if (pLed->BlinkTimes == 0)
207 bStopBlinking = true;
209 case LED_BLINK_StartToBlink:
210 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
211 (pmlmepriv->fw_state & WIFI_STATION_STATE))
212 bStopBlinking = true;
213 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
214 ((pmlmepriv->fw_state & WIFI_ADHOC_STATE) ||
215 (pmlmepriv->fw_state & WIFI_ADHOC_MASTER_STATE)))
216 bStopBlinking = true;
217 else if (pLed->BlinkTimes == 0)
218 bStopBlinking = true;
221 if (pLed->BlinkTimes == 0)
222 bStopBlinking = true;
225 bStopBlinking = true;
229 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
231 SwLedOn(padapter, pLed);
232 else if (check_fwstate(pmlmepriv, _FW_LINKED) && pLed->bLedOn)
233 SwLedOff(padapter, pLed);
234 pLed->BlinkTimes = 0;
235 pLed->bLedBlinkInProgress = false;
237 /* Assign LED state to toggle. */
238 if (pLed->BlinkingLedState == LED_STATE_ON)
239 pLed->BlinkingLedState = LED_STATE_OFF;
241 pLed->BlinkingLedState = LED_STATE_ON;
243 /* Schedule a timer to toggle LED state. */
244 switch (pLed->CurrLedState) {
245 case LED_BLINK_NORMAL:
246 mod_timer(&pLed->BlinkTimer, jiffies +
247 msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
249 case LED_BLINK_SLOWLY:
250 case LED_BLINK_StartToBlink:
251 mod_timer(&pLed->BlinkTimer, jiffies +
252 msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
255 mod_timer(&pLed->BlinkTimer, jiffies +
256 msecs_to_jiffies(LED_BLINK_LONG_INTERVAL));
259 mod_timer(&pLed->BlinkTimer, jiffies +
260 msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
266 static void SwLedBlink1(struct LED_871x *pLed)
268 struct _adapter *padapter = pLed->padapter;
269 struct led_priv *ledpriv = &padapter->ledpriv;
270 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
271 struct eeprom_priv *peeprompriv = &padapter->eeprompriv;
272 struct LED_871x *pLed1 = &ledpriv->SwLed1;
273 u8 bStopBlinking = false;
275 if (peeprompriv->CustomerID == RT_CID_819x_CAMEO)
276 pLed = &ledpriv->SwLed1;
277 /* Change LED according to BlinkingLedState specified. */
278 if (pLed->BlinkingLedState == LED_STATE_ON)
279 SwLedOn(padapter, pLed);
281 SwLedOff(padapter, pLed);
282 if (peeprompriv->CustomerID == RT_CID_DEFAULT) {
283 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
284 if (!pLed1->bSWLedCtrl) {
285 SwLedOn(padapter, pLed1);
286 pLed1->bSWLedCtrl = true;
287 } else if (!pLed1->bLedOn) {
288 SwLedOn(padapter, pLed1);
291 if (!pLed1->bSWLedCtrl) {
292 SwLedOff(padapter, pLed1);
293 pLed1->bSWLedCtrl = true;
294 } else if (pLed1->bLedOn) {
295 SwLedOff(padapter, pLed1);
299 switch (pLed->CurrLedState) {
300 case LED_BLINK_SLOWLY:
302 pLed->BlinkingLedState = LED_STATE_OFF;
304 pLed->BlinkingLedState = LED_STATE_ON;
305 mod_timer(&pLed->BlinkTimer, jiffies +
306 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
308 case LED_BLINK_NORMAL:
310 pLed->BlinkingLedState = LED_STATE_OFF;
312 pLed->BlinkingLedState = LED_STATE_ON;
313 mod_timer(&pLed->BlinkTimer, jiffies +
314 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
318 if (pLed->BlinkTimes == 0)
319 bStopBlinking = true;
321 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
322 pLed->bLedLinkBlinkInProgress = true;
323 pLed->CurrLedState = LED_BLINK_NORMAL;
325 pLed->BlinkingLedState = LED_STATE_OFF;
327 pLed->BlinkingLedState = LED_STATE_ON;
328 mod_timer(&pLed->BlinkTimer, jiffies +
329 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
330 } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
331 pLed->bLedNoLinkBlinkInProgress = true;
332 pLed->CurrLedState = LED_BLINK_SLOWLY;
334 pLed->BlinkingLedState = LED_STATE_OFF;
336 pLed->BlinkingLedState = LED_STATE_ON;
337 mod_timer(&pLed->BlinkTimer, jiffies +
338 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
340 pLed->bLedScanBlinkInProgress = false;
343 pLed->BlinkingLedState = LED_STATE_OFF;
345 pLed->BlinkingLedState = LED_STATE_ON;
346 mod_timer(&pLed->BlinkTimer, jiffies +
347 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
352 if (pLed->BlinkTimes == 0)
353 bStopBlinking = true;
355 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
356 pLed->bLedLinkBlinkInProgress = true;
357 pLed->CurrLedState = LED_BLINK_NORMAL;
359 pLed->BlinkingLedState = LED_STATE_OFF;
361 pLed->BlinkingLedState = LED_STATE_ON;
362 mod_timer(&pLed->BlinkTimer, jiffies +
363 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
364 } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
365 pLed->bLedNoLinkBlinkInProgress = true;
366 pLed->CurrLedState = LED_BLINK_SLOWLY;
368 pLed->BlinkingLedState = LED_STATE_OFF;
370 pLed->BlinkingLedState = LED_STATE_ON;
371 mod_timer(&pLed->BlinkTimer, jiffies +
372 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
374 pLed->BlinkTimes = 0;
375 pLed->bLedBlinkInProgress = false;
378 pLed->BlinkingLedState = LED_STATE_OFF;
380 pLed->BlinkingLedState = LED_STATE_ON;
381 mod_timer(&pLed->BlinkTimer, jiffies +
382 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
387 pLed->BlinkingLedState = LED_STATE_OFF;
389 pLed->BlinkingLedState = LED_STATE_ON;
390 mod_timer(&pLed->BlinkTimer, jiffies +
391 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
393 case LED_BLINK_WPS_STOP: /* WPS success */
394 if (pLed->BlinkingLedState == LED_STATE_ON) {
395 pLed->BlinkingLedState = LED_STATE_OFF;
396 mod_timer(&pLed->BlinkTimer, jiffies +
397 msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
398 bStopBlinking = false;
400 bStopBlinking = true;
403 pLed->bLedLinkBlinkInProgress = true;
404 pLed->CurrLedState = LED_BLINK_NORMAL;
406 pLed->BlinkingLedState = LED_STATE_OFF;
408 pLed->BlinkingLedState = LED_STATE_ON;
409 mod_timer(&pLed->BlinkTimer, jiffies +
410 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
412 pLed->bLedWPSBlinkInProgress = false;
419 static void SwLedBlink2(struct LED_871x *pLed)
421 struct _adapter *padapter = pLed->padapter;
422 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
423 u8 bStopBlinking = false;
425 /* Change LED according to BlinkingLedState specified. */
426 if (pLed->BlinkingLedState == LED_STATE_ON)
427 SwLedOn(padapter, pLed);
429 SwLedOff(padapter, pLed);
430 switch (pLed->CurrLedState) {
433 if (pLed->BlinkTimes == 0)
434 bStopBlinking = true;
436 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
437 pLed->CurrLedState = LED_STATE_ON;
438 pLed->BlinkingLedState = LED_STATE_ON;
439 SwLedOn(padapter, pLed);
440 } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
441 pLed->CurrLedState = LED_STATE_OFF;
442 pLed->BlinkingLedState = LED_STATE_OFF;
443 SwLedOff(padapter, pLed);
445 pLed->bLedScanBlinkInProgress = false;
448 pLed->BlinkingLedState = LED_STATE_OFF;
450 pLed->BlinkingLedState = LED_STATE_ON;
451 mod_timer(&pLed->BlinkTimer, jiffies +
452 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
457 if (pLed->BlinkTimes == 0)
458 bStopBlinking = true;
460 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
461 pLed->CurrLedState = LED_STATE_ON;
462 pLed->BlinkingLedState = LED_STATE_ON;
463 SwLedOn(padapter, pLed);
464 } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
465 pLed->CurrLedState = LED_STATE_OFF;
466 pLed->BlinkingLedState = LED_STATE_OFF;
467 SwLedOff(padapter, pLed);
469 pLed->bLedBlinkInProgress = false;
472 pLed->BlinkingLedState = LED_STATE_OFF;
474 pLed->BlinkingLedState = LED_STATE_ON;
475 mod_timer(&pLed->BlinkTimer, jiffies +
476 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
484 static void SwLedBlink3(struct LED_871x *pLed)
486 struct _adapter *padapter = pLed->padapter;
487 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
488 u8 bStopBlinking = false;
490 /* Change LED according to BlinkingLedState specified. */
491 if (pLed->BlinkingLedState == LED_STATE_ON)
492 SwLedOn(padapter, pLed);
494 if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
495 SwLedOff(padapter, pLed);
496 switch (pLed->CurrLedState) {
499 if (pLed->BlinkTimes == 0)
500 bStopBlinking = true;
502 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
503 pLed->CurrLedState = LED_STATE_ON;
504 pLed->BlinkingLedState = LED_STATE_ON;
506 SwLedOn(padapter, pLed);
507 } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
508 pLed->CurrLedState = LED_STATE_OFF;
509 pLed->BlinkingLedState = LED_STATE_OFF;
511 SwLedOff(padapter, pLed);
513 pLed->bLedScanBlinkInProgress = false;
516 pLed->BlinkingLedState = LED_STATE_OFF;
518 pLed->BlinkingLedState = LED_STATE_ON;
519 mod_timer(&pLed->BlinkTimer, jiffies +
520 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
525 if (pLed->BlinkTimes == 0)
526 bStopBlinking = true;
528 if (check_fwstate(pmlmepriv, _FW_LINKED)) {
529 pLed->CurrLedState = LED_STATE_ON;
530 pLed->BlinkingLedState = LED_STATE_ON;
532 SwLedOn(padapter, pLed);
533 } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
534 pLed->CurrLedState = LED_STATE_OFF;
535 pLed->BlinkingLedState = LED_STATE_OFF;
537 SwLedOff(padapter, pLed);
539 pLed->bLedBlinkInProgress = false;
542 pLed->BlinkingLedState = LED_STATE_OFF;
544 pLed->BlinkingLedState = LED_STATE_ON;
545 mod_timer(&pLed->BlinkTimer, jiffies +
546 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
551 pLed->BlinkingLedState = LED_STATE_OFF;
553 pLed->BlinkingLedState = LED_STATE_ON;
554 mod_timer(&pLed->BlinkTimer, jiffies +
555 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
557 case LED_BLINK_WPS_STOP: /*WPS success*/
558 if (pLed->BlinkingLedState == LED_STATE_ON) {
559 pLed->BlinkingLedState = LED_STATE_OFF;
560 mod_timer(&pLed->BlinkTimer, jiffies +
561 msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
562 bStopBlinking = false;
564 bStopBlinking = true;
567 pLed->CurrLedState = LED_STATE_ON;
568 pLed->BlinkingLedState = LED_STATE_ON;
569 SwLedOn(padapter, pLed);
570 pLed->bLedWPSBlinkInProgress = false;
578 static void SwLedBlink4(struct LED_871x *pLed)
580 struct _adapter *padapter = pLed->padapter;
581 struct led_priv *ledpriv = &padapter->ledpriv;
582 struct LED_871x *pLed1 = &ledpriv->SwLed1;
583 u8 bStopBlinking = false;
585 /* Change LED according to BlinkingLedState specified. */
586 if (pLed->BlinkingLedState == LED_STATE_ON)
587 SwLedOn(padapter, pLed);
589 SwLedOff(padapter, pLed);
590 if (!pLed1->bLedWPSBlinkInProgress &&
591 pLed1->BlinkingLedState == LED_UNKNOWN) {
592 pLed1->BlinkingLedState = LED_STATE_OFF;
593 pLed1->CurrLedState = LED_STATE_OFF;
594 SwLedOff(padapter, pLed1);
596 switch (pLed->CurrLedState) {
597 case LED_BLINK_SLOWLY:
599 pLed->BlinkingLedState = LED_STATE_OFF;
601 pLed->BlinkingLedState = LED_STATE_ON;
602 mod_timer(&pLed->BlinkTimer, jiffies +
603 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
605 case LED_BLINK_StartToBlink:
607 pLed->BlinkingLedState = LED_STATE_OFF;
608 mod_timer(&pLed->BlinkTimer, jiffies +
609 msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
611 pLed->BlinkingLedState = LED_STATE_ON;
612 mod_timer(&pLed->BlinkTimer, jiffies +
613 msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
618 if (pLed->BlinkTimes == 0)
619 bStopBlinking = true;
621 pLed->bLedNoLinkBlinkInProgress = true;
622 pLed->CurrLedState = LED_BLINK_SLOWLY;
624 pLed->BlinkingLedState = LED_STATE_OFF;
626 pLed->BlinkingLedState = LED_STATE_ON;
627 mod_timer(&pLed->BlinkTimer, jiffies +
628 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
629 pLed->bLedScanBlinkInProgress = false;
632 pLed->BlinkingLedState = LED_STATE_OFF;
634 pLed->BlinkingLedState = LED_STATE_ON;
635 mod_timer(&pLed->BlinkTimer, jiffies +
636 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
641 if (pLed->BlinkTimes == 0)
642 bStopBlinking = true;
644 pLed->bLedNoLinkBlinkInProgress = true;
645 pLed->CurrLedState = LED_BLINK_SLOWLY;
647 pLed->BlinkingLedState = LED_STATE_OFF;
649 pLed->BlinkingLedState = LED_STATE_ON;
650 mod_timer(&pLed->BlinkTimer, jiffies +
651 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
652 pLed->bLedBlinkInProgress = false;
655 pLed->BlinkingLedState = LED_STATE_OFF;
657 pLed->BlinkingLedState = LED_STATE_ON;
658 mod_timer(&pLed->BlinkTimer, jiffies +
659 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
664 pLed->BlinkingLedState = LED_STATE_OFF;
665 mod_timer(&pLed->BlinkTimer, jiffies +
666 msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
668 pLed->BlinkingLedState = LED_STATE_ON;
669 mod_timer(&pLed->BlinkTimer, jiffies +
670 msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
673 case LED_BLINK_WPS_STOP: /*WPS authentication fail*/
675 pLed->BlinkingLedState = LED_STATE_OFF;
677 pLed->BlinkingLedState = LED_STATE_ON;
678 mod_timer(&pLed->BlinkTimer, jiffies +
679 msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
681 case LED_BLINK_WPS_STOP_OVERLAP: /*WPS session overlap */
683 if (pLed->BlinkTimes == 0) {
685 pLed->BlinkTimes = 1;
687 bStopBlinking = true;
690 pLed->BlinkTimes = 10;
691 pLed->BlinkingLedState = LED_STATE_ON;
692 mod_timer(&pLed->BlinkTimer, jiffies +
693 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
696 pLed->BlinkingLedState = LED_STATE_OFF;
698 pLed->BlinkingLedState = LED_STATE_ON;
699 mod_timer(&pLed->BlinkTimer, jiffies +
700 msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
708 static void SwLedBlink5(struct LED_871x *pLed)
710 struct _adapter *padapter = pLed->padapter;
711 u8 bStopBlinking = false;
713 /* Change LED according to BlinkingLedState specified. */
714 if (pLed->BlinkingLedState == LED_STATE_ON)
715 SwLedOn(padapter, pLed);
717 SwLedOff(padapter, pLed);
718 switch (pLed->CurrLedState) {
721 if (pLed->BlinkTimes == 0)
722 bStopBlinking = true;
724 pLed->CurrLedState = LED_STATE_ON;
725 pLed->BlinkingLedState = LED_STATE_ON;
727 mod_timer(&pLed->BlinkTimer, jiffies +
728 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
729 pLed->bLedScanBlinkInProgress = false;
732 pLed->BlinkingLedState = LED_STATE_OFF;
734 pLed->BlinkingLedState = LED_STATE_ON;
735 mod_timer(&pLed->BlinkTimer, jiffies +
736 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
741 if (pLed->BlinkTimes == 0)
742 bStopBlinking = true;
744 pLed->CurrLedState = LED_STATE_ON;
745 pLed->BlinkingLedState = LED_STATE_ON;
747 mod_timer(&pLed->BlinkTimer, jiffies +
748 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
749 pLed->bLedBlinkInProgress = false;
752 pLed->BlinkingLedState = LED_STATE_OFF;
754 pLed->BlinkingLedState = LED_STATE_ON;
755 mod_timer(&pLed->BlinkTimer, jiffies +
756 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
764 static void SwLedBlink6(struct LED_871x *pLed)
766 struct _adapter *padapter = pLed->padapter;
767 u8 bStopBlinking = false;
769 /* Change LED according to BlinkingLedState specified. */
770 if (pLed->BlinkingLedState == LED_STATE_ON)
771 SwLedOn(padapter, pLed);
773 SwLedOff(padapter, pLed);
774 switch (pLed->CurrLedState) {
777 if (pLed->BlinkTimes == 0)
778 bStopBlinking = true;
780 pLed->CurrLedState = LED_STATE_ON;
781 pLed->BlinkingLedState = LED_STATE_ON;
783 SwLedOn(padapter, pLed);
784 pLed->bLedBlinkInProgress = false;
787 pLed->BlinkingLedState = LED_STATE_OFF;
789 pLed->BlinkingLedState = LED_STATE_ON;
790 mod_timer(&pLed->BlinkTimer, jiffies +
791 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
796 pLed->BlinkingLedState = LED_STATE_OFF;
798 pLed->BlinkingLedState = LED_STATE_ON;
799 mod_timer(&pLed->BlinkTimer, jiffies +
800 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
809 * Callback function of LED BlinkTimer,
810 * it just schedules to corresponding BlinkWorkItem.
812 static void BlinkTimerCallback(struct timer_list *t)
814 struct LED_871x *pLed = from_timer(pLed, t, BlinkTimer);
816 /* This fixed the crash problem on Fedora 12 when trying to do the
817 * insmod;ifconfig up;rmmod commands.
819 if (pLed->padapter->surprise_removed || pLed->padapter->driver_stopped)
821 schedule_work(&pLed->BlinkWorkItem);
825 * Callback function of LED BlinkWorkItem.
826 * We dispatch actual LED blink action according to LedStrategy.
828 static void BlinkWorkItemCallback(struct work_struct *work)
830 struct LED_871x *pLed = container_of(work, struct LED_871x,
832 struct led_priv *ledpriv = &pLed->padapter->ledpriv;
834 switch (ledpriv->LedStrategy) {
862 /*============================================================================
863 * Default LED behavior.
864 *============================================================================
867 * Implement each led action for SW_LED_MODE0.
868 * This is default strategy.
871 static void SwLedControlMode1(struct _adapter *padapter,
872 enum LED_CTL_MODE LedAction)
874 struct led_priv *ledpriv = &padapter->ledpriv;
875 struct LED_871x *pLed = &ledpriv->SwLed0;
876 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
877 struct sitesurvey_ctrl *psitesurveyctrl = &pmlmepriv->sitesurveyctrl;
879 if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO)
880 pLed = &ledpriv->SwLed1;
882 case LED_CTL_START_TO_LINK:
883 case LED_CTL_NO_LINK:
884 if (!pLed->bLedNoLinkBlinkInProgress) {
885 if (pLed->CurrLedState == LED_SCAN_BLINK ||
886 IS_LED_WPS_BLINKING(pLed))
888 if (pLed->bLedLinkBlinkInProgress) {
889 del_timer(&pLed->BlinkTimer);
890 pLed->bLedLinkBlinkInProgress = false;
892 if (pLed->bLedBlinkInProgress) {
893 del_timer(&pLed->BlinkTimer);
894 pLed->bLedBlinkInProgress = false;
896 pLed->bLedNoLinkBlinkInProgress = true;
897 pLed->CurrLedState = LED_BLINK_SLOWLY;
899 pLed->BlinkingLedState = LED_STATE_OFF;
901 pLed->BlinkingLedState = LED_STATE_ON;
902 mod_timer(&pLed->BlinkTimer, jiffies +
903 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
907 if (!pLed->bLedLinkBlinkInProgress) {
908 if (pLed->CurrLedState == LED_SCAN_BLINK ||
909 IS_LED_WPS_BLINKING(pLed))
911 if (pLed->bLedNoLinkBlinkInProgress) {
912 del_timer(&pLed->BlinkTimer);
913 pLed->bLedNoLinkBlinkInProgress = false;
915 if (pLed->bLedBlinkInProgress) {
916 del_timer(&pLed->BlinkTimer);
917 pLed->bLedBlinkInProgress = false;
919 pLed->bLedLinkBlinkInProgress = true;
920 pLed->CurrLedState = LED_BLINK_NORMAL;
922 pLed->BlinkingLedState = LED_STATE_OFF;
924 pLed->BlinkingLedState = LED_STATE_ON;
925 mod_timer(&pLed->BlinkTimer, jiffies +
926 msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
929 case LED_CTL_SITE_SURVEY:
930 if (psitesurveyctrl->traffic_busy &&
931 check_fwstate(pmlmepriv, _FW_LINKED))
933 else if (!pLed->bLedScanBlinkInProgress) {
934 if (IS_LED_WPS_BLINKING(pLed))
936 if (pLed->bLedNoLinkBlinkInProgress) {
937 del_timer(&pLed->BlinkTimer);
938 pLed->bLedNoLinkBlinkInProgress = false;
940 if (pLed->bLedLinkBlinkInProgress) {
941 del_timer(&pLed->BlinkTimer);
942 pLed->bLedLinkBlinkInProgress = false;
944 if (pLed->bLedBlinkInProgress) {
945 del_timer(&pLed->BlinkTimer);
946 pLed->bLedBlinkInProgress = false;
948 pLed->bLedScanBlinkInProgress = true;
949 pLed->CurrLedState = LED_SCAN_BLINK;
950 pLed->BlinkTimes = 24;
952 pLed->BlinkingLedState = LED_STATE_OFF;
954 pLed->BlinkingLedState = LED_STATE_ON;
955 mod_timer(&pLed->BlinkTimer, jiffies +
956 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
961 if (!pLed->bLedBlinkInProgress) {
962 if (pLed->CurrLedState == LED_SCAN_BLINK ||
963 IS_LED_WPS_BLINKING(pLed))
965 if (pLed->bLedNoLinkBlinkInProgress) {
966 del_timer(&pLed->BlinkTimer);
967 pLed->bLedNoLinkBlinkInProgress = false;
969 if (pLed->bLedLinkBlinkInProgress) {
970 del_timer(&pLed->BlinkTimer);
971 pLed->bLedLinkBlinkInProgress = false;
973 pLed->bLedBlinkInProgress = true;
974 pLed->CurrLedState = LED_TXRX_BLINK;
975 pLed->BlinkTimes = 2;
977 pLed->BlinkingLedState = LED_STATE_OFF;
979 pLed->BlinkingLedState = LED_STATE_ON;
980 mod_timer(&pLed->BlinkTimer, jiffies +
981 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
985 case LED_CTL_START_WPS: /*wait until xinpin finish */
986 case LED_CTL_START_WPS_BOTTON:
987 if (!pLed->bLedWPSBlinkInProgress) {
988 if (pLed->bLedNoLinkBlinkInProgress) {
989 del_timer(&pLed->BlinkTimer);
990 pLed->bLedNoLinkBlinkInProgress = false;
992 if (pLed->bLedLinkBlinkInProgress) {
993 del_timer(&pLed->BlinkTimer);
994 pLed->bLedLinkBlinkInProgress = false;
996 if (pLed->bLedBlinkInProgress) {
997 del_timer(&pLed->BlinkTimer);
998 pLed->bLedBlinkInProgress = false;
1000 if (pLed->bLedScanBlinkInProgress) {
1001 del_timer(&pLed->BlinkTimer);
1002 pLed->bLedScanBlinkInProgress = false;
1004 pLed->bLedWPSBlinkInProgress = true;
1005 pLed->CurrLedState = LED_BLINK_WPS;
1007 pLed->BlinkingLedState = LED_STATE_OFF;
1009 pLed->BlinkingLedState = LED_STATE_ON;
1010 mod_timer(&pLed->BlinkTimer, jiffies +
1011 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1014 case LED_CTL_STOP_WPS:
1015 if (pLed->bLedNoLinkBlinkInProgress) {
1016 del_timer(&pLed->BlinkTimer);
1017 pLed->bLedNoLinkBlinkInProgress = false;
1019 if (pLed->bLedLinkBlinkInProgress) {
1020 del_timer(&pLed->BlinkTimer);
1021 pLed->bLedLinkBlinkInProgress = false;
1023 if (pLed->bLedBlinkInProgress) {
1024 del_timer(&pLed->BlinkTimer);
1025 pLed->bLedBlinkInProgress = false;
1027 if (pLed->bLedScanBlinkInProgress) {
1028 del_timer(&pLed->BlinkTimer);
1029 pLed->bLedScanBlinkInProgress = false;
1031 if (pLed->bLedWPSBlinkInProgress)
1032 del_timer(&pLed->BlinkTimer);
1034 pLed->bLedWPSBlinkInProgress = true;
1035 pLed->CurrLedState = LED_BLINK_WPS_STOP;
1037 pLed->BlinkingLedState = LED_STATE_OFF;
1038 mod_timer(&pLed->BlinkTimer, jiffies +
1039 msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
1041 pLed->BlinkingLedState = LED_STATE_ON;
1042 mod_timer(&pLed->BlinkTimer,
1043 jiffies + msecs_to_jiffies(0));
1046 case LED_CTL_STOP_WPS_FAIL:
1047 if (pLed->bLedWPSBlinkInProgress) {
1048 del_timer(&pLed->BlinkTimer);
1049 pLed->bLedWPSBlinkInProgress = false;
1051 pLed->bLedNoLinkBlinkInProgress = true;
1052 pLed->CurrLedState = LED_BLINK_SLOWLY;
1054 pLed->BlinkingLedState = LED_STATE_OFF;
1056 pLed->BlinkingLedState = LED_STATE_ON;
1057 mod_timer(&pLed->BlinkTimer, jiffies +
1058 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1060 case LED_CTL_POWER_OFF:
1061 pLed->CurrLedState = LED_STATE_OFF;
1062 pLed->BlinkingLedState = LED_STATE_OFF;
1063 if (pLed->bLedNoLinkBlinkInProgress) {
1064 del_timer(&pLed->BlinkTimer);
1065 pLed->bLedNoLinkBlinkInProgress = false;
1067 if (pLed->bLedLinkBlinkInProgress) {
1068 del_timer(&pLed->BlinkTimer);
1069 pLed->bLedLinkBlinkInProgress = false;
1071 if (pLed->bLedBlinkInProgress) {
1072 del_timer(&pLed->BlinkTimer);
1073 pLed->bLedBlinkInProgress = false;
1075 if (pLed->bLedWPSBlinkInProgress) {
1076 del_timer(&pLed->BlinkTimer);
1077 pLed->bLedWPSBlinkInProgress = false;
1079 if (pLed->bLedScanBlinkInProgress) {
1080 del_timer(&pLed->BlinkTimer);
1081 pLed->bLedScanBlinkInProgress = false;
1083 mod_timer(&pLed->BlinkTimer,
1084 jiffies + msecs_to_jiffies(0));
1091 static void SwLedControlMode2(struct _adapter *padapter,
1092 enum LED_CTL_MODE LedAction)
1094 struct led_priv *ledpriv = &padapter->ledpriv;
1095 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1096 struct LED_871x *pLed = &ledpriv->SwLed0;
1098 switch (LedAction) {
1099 case LED_CTL_SITE_SURVEY:
1100 if (pmlmepriv->sitesurveyctrl.traffic_busy)
1101 ; /* dummy branch */
1102 else if (!pLed->bLedScanBlinkInProgress) {
1103 if (IS_LED_WPS_BLINKING(pLed))
1106 if (pLed->bLedBlinkInProgress) {
1107 del_timer(&pLed->BlinkTimer);
1108 pLed->bLedBlinkInProgress = false;
1110 pLed->bLedScanBlinkInProgress = true;
1111 pLed->CurrLedState = LED_SCAN_BLINK;
1112 pLed->BlinkTimes = 24;
1114 pLed->BlinkingLedState = LED_STATE_OFF;
1116 pLed->BlinkingLedState = LED_STATE_ON;
1117 mod_timer(&pLed->BlinkTimer, jiffies +
1118 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1124 if (!pLed->bLedBlinkInProgress &&
1125 check_fwstate(pmlmepriv, _FW_LINKED)) {
1126 if (pLed->CurrLedState == LED_SCAN_BLINK ||
1127 IS_LED_WPS_BLINKING(pLed))
1129 pLed->bLedBlinkInProgress = true;
1130 pLed->CurrLedState = LED_TXRX_BLINK;
1131 pLed->BlinkTimes = 2;
1133 pLed->BlinkingLedState = LED_STATE_OFF;
1135 pLed->BlinkingLedState = LED_STATE_ON;
1136 mod_timer(&pLed->BlinkTimer, jiffies +
1137 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1142 pLed->CurrLedState = LED_STATE_ON;
1143 pLed->BlinkingLedState = LED_STATE_ON;
1144 if (pLed->bLedBlinkInProgress) {
1145 del_timer(&pLed->BlinkTimer);
1146 pLed->bLedBlinkInProgress = false;
1148 if (pLed->bLedScanBlinkInProgress) {
1149 del_timer(&pLed->BlinkTimer);
1150 pLed->bLedScanBlinkInProgress = false;
1153 mod_timer(&pLed->BlinkTimer,
1154 jiffies + msecs_to_jiffies(0));
1157 case LED_CTL_START_WPS: /*wait until xinpin finish*/
1158 case LED_CTL_START_WPS_BOTTON:
1159 if (!pLed->bLedWPSBlinkInProgress) {
1160 if (pLed->bLedBlinkInProgress) {
1161 del_timer(&pLed->BlinkTimer);
1162 pLed->bLedBlinkInProgress = false;
1164 if (pLed->bLedScanBlinkInProgress) {
1165 del_timer(&pLed->BlinkTimer);
1166 pLed->bLedScanBlinkInProgress = false;
1168 pLed->bLedWPSBlinkInProgress = true;
1169 pLed->CurrLedState = LED_STATE_ON;
1170 pLed->BlinkingLedState = LED_STATE_ON;
1171 mod_timer(&pLed->BlinkTimer,
1172 jiffies + msecs_to_jiffies(0));
1176 case LED_CTL_STOP_WPS:
1177 pLed->bLedWPSBlinkInProgress = false;
1178 pLed->CurrLedState = LED_STATE_ON;
1179 pLed->BlinkingLedState = LED_STATE_ON;
1180 mod_timer(&pLed->BlinkTimer,
1181 jiffies + msecs_to_jiffies(0));
1184 case LED_CTL_STOP_WPS_FAIL:
1185 pLed->bLedWPSBlinkInProgress = false;
1186 pLed->CurrLedState = LED_STATE_OFF;
1187 pLed->BlinkingLedState = LED_STATE_OFF;
1188 mod_timer(&pLed->BlinkTimer,
1189 jiffies + msecs_to_jiffies(0));
1192 case LED_CTL_START_TO_LINK:
1193 case LED_CTL_NO_LINK:
1194 if (!IS_LED_BLINKING(pLed)) {
1195 pLed->CurrLedState = LED_STATE_OFF;
1196 pLed->BlinkingLedState = LED_STATE_OFF;
1197 mod_timer(&pLed->BlinkTimer,
1198 jiffies + msecs_to_jiffies(0));
1201 case LED_CTL_POWER_OFF:
1202 pLed->CurrLedState = LED_STATE_OFF;
1203 pLed->BlinkingLedState = LED_STATE_OFF;
1204 if (pLed->bLedBlinkInProgress) {
1205 del_timer(&pLed->BlinkTimer);
1206 pLed->bLedBlinkInProgress = false;
1208 if (pLed->bLedScanBlinkInProgress) {
1209 del_timer(&pLed->BlinkTimer);
1210 pLed->bLedScanBlinkInProgress = false;
1212 if (pLed->bLedWPSBlinkInProgress) {
1213 del_timer(&pLed->BlinkTimer);
1214 pLed->bLedWPSBlinkInProgress = false;
1216 mod_timer(&pLed->BlinkTimer,
1217 jiffies + msecs_to_jiffies(0));
1224 static void SwLedControlMode3(struct _adapter *padapter,
1225 enum LED_CTL_MODE LedAction)
1227 struct led_priv *ledpriv = &padapter->ledpriv;
1228 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1229 struct LED_871x *pLed = &ledpriv->SwLed0;
1231 switch (LedAction) {
1232 case LED_CTL_SITE_SURVEY:
1233 if (pmlmepriv->sitesurveyctrl.traffic_busy)
1234 ; /* dummy branch */
1235 else if (!pLed->bLedScanBlinkInProgress) {
1236 if (IS_LED_WPS_BLINKING(pLed))
1238 if (pLed->bLedBlinkInProgress) {
1239 del_timer(&pLed->BlinkTimer);
1240 pLed->bLedBlinkInProgress = false;
1242 pLed->bLedScanBlinkInProgress = true;
1243 pLed->CurrLedState = LED_SCAN_BLINK;
1244 pLed->BlinkTimes = 24;
1246 pLed->BlinkingLedState = LED_STATE_OFF;
1248 pLed->BlinkingLedState = LED_STATE_ON;
1249 mod_timer(&pLed->BlinkTimer, jiffies +
1250 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1255 if (!pLed->bLedBlinkInProgress &&
1256 check_fwstate(pmlmepriv, _FW_LINKED)) {
1257 if (pLed->CurrLedState == LED_SCAN_BLINK ||
1258 IS_LED_WPS_BLINKING(pLed))
1260 pLed->bLedBlinkInProgress = true;
1261 pLed->CurrLedState = LED_TXRX_BLINK;
1262 pLed->BlinkTimes = 2;
1264 pLed->BlinkingLedState = LED_STATE_OFF;
1266 pLed->BlinkingLedState = LED_STATE_ON;
1267 mod_timer(&pLed->BlinkTimer, jiffies +
1268 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1272 if (IS_LED_WPS_BLINKING(pLed))
1274 pLed->CurrLedState = LED_STATE_ON;
1275 pLed->BlinkingLedState = LED_STATE_ON;
1276 if (pLed->bLedBlinkInProgress) {
1277 del_timer(&pLed->BlinkTimer);
1278 pLed->bLedBlinkInProgress = false;
1280 if (pLed->bLedScanBlinkInProgress) {
1281 del_timer(&pLed->BlinkTimer);
1282 pLed->bLedScanBlinkInProgress = false;
1284 mod_timer(&pLed->BlinkTimer,
1285 jiffies + msecs_to_jiffies(0));
1287 case LED_CTL_START_WPS: /* wait until xinpin finish */
1288 case LED_CTL_START_WPS_BOTTON:
1289 if (!pLed->bLedWPSBlinkInProgress) {
1290 if (pLed->bLedBlinkInProgress) {
1291 del_timer(&pLed->BlinkTimer);
1292 pLed->bLedBlinkInProgress = false;
1294 if (pLed->bLedScanBlinkInProgress) {
1295 del_timer(&pLed->BlinkTimer);
1296 pLed->bLedScanBlinkInProgress = false;
1298 pLed->bLedWPSBlinkInProgress = true;
1299 pLed->CurrLedState = LED_BLINK_WPS;
1301 pLed->BlinkingLedState = LED_STATE_OFF;
1303 pLed->BlinkingLedState = LED_STATE_ON;
1304 mod_timer(&pLed->BlinkTimer, jiffies +
1305 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1308 case LED_CTL_STOP_WPS:
1309 if (pLed->bLedWPSBlinkInProgress) {
1310 del_timer(&pLed->BlinkTimer);
1311 pLed->bLedWPSBlinkInProgress = false;
1313 pLed->bLedWPSBlinkInProgress = true;
1315 pLed->CurrLedState = LED_BLINK_WPS_STOP;
1317 pLed->BlinkingLedState = LED_STATE_OFF;
1318 mod_timer(&pLed->BlinkTimer, jiffies +
1319 msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
1321 pLed->BlinkingLedState = LED_STATE_ON;
1322 mod_timer(&pLed->BlinkTimer,
1323 jiffies + msecs_to_jiffies(0));
1326 case LED_CTL_STOP_WPS_FAIL:
1327 if (pLed->bLedWPSBlinkInProgress) {
1328 del_timer(&pLed->BlinkTimer);
1329 pLed->bLedWPSBlinkInProgress = false;
1331 pLed->CurrLedState = LED_STATE_OFF;
1332 pLed->BlinkingLedState = LED_STATE_OFF;
1333 mod_timer(&pLed->BlinkTimer,
1334 jiffies + msecs_to_jiffies(0));
1336 case LED_CTL_START_TO_LINK:
1337 case LED_CTL_NO_LINK:
1338 if (!IS_LED_BLINKING(pLed)) {
1339 pLed->CurrLedState = LED_STATE_OFF;
1340 pLed->BlinkingLedState = LED_STATE_OFF;
1341 mod_timer(&pLed->BlinkTimer,
1342 jiffies + msecs_to_jiffies(0));
1345 case LED_CTL_POWER_OFF:
1346 pLed->CurrLedState = LED_STATE_OFF;
1347 pLed->BlinkingLedState = LED_STATE_OFF;
1348 if (pLed->bLedBlinkInProgress) {
1349 del_timer(&pLed->BlinkTimer);
1350 pLed->bLedBlinkInProgress = false;
1352 if (pLed->bLedScanBlinkInProgress) {
1353 del_timer(&pLed->BlinkTimer);
1354 pLed->bLedScanBlinkInProgress = false;
1356 if (pLed->bLedWPSBlinkInProgress) {
1357 del_timer(&pLed->BlinkTimer);
1358 pLed->bLedWPSBlinkInProgress = false;
1360 mod_timer(&pLed->BlinkTimer,
1361 jiffies + msecs_to_jiffies(0));
1368 static void SwLedControlMode4(struct _adapter *padapter,
1369 enum LED_CTL_MODE LedAction)
1371 struct led_priv *ledpriv = &padapter->ledpriv;
1372 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1373 struct LED_871x *pLed = &ledpriv->SwLed0;
1374 struct LED_871x *pLed1 = &ledpriv->SwLed1;
1376 switch (LedAction) {
1377 case LED_CTL_START_TO_LINK:
1378 if (pLed1->bLedWPSBlinkInProgress) {
1379 pLed1->bLedWPSBlinkInProgress = false;
1380 del_timer(&pLed1->BlinkTimer);
1381 pLed1->BlinkingLedState = LED_STATE_OFF;
1382 pLed1->CurrLedState = LED_STATE_OFF;
1384 mod_timer(&pLed->BlinkTimer,
1385 jiffies + msecs_to_jiffies(0));
1387 if (!pLed->bLedStartToLinkBlinkInProgress) {
1388 if (pLed->CurrLedState == LED_SCAN_BLINK ||
1389 IS_LED_WPS_BLINKING(pLed))
1391 if (pLed->bLedBlinkInProgress) {
1392 del_timer(&pLed->BlinkTimer);
1393 pLed->bLedBlinkInProgress = false;
1395 if (pLed->bLedNoLinkBlinkInProgress) {
1396 del_timer(&pLed->BlinkTimer);
1397 pLed->bLedNoLinkBlinkInProgress = false;
1399 pLed->bLedStartToLinkBlinkInProgress = true;
1400 pLed->CurrLedState = LED_BLINK_StartToBlink;
1402 pLed->BlinkingLedState = LED_STATE_OFF;
1403 mod_timer(&pLed->BlinkTimer, jiffies +
1404 msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
1406 pLed->BlinkingLedState = LED_STATE_ON;
1407 mod_timer(&pLed->BlinkTimer, jiffies +
1408 msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
1413 case LED_CTL_NO_LINK:
1415 if (LedAction == LED_CTL_LINK) {
1416 if (pLed1->bLedWPSBlinkInProgress) {
1417 pLed1->bLedWPSBlinkInProgress = false;
1418 del_timer(&pLed1->BlinkTimer);
1419 pLed1->BlinkingLedState = LED_STATE_OFF;
1420 pLed1->CurrLedState = LED_STATE_OFF;
1422 mod_timer(&pLed->BlinkTimer,
1423 jiffies + msecs_to_jiffies(0));
1426 if (!pLed->bLedNoLinkBlinkInProgress) {
1427 if (pLed->CurrLedState == LED_SCAN_BLINK ||
1428 IS_LED_WPS_BLINKING(pLed))
1430 if (pLed->bLedBlinkInProgress) {
1431 del_timer(&pLed->BlinkTimer);
1432 pLed->bLedBlinkInProgress = false;
1434 pLed->bLedNoLinkBlinkInProgress = true;
1435 pLed->CurrLedState = LED_BLINK_SLOWLY;
1437 pLed->BlinkingLedState = LED_STATE_OFF;
1439 pLed->BlinkingLedState = LED_STATE_ON;
1440 mod_timer(&pLed->BlinkTimer, jiffies +
1441 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1444 case LED_CTL_SITE_SURVEY:
1445 if (pmlmepriv->sitesurveyctrl.traffic_busy &&
1446 check_fwstate(pmlmepriv, _FW_LINKED))
1448 else if (!pLed->bLedScanBlinkInProgress) {
1449 if (IS_LED_WPS_BLINKING(pLed))
1451 if (pLed->bLedNoLinkBlinkInProgress) {
1452 del_timer(&pLed->BlinkTimer);
1453 pLed->bLedNoLinkBlinkInProgress = false;
1455 if (pLed->bLedBlinkInProgress) {
1456 del_timer(&pLed->BlinkTimer);
1457 pLed->bLedBlinkInProgress = false;
1459 pLed->bLedScanBlinkInProgress = true;
1460 pLed->CurrLedState = LED_SCAN_BLINK;
1461 pLed->BlinkTimes = 24;
1463 pLed->BlinkingLedState = LED_STATE_OFF;
1465 pLed->BlinkingLedState = LED_STATE_ON;
1466 mod_timer(&pLed->BlinkTimer, jiffies +
1467 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1472 if (!pLed->bLedBlinkInProgress) {
1473 if (pLed->CurrLedState == LED_SCAN_BLINK ||
1474 IS_LED_WPS_BLINKING(pLed))
1476 if (pLed->bLedNoLinkBlinkInProgress) {
1477 del_timer(&pLed->BlinkTimer);
1478 pLed->bLedNoLinkBlinkInProgress = false;
1480 pLed->bLedBlinkInProgress = true;
1481 pLed->CurrLedState = LED_TXRX_BLINK;
1482 pLed->BlinkTimes = 2;
1484 pLed->BlinkingLedState = LED_STATE_OFF;
1486 pLed->BlinkingLedState = LED_STATE_ON;
1487 mod_timer(&pLed->BlinkTimer, jiffies +
1488 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1491 case LED_CTL_START_WPS: /*wait until xinpin finish*/
1492 case LED_CTL_START_WPS_BOTTON:
1493 if (pLed1->bLedWPSBlinkInProgress) {
1494 pLed1->bLedWPSBlinkInProgress = false;
1495 del_timer(&pLed1->BlinkTimer);
1496 pLed1->BlinkingLedState = LED_STATE_OFF;
1497 pLed1->CurrLedState = LED_STATE_OFF;
1499 mod_timer(&pLed->BlinkTimer,
1500 jiffies + msecs_to_jiffies(0));
1502 if (!pLed->bLedWPSBlinkInProgress) {
1503 if (pLed->bLedNoLinkBlinkInProgress) {
1504 del_timer(&pLed->BlinkTimer);
1505 pLed->bLedNoLinkBlinkInProgress = false;
1507 if (pLed->bLedBlinkInProgress) {
1508 del_timer(&pLed->BlinkTimer);
1509 pLed->bLedBlinkInProgress = false;
1511 if (pLed->bLedScanBlinkInProgress) {
1512 del_timer(&pLed->BlinkTimer);
1513 pLed->bLedScanBlinkInProgress = false;
1515 pLed->bLedWPSBlinkInProgress = true;
1516 pLed->CurrLedState = LED_BLINK_WPS;
1518 pLed->BlinkingLedState = LED_STATE_OFF;
1519 mod_timer(&pLed->BlinkTimer, jiffies +
1520 msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
1522 pLed->BlinkingLedState = LED_STATE_ON;
1523 mod_timer(&pLed->BlinkTimer, jiffies +
1524 msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
1528 case LED_CTL_STOP_WPS: /*WPS connect success*/
1529 if (pLed->bLedWPSBlinkInProgress) {
1530 del_timer(&pLed->BlinkTimer);
1531 pLed->bLedWPSBlinkInProgress = false;
1533 pLed->bLedNoLinkBlinkInProgress = true;
1534 pLed->CurrLedState = LED_BLINK_SLOWLY;
1536 pLed->BlinkingLedState = LED_STATE_OFF;
1538 pLed->BlinkingLedState = LED_STATE_ON;
1539 mod_timer(&pLed->BlinkTimer, jiffies +
1540 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1542 case LED_CTL_STOP_WPS_FAIL: /*WPS authentication fail*/
1543 if (pLed->bLedWPSBlinkInProgress) {
1544 del_timer(&pLed->BlinkTimer);
1545 pLed->bLedWPSBlinkInProgress = false;
1547 pLed->bLedNoLinkBlinkInProgress = true;
1548 pLed->CurrLedState = LED_BLINK_SLOWLY;
1550 pLed->BlinkingLedState = LED_STATE_OFF;
1552 pLed->BlinkingLedState = LED_STATE_ON;
1553 mod_timer(&pLed->BlinkTimer, jiffies +
1554 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1556 if (pLed1->bLedWPSBlinkInProgress)
1557 del_timer(&pLed1->BlinkTimer);
1559 pLed1->bLedWPSBlinkInProgress = true;
1560 pLed1->CurrLedState = LED_BLINK_WPS_STOP;
1562 pLed1->BlinkingLedState = LED_STATE_OFF;
1564 pLed1->BlinkingLedState = LED_STATE_ON;
1565 mod_timer(&pLed->BlinkTimer, jiffies +
1566 msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
1568 case LED_CTL_STOP_WPS_FAIL_OVERLAP: /*WPS session overlap*/
1569 if (pLed->bLedWPSBlinkInProgress) {
1570 del_timer(&pLed->BlinkTimer);
1571 pLed->bLedWPSBlinkInProgress = false;
1573 pLed->bLedNoLinkBlinkInProgress = true;
1574 pLed->CurrLedState = LED_BLINK_SLOWLY;
1576 pLed->BlinkingLedState = LED_STATE_OFF;
1578 pLed->BlinkingLedState = LED_STATE_ON;
1579 mod_timer(&pLed->BlinkTimer, jiffies +
1580 msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1582 if (pLed1->bLedWPSBlinkInProgress)
1583 del_timer(&pLed1->BlinkTimer);
1585 pLed1->bLedWPSBlinkInProgress = true;
1586 pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
1587 pLed1->BlinkTimes = 10;
1589 pLed1->BlinkingLedState = LED_STATE_OFF;
1591 pLed1->BlinkingLedState = LED_STATE_ON;
1592 mod_timer(&pLed->BlinkTimer, jiffies +
1593 msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
1595 case LED_CTL_POWER_OFF:
1596 pLed->CurrLedState = LED_STATE_OFF;
1597 pLed->BlinkingLedState = LED_STATE_OFF;
1598 if (pLed->bLedNoLinkBlinkInProgress) {
1599 del_timer(&pLed->BlinkTimer);
1600 pLed->bLedNoLinkBlinkInProgress = false;
1602 if (pLed->bLedLinkBlinkInProgress) {
1603 del_timer(&pLed->BlinkTimer);
1604 pLed->bLedLinkBlinkInProgress = false;
1606 if (pLed->bLedBlinkInProgress) {
1607 del_timer(&pLed->BlinkTimer);
1608 pLed->bLedBlinkInProgress = false;
1610 if (pLed->bLedWPSBlinkInProgress) {
1611 del_timer(&pLed->BlinkTimer);
1612 pLed->bLedWPSBlinkInProgress = false;
1614 if (pLed->bLedScanBlinkInProgress) {
1615 del_timer(&pLed->BlinkTimer);
1616 pLed->bLedScanBlinkInProgress = false;
1618 if (pLed->bLedStartToLinkBlinkInProgress) {
1619 del_timer(&pLed->BlinkTimer);
1620 pLed->bLedStartToLinkBlinkInProgress = false;
1622 if (pLed1->bLedWPSBlinkInProgress) {
1623 del_timer(&pLed1->BlinkTimer);
1624 pLed1->bLedWPSBlinkInProgress = false;
1626 pLed1->BlinkingLedState = LED_UNKNOWN;
1627 SwLedOff(padapter, pLed);
1628 SwLedOff(padapter, pLed1);
1635 static void SwLedControlMode5(struct _adapter *padapter,
1636 enum LED_CTL_MODE LedAction)
1638 struct led_priv *ledpriv = &padapter->ledpriv;
1639 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1640 struct LED_871x *pLed = &ledpriv->SwLed0;
1642 if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO)
1643 pLed = &ledpriv->SwLed1;
1645 switch (LedAction) {
1646 case LED_CTL_POWER_ON:
1647 case LED_CTL_NO_LINK:
1648 case LED_CTL_LINK: /* solid blue */
1649 if (pLed->CurrLedState == LED_SCAN_BLINK)
1651 pLed->CurrLedState = LED_STATE_ON;
1652 pLed->BlinkingLedState = LED_STATE_ON;
1653 pLed->bLedBlinkInProgress = false;
1654 mod_timer(&pLed->BlinkTimer,
1655 jiffies + msecs_to_jiffies(0));
1657 case LED_CTL_SITE_SURVEY:
1658 if (pmlmepriv->sitesurveyctrl.traffic_busy &&
1659 check_fwstate(pmlmepriv, _FW_LINKED))
1660 ; /* dummy branch */
1661 else if (!pLed->bLedScanBlinkInProgress) {
1662 if (pLed->bLedBlinkInProgress) {
1663 del_timer(&pLed->BlinkTimer);
1664 pLed->bLedBlinkInProgress = false;
1666 pLed->bLedScanBlinkInProgress = true;
1667 pLed->CurrLedState = LED_SCAN_BLINK;
1668 pLed->BlinkTimes = 24;
1670 pLed->BlinkingLedState = LED_STATE_OFF;
1672 pLed->BlinkingLedState = LED_STATE_ON;
1673 mod_timer(&pLed->BlinkTimer, jiffies +
1674 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1679 if (!pLed->bLedBlinkInProgress) {
1680 if (pLed->CurrLedState == LED_SCAN_BLINK)
1682 pLed->bLedBlinkInProgress = true;
1683 pLed->CurrLedState = LED_TXRX_BLINK;
1684 pLed->BlinkTimes = 2;
1686 pLed->BlinkingLedState = LED_STATE_OFF;
1688 pLed->BlinkingLedState = LED_STATE_ON;
1689 mod_timer(&pLed->BlinkTimer, jiffies +
1690 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1693 case LED_CTL_POWER_OFF:
1694 pLed->CurrLedState = LED_STATE_OFF;
1695 pLed->BlinkingLedState = LED_STATE_OFF;
1696 if (pLed->bLedBlinkInProgress) {
1697 del_timer(&pLed->BlinkTimer);
1698 pLed->bLedBlinkInProgress = false;
1700 SwLedOff(padapter, pLed);
1707 static void SwLedControlMode6(struct _adapter *padapter,
1708 enum LED_CTL_MODE LedAction)
1710 struct led_priv *ledpriv = &padapter->ledpriv;
1711 struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1712 struct LED_871x *pLed = &ledpriv->SwLed0;
1714 switch (LedAction) {
1715 case LED_CTL_POWER_ON:
1716 case LED_CTL_NO_LINK:
1717 case LED_CTL_LINK: /*solid blue*/
1718 case LED_CTL_SITE_SURVEY:
1719 if (IS_LED_WPS_BLINKING(pLed))
1721 pLed->CurrLedState = LED_STATE_ON;
1722 pLed->BlinkingLedState = LED_STATE_ON;
1723 pLed->bLedBlinkInProgress = false;
1724 mod_timer(&pLed->BlinkTimer, jiffies + msecs_to_jiffies(0));
1728 if (!pLed->bLedBlinkInProgress &&
1729 check_fwstate(pmlmepriv, _FW_LINKED)) {
1730 if (IS_LED_WPS_BLINKING(pLed))
1732 pLed->bLedBlinkInProgress = true;
1733 pLed->CurrLedState = LED_TXRX_BLINK;
1734 pLed->BlinkTimes = 2;
1736 pLed->BlinkingLedState = LED_STATE_OFF;
1738 pLed->BlinkingLedState = LED_STATE_ON;
1739 mod_timer(&pLed->BlinkTimer, jiffies +
1740 msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1743 case LED_CTL_START_WPS: /*wait until xinpin finish*/
1744 case LED_CTL_START_WPS_BOTTON:
1745 if (!pLed->bLedWPSBlinkInProgress) {
1746 if (pLed->bLedBlinkInProgress) {
1747 del_timer(&pLed->BlinkTimer);
1748 pLed->bLedBlinkInProgress = false;
1750 pLed->bLedWPSBlinkInProgress = true;
1751 pLed->CurrLedState = LED_BLINK_WPS;
1753 pLed->BlinkingLedState = LED_STATE_OFF;
1755 pLed->BlinkingLedState = LED_STATE_ON;
1756 mod_timer(&pLed->BlinkTimer, jiffies +
1757 msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1760 case LED_CTL_STOP_WPS_FAIL:
1761 case LED_CTL_STOP_WPS:
1762 if (pLed->bLedWPSBlinkInProgress) {
1763 del_timer(&pLed->BlinkTimer);
1764 pLed->bLedWPSBlinkInProgress = false;
1766 pLed->CurrLedState = LED_STATE_ON;
1767 pLed->BlinkingLedState = LED_STATE_ON;
1768 mod_timer(&pLed->BlinkTimer,
1769 jiffies + msecs_to_jiffies(0));
1771 case LED_CTL_POWER_OFF:
1772 pLed->CurrLedState = LED_STATE_OFF;
1773 pLed->BlinkingLedState = LED_STATE_OFF;
1774 if (pLed->bLedBlinkInProgress) {
1775 del_timer(&pLed->BlinkTimer);
1776 pLed->bLedBlinkInProgress = false;
1778 if (pLed->bLedWPSBlinkInProgress) {
1779 del_timer(&pLed->BlinkTimer);
1780 pLed->bLedWPSBlinkInProgress = false;
1782 SwLedOff(padapter, pLed);
1790 * Dispatch LED action according to pHalData->LedStrategy.
1792 void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction)
1794 struct led_priv *ledpriv = &padapter->ledpriv;
1796 if (!ledpriv->bRegUseLed)
1798 switch (ledpriv->LedStrategy) {
1802 SwLedControlMode1(padapter, LedAction);
1805 SwLedControlMode2(padapter, LedAction);
1808 SwLedControlMode3(padapter, LedAction);
1811 SwLedControlMode4(padapter, LedAction);
1814 SwLedControlMode5(padapter, LedAction);
1817 SwLedControlMode6(padapter, LedAction);
1824 void r8712_flush_led_works(struct _adapter *padapter)
1826 struct led_priv *pledpriv = &padapter->ledpriv;
1828 flush_work(&pledpriv->SwLed0.BlinkWorkItem);
1829 flush_work(&pledpriv->SwLed1.BlinkWorkItem);