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