/****************************************************************************** * rtl8712_led.c * * Copyright(c) 2007 - 2010 Realtek Corporation. All rights reserved. * Linux device driver for RTL8192SU * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA * * Modifications for inclusion into the Linux staging tree are * Copyright(c) 2010 Larry Finger. All rights reserved. * * Contact information: * WLAN FAE * Larry Finger * ******************************************************************************/ #include "drv_types.h" /*=========================================================================== * Constant. *=========================================================================== * * Default LED behavior. */ #define LED_BLINK_NORMAL_INTERVAL 100 #define LED_BLINK_SLOWLY_INTERVAL 200 #define LED_BLINK_LONG_INTERVAL 400 #define LED_BLINK_NO_LINK_INTERVAL_ALPHA 1000 #define LED_BLINK_LINK_INTERVAL_ALPHA 500 #define LED_BLINK_SCAN_INTERVAL_ALPHA 180 #define LED_BLINK_FASTER_INTERVAL_ALPHA 50 #define LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA 5000 /*=========================================================================== * LED object. *=========================================================================== */ enum _LED_STATE_871x { LED_UNKNOWN = 0, LED_ON = 1, LED_OFF = 2, LED_BLINK_NORMAL = 3, LED_BLINK_SLOWLY = 4, LED_POWER_ON_BLINK = 5, LED_SCAN_BLINK = 6, /* LED is blinking during scanning period, * the # of times to blink is depend on time * for scanning. */ LED_NO_LINK_BLINK = 7, /* LED is blinking during no link state. */ LED_BLINK_StartToBlink = 8,/* Customized for Sercomm Printer * Server case */ LED_BLINK_WPS = 9, /* LED is blinkg during WPS communication */ LED_TXRX_BLINK = 10, LED_BLINK_WPS_STOP = 11, /*for ALPHA */ LED_BLINK_WPS_STOP_OVERLAP = 12, /*for BELKIN */ }; /*=========================================================================== * Prototype of protected function. *=========================================================================== */ static void BlinkTimerCallback(unsigned long data); static void BlinkWorkItemCallback(struct work_struct *work); /*=========================================================================== * LED_819xUsb routines. *=========================================================================== * * * * Description: * Initialize an LED_871x object. */ static void InitLed871x(struct _adapter *padapter, struct LED_871x *pLed, enum LED_PIN_871x LedPin) { struct net_device *nic; nic = padapter->pnetdev; pLed->padapter = padapter; pLed->LedPin = LedPin; pLed->CurrLedState = LED_OFF; pLed->bLedOn = false; pLed->bLedBlinkInProgress = false; pLed->BlinkTimes = 0; pLed->BlinkingLedState = LED_UNKNOWN; _init_timer(&(pLed->BlinkTimer), nic, BlinkTimerCallback, pLed); _init_workitem(&(pLed->BlinkWorkItem), BlinkWorkItemCallback, pLed); } /* * Description: * DeInitialize an LED_871x object. */ static void DeInitLed871x(struct LED_871x *pLed) { _cancel_timer_ex(&(pLed->BlinkTimer)); /* We should reset bLedBlinkInProgress if we cancel * the LedControlTimer, */ pLed->bLedBlinkInProgress = false; } /* * Description: * Turn on LED according to LedPin specified. */ static void SwLedOn(struct _adapter *padapter, struct LED_871x *pLed) { u8 LedCfg; if ((padapter->bSurpriseRemoved == true) || (padapter->bDriverStopped == true)) return; LedCfg = r8712_read8(padapter, LEDCFG); switch (pLed->LedPin) { case LED_PIN_GPIO0: break; case LED_PIN_LED0: /* SW control led0 on.*/ r8712_write8(padapter, LEDCFG, LedCfg&0xf0); break; case LED_PIN_LED1: /* SW control led1 on.*/ r8712_write8(padapter, LEDCFG, LedCfg&0x0f); break; default: break; } pLed->bLedOn = true; } /* * Description: * Turn off LED according to LedPin specified. */ static void SwLedOff(struct _adapter *padapter, struct LED_871x *pLed) { u8 LedCfg; if ((padapter->bSurpriseRemoved == true) || (padapter->bDriverStopped == true)) return; LedCfg = r8712_read8(padapter, LEDCFG); switch (pLed->LedPin) { case LED_PIN_GPIO0: break; case LED_PIN_LED0: LedCfg &= 0xf0; /* Set to software control.*/ r8712_write8(padapter, LEDCFG, (LedCfg|BIT(3))); break; case LED_PIN_LED1: LedCfg &= 0x0f; /* Set to software control.*/ r8712_write8(padapter, LEDCFG, (LedCfg|BIT(7))); break; default: break; } pLed->bLedOn = false; } /*=========================================================================== * Interface to manipulate LED objects. *=========================================================================== * * Description: * Initialize all LED_871x objects. */ void r8712_InitSwLeds(struct _adapter *padapter) { struct led_priv *pledpriv = &(padapter->ledpriv); pledpriv->LedControlHandler = LedControl871x; InitLed871x(padapter, &(pledpriv->SwLed0), LED_PIN_LED0); InitLed871x(padapter, &(pledpriv->SwLed1), LED_PIN_LED1); } /* Description: * DeInitialize all LED_819xUsb objects. */ void r8712_DeInitSwLeds(struct _adapter *padapter) { struct led_priv *ledpriv = &(padapter->ledpriv); DeInitLed871x(&(ledpriv->SwLed0)); DeInitLed871x(&(ledpriv->SwLed1)); } /* Description: * Implementation of LED blinking behavior. * It toggle off LED and schedule corresponding timer if necessary. */ static void SwLedBlink(struct LED_871x *pLed) { struct _adapter *padapter = pLed->padapter; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); u8 bStopBlinking = false; /* Change LED according to BlinkingLedState specified. */ if (pLed->BlinkingLedState == LED_ON) SwLedOn(padapter, pLed); else SwLedOff(padapter, pLed); /* Determine if we shall change LED state again. */ pLed->BlinkTimes--; switch (pLed->CurrLedState) { case LED_BLINK_NORMAL: if (pLed->BlinkTimes == 0) bStopBlinking = true; break; case LED_BLINK_StartToBlink: if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && (pmlmepriv->fw_state & WIFI_STATION_STATE)) bStopBlinking = true; if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && ((pmlmepriv->fw_state & WIFI_ADHOC_STATE) || (pmlmepriv->fw_state & WIFI_ADHOC_MASTER_STATE))) bStopBlinking = true; else if (pLed->BlinkTimes == 0) bStopBlinking = true; break; case LED_BLINK_WPS: if (pLed->BlinkTimes == 0) bStopBlinking = true; break; default: bStopBlinking = true; break; } if (bStopBlinking) { if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && (pLed->bLedOn == false)) SwLedOn(padapter, pLed); else if ((check_fwstate(pmlmepriv, _FW_LINKED) == true) && pLed->bLedOn == true) SwLedOff(padapter, pLed); pLed->BlinkTimes = 0; pLed->bLedBlinkInProgress = false; } else { /* Assign LED state to toggle. */ if (pLed->BlinkingLedState == LED_ON) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; /* Schedule a timer to toggle LED state. */ switch (pLed->CurrLedState) { case LED_BLINK_NORMAL: _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); break; case LED_BLINK_SLOWLY: case LED_BLINK_StartToBlink: _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); break; case LED_BLINK_WPS: _set_timer(&(pLed->BlinkTimer), LED_BLINK_LONG_INTERVAL); break; default: _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); break; } } } static void SwLedBlink1(struct LED_871x *pLed) { struct _adapter *padapter = pLed->padapter; struct led_priv *ledpriv = &(padapter->ledpriv); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct eeprom_priv *peeprompriv = &(padapter->eeprompriv); struct LED_871x *pLed1 = &(ledpriv->SwLed1); u8 bStopBlinking = false; if (peeprompriv->CustomerID == RT_CID_819x_CAMEO) pLed = &(ledpriv->SwLed1); /* Change LED according to BlinkingLedState specified. */ if (pLed->BlinkingLedState == LED_ON) SwLedOn(padapter, pLed); else SwLedOff(padapter, pLed); if (peeprompriv->CustomerID == RT_CID_DEFAULT) { if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { if (!pLed1->bSWLedCtrl) { SwLedOn(padapter, pLed1); pLed1->bSWLedCtrl = true; } else if (!pLed1->bLedOn) SwLedOn(padapter, pLed1); } else { if (!pLed1->bSWLedCtrl) { SwLedOff(padapter, pLed1); pLed1->bSWLedCtrl = true; } else if (pLed1->bLedOn) SwLedOff(padapter, pLed1); } } switch (pLed->CurrLedState) { case LED_BLINK_SLOWLY: if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); break; case LED_BLINK_NORMAL: if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); break; case LED_SCAN_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); } pLed->bLedScanBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_TXRX_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); } pLed->BlinkTimes = 0; pLed->bLedBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_BLINK_WPS: if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); break; case LED_BLINK_WPS_STOP: /* WPS success */ if (pLed->BlinkingLedState == LED_ON) { pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); bStopBlinking = false; } else bStopBlinking = true; if (bStopBlinking) { pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); } pLed->bLedWPSBlinkInProgress = false; break; default: break; } } static void SwLedBlink2(struct LED_871x *pLed) { struct _adapter *padapter = pLed->padapter; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); u8 bStopBlinking = false; /* Change LED according to BlinkingLedState specified. */ if (pLed->BlinkingLedState == LED_ON) SwLedOn(padapter, pLed); else SwLedOff(padapter, pLed); switch (pLed->CurrLedState) { case LED_SCAN_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; SwLedOn(padapter, pLed); } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; SwLedOff(padapter, pLed); } pLed->bLedScanBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_TXRX_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; SwLedOn(padapter, pLed); } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; SwLedOff(padapter, pLed); } pLed->bLedBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; default: break; } } static void SwLedBlink3(struct LED_871x *pLed) { struct _adapter *padapter = pLed->padapter; struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); u8 bStopBlinking = false; /* Change LED according to BlinkingLedState specified. */ if (pLed->BlinkingLedState == LED_ON) SwLedOn(padapter, pLed); else if (pLed->CurrLedState != LED_BLINK_WPS_STOP) SwLedOff(padapter, pLed); switch (pLed->CurrLedState) { case LED_SCAN_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; if (!pLed->bLedOn) SwLedOn(padapter, pLed); } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedOn) SwLedOff(padapter, pLed); } pLed->bLedScanBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_TXRX_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { if (check_fwstate(pmlmepriv, _FW_LINKED) == true) { pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; if (!pLed->bLedOn) SwLedOn(padapter, pLed); } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) { pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedOn) SwLedOff(padapter, pLed); } pLed->bLedBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_BLINK_WPS: if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); break; case LED_BLINK_WPS_STOP: /*WPS success*/ if (pLed->BlinkingLedState == LED_ON) { pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); bStopBlinking = false; } else bStopBlinking = true; if (bStopBlinking) { pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; SwLedOn(padapter, pLed); pLed->bLedWPSBlinkInProgress = false; } break; default: break; } } static void SwLedBlink4(struct LED_871x *pLed) { struct _adapter *padapter = pLed->padapter; struct led_priv *ledpriv = &(padapter->ledpriv); struct LED_871x *pLed1 = &(ledpriv->SwLed1); u8 bStopBlinking = false; /* Change LED according to BlinkingLedState specified. */ if (pLed->BlinkingLedState == LED_ON) SwLedOn(padapter, pLed); else SwLedOff(padapter, pLed); if (!pLed1->bLedWPSBlinkInProgress && pLed1->BlinkingLedState == LED_UNKNOWN) { pLed1->BlinkingLedState = LED_OFF; pLed1->CurrLedState = LED_OFF; SwLedOff(padapter, pLed1); } switch (pLed->CurrLedState) { case LED_BLINK_SLOWLY: if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); break; case LED_BLINK_StartToBlink: if (pLed->bLedOn) { pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); } else { pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); } break; case LED_SCAN_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); pLed->bLedScanBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_TXRX_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); pLed->bLedBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_BLINK_WPS: if (pLed->bLedOn) { pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); } else { pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); } break; case LED_BLINK_WPS_STOP: /*WPS authentication fail*/ if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); break; case LED_BLINK_WPS_STOP_OVERLAP: /*WPS session overlap */ pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) { if (pLed->bLedOn) pLed->BlinkTimes = 1; else bStopBlinking = true; } if (bStopBlinking) { pLed->BlinkTimes = 10; pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); } break; default: break; } } static void SwLedBlink5(struct LED_871x *pLed) { struct _adapter *padapter = pLed->padapter; u8 bStopBlinking = false; /* Change LED according to BlinkingLedState specified. */ if (pLed->BlinkingLedState == LED_ON) SwLedOn(padapter, pLed); else SwLedOff(padapter, pLed); switch (pLed->CurrLedState) { case LED_SCAN_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; if (!pLed->bLedOn) _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); pLed->bLedScanBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_TXRX_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; if (!pLed->bLedOn) _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); pLed->bLedBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; default: break; } } static void SwLedBlink6(struct LED_871x *pLed) { struct _adapter *padapter = pLed->padapter; u8 bStopBlinking = false; /* Change LED according to BlinkingLedState specified. */ if (pLed->BlinkingLedState == LED_ON) SwLedOn(padapter, pLed); else SwLedOff(padapter, pLed); switch (pLed->CurrLedState) { case LED_TXRX_BLINK: pLed->BlinkTimes--; if (pLed->BlinkTimes == 0) bStopBlinking = true; if (bStopBlinking) { pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; if (!pLed->bLedOn) SwLedOn(padapter, pLed); pLed->bLedBlinkInProgress = false; } else { if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_BLINK_WPS: if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); break; default: break; } } /* Description: * Callback function of LED BlinkTimer, * it just schedules to corresponding BlinkWorkItem. */ static void BlinkTimerCallback(unsigned long data) { struct LED_871x *pLed = (struct LED_871x *)data; /* This fixed the crash problem on Fedora 12 when trying to do the * insmod;ifconfig up;rmmod commands. */ if ((pLed->padapter->bSurpriseRemoved == true) || (pLed->padapter->bDriverStopped == true)) return; _set_workitem(&(pLed->BlinkWorkItem)); } /* Description: * Callback function of LED BlinkWorkItem. * We dispatch actual LED blink action according to LedStrategy. */ static void BlinkWorkItemCallback(struct work_struct *work) { struct LED_871x *pLed = container_of(work, struct LED_871x, BlinkWorkItem); struct led_priv *ledpriv = &(pLed->padapter->ledpriv); switch (ledpriv->LedStrategy) { case SW_LED_MODE0: SwLedBlink(pLed); break; case SW_LED_MODE1: SwLedBlink1(pLed); break; case SW_LED_MODE2: SwLedBlink2(pLed); break; case SW_LED_MODE3: SwLedBlink3(pLed); break; case SW_LED_MODE4: SwLedBlink4(pLed); break; case SW_LED_MODE5: SwLedBlink5(pLed); break; case SW_LED_MODE6: SwLedBlink6(pLed); break; default: SwLedBlink(pLed); break; } } /*============================================================================ * Default LED behavior. *============================================================================ * * Description: * Implement each led action for SW_LED_MODE0. * This is default strategy. */ static void SwLedControlMode1(struct _adapter *padapter, enum LED_CTL_MODE LedAction) { struct led_priv *ledpriv = &(padapter->ledpriv); struct LED_871x *pLed = &(ledpriv->SwLed0); struct mlme_priv *pmlmepriv = &(padapter->mlmepriv); struct sitesurvey_ctrl *psitesurveyctrl = &(pmlmepriv->sitesurveyctrl); if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO) pLed = &(ledpriv->SwLed1); switch (LedAction) { case LED_CTL_START_TO_LINK: case LED_CTL_NO_LINK: if (pLed->bLedNoLinkBlinkInProgress == false) { if (pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); } break; case LED_CTL_LINK: if (pLed->bLedLinkBlinkInProgress == false) { if (pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_NORMAL; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_LINK_INTERVAL_ALPHA); } break; case LED_CTL_SITE_SURVEY: if ((psitesurveyctrl->traffic_busy) && (check_fwstate(pmlmepriv, _FW_LINKED) == true)) ; /* dummy branch */ else if (pLed->bLedScanBlinkInProgress == false) { if (IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; pLed->CurrLedState = LED_SCAN_BLINK; pLed->BlinkTimes = 24; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_TX: case LED_CTL_RX: if (pLed->bLedBlinkInProgress == false) { if (pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } pLed->bLedBlinkInProgress = true; pLed->CurrLedState = LED_TXRX_BLINK; pLed->BlinkTimes = 2; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_CTL_START_WPS: /*wait until xinpin finish */ case LED_CTL_START_WPS_BOTTON: if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedNoLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_STOP_WPS: if (pLed->bLedNoLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) _cancel_timer_ex(&(pLed->BlinkTimer)); else pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS_STOP; if (pLed->bLedOn) { pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); } else { pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), 0); } break; case LED_CTL_STOP_WPS_FAIL: if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); break; case LED_CTL_POWER_OFF: pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedNoLinkBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } _set_timer(&(pLed->BlinkTimer), 0); break; default: break; } } static void SwLedControlMode2(struct _adapter *padapter, enum LED_CTL_MODE LedAction) { struct led_priv *ledpriv = &(padapter->ledpriv); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct LED_871x *pLed = &(ledpriv->SwLed0); switch (LedAction) { case LED_CTL_SITE_SURVEY: if (pmlmepriv->sitesurveyctrl.traffic_busy) ; /* dummy branch */ else if (pLed->bLedScanBlinkInProgress == false) { if (IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; pLed->CurrLedState = LED_SCAN_BLINK; pLed->BlinkTimes = 24; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_TX: case LED_CTL_RX: if ((pLed->bLedBlinkInProgress == false) && (check_fwstate(pmlmepriv, _FW_LINKED) == true)) { if (pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) return; pLed->bLedBlinkInProgress = true; pLed->CurrLedState = LED_TXRX_BLINK; pLed->BlinkTimes = 2; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_CTL_LINK: pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; if (pLed->bLedBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } _set_timer(&(pLed->BlinkTimer), 0); break; case LED_CTL_START_WPS: /*wait until xinpin finish*/ case LED_CTL_START_WPS_BOTTON: if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), 0); } break; case LED_CTL_STOP_WPS: pLed->bLedWPSBlinkInProgress = false; pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), 0); break; case LED_CTL_STOP_WPS_FAIL: pLed->bLedWPSBlinkInProgress = false; pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), 0); break; case LED_CTL_START_TO_LINK: case LED_CTL_NO_LINK: if (!IS_LED_BLINKING(pLed)) { pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), 0); } break; case LED_CTL_POWER_OFF: pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } _set_timer(&(pLed->BlinkTimer), 0); break; default: break; } } static void SwLedControlMode3(struct _adapter *padapter, enum LED_CTL_MODE LedAction) { struct led_priv *ledpriv = &(padapter->ledpriv); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct LED_871x *pLed = &(ledpriv->SwLed0); switch (LedAction) { case LED_CTL_SITE_SURVEY: if (pmlmepriv->sitesurveyctrl.traffic_busy) ; /* dummy branch */ else if (pLed->bLedScanBlinkInProgress == false) { if (IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; pLed->CurrLedState = LED_SCAN_BLINK; pLed->BlinkTimes = 24; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_TX: case LED_CTL_RX: if ((pLed->bLedBlinkInProgress == false) && (check_fwstate(pmlmepriv, _FW_LINKED) == true)) { if (pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) return; pLed->bLedBlinkInProgress = true; pLed->CurrLedState = LED_TXRX_BLINK; pLed->BlinkTimes = 2; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_CTL_LINK: if (IS_LED_WPS_BLINKING(pLed)) return; pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; if (pLed->bLedBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } _set_timer(&(pLed->BlinkTimer), 0); break; case LED_CTL_START_WPS: /* wait until xinpin finish */ case LED_CTL_START_WPS_BOTTON: if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_STOP_WPS: if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } else pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS_STOP; if (pLed->bLedOn) { pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_WPS_SUCESS_INTERVAL_ALPHA); } else { pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), 0); } break; case LED_CTL_STOP_WPS_FAIL: if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), 0); break; case LED_CTL_START_TO_LINK: case LED_CTL_NO_LINK: if (!IS_LED_BLINKING(pLed)) { pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), 0); } break; case LED_CTL_POWER_OFF: pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } _set_timer(&(pLed->BlinkTimer), 0); break; default: break; } } static void SwLedControlMode4(struct _adapter *padapter, enum LED_CTL_MODE LedAction) { struct led_priv *ledpriv = &(padapter->ledpriv); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct LED_871x *pLed = &(ledpriv->SwLed0); struct LED_871x *pLed1 = &(ledpriv->SwLed1); switch (LedAction) { case LED_CTL_START_TO_LINK: if (pLed1->bLedWPSBlinkInProgress) { pLed1->bLedWPSBlinkInProgress = false; _cancel_timer_ex(&(pLed1->BlinkTimer)); pLed1->BlinkingLedState = LED_OFF; pLed1->CurrLedState = LED_OFF; if (pLed1->bLedOn) _set_timer(&(pLed->BlinkTimer), 0); } if (pLed->bLedStartToLinkBlinkInProgress == false) { if (pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedNoLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } pLed->bLedStartToLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_StartToBlink; if (pLed->bLedOn) { pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); } else { pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); } } break; case LED_CTL_LINK: case LED_CTL_NO_LINK: /*LED1 settings*/ if (LedAction == LED_CTL_LINK) { if (pLed1->bLedWPSBlinkInProgress) { pLed1->bLedWPSBlinkInProgress = false; _cancel_timer_ex(&(pLed1->BlinkTimer)); pLed1->BlinkingLedState = LED_OFF; pLed1->CurrLedState = LED_OFF; if (pLed1->bLedOn) _set_timer(&(pLed->BlinkTimer), 0); } } if (pLed->bLedNoLinkBlinkInProgress == false) { if (pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); } break; case LED_CTL_SITE_SURVEY: if ((pmlmepriv->sitesurveyctrl.traffic_busy) && (check_fwstate(pmlmepriv, _FW_LINKED) == true)) ; else if (pLed->bLedScanBlinkInProgress == false) { if (IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; pLed->CurrLedState = LED_SCAN_BLINK; pLed->BlinkTimes = 24; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_TX: case LED_CTL_RX: if (pLed->bLedBlinkInProgress == false) { if (pLed->CurrLedState == LED_SCAN_BLINK || IS_LED_WPS_BLINKING(pLed)) return; if (pLed->bLedNoLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } pLed->bLedBlinkInProgress = true; pLed->CurrLedState = LED_TXRX_BLINK; pLed->BlinkTimes = 2; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_CTL_START_WPS: /*wait until xinpin finish*/ case LED_CTL_START_WPS_BOTTON: if (pLed1->bLedWPSBlinkInProgress) { pLed1->bLedWPSBlinkInProgress = false; _cancel_timer_ex(&(pLed1->BlinkTimer)); pLed1->BlinkingLedState = LED_OFF; pLed1->CurrLedState = LED_OFF; if (pLed1->bLedOn) _set_timer(&(pLed->BlinkTimer), 0); } if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedNoLinkBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS; if (pLed->bLedOn) { pLed->BlinkingLedState = LED_OFF; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SLOWLY_INTERVAL); } else { pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); } } break; case LED_CTL_STOP_WPS: /*WPS connect success*/ if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); break; case LED_CTL_STOP_WPS_FAIL: /*WPS authentication fail*/ if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); /*LED1 settings*/ if (pLed1->bLedWPSBlinkInProgress) _cancel_timer_ex(&(pLed1->BlinkTimer)); else pLed1->bLedWPSBlinkInProgress = true; pLed1->CurrLedState = LED_BLINK_WPS_STOP; if (pLed1->bLedOn) pLed1->BlinkingLedState = LED_OFF; else pLed1->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); break; case LED_CTL_STOP_WPS_FAIL_OVERLAP: /*WPS session overlap*/ if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } pLed->bLedNoLinkBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_SLOWLY; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NO_LINK_INTERVAL_ALPHA); /*LED1 settings*/ if (pLed1->bLedWPSBlinkInProgress) _cancel_timer_ex(&(pLed1->BlinkTimer)); else pLed1->bLedWPSBlinkInProgress = true; pLed1->CurrLedState = LED_BLINK_WPS_STOP_OVERLAP; pLed1->BlinkTimes = 10; if (pLed1->bLedOn) pLed1->BlinkingLedState = LED_OFF; else pLed1->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_NORMAL_INTERVAL); break; case LED_CTL_POWER_OFF: pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedNoLinkBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedNoLinkBlinkInProgress = false; } if (pLed->bLedLinkBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedLinkBlinkInProgress = false; } if (pLed->bLedBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } if (pLed->bLedScanBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedScanBlinkInProgress = false; } if (pLed->bLedStartToLinkBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedStartToLinkBlinkInProgress = false; } if (pLed1->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed1->BlinkTimer)); pLed1->bLedWPSBlinkInProgress = false; } pLed1->BlinkingLedState = LED_UNKNOWN; SwLedOff(padapter, pLed); SwLedOff(padapter, pLed1); break; default: break; } } static void SwLedControlMode5(struct _adapter *padapter, enum LED_CTL_MODE LedAction) { struct led_priv *ledpriv = &(padapter->ledpriv); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct LED_871x *pLed = &(ledpriv->SwLed0); if (padapter->eeprompriv.CustomerID == RT_CID_819x_CAMEO) pLed = &(ledpriv->SwLed1); switch (LedAction) { case LED_CTL_POWER_ON: case LED_CTL_NO_LINK: case LED_CTL_LINK: /* solid blue */ if (pLed->CurrLedState == LED_SCAN_BLINK) return; pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; pLed->bLedBlinkInProgress = false; _set_timer(&(pLed->BlinkTimer), 0); break; case LED_CTL_SITE_SURVEY: if ((pmlmepriv->sitesurveyctrl.traffic_busy) && (check_fwstate(pmlmepriv, _FW_LINKED) == true)) ; /* dummy branch */ else if (pLed->bLedScanBlinkInProgress == false) { if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedScanBlinkInProgress = true; pLed->CurrLedState = LED_SCAN_BLINK; pLed->BlinkTimes = 24; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_TX: case LED_CTL_RX: if (pLed->bLedBlinkInProgress == false) { if (pLed->CurrLedState == LED_SCAN_BLINK) return; pLed->bLedBlinkInProgress = true; pLed->CurrLedState = LED_TXRX_BLINK; pLed->BlinkTimes = 2; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_CTL_POWER_OFF: pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } SwLedOff(padapter, pLed); break; default: break; } } static void SwLedControlMode6(struct _adapter *padapter, enum LED_CTL_MODE LedAction) { struct led_priv *ledpriv = &(padapter->ledpriv); struct mlme_priv *pmlmepriv = &padapter->mlmepriv; struct LED_871x *pLed = &(ledpriv->SwLed0); switch (LedAction) { case LED_CTL_POWER_ON: case LED_CTL_NO_LINK: case LED_CTL_LINK: /*solid blue*/ case LED_CTL_SITE_SURVEY: if (IS_LED_WPS_BLINKING(pLed)) return; pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; pLed->bLedBlinkInProgress = false; _set_timer(&(pLed->BlinkTimer), 0); break; case LED_CTL_TX: case LED_CTL_RX: if (pLed->bLedBlinkInProgress == false && (check_fwstate(pmlmepriv, _FW_LINKED) == true)) { if (IS_LED_WPS_BLINKING(pLed)) return; pLed->bLedBlinkInProgress = true; pLed->CurrLedState = LED_TXRX_BLINK; pLed->BlinkTimes = 2; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_FASTER_INTERVAL_ALPHA); } break; case LED_CTL_START_WPS: /*wait until xinpin finish*/ case LED_CTL_START_WPS_BOTTON: if (pLed->bLedWPSBlinkInProgress == false) { if (pLed->bLedBlinkInProgress == true) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } pLed->bLedWPSBlinkInProgress = true; pLed->CurrLedState = LED_BLINK_WPS; if (pLed->bLedOn) pLed->BlinkingLedState = LED_OFF; else pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), LED_BLINK_SCAN_INTERVAL_ALPHA); } break; case LED_CTL_STOP_WPS_FAIL: case LED_CTL_STOP_WPS: if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } pLed->CurrLedState = LED_ON; pLed->BlinkingLedState = LED_ON; _set_timer(&(pLed->BlinkTimer), 0); break; case LED_CTL_POWER_OFF: pLed->CurrLedState = LED_OFF; pLed->BlinkingLedState = LED_OFF; if (pLed->bLedBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedBlinkInProgress = false; } if (pLed->bLedWPSBlinkInProgress) { _cancel_timer_ex(&(pLed->BlinkTimer)); pLed->bLedWPSBlinkInProgress = false; } SwLedOff(padapter, pLed); break; default: break; } } /* Description: * Dispatch LED action according to pHalData->LedStrategy. */ void LedControl871x(struct _adapter *padapter, enum LED_CTL_MODE LedAction) { struct led_priv *ledpriv = &(padapter->ledpriv); if (ledpriv->bRegUseLed == false) return; switch (ledpriv->LedStrategy) { case SW_LED_MODE0: break; case SW_LED_MODE1: SwLedControlMode1(padapter, LedAction); break; case SW_LED_MODE2: SwLedControlMode2(padapter, LedAction); break; case SW_LED_MODE3: SwLedControlMode3(padapter, LedAction); break; case SW_LED_MODE4: SwLedControlMode4(padapter, LedAction); break; case SW_LED_MODE5: SwLedControlMode5(padapter, LedAction); break; case SW_LED_MODE6: SwLedControlMode6(padapter, LedAction); break; default: break; } }