Linux 6.9-rc4
[sfrench/cifs-2.6.git] / drivers / staging / rtl8712 / rtl8712_led.c
1 // SPDX-License-Identifier: GPL-2.0
2 /******************************************************************************
3  * rtl8712_led.c
4  *
5  * Copyright(c) 2007 - 2010  Realtek Corporation. All rights reserved.
6  * Linux device driver for RTL8192SU
7  *
8  * Modifications for inclusion into the Linux staging tree are
9  * Copyright(c) 2010 Larry Finger. All rights reserved.
10  *
11  * Contact information:
12  * WLAN FAE <wlanfae@realtek.com>
13  * Larry Finger <Larry.Finger@lwfinger.net>
14  *
15  ******************************************************************************/
16
17 #include "drv_types.h"
18
19 /*===========================================================================
20  *      Constant.
21  *===========================================================================
22
23  *
24  * Default LED behavior.
25  */
26 #define LED_BLINK_NORMAL_INTERVAL       100
27 #define LED_BLINK_SLOWLY_INTERVAL       200
28 #define LED_BLINK_LONG_INTERVAL 400
29
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
35
36 /*===========================================================================
37  * LED object.
38  *===========================================================================
39  */
40 enum _LED_STATE_871x {
41         LED_UNKNOWN = 0,
42         LED_STATE_ON = 1,
43         LED_STATE_OFF = 2,
44         LED_BLINK_NORMAL = 3,
45         LED_BLINK_SLOWLY = 4,
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
49                              * for scanning.
50                              */
51         LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */
52         LED_BLINK_StartToBlink = 8,/* Customized for Sercomm Printer
53                                     * Server case
54                                     */
55         LED_BLINK_WPS = 9,      /* LED is blinkg during WPS communication */
56         LED_TXRX_BLINK = 10,
57         LED_BLINK_WPS_STOP = 11,        /*for ALPHA */
58         LED_BLINK_WPS_STOP_OVERLAP = 12,        /*for BELKIN */
59 };
60
61 /*===========================================================================
62  *      Prototype of protected function.
63  *===========================================================================
64  */
65 static void BlinkTimerCallback(struct timer_list *t);
66
67 static void BlinkWorkItemCallback(struct work_struct *work);
68 /*===========================================================================
69  * LED_819xUsb routines.
70  *===========================================================================
71  *
72  *
73  *
74  *      Description:
75  *              Initialize an LED_871x object.
76  */
77 static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed,
78                         enum LED_PIN_871x       LedPin)
79 {
80         pLed->padapter = padapter;
81         pLed->LedPin = LedPin;
82         pLed->CurrLedState = LED_STATE_OFF;
83         pLed->bLedOn = false;
84         pLed->bLedBlinkInProgress = false;
85         pLed->BlinkTimes = 0;
86         pLed->BlinkingLedState = LED_UNKNOWN;
87         timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0);
88         INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback);
89 }
90
91 /*
92  *      Description:
93  *              DeInitialize an LED_871x object.
94  */
95 static void DeInitLed871x(struct LED_871x *pLed)
96 {
97         del_timer_sync(&pLed->BlinkTimer);
98         /* We should reset bLedBlinkInProgress if we cancel
99          * the LedControlTimer,
100          */
101         pLed->bLedBlinkInProgress = false;
102 }
103
104 /*
105  *      Description:
106  *              Turn on LED according to LedPin specified.
107  */
108 static void SwLedOn(struct _adapter *padapter, struct LED_871x *pLed)
109 {
110         u8      LedCfg;
111
112         if (padapter->surprise_removed || padapter->driver_stopped)
113                 return;
114         LedCfg = r8712_read8(padapter, LEDCFG);
115         switch (pLed->LedPin) {
116         case LED_PIN_GPIO0:
117                 break;
118         case LED_PIN_LED0:
119                 /* SW control led0 on.*/
120                 r8712_write8(padapter, LEDCFG, LedCfg & 0xf0);
121                 break;
122         case LED_PIN_LED1:
123                 /* SW control led1 on.*/
124                 r8712_write8(padapter, LEDCFG, LedCfg & 0x0f);
125                 break;
126         default:
127                 break;
128         }
129         pLed->bLedOn = true;
130 }
131
132 /*
133  *      Description:
134  *              Turn off LED according to LedPin specified.
135  */
136 static void SwLedOff(struct _adapter *padapter, struct LED_871x *pLed)
137 {
138         u8      LedCfg;
139
140         if (padapter->surprise_removed || padapter->driver_stopped)
141                 return;
142         LedCfg = r8712_read8(padapter, LEDCFG);
143         switch (pLed->LedPin) {
144         case LED_PIN_GPIO0:
145                 break;
146         case LED_PIN_LED0:
147                 LedCfg &= 0xf0; /* Set to software control.*/
148                 r8712_write8(padapter, LEDCFG, (LedCfg | BIT(3)));
149                 break;
150         case LED_PIN_LED1:
151                 LedCfg &= 0x0f; /* Set to software control.*/
152                 r8712_write8(padapter, LEDCFG, (LedCfg | BIT(7)));
153                 break;
154         default:
155                 break;
156         }
157         pLed->bLedOn = false;
158 }
159
160 /*===========================================================================
161  * Interface to manipulate LED objects.
162  *===========================================================================
163  *
164  *      Description:
165  *              Initialize all LED_871x objects.
166  */
167 void r8712_InitSwLeds(struct _adapter *padapter)
168 {
169         struct led_priv *pledpriv = &padapter->ledpriv;
170
171         pledpriv->LedControlHandler = LedControl871x;
172         InitLed871x(padapter, &pledpriv->SwLed0, LED_PIN_LED0);
173         InitLed871x(padapter, &pledpriv->SwLed1, LED_PIN_LED1);
174 }
175
176 /*      Description:
177  *              DeInitialize all LED_819xUsb objects.
178  */
179 void r8712_DeInitSwLeds(struct _adapter *padapter)
180 {
181         struct led_priv *ledpriv = &padapter->ledpriv;
182
183         DeInitLed871x(&ledpriv->SwLed0);
184         DeInitLed871x(&ledpriv->SwLed1);
185 }
186
187 /*      Description:
188  *              Implementation of LED blinking behavior.
189  *              It toggle off LED and schedule corresponding timer if necessary.
190  */
191 static void SwLedBlink(struct LED_871x *pLed)
192 {
193         struct _adapter *padapter = pLed->padapter;
194         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
195         u8 bStopBlinking = false;
196
197         /* Change LED according to BlinkingLedState specified. */
198         if (pLed->BlinkingLedState == LED_STATE_ON)
199                 SwLedOn(padapter, pLed);
200         else
201                 SwLedOff(padapter, pLed);
202         /* Determine if we shall change LED state again. */
203         pLed->BlinkTimes--;
204         switch (pLed->CurrLedState) {
205         case LED_BLINK_NORMAL:
206                 if (pLed->BlinkTimes == 0)
207                         bStopBlinking = true;
208                 break;
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;
219                 break;
220         case LED_BLINK_WPS:
221                 if (pLed->BlinkTimes == 0)
222                         bStopBlinking = true;
223                 break;
224         default:
225                 bStopBlinking = true;
226                 break;
227         }
228         if (bStopBlinking) {
229                 if (check_fwstate(pmlmepriv, _FW_LINKED) &&
230                     !pLed->bLedOn)
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;
236         } else {
237                 /* Assign LED state to toggle. */
238                 if (pLed->BlinkingLedState == LED_STATE_ON)
239                         pLed->BlinkingLedState = LED_STATE_OFF;
240                 else
241                         pLed->BlinkingLedState = LED_STATE_ON;
242
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));
248                         break;
249                 case LED_BLINK_SLOWLY:
250                 case LED_BLINK_StartToBlink:
251                         mod_timer(&pLed->BlinkTimer, jiffies +
252                                   msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
253                         break;
254                 case LED_BLINK_WPS:
255                         mod_timer(&pLed->BlinkTimer, jiffies +
256                                   msecs_to_jiffies(LED_BLINK_LONG_INTERVAL));
257                         break;
258                 default:
259                         mod_timer(&pLed->BlinkTimer, jiffies +
260                                   msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
261                         break;
262                 }
263         }
264 }
265
266 static void SwLedBlink1(struct LED_871x *pLed)
267 {
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;
274
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);
280         else
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);
289                         }
290                 } else {
291                         if (!pLed1->bSWLedCtrl) {
292                                 SwLedOff(padapter, pLed1);
293                                 pLed1->bSWLedCtrl = true;
294                         } else if (pLed1->bLedOn) {
295                                 SwLedOff(padapter, pLed1);
296                         }
297                 }
298         }
299         switch (pLed->CurrLedState) {
300         case LED_BLINK_SLOWLY:
301                 if (pLed->bLedOn)
302                         pLed->BlinkingLedState = LED_STATE_OFF;
303                 else
304                         pLed->BlinkingLedState = LED_STATE_ON;
305                 mod_timer(&pLed->BlinkTimer, jiffies +
306                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
307                 break;
308         case LED_BLINK_NORMAL:
309                 if (pLed->bLedOn)
310                         pLed->BlinkingLedState = LED_STATE_OFF;
311                 else
312                         pLed->BlinkingLedState = LED_STATE_ON;
313                 mod_timer(&pLed->BlinkTimer, jiffies +
314                           msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
315                 break;
316         case LED_SCAN_BLINK:
317                 pLed->BlinkTimes--;
318                 if (pLed->BlinkTimes == 0)
319                         bStopBlinking = true;
320                 if (bStopBlinking) {
321                         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
322                                 pLed->bLedLinkBlinkInProgress = true;
323                                 pLed->CurrLedState = LED_BLINK_NORMAL;
324                                 if (pLed->bLedOn)
325                                         pLed->BlinkingLedState = LED_STATE_OFF;
326                                 else
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;
333                                 if (pLed->bLedOn)
334                                         pLed->BlinkingLedState = LED_STATE_OFF;
335                                 else
336                                         pLed->BlinkingLedState = LED_STATE_ON;
337                                 mod_timer(&pLed->BlinkTimer, jiffies +
338                                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
339                         }
340                         pLed->bLedScanBlinkInProgress = false;
341                 } else {
342                         if (pLed->bLedOn)
343                                 pLed->BlinkingLedState = LED_STATE_OFF;
344                         else
345                                 pLed->BlinkingLedState = LED_STATE_ON;
346                         mod_timer(&pLed->BlinkTimer, jiffies +
347                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
348                 }
349                 break;
350         case LED_TXRX_BLINK:
351                 pLed->BlinkTimes--;
352                 if (pLed->BlinkTimes == 0)
353                         bStopBlinking = true;
354                 if (bStopBlinking) {
355                         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
356                                 pLed->bLedLinkBlinkInProgress = true;
357                                 pLed->CurrLedState = LED_BLINK_NORMAL;
358                                 if (pLed->bLedOn)
359                                         pLed->BlinkingLedState = LED_STATE_OFF;
360                                 else
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;
367                                 if (pLed->bLedOn)
368                                         pLed->BlinkingLedState = LED_STATE_OFF;
369                                 else
370                                         pLed->BlinkingLedState = LED_STATE_ON;
371                                 mod_timer(&pLed->BlinkTimer, jiffies +
372                                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
373                         }
374                         pLed->BlinkTimes = 0;
375                         pLed->bLedBlinkInProgress = false;
376                 } else {
377                         if (pLed->bLedOn)
378                                 pLed->BlinkingLedState = LED_STATE_OFF;
379                         else
380                                 pLed->BlinkingLedState = LED_STATE_ON;
381                         mod_timer(&pLed->BlinkTimer, jiffies +
382                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
383                 }
384                 break;
385         case LED_BLINK_WPS:
386                 if (pLed->bLedOn)
387                         pLed->BlinkingLedState = LED_STATE_OFF;
388                 else
389                         pLed->BlinkingLedState = LED_STATE_ON;
390                 mod_timer(&pLed->BlinkTimer, jiffies +
391                           msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
392                 break;
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;
399                 } else {
400                         bStopBlinking = true;
401                 }
402                 if (bStopBlinking) {
403                         pLed->bLedLinkBlinkInProgress = true;
404                         pLed->CurrLedState = LED_BLINK_NORMAL;
405                         if (pLed->bLedOn)
406                                 pLed->BlinkingLedState = LED_STATE_OFF;
407                         else
408                                 pLed->BlinkingLedState = LED_STATE_ON;
409                         mod_timer(&pLed->BlinkTimer, jiffies +
410                                   msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
411                 }
412                 pLed->bLedWPSBlinkInProgress = false;
413                 break;
414         default:
415                 break;
416         }
417 }
418
419 static void SwLedBlink2(struct LED_871x *pLed)
420 {
421         struct _adapter *padapter = pLed->padapter;
422         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
423         u8 bStopBlinking = false;
424
425         /* Change LED according to BlinkingLedState specified. */
426         if (pLed->BlinkingLedState == LED_STATE_ON)
427                 SwLedOn(padapter, pLed);
428         else
429                 SwLedOff(padapter, pLed);
430         switch (pLed->CurrLedState) {
431         case LED_SCAN_BLINK:
432                 pLed->BlinkTimes--;
433                 if (pLed->BlinkTimes == 0)
434                         bStopBlinking = true;
435                 if (bStopBlinking) {
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);
444                         }
445                         pLed->bLedScanBlinkInProgress = false;
446                 } else {
447                         if (pLed->bLedOn)
448                                 pLed->BlinkingLedState = LED_STATE_OFF;
449                         else
450                                 pLed->BlinkingLedState = LED_STATE_ON;
451                         mod_timer(&pLed->BlinkTimer, jiffies +
452                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
453                 }
454                 break;
455         case LED_TXRX_BLINK:
456                 pLed->BlinkTimes--;
457                 if (pLed->BlinkTimes == 0)
458                         bStopBlinking = true;
459                 if (bStopBlinking) {
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);
468                         }
469                         pLed->bLedBlinkInProgress = false;
470                 } else {
471                         if (pLed->bLedOn)
472                                 pLed->BlinkingLedState = LED_STATE_OFF;
473                         else
474                                 pLed->BlinkingLedState = LED_STATE_ON;
475                         mod_timer(&pLed->BlinkTimer, jiffies +
476                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
477                 }
478                 break;
479         default:
480                 break;
481         }
482 }
483
484 static void SwLedBlink3(struct LED_871x *pLed)
485 {
486         struct _adapter *padapter = pLed->padapter;
487         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
488         u8 bStopBlinking = false;
489
490         /* Change LED according to BlinkingLedState specified. */
491         if (pLed->BlinkingLedState == LED_STATE_ON)
492                 SwLedOn(padapter, pLed);
493         else
494                 if (pLed->CurrLedState != LED_BLINK_WPS_STOP)
495                         SwLedOff(padapter, pLed);
496         switch (pLed->CurrLedState) {
497         case LED_SCAN_BLINK:
498                 pLed->BlinkTimes--;
499                 if (pLed->BlinkTimes == 0)
500                         bStopBlinking = true;
501                 if (bStopBlinking) {
502                         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
503                                 pLed->CurrLedState = LED_STATE_ON;
504                                 pLed->BlinkingLedState = LED_STATE_ON;
505                                 if (!pLed->bLedOn)
506                                         SwLedOn(padapter, pLed);
507                         } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
508                                 pLed->CurrLedState = LED_STATE_OFF;
509                                 pLed->BlinkingLedState = LED_STATE_OFF;
510                                 if (pLed->bLedOn)
511                                         SwLedOff(padapter, pLed);
512                         }
513                         pLed->bLedScanBlinkInProgress = false;
514                 } else {
515                         if (pLed->bLedOn)
516                                 pLed->BlinkingLedState = LED_STATE_OFF;
517                         else
518                                 pLed->BlinkingLedState = LED_STATE_ON;
519                         mod_timer(&pLed->BlinkTimer, jiffies +
520                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
521                 }
522                 break;
523         case LED_TXRX_BLINK:
524                 pLed->BlinkTimes--;
525                 if (pLed->BlinkTimes == 0)
526                         bStopBlinking = true;
527                 if (bStopBlinking) {
528                         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
529                                 pLed->CurrLedState = LED_STATE_ON;
530                                 pLed->BlinkingLedState = LED_STATE_ON;
531                                 if (!pLed->bLedOn)
532                                         SwLedOn(padapter, pLed);
533                         } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
534                                 pLed->CurrLedState = LED_STATE_OFF;
535                                 pLed->BlinkingLedState = LED_STATE_OFF;
536                                 if (pLed->bLedOn)
537                                         SwLedOff(padapter, pLed);
538                         }
539                         pLed->bLedBlinkInProgress = false;
540                 } else {
541                         if (pLed->bLedOn)
542                                 pLed->BlinkingLedState = LED_STATE_OFF;
543                         else
544                                 pLed->BlinkingLedState = LED_STATE_ON;
545                         mod_timer(&pLed->BlinkTimer, jiffies +
546                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
547                 }
548                 break;
549         case LED_BLINK_WPS:
550                 if (pLed->bLedOn)
551                         pLed->BlinkingLedState = LED_STATE_OFF;
552                 else
553                         pLed->BlinkingLedState = LED_STATE_ON;
554                 mod_timer(&pLed->BlinkTimer, jiffies +
555                           msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
556                 break;
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;
563                 } else {
564                         bStopBlinking = true;
565                 }
566                 if (bStopBlinking) {
567                         pLed->CurrLedState = LED_STATE_ON;
568                         pLed->BlinkingLedState = LED_STATE_ON;
569                         SwLedOn(padapter, pLed);
570                         pLed->bLedWPSBlinkInProgress = false;
571                 }
572                 break;
573         default:
574                 break;
575         }
576 }
577
578 static void SwLedBlink4(struct LED_871x *pLed)
579 {
580         struct _adapter *padapter = pLed->padapter;
581         struct led_priv *ledpriv = &padapter->ledpriv;
582         struct LED_871x *pLed1 = &ledpriv->SwLed1;
583         u8 bStopBlinking = false;
584
585         /* Change LED according to BlinkingLedState specified. */
586         if (pLed->BlinkingLedState == LED_STATE_ON)
587                 SwLedOn(padapter, pLed);
588         else
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);
595         }
596         switch (pLed->CurrLedState) {
597         case LED_BLINK_SLOWLY:
598                 if (pLed->bLedOn)
599                         pLed->BlinkingLedState = LED_STATE_OFF;
600                 else
601                         pLed->BlinkingLedState = LED_STATE_ON;
602                 mod_timer(&pLed->BlinkTimer, jiffies +
603                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
604                 break;
605         case LED_BLINK_StartToBlink:
606                 if (pLed->bLedOn) {
607                         pLed->BlinkingLedState = LED_STATE_OFF;
608                         mod_timer(&pLed->BlinkTimer, jiffies +
609                                   msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
610                 } else {
611                         pLed->BlinkingLedState = LED_STATE_ON;
612                         mod_timer(&pLed->BlinkTimer, jiffies +
613                                   msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
614                 }
615                 break;
616         case LED_SCAN_BLINK:
617                 pLed->BlinkTimes--;
618                 if (pLed->BlinkTimes == 0)
619                         bStopBlinking = true;
620                 if (bStopBlinking) {
621                         pLed->bLedNoLinkBlinkInProgress = true;
622                         pLed->CurrLedState = LED_BLINK_SLOWLY;
623                         if (pLed->bLedOn)
624                                 pLed->BlinkingLedState = LED_STATE_OFF;
625                         else
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;
630                 } else {
631                         if (pLed->bLedOn)
632                                 pLed->BlinkingLedState = LED_STATE_OFF;
633                         else
634                                 pLed->BlinkingLedState = LED_STATE_ON;
635                         mod_timer(&pLed->BlinkTimer, jiffies +
636                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
637                 }
638                 break;
639         case LED_TXRX_BLINK:
640                 pLed->BlinkTimes--;
641                 if (pLed->BlinkTimes == 0)
642                         bStopBlinking = true;
643                 if (bStopBlinking) {
644                         pLed->bLedNoLinkBlinkInProgress = true;
645                         pLed->CurrLedState = LED_BLINK_SLOWLY;
646                         if (pLed->bLedOn)
647                                 pLed->BlinkingLedState = LED_STATE_OFF;
648                         else
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;
653                 } else {
654                         if (pLed->bLedOn)
655                                 pLed->BlinkingLedState = LED_STATE_OFF;
656                         else
657                                 pLed->BlinkingLedState = LED_STATE_ON;
658                         mod_timer(&pLed->BlinkTimer, jiffies +
659                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
660                 }
661                 break;
662         case LED_BLINK_WPS:
663                 if (pLed->bLedOn) {
664                         pLed->BlinkingLedState = LED_STATE_OFF;
665                         mod_timer(&pLed->BlinkTimer, jiffies +
666                                   msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
667                 } else {
668                         pLed->BlinkingLedState = LED_STATE_ON;
669                         mod_timer(&pLed->BlinkTimer, jiffies +
670                                   msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
671                 }
672                 break;
673         case LED_BLINK_WPS_STOP:        /*WPS authentication fail*/
674                 if (pLed->bLedOn)
675                         pLed->BlinkingLedState = LED_STATE_OFF;
676                 else
677                         pLed->BlinkingLedState = LED_STATE_ON;
678                 mod_timer(&pLed->BlinkTimer, jiffies +
679                           msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
680                 break;
681         case LED_BLINK_WPS_STOP_OVERLAP:        /*WPS session overlap */
682                 pLed->BlinkTimes--;
683                 if (pLed->BlinkTimes == 0) {
684                         if (pLed->bLedOn)
685                                 pLed->BlinkTimes = 1;
686                         else
687                                 bStopBlinking = true;
688                 }
689                 if (bStopBlinking) {
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));
694                 } else {
695                         if (pLed->bLedOn)
696                                 pLed->BlinkingLedState = LED_STATE_OFF;
697                         else
698                                 pLed->BlinkingLedState = LED_STATE_ON;
699                         mod_timer(&pLed->BlinkTimer, jiffies +
700                                   msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
701                 }
702                 break;
703         default:
704                 break;
705         }
706 }
707
708 static void SwLedBlink5(struct LED_871x *pLed)
709 {
710         struct _adapter *padapter = pLed->padapter;
711         u8 bStopBlinking = false;
712
713         /* Change LED according to BlinkingLedState specified. */
714         if (pLed->BlinkingLedState == LED_STATE_ON)
715                 SwLedOn(padapter, pLed);
716         else
717                 SwLedOff(padapter, pLed);
718         switch (pLed->CurrLedState) {
719         case LED_SCAN_BLINK:
720                 pLed->BlinkTimes--;
721                 if (pLed->BlinkTimes == 0)
722                         bStopBlinking = true;
723                 if (bStopBlinking) {
724                         pLed->CurrLedState = LED_STATE_ON;
725                         pLed->BlinkingLedState = LED_STATE_ON;
726                         if (!pLed->bLedOn)
727                                 mod_timer(&pLed->BlinkTimer, jiffies +
728                                           msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
729                         pLed->bLedScanBlinkInProgress = false;
730                 } else {
731                         if (pLed->bLedOn)
732                                 pLed->BlinkingLedState = LED_STATE_OFF;
733                         else
734                                 pLed->BlinkingLedState = LED_STATE_ON;
735                         mod_timer(&pLed->BlinkTimer, jiffies +
736                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
737                 }
738                 break;
739         case LED_TXRX_BLINK:
740                 pLed->BlinkTimes--;
741                 if (pLed->BlinkTimes == 0)
742                         bStopBlinking = true;
743                 if (bStopBlinking) {
744                         pLed->CurrLedState = LED_STATE_ON;
745                         pLed->BlinkingLedState = LED_STATE_ON;
746                         if (!pLed->bLedOn)
747                                 mod_timer(&pLed->BlinkTimer, jiffies +
748                                           msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
749                         pLed->bLedBlinkInProgress = false;
750                 } else {
751                         if (pLed->bLedOn)
752                                 pLed->BlinkingLedState = LED_STATE_OFF;
753                         else
754                                 pLed->BlinkingLedState = LED_STATE_ON;
755                         mod_timer(&pLed->BlinkTimer, jiffies +
756                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
757                 }
758                 break;
759         default:
760                 break;
761         }
762 }
763
764 static void SwLedBlink6(struct LED_871x *pLed)
765 {
766         struct _adapter *padapter = pLed->padapter;
767         u8 bStopBlinking = false;
768
769         /* Change LED according to BlinkingLedState specified. */
770         if (pLed->BlinkingLedState == LED_STATE_ON)
771                 SwLedOn(padapter, pLed);
772         else
773                 SwLedOff(padapter, pLed);
774         switch (pLed->CurrLedState) {
775         case LED_TXRX_BLINK:
776                 pLed->BlinkTimes--;
777                 if (pLed->BlinkTimes == 0)
778                         bStopBlinking = true;
779                 if (bStopBlinking) {
780                         pLed->CurrLedState = LED_STATE_ON;
781                         pLed->BlinkingLedState = LED_STATE_ON;
782                         if (!pLed->bLedOn)
783                                 SwLedOn(padapter, pLed);
784                         pLed->bLedBlinkInProgress = false;
785                 } else {
786                         if (pLed->bLedOn)
787                                 pLed->BlinkingLedState = LED_STATE_OFF;
788                         else
789                                 pLed->BlinkingLedState = LED_STATE_ON;
790                         mod_timer(&pLed->BlinkTimer, jiffies +
791                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
792                 }
793                 break;
794         case LED_BLINK_WPS:
795                 if (pLed->bLedOn)
796                         pLed->BlinkingLedState = LED_STATE_OFF;
797                 else
798                         pLed->BlinkingLedState = LED_STATE_ON;
799                 mod_timer(&pLed->BlinkTimer, jiffies +
800                           msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
801                 break;
802
803         default:
804                 break;
805         }
806 }
807
808 /*      Description:
809  *              Callback function of LED BlinkTimer,
810  *              it just schedules to corresponding BlinkWorkItem.
811  */
812 static void BlinkTimerCallback(struct timer_list *t)
813 {
814         struct LED_871x  *pLed = from_timer(pLed, t, BlinkTimer);
815
816         /* This fixed the crash problem on Fedora 12 when trying to do the
817          * insmod;ifconfig up;rmmod commands.
818          */
819         if (pLed->padapter->surprise_removed || pLed->padapter->driver_stopped)
820                 return;
821         schedule_work(&pLed->BlinkWorkItem);
822 }
823
824 /*      Description:
825  *              Callback function of LED BlinkWorkItem.
826  *              We dispatch actual LED blink action according to LedStrategy.
827  */
828 static void BlinkWorkItemCallback(struct work_struct *work)
829 {
830         struct LED_871x *pLed = container_of(work, struct LED_871x,
831                                 BlinkWorkItem);
832         struct led_priv *ledpriv = &pLed->padapter->ledpriv;
833
834         switch (ledpriv->LedStrategy) {
835         case SW_LED_MODE0:
836                 SwLedBlink(pLed);
837                 break;
838         case SW_LED_MODE1:
839                 SwLedBlink1(pLed);
840                 break;
841         case SW_LED_MODE2:
842                 SwLedBlink2(pLed);
843                 break;
844         case SW_LED_MODE3:
845                 SwLedBlink3(pLed);
846                 break;
847         case SW_LED_MODE4:
848                 SwLedBlink4(pLed);
849                 break;
850         case SW_LED_MODE5:
851                 SwLedBlink5(pLed);
852                 break;
853         case SW_LED_MODE6:
854                 SwLedBlink6(pLed);
855                 break;
856         default:
857                 SwLedBlink(pLed);
858                 break;
859         }
860 }
861
862 /*============================================================================
863  * Default LED behavior.
864  *============================================================================
865  *
866  *      Description:
867  *              Implement each led action for SW_LED_MODE0.
868  *              This is default strategy.
869  */
870
871 static void SwLedControlMode1(struct _adapter *padapter,
872                               enum LED_CTL_MODE LedAction)
873 {
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;
878
879         if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO)
880                 pLed = &ledpriv->SwLed1;
881         switch (LedAction) {
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))
887                                 return;
888                         if (pLed->bLedLinkBlinkInProgress) {
889                                 del_timer(&pLed->BlinkTimer);
890                                 pLed->bLedLinkBlinkInProgress = false;
891                         }
892                         if (pLed->bLedBlinkInProgress) {
893                                 del_timer(&pLed->BlinkTimer);
894                                 pLed->bLedBlinkInProgress = false;
895                         }
896                         pLed->bLedNoLinkBlinkInProgress = true;
897                         pLed->CurrLedState = LED_BLINK_SLOWLY;
898                         if (pLed->bLedOn)
899                                 pLed->BlinkingLedState = LED_STATE_OFF;
900                         else
901                                 pLed->BlinkingLedState = LED_STATE_ON;
902                         mod_timer(&pLed->BlinkTimer, jiffies +
903                                   msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
904                 }
905                 break;
906         case LED_CTL_LINK:
907                 if (!pLed->bLedLinkBlinkInProgress) {
908                         if (pLed->CurrLedState == LED_SCAN_BLINK ||
909                             IS_LED_WPS_BLINKING(pLed))
910                                 return;
911                         if (pLed->bLedNoLinkBlinkInProgress) {
912                                 del_timer(&pLed->BlinkTimer);
913                                 pLed->bLedNoLinkBlinkInProgress = false;
914                         }
915                         if (pLed->bLedBlinkInProgress) {
916                                 del_timer(&pLed->BlinkTimer);
917                                 pLed->bLedBlinkInProgress = false;
918                         }
919                         pLed->bLedLinkBlinkInProgress = true;
920                         pLed->CurrLedState = LED_BLINK_NORMAL;
921                         if (pLed->bLedOn)
922                                 pLed->BlinkingLedState = LED_STATE_OFF;
923                         else
924                                 pLed->BlinkingLedState = LED_STATE_ON;
925                         mod_timer(&pLed->BlinkTimer, jiffies +
926                                   msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
927                 }
928                 break;
929         case LED_CTL_SITE_SURVEY:
930                 if (psitesurveyctrl->traffic_busy &&
931                     check_fwstate(pmlmepriv, _FW_LINKED))
932                         ; /* dummy branch */
933                 else if (!pLed->bLedScanBlinkInProgress) {
934                         if (IS_LED_WPS_BLINKING(pLed))
935                                 return;
936                         if (pLed->bLedNoLinkBlinkInProgress) {
937                                 del_timer(&pLed->BlinkTimer);
938                                 pLed->bLedNoLinkBlinkInProgress = false;
939                         }
940                         if (pLed->bLedLinkBlinkInProgress) {
941                                 del_timer(&pLed->BlinkTimer);
942                                 pLed->bLedLinkBlinkInProgress = false;
943                         }
944                         if (pLed->bLedBlinkInProgress) {
945                                 del_timer(&pLed->BlinkTimer);
946                                 pLed->bLedBlinkInProgress = false;
947                         }
948                         pLed->bLedScanBlinkInProgress = true;
949                         pLed->CurrLedState = LED_SCAN_BLINK;
950                         pLed->BlinkTimes = 24;
951                         if (pLed->bLedOn)
952                                 pLed->BlinkingLedState = LED_STATE_OFF;
953                         else
954                                 pLed->BlinkingLedState = LED_STATE_ON;
955                         mod_timer(&pLed->BlinkTimer, jiffies +
956                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
957                 }
958                 break;
959         case LED_CTL_TX:
960         case LED_CTL_RX:
961                 if (!pLed->bLedBlinkInProgress) {
962                         if (pLed->CurrLedState == LED_SCAN_BLINK ||
963                             IS_LED_WPS_BLINKING(pLed))
964                                 return;
965                         if (pLed->bLedNoLinkBlinkInProgress) {
966                                 del_timer(&pLed->BlinkTimer);
967                                 pLed->bLedNoLinkBlinkInProgress = false;
968                         }
969                         if (pLed->bLedLinkBlinkInProgress) {
970                                 del_timer(&pLed->BlinkTimer);
971                                 pLed->bLedLinkBlinkInProgress = false;
972                         }
973                         pLed->bLedBlinkInProgress = true;
974                         pLed->CurrLedState = LED_TXRX_BLINK;
975                         pLed->BlinkTimes = 2;
976                         if (pLed->bLedOn)
977                                 pLed->BlinkingLedState = LED_STATE_OFF;
978                         else
979                                 pLed->BlinkingLedState = LED_STATE_ON;
980                         mod_timer(&pLed->BlinkTimer, jiffies +
981                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
982                 }
983                 break;
984
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;
991                         }
992                         if (pLed->bLedLinkBlinkInProgress) {
993                                 del_timer(&pLed->BlinkTimer);
994                                 pLed->bLedLinkBlinkInProgress = false;
995                         }
996                         if (pLed->bLedBlinkInProgress) {
997                                 del_timer(&pLed->BlinkTimer);
998                                 pLed->bLedBlinkInProgress = false;
999                         }
1000                         if (pLed->bLedScanBlinkInProgress) {
1001                                 del_timer(&pLed->BlinkTimer);
1002                                 pLed->bLedScanBlinkInProgress = false;
1003                         }
1004                         pLed->bLedWPSBlinkInProgress = true;
1005                         pLed->CurrLedState = LED_BLINK_WPS;
1006                         if (pLed->bLedOn)
1007                                 pLed->BlinkingLedState = LED_STATE_OFF;
1008                         else
1009                                 pLed->BlinkingLedState = LED_STATE_ON;
1010                         mod_timer(&pLed->BlinkTimer, jiffies +
1011                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1012                 }
1013                 break;
1014         case LED_CTL_STOP_WPS:
1015                 if (pLed->bLedNoLinkBlinkInProgress) {
1016                         del_timer(&pLed->BlinkTimer);
1017                         pLed->bLedNoLinkBlinkInProgress = false;
1018                 }
1019                 if (pLed->bLedLinkBlinkInProgress) {
1020                         del_timer(&pLed->BlinkTimer);
1021                         pLed->bLedLinkBlinkInProgress = false;
1022                 }
1023                 if (pLed->bLedBlinkInProgress) {
1024                         del_timer(&pLed->BlinkTimer);
1025                         pLed->bLedBlinkInProgress = false;
1026                 }
1027                 if (pLed->bLedScanBlinkInProgress) {
1028                         del_timer(&pLed->BlinkTimer);
1029                         pLed->bLedScanBlinkInProgress = false;
1030                 }
1031                 if (pLed->bLedWPSBlinkInProgress)
1032                         del_timer(&pLed->BlinkTimer);
1033                 else
1034                         pLed->bLedWPSBlinkInProgress = true;
1035                 pLed->CurrLedState = LED_BLINK_WPS_STOP;
1036                 if (pLed->bLedOn) {
1037                         pLed->BlinkingLedState = LED_STATE_OFF;
1038                         mod_timer(&pLed->BlinkTimer, jiffies +
1039                                   msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
1040                 } else {
1041                         pLed->BlinkingLedState = LED_STATE_ON;
1042                         mod_timer(&pLed->BlinkTimer,
1043                                   jiffies + msecs_to_jiffies(0));
1044                 }
1045                 break;
1046         case LED_CTL_STOP_WPS_FAIL:
1047                 if (pLed->bLedWPSBlinkInProgress) {
1048                         del_timer(&pLed->BlinkTimer);
1049                         pLed->bLedWPSBlinkInProgress = false;
1050                 }
1051                 pLed->bLedNoLinkBlinkInProgress = true;
1052                 pLed->CurrLedState = LED_BLINK_SLOWLY;
1053                 if (pLed->bLedOn)
1054                         pLed->BlinkingLedState = LED_STATE_OFF;
1055                 else
1056                         pLed->BlinkingLedState = LED_STATE_ON;
1057                 mod_timer(&pLed->BlinkTimer, jiffies +
1058                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1059                 break;
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;
1066                 }
1067                 if (pLed->bLedLinkBlinkInProgress) {
1068                         del_timer(&pLed->BlinkTimer);
1069                         pLed->bLedLinkBlinkInProgress = false;
1070                 }
1071                 if (pLed->bLedBlinkInProgress) {
1072                         del_timer(&pLed->BlinkTimer);
1073                         pLed->bLedBlinkInProgress = false;
1074                 }
1075                 if (pLed->bLedWPSBlinkInProgress) {
1076                         del_timer(&pLed->BlinkTimer);
1077                         pLed->bLedWPSBlinkInProgress = false;
1078                 }
1079                 if (pLed->bLedScanBlinkInProgress) {
1080                         del_timer(&pLed->BlinkTimer);
1081                         pLed->bLedScanBlinkInProgress = false;
1082                 }
1083                 mod_timer(&pLed->BlinkTimer,
1084                           jiffies + msecs_to_jiffies(0));
1085                 break;
1086         default:
1087                 break;
1088         }
1089 }
1090
1091 static void SwLedControlMode2(struct _adapter *padapter,
1092                               enum LED_CTL_MODE LedAction)
1093 {
1094         struct led_priv  *ledpriv = &padapter->ledpriv;
1095         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1096         struct LED_871x *pLed = &ledpriv->SwLed0;
1097
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))
1104                                 return;
1105
1106                         if (pLed->bLedBlinkInProgress) {
1107                                 del_timer(&pLed->BlinkTimer);
1108                                 pLed->bLedBlinkInProgress = false;
1109                         }
1110                         pLed->bLedScanBlinkInProgress = true;
1111                         pLed->CurrLedState = LED_SCAN_BLINK;
1112                         pLed->BlinkTimes = 24;
1113                         if (pLed->bLedOn)
1114                                 pLed->BlinkingLedState = LED_STATE_OFF;
1115                         else
1116                                 pLed->BlinkingLedState = LED_STATE_ON;
1117                         mod_timer(&pLed->BlinkTimer, jiffies +
1118                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1119                 }
1120                 break;
1121
1122         case LED_CTL_TX:
1123         case LED_CTL_RX:
1124                 if (!pLed->bLedBlinkInProgress &&
1125                     check_fwstate(pmlmepriv, _FW_LINKED)) {
1126                         if (pLed->CurrLedState == LED_SCAN_BLINK ||
1127                             IS_LED_WPS_BLINKING(pLed))
1128                                 return;
1129                         pLed->bLedBlinkInProgress = true;
1130                         pLed->CurrLedState = LED_TXRX_BLINK;
1131                         pLed->BlinkTimes = 2;
1132                         if (pLed->bLedOn)
1133                                 pLed->BlinkingLedState = LED_STATE_OFF;
1134                         else
1135                                 pLed->BlinkingLedState = LED_STATE_ON;
1136                         mod_timer(&pLed->BlinkTimer, jiffies +
1137                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1138                 }
1139                 break;
1140
1141         case LED_CTL_LINK:
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;
1147                 }
1148                 if (pLed->bLedScanBlinkInProgress) {
1149                         del_timer(&pLed->BlinkTimer);
1150                         pLed->bLedScanBlinkInProgress = false;
1151                 }
1152
1153                 mod_timer(&pLed->BlinkTimer,
1154                           jiffies + msecs_to_jiffies(0));
1155                 break;
1156
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;
1163                         }
1164                         if (pLed->bLedScanBlinkInProgress) {
1165                                 del_timer(&pLed->BlinkTimer);
1166                                 pLed->bLedScanBlinkInProgress = false;
1167                         }
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));
1173                 }
1174                 break;
1175
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));
1182                 break;
1183
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));
1190                 break;
1191
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));
1199                 }
1200                 break;
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;
1207                 }
1208                 if (pLed->bLedScanBlinkInProgress) {
1209                         del_timer(&pLed->BlinkTimer);
1210                         pLed->bLedScanBlinkInProgress = false;
1211                 }
1212                 if (pLed->bLedWPSBlinkInProgress) {
1213                         del_timer(&pLed->BlinkTimer);
1214                         pLed->bLedWPSBlinkInProgress = false;
1215                 }
1216                 mod_timer(&pLed->BlinkTimer,
1217                           jiffies + msecs_to_jiffies(0));
1218                 break;
1219         default:
1220                 break;
1221         }
1222 }
1223
1224 static void SwLedControlMode3(struct _adapter *padapter,
1225                               enum LED_CTL_MODE LedAction)
1226 {
1227         struct led_priv *ledpriv = &padapter->ledpriv;
1228         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1229         struct LED_871x *pLed = &ledpriv->SwLed0;
1230
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))
1237                                 return;
1238                         if (pLed->bLedBlinkInProgress) {
1239                                 del_timer(&pLed->BlinkTimer);
1240                                 pLed->bLedBlinkInProgress = false;
1241                         }
1242                         pLed->bLedScanBlinkInProgress = true;
1243                         pLed->CurrLedState = LED_SCAN_BLINK;
1244                         pLed->BlinkTimes = 24;
1245                         if (pLed->bLedOn)
1246                                 pLed->BlinkingLedState = LED_STATE_OFF;
1247                         else
1248                                 pLed->BlinkingLedState = LED_STATE_ON;
1249                         mod_timer(&pLed->BlinkTimer, jiffies +
1250                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1251                 }
1252                 break;
1253         case LED_CTL_TX:
1254         case LED_CTL_RX:
1255                 if (!pLed->bLedBlinkInProgress &&
1256                     check_fwstate(pmlmepriv, _FW_LINKED)) {
1257                         if (pLed->CurrLedState == LED_SCAN_BLINK ||
1258                             IS_LED_WPS_BLINKING(pLed))
1259                                 return;
1260                         pLed->bLedBlinkInProgress = true;
1261                         pLed->CurrLedState = LED_TXRX_BLINK;
1262                         pLed->BlinkTimes = 2;
1263                         if (pLed->bLedOn)
1264                                 pLed->BlinkingLedState = LED_STATE_OFF;
1265                         else
1266                                 pLed->BlinkingLedState = LED_STATE_ON;
1267                         mod_timer(&pLed->BlinkTimer, jiffies +
1268                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1269                 }
1270                 break;
1271         case LED_CTL_LINK:
1272                 if (IS_LED_WPS_BLINKING(pLed))
1273                         return;
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;
1279                 }
1280                 if (pLed->bLedScanBlinkInProgress) {
1281                         del_timer(&pLed->BlinkTimer);
1282                         pLed->bLedScanBlinkInProgress = false;
1283                 }
1284                 mod_timer(&pLed->BlinkTimer,
1285                           jiffies + msecs_to_jiffies(0));
1286                 break;
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;
1293                         }
1294                         if (pLed->bLedScanBlinkInProgress) {
1295                                 del_timer(&pLed->BlinkTimer);
1296                                 pLed->bLedScanBlinkInProgress = false;
1297                         }
1298                         pLed->bLedWPSBlinkInProgress = true;
1299                         pLed->CurrLedState = LED_BLINK_WPS;
1300                         if (pLed->bLedOn)
1301                                 pLed->BlinkingLedState = LED_STATE_OFF;
1302                         else
1303                                 pLed->BlinkingLedState = LED_STATE_ON;
1304                         mod_timer(&pLed->BlinkTimer, jiffies +
1305                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1306                 }
1307                 break;
1308         case LED_CTL_STOP_WPS:
1309                 if (pLed->bLedWPSBlinkInProgress) {
1310                         del_timer(&pLed->BlinkTimer);
1311                         pLed->bLedWPSBlinkInProgress = false;
1312                 } else {
1313                         pLed->bLedWPSBlinkInProgress = true;
1314                 }
1315                 pLed->CurrLedState = LED_BLINK_WPS_STOP;
1316                 if (pLed->bLedOn) {
1317                         pLed->BlinkingLedState = LED_STATE_OFF;
1318                         mod_timer(&pLed->BlinkTimer, jiffies +
1319                                   msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
1320                 } else {
1321                         pLed->BlinkingLedState = LED_STATE_ON;
1322                         mod_timer(&pLed->BlinkTimer,
1323                                   jiffies + msecs_to_jiffies(0));
1324                 }
1325                 break;
1326         case LED_CTL_STOP_WPS_FAIL:
1327                 if (pLed->bLedWPSBlinkInProgress) {
1328                         del_timer(&pLed->BlinkTimer);
1329                         pLed->bLedWPSBlinkInProgress = false;
1330                 }
1331                 pLed->CurrLedState = LED_STATE_OFF;
1332                 pLed->BlinkingLedState = LED_STATE_OFF;
1333                 mod_timer(&pLed->BlinkTimer,
1334                           jiffies + msecs_to_jiffies(0));
1335                 break;
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));
1343                 }
1344                 break;
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;
1351                 }
1352                 if (pLed->bLedScanBlinkInProgress) {
1353                         del_timer(&pLed->BlinkTimer);
1354                         pLed->bLedScanBlinkInProgress = false;
1355                 }
1356                 if (pLed->bLedWPSBlinkInProgress) {
1357                         del_timer(&pLed->BlinkTimer);
1358                         pLed->bLedWPSBlinkInProgress = false;
1359                 }
1360                 mod_timer(&pLed->BlinkTimer,
1361                           jiffies + msecs_to_jiffies(0));
1362                 break;
1363         default:
1364                 break;
1365         }
1366 }
1367
1368 static void SwLedControlMode4(struct _adapter *padapter,
1369                               enum LED_CTL_MODE LedAction)
1370 {
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;
1375
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;
1383                         if (pLed1->bLedOn)
1384                                 mod_timer(&pLed->BlinkTimer,
1385                                           jiffies + msecs_to_jiffies(0));
1386                 }
1387                 if (!pLed->bLedStartToLinkBlinkInProgress) {
1388                         if (pLed->CurrLedState == LED_SCAN_BLINK ||
1389                             IS_LED_WPS_BLINKING(pLed))
1390                                 return;
1391                         if (pLed->bLedBlinkInProgress) {
1392                                 del_timer(&pLed->BlinkTimer);
1393                                 pLed->bLedBlinkInProgress = false;
1394                         }
1395                         if (pLed->bLedNoLinkBlinkInProgress) {
1396                                 del_timer(&pLed->BlinkTimer);
1397                                 pLed->bLedNoLinkBlinkInProgress = false;
1398                         }
1399                         pLed->bLedStartToLinkBlinkInProgress = true;
1400                         pLed->CurrLedState = LED_BLINK_StartToBlink;
1401                         if (pLed->bLedOn) {
1402                                 pLed->BlinkingLedState = LED_STATE_OFF;
1403                                 mod_timer(&pLed->BlinkTimer, jiffies +
1404                                           msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
1405                         } else {
1406                                 pLed->BlinkingLedState = LED_STATE_ON;
1407                                 mod_timer(&pLed->BlinkTimer, jiffies +
1408                                           msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
1409                         }
1410                 }
1411                 break;
1412         case LED_CTL_LINK:
1413         case LED_CTL_NO_LINK:
1414                 /*LED1 settings*/
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;
1421                                 if (pLed1->bLedOn)
1422                                         mod_timer(&pLed->BlinkTimer,
1423                                                   jiffies + msecs_to_jiffies(0));
1424                         }
1425                 }
1426                 if (!pLed->bLedNoLinkBlinkInProgress) {
1427                         if (pLed->CurrLedState == LED_SCAN_BLINK ||
1428                             IS_LED_WPS_BLINKING(pLed))
1429                                 return;
1430                         if (pLed->bLedBlinkInProgress) {
1431                                 del_timer(&pLed->BlinkTimer);
1432                                 pLed->bLedBlinkInProgress = false;
1433                         }
1434                         pLed->bLedNoLinkBlinkInProgress = true;
1435                         pLed->CurrLedState = LED_BLINK_SLOWLY;
1436                         if (pLed->bLedOn)
1437                                 pLed->BlinkingLedState = LED_STATE_OFF;
1438                         else
1439                                 pLed->BlinkingLedState = LED_STATE_ON;
1440                         mod_timer(&pLed->BlinkTimer, jiffies +
1441                                   msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1442                 }
1443                 break;
1444         case LED_CTL_SITE_SURVEY:
1445                 if (pmlmepriv->sitesurveyctrl.traffic_busy &&
1446                     check_fwstate(pmlmepriv, _FW_LINKED))
1447                         ;
1448                 else if (!pLed->bLedScanBlinkInProgress) {
1449                         if (IS_LED_WPS_BLINKING(pLed))
1450                                 return;
1451                         if (pLed->bLedNoLinkBlinkInProgress) {
1452                                 del_timer(&pLed->BlinkTimer);
1453                                 pLed->bLedNoLinkBlinkInProgress = false;
1454                         }
1455                         if (pLed->bLedBlinkInProgress) {
1456                                 del_timer(&pLed->BlinkTimer);
1457                                 pLed->bLedBlinkInProgress = false;
1458                         }
1459                         pLed->bLedScanBlinkInProgress = true;
1460                         pLed->CurrLedState = LED_SCAN_BLINK;
1461                         pLed->BlinkTimes = 24;
1462                         if (pLed->bLedOn)
1463                                 pLed->BlinkingLedState = LED_STATE_OFF;
1464                         else
1465                                 pLed->BlinkingLedState = LED_STATE_ON;
1466                         mod_timer(&pLed->BlinkTimer, jiffies +
1467                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1468                 }
1469                 break;
1470         case LED_CTL_TX:
1471         case LED_CTL_RX:
1472                 if (!pLed->bLedBlinkInProgress) {
1473                         if (pLed->CurrLedState == LED_SCAN_BLINK ||
1474                             IS_LED_WPS_BLINKING(pLed))
1475                                 return;
1476                         if (pLed->bLedNoLinkBlinkInProgress) {
1477                                 del_timer(&pLed->BlinkTimer);
1478                                 pLed->bLedNoLinkBlinkInProgress = false;
1479                         }
1480                         pLed->bLedBlinkInProgress = true;
1481                         pLed->CurrLedState = LED_TXRX_BLINK;
1482                         pLed->BlinkTimes = 2;
1483                         if (pLed->bLedOn)
1484                                 pLed->BlinkingLedState = LED_STATE_OFF;
1485                         else
1486                                 pLed->BlinkingLedState = LED_STATE_ON;
1487                         mod_timer(&pLed->BlinkTimer, jiffies +
1488                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1489                 }
1490                 break;
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;
1498                         if (pLed1->bLedOn)
1499                                 mod_timer(&pLed->BlinkTimer,
1500                                           jiffies + msecs_to_jiffies(0));
1501                 }
1502                 if (!pLed->bLedWPSBlinkInProgress) {
1503                         if (pLed->bLedNoLinkBlinkInProgress) {
1504                                 del_timer(&pLed->BlinkTimer);
1505                                 pLed->bLedNoLinkBlinkInProgress = false;
1506                         }
1507                         if (pLed->bLedBlinkInProgress) {
1508                                 del_timer(&pLed->BlinkTimer);
1509                                 pLed->bLedBlinkInProgress = false;
1510                         }
1511                         if (pLed->bLedScanBlinkInProgress) {
1512                                 del_timer(&pLed->BlinkTimer);
1513                                 pLed->bLedScanBlinkInProgress = false;
1514                         }
1515                         pLed->bLedWPSBlinkInProgress = true;
1516                         pLed->CurrLedState = LED_BLINK_WPS;
1517                         if (pLed->bLedOn) {
1518                                 pLed->BlinkingLedState = LED_STATE_OFF;
1519                                 mod_timer(&pLed->BlinkTimer, jiffies +
1520                                           msecs_to_jiffies(LED_BLINK_SLOWLY_INTERVAL));
1521                         } else {
1522                                 pLed->BlinkingLedState = LED_STATE_ON;
1523                                 mod_timer(&pLed->BlinkTimer, jiffies +
1524                                           msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
1525                         }
1526                 }
1527                 break;
1528         case LED_CTL_STOP_WPS:  /*WPS connect success*/
1529                 if (pLed->bLedWPSBlinkInProgress) {
1530                         del_timer(&pLed->BlinkTimer);
1531                         pLed->bLedWPSBlinkInProgress = false;
1532                 }
1533                 pLed->bLedNoLinkBlinkInProgress = true;
1534                 pLed->CurrLedState = LED_BLINK_SLOWLY;
1535                 if (pLed->bLedOn)
1536                         pLed->BlinkingLedState = LED_STATE_OFF;
1537                 else
1538                         pLed->BlinkingLedState = LED_STATE_ON;
1539                 mod_timer(&pLed->BlinkTimer, jiffies +
1540                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1541                 break;
1542         case LED_CTL_STOP_WPS_FAIL:     /*WPS authentication fail*/
1543                 if (pLed->bLedWPSBlinkInProgress) {
1544                         del_timer(&pLed->BlinkTimer);
1545                         pLed->bLedWPSBlinkInProgress = false;
1546                 }
1547                 pLed->bLedNoLinkBlinkInProgress = true;
1548                 pLed->CurrLedState = LED_BLINK_SLOWLY;
1549                 if (pLed->bLedOn)
1550                         pLed->BlinkingLedState = LED_STATE_OFF;
1551                 else
1552                         pLed->BlinkingLedState = LED_STATE_ON;
1553                 mod_timer(&pLed->BlinkTimer, jiffies +
1554                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1555                 /*LED1 settings*/
1556                 if (pLed1->bLedWPSBlinkInProgress)
1557                         del_timer(&pLed1->BlinkTimer);
1558                 else
1559                         pLed1->bLedWPSBlinkInProgress = true;
1560                 pLed1->CurrLedState = LED_BLINK_WPS_STOP;
1561                 if (pLed1->bLedOn)
1562                         pLed1->BlinkingLedState = LED_STATE_OFF;
1563                 else
1564                         pLed1->BlinkingLedState = LED_STATE_ON;
1565                 mod_timer(&pLed->BlinkTimer, jiffies +
1566                           msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
1567                 break;
1568         case LED_CTL_STOP_WPS_FAIL_OVERLAP:     /*WPS session overlap*/
1569                 if (pLed->bLedWPSBlinkInProgress) {
1570                         del_timer(&pLed->BlinkTimer);
1571                         pLed->bLedWPSBlinkInProgress = false;
1572                 }
1573                 pLed->bLedNoLinkBlinkInProgress = true;
1574                 pLed->CurrLedState = LED_BLINK_SLOWLY;
1575                 if (pLed->bLedOn)
1576                         pLed->BlinkingLedState = LED_STATE_OFF;
1577                 else
1578                         pLed->BlinkingLedState = LED_STATE_ON;
1579                 mod_timer(&pLed->BlinkTimer, jiffies +
1580                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
1581                 /*LED1 settings*/
1582                 if (pLed1->bLedWPSBlinkInProgress)
1583                         del_timer(&pLed1->BlinkTimer);
1584                 else
1585                         pLed1->bLedWPSBlinkInProgress = true;
1586                 pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP;
1587                 pLed1->BlinkTimes = 10;
1588                 if (pLed1->bLedOn)
1589                         pLed1->BlinkingLedState = LED_STATE_OFF;
1590                 else
1591                         pLed1->BlinkingLedState = LED_STATE_ON;
1592                 mod_timer(&pLed->BlinkTimer, jiffies +
1593                           msecs_to_jiffies(LED_BLINK_NORMAL_INTERVAL));
1594                 break;
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;
1601                 }
1602                 if (pLed->bLedLinkBlinkInProgress) {
1603                         del_timer(&pLed->BlinkTimer);
1604                         pLed->bLedLinkBlinkInProgress = false;
1605                 }
1606                 if (pLed->bLedBlinkInProgress) {
1607                         del_timer(&pLed->BlinkTimer);
1608                         pLed->bLedBlinkInProgress = false;
1609                 }
1610                 if (pLed->bLedWPSBlinkInProgress) {
1611                         del_timer(&pLed->BlinkTimer);
1612                         pLed->bLedWPSBlinkInProgress = false;
1613                 }
1614                 if (pLed->bLedScanBlinkInProgress) {
1615                         del_timer(&pLed->BlinkTimer);
1616                         pLed->bLedScanBlinkInProgress = false;
1617                 }
1618                 if (pLed->bLedStartToLinkBlinkInProgress) {
1619                         del_timer(&pLed->BlinkTimer);
1620                         pLed->bLedStartToLinkBlinkInProgress = false;
1621                 }
1622                 if (pLed1->bLedWPSBlinkInProgress) {
1623                         del_timer(&pLed1->BlinkTimer);
1624                         pLed1->bLedWPSBlinkInProgress = false;
1625                 }
1626                 pLed1->BlinkingLedState = LED_UNKNOWN;
1627                 SwLedOff(padapter, pLed);
1628                 SwLedOff(padapter, pLed1);
1629                 break;
1630         default:
1631                 break;
1632         }
1633 }
1634
1635 static void SwLedControlMode5(struct _adapter *padapter,
1636                               enum LED_CTL_MODE LedAction)
1637 {
1638         struct led_priv *ledpriv = &padapter->ledpriv;
1639         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1640         struct LED_871x *pLed = &ledpriv->SwLed0;
1641
1642         if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO)
1643                 pLed = &ledpriv->SwLed1;
1644
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)
1650                         return;
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));
1656                 break;
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;
1665                         }
1666                         pLed->bLedScanBlinkInProgress = true;
1667                         pLed->CurrLedState = LED_SCAN_BLINK;
1668                         pLed->BlinkTimes = 24;
1669                         if (pLed->bLedOn)
1670                                 pLed->BlinkingLedState = LED_STATE_OFF;
1671                         else
1672                                 pLed->BlinkingLedState = LED_STATE_ON;
1673                         mod_timer(&pLed->BlinkTimer, jiffies +
1674                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1675                 }
1676                 break;
1677         case LED_CTL_TX:
1678         case LED_CTL_RX:
1679                 if (!pLed->bLedBlinkInProgress) {
1680                         if (pLed->CurrLedState == LED_SCAN_BLINK)
1681                                 return;
1682                         pLed->bLedBlinkInProgress = true;
1683                         pLed->CurrLedState = LED_TXRX_BLINK;
1684                         pLed->BlinkTimes = 2;
1685                         if (pLed->bLedOn)
1686                                 pLed->BlinkingLedState = LED_STATE_OFF;
1687                         else
1688                                 pLed->BlinkingLedState = LED_STATE_ON;
1689                         mod_timer(&pLed->BlinkTimer, jiffies +
1690                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1691                 }
1692                 break;
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;
1699                 }
1700                 SwLedOff(padapter, pLed);
1701                 break;
1702         default:
1703                 break;
1704         }
1705 }
1706
1707 static void SwLedControlMode6(struct _adapter *padapter,
1708                               enum LED_CTL_MODE LedAction)
1709 {
1710         struct led_priv *ledpriv = &padapter->ledpriv;
1711         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
1712         struct LED_871x *pLed = &ledpriv->SwLed0;
1713
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))
1720                         return;
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));
1725                 break;
1726         case LED_CTL_TX:
1727         case LED_CTL_RX:
1728                 if (!pLed->bLedBlinkInProgress &&
1729                     check_fwstate(pmlmepriv, _FW_LINKED)) {
1730                         if (IS_LED_WPS_BLINKING(pLed))
1731                                 return;
1732                         pLed->bLedBlinkInProgress = true;
1733                         pLed->CurrLedState = LED_TXRX_BLINK;
1734                         pLed->BlinkTimes = 2;
1735                         if (pLed->bLedOn)
1736                                 pLed->BlinkingLedState = LED_STATE_OFF;
1737                         else
1738                                 pLed->BlinkingLedState = LED_STATE_ON;
1739                         mod_timer(&pLed->BlinkTimer, jiffies +
1740                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
1741                 }
1742                 break;
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;
1749                         }
1750                         pLed->bLedWPSBlinkInProgress = true;
1751                         pLed->CurrLedState = LED_BLINK_WPS;
1752                         if (pLed->bLedOn)
1753                                 pLed->BlinkingLedState = LED_STATE_OFF;
1754                         else
1755                                 pLed->BlinkingLedState = LED_STATE_ON;
1756                         mod_timer(&pLed->BlinkTimer, jiffies +
1757                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
1758                 }
1759                 break;
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;
1765                 }
1766                 pLed->CurrLedState = LED_STATE_ON;
1767                 pLed->BlinkingLedState = LED_STATE_ON;
1768                 mod_timer(&pLed->BlinkTimer,
1769                           jiffies + msecs_to_jiffies(0));
1770                 break;
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;
1777                 }
1778                 if (pLed->bLedWPSBlinkInProgress) {
1779                         del_timer(&pLed->BlinkTimer);
1780                         pLed->bLedWPSBlinkInProgress = false;
1781                 }
1782                 SwLedOff(padapter, pLed);
1783                 break;
1784         default:
1785                 break;
1786         }
1787 }
1788
1789 /*      Description:
1790  *              Dispatch LED action according to pHalData->LedStrategy.
1791  */
1792 void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction)
1793 {
1794         struct led_priv *ledpriv = &padapter->ledpriv;
1795
1796         if (!ledpriv->bRegUseLed)
1797                 return;
1798         switch (ledpriv->LedStrategy) {
1799         case SW_LED_MODE0:
1800                 break;
1801         case SW_LED_MODE1:
1802                 SwLedControlMode1(padapter, LedAction);
1803                 break;
1804         case SW_LED_MODE2:
1805                 SwLedControlMode2(padapter, LedAction);
1806                 break;
1807         case SW_LED_MODE3:
1808                 SwLedControlMode3(padapter, LedAction);
1809                 break;
1810         case SW_LED_MODE4:
1811                 SwLedControlMode4(padapter, LedAction);
1812                 break;
1813         case SW_LED_MODE5:
1814                 SwLedControlMode5(padapter, LedAction);
1815                 break;
1816         case SW_LED_MODE6:
1817                 SwLedControlMode6(padapter, LedAction);
1818                 break;
1819         default:
1820                 break;
1821         }
1822 }
1823
1824 void r8712_flush_led_works(struct _adapter *padapter)
1825 {
1826         struct led_priv *pledpriv = &padapter->ledpriv;
1827
1828         flush_work(&pledpriv->SwLed0.BlinkWorkItem);
1829         flush_work(&pledpriv->SwLed1.BlinkWorkItem);
1830 }