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