1 /******************************************************************************
2  * rtl8712_led.c
3  *
4  * Copyright(c) 2007 - 2010  Realtek Corporation. All rights reserved.
5  * Linux device driver for RTL8192SU
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of version 2 of the GNU General Public License as
9  * published by the Free Software Foundation.
10  *
11  * This program is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
14  * more details.
15  *
16  * You should have received a copy of the GNU General Public License along with
17  * this program; if not, write to the Free Software Foundation, Inc.,
18  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19  *
20  * Modifications for inclusion into the Linux staging tree are
21  * Copyright(c) 2010 Larry Finger. All rights reserved.
22  *
23  * Contact information:
24  * WLAN FAE <wlanfae@realtek.com>
25  * Larry Finger <Larry.Finger@lwfinger.net>
26  *
27  ******************************************************************************/
28 
29 #include "drv_types.h"
30 
31 /*===========================================================================
32  *	Constant.
33  *===========================================================================
34 
35  *
36  * Default LED behavior.
37  */
38 #define LED_BLINK_NORMAL_INTERVAL	100
39 #define LED_BLINK_SLOWLY_INTERVAL	200
40 #define LED_BLINK_LONG_INTERVAL	400
41 
42 #define LED_BLINK_NO_LINK_INTERVAL_ALPHA	1000
43 #define LED_BLINK_LINK_INTERVAL_ALPHA		500
44 #define LED_BLINK_SCAN_INTERVAL_ALPHA		180
45 #define LED_BLINK_FASTER_INTERVAL_ALPHA		50
46 #define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA	5000
47 
48 /*===========================================================================
49  * LED object.
50  *===========================================================================
51  */
52 enum _LED_STATE_871x {
53 	LED_UNKNOWN = 0,
54 	LED_ON = 1,
55 	LED_OFF = 2,
56 	LED_BLINK_NORMAL = 3,
57 	LED_BLINK_SLOWLY = 4,
58 	LED_POWER_ON_BLINK = 5,
59 	LED_SCAN_BLINK = 6, /* LED is blinking during scanning period,
60 			     * the # of times to blink is depend on time
61 			     * for scanning. */
62 	LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */
63 	LED_BLINK_StartToBlink = 8,/* Customized for Sercomm Printer
64 				    * Server case */
65 	LED_BLINK_WPS = 9,	/* LED is blinkg during WPS communication */
66 	LED_TXRX_BLINK = 10,
67 	LED_BLINK_WPS_STOP = 11,	/*for ALPHA */
68 	LED_BLINK_WPS_STOP_OVERLAP = 12,	/*for BELKIN */
69 };
70 
71 /*===========================================================================
72  *	Prototype of protected function.
73  *===========================================================================
74  */
75 static void BlinkTimerCallback(unsigned long data);
76 
77 static void BlinkWorkItemCallback(struct work_struct *work);
78 /*===========================================================================
79  * LED_819xUsb routines.
80  *===========================================================================
81  *
82  *
83  *
84  *	Description:
85  *		Initialize an LED_871x object.
86  */
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 	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  */
DeInitLed871x(struct LED_871x * pLed)109 static 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  */
SwLedOn(struct _adapter * padapter,struct LED_871x * pLed)121 static 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  */
SwLedOff(struct _adapter * padapter,struct LED_871x * pLed)150 static 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  */
r8712_InitSwLeds(struct _adapter * padapter)182 void r8712_InitSwLeds(struct _adapter *padapter)
183 {
184 	struct led_priv	*pledpriv = &(padapter->ledpriv);
185 
186 	pledpriv->LedControlHandler = LedControl871x;
187 	InitLed871x(padapter, &(pledpriv->SwLed0), LED_PIN_LED0);
188 	InitLed871x(padapter, &(pledpriv->SwLed1), LED_PIN_LED1);
189 }
190 
191 /*	Description:
192  *		DeInitialize all LED_819xUsb objects.
193  */
r8712_DeInitSwLeds(struct _adapter * padapter)194 void r8712_DeInitSwLeds(struct _adapter *padapter)
195 {
196 	struct led_priv	*ledpriv = &(padapter->ledpriv);
197 
198 	DeInitLed871x(&(ledpriv->SwLed0));
199 	DeInitLed871x(&(ledpriv->SwLed1));
200 }
201 
202 /*	Description:
203  *		Implementation of LED blinking behavior.
204  *		It toggle off LED and schedule corresponding timer if necessary.
205  */
SwLedBlink(struct LED_871x * pLed)206 static void SwLedBlink(struct LED_871x *pLed)
207 {
208 	struct _adapter *padapter = pLed->padapter;
209 	struct mlme_priv *pmlmepriv = &(padapter->mlmepriv);
210 	u8 bStopBlinking = false;
211 
212 	/* Change LED according to BlinkingLedState specified. */
213 	if (pLed->BlinkingLedState == LED_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 
SwLedBlink1(struct LED_871x * pLed)282 static 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 
SwLedBlink2(struct LED_871x * pLed)432 static 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 
SwLedBlink3(struct LED_871x * pLed)497 static 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 
SwLedBlink4(struct LED_871x * pLed)590 static 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 
SwLedBlink5(struct LED_871x * pLed)720 static 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 
SwLedBlink6(struct LED_871x * pLed)776 static 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  */
BlinkTimerCallback(unsigned long data)824 static 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  */
BlinkWorkItemCallback(struct work_struct * work)840 static 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 
SwLedControlMode1(struct _adapter * padapter,enum LED_CTL_MODE LedAction)883 static 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 
SwLedControlMode2(struct _adapter * padapter,enum LED_CTL_MODE LedAction)1103 static 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 
SwLedControlMode3(struct _adapter * padapter,enum LED_CTL_MODE LedAction)1236 static 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 
SwLedControlMode4(struct _adapter * padapter,enum LED_CTL_MODE LedAction)1379 static 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 
SwLedControlMode5(struct _adapter * padapter,enum LED_CTL_MODE LedAction)1646 static 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 
SwLedControlMode6(struct _adapter * padapter,enum LED_CTL_MODE LedAction)1719 static 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  */
LedControl871x(struct _adapter * padapter,enum LED_CTL_MODE LedAction)1804 void 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