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