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