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