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