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 */
52enum _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 */
75static void BlinkTimerCallback(unsigned long data);
76
77static void BlinkWorkItemCallback(struct work_struct *work);
78/*===========================================================================
79 * LED_819xUsb routines.
80 *===========================================================================
81 *
82 *
83 *
84 *	Description:
85 *		Initialize an LED_871x object.
86 */
87static 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 */
108static 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 */
120static 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 */
149static 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 */
181void 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 */
193void 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 */
205static 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
281static 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
431static 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
496static 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
589static 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
718static 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
774static 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 */
821static 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 */
837static 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
880static 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
1098static 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
1225static 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
1363static 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
1625static 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
1697static 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 */
1781void 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