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