root/drivers/staging/rtl8188eu/core/rtw_led.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. BlinkTimerCallback
  2. BlinkWorkItemCallback
  3. ResetLedStatus
  4. InitLed871x
  5. DeInitLed871x
  6. SwLedBlink1
  7. SwLedControlMode1
  8. blink_handler
  9. led_control_8188eu

   1 // SPDX-License-Identifier: GPL-2.0
   2 /******************************************************************************
   3  *
   4  * Copyright(c) 2007 - 2012 Realtek Corporation. All rights reserved.
   5  *
   6  ******************************************************************************/
   7 
   8 #include <drv_types.h>
   9 #include "rtw_led.h"
  10 
  11 /*  */
  12 /*      Description: */
  13 /*              Callback function of LED BlinkTimer, */
  14 /*              it just schedules to corresponding BlinkWorkItem/led_blink_hdl */
  15 /*  */
  16 static void BlinkTimerCallback(struct timer_list *t)
  17 {
  18         struct LED_871x *pLed = from_timer(pLed, t, BlinkTimer);
  19         struct adapter *padapter = pLed->padapter;
  20 
  21         if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
  22                 return;
  23 
  24         schedule_work(&pLed->BlinkWorkItem);
  25 }
  26 
  27 /*  */
  28 /*      Description: */
  29 /*              Callback function of LED BlinkWorkItem. */
  30 /*  */
  31 void BlinkWorkItemCallback(struct work_struct *work)
  32 {
  33         struct LED_871x *pLed = container_of(work, struct LED_871x,
  34                                                 BlinkWorkItem);
  35 
  36         blink_handler(pLed);
  37 }
  38 
  39 /*  */
  40 /*      Description: */
  41 /*              Reset status of LED_871x object. */
  42 /*  */
  43 void ResetLedStatus(struct LED_871x *pLed)
  44 {
  45         pLed->CurrLedState = RTW_LED_OFF; /*  Current LED state. */
  46         pLed->bLedOn = false; /*  true if LED is ON, false if LED is OFF. */
  47 
  48         pLed->bLedBlinkInProgress = false; /*  true if it is blinking, false o.w.. */
  49         pLed->bLedWPSBlinkInProgress = false;
  50 
  51         pLed->BlinkTimes = 0; /*  Number of times to toggle led state for blinking. */
  52         pLed->BlinkingLedState = LED_UNKNOWN; /*  Next state for blinking, either RTW_LED_ON or RTW_LED_OFF are. */
  53 
  54         pLed->bLedNoLinkBlinkInProgress = false;
  55         pLed->bLedLinkBlinkInProgress = false;
  56         pLed->bLedScanBlinkInProgress = false;
  57 }
  58 
  59 /*Description: */
  60 /*              Initialize an LED_871x object. */
  61 void InitLed871x(struct adapter *padapter, struct LED_871x *pLed)
  62 {
  63         pLed->padapter = padapter;
  64 
  65         ResetLedStatus(pLed);
  66 
  67         timer_setup(&pLed->BlinkTimer, BlinkTimerCallback, 0);
  68 
  69         INIT_WORK(&pLed->BlinkWorkItem, BlinkWorkItemCallback);
  70 }
  71 
  72 /*  */
  73 /*      Description: */
  74 /*              DeInitialize an LED_871x object. */
  75 /*  */
  76 void DeInitLed871x(struct LED_871x *pLed)
  77 {
  78         cancel_work_sync(&pLed->BlinkWorkItem);
  79         del_timer_sync(&pLed->BlinkTimer);
  80         ResetLedStatus(pLed);
  81 }
  82 
  83 /*  */
  84 /*      Description: */
  85 /*              Implementation of LED blinking behavior. */
  86 /*              It toggle off LED and schedule corresponding timer if necessary. */
  87 /*  */
  88 
  89 static void SwLedBlink1(struct LED_871x *pLed)
  90 {
  91         struct adapter *padapter = pLed->padapter;
  92         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
  93         u8 bStopBlinking = false;
  94 
  95         /*  Change LED according to BlinkingLedState specified. */
  96         if (pLed->BlinkingLedState == RTW_LED_ON) {
  97                 sw_led_on(padapter, pLed);
  98                 RT_TRACE(_module_rtl8712_led_c_, _drv_info_,
  99                          ("Blinktimes (%d): turn on\n", pLed->BlinkTimes));
 100         } else {
 101                 sw_led_off(padapter, pLed);
 102                 RT_TRACE(_module_rtl8712_led_c_, _drv_info_,
 103                          ("Blinktimes (%d): turn off\n", pLed->BlinkTimes));
 104         }
 105 
 106         if (padapter->pwrctrlpriv.rf_pwrstate != rf_on) {
 107                 sw_led_off(padapter, pLed);
 108                 ResetLedStatus(pLed);
 109                 return;
 110         }
 111 
 112         switch (pLed->CurrLedState) {
 113         case LED_BLINK_SLOWLY:
 114                 if (pLed->bLedOn)
 115                         pLed->BlinkingLedState = RTW_LED_OFF;
 116                 else
 117                         pLed->BlinkingLedState = RTW_LED_ON;
 118                 mod_timer(&pLed->BlinkTimer, jiffies +
 119                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
 120                 break;
 121         case LED_BLINK_NORMAL:
 122                 if (pLed->bLedOn)
 123                         pLed->BlinkingLedState = RTW_LED_OFF;
 124                 else
 125                         pLed->BlinkingLedState = RTW_LED_ON;
 126                 mod_timer(&pLed->BlinkTimer, jiffies +
 127                           msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
 128                 break;
 129         case LED_BLINK_SCAN:
 130                 pLed->BlinkTimes--;
 131                 if (pLed->BlinkTimes == 0)
 132                         bStopBlinking = true;
 133                 if (bStopBlinking) {
 134                         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
 135                                 pLed->bLedLinkBlinkInProgress = true;
 136                                 pLed->CurrLedState = LED_BLINK_NORMAL;
 137                                 if (pLed->bLedOn)
 138                                         pLed->BlinkingLedState = RTW_LED_OFF;
 139                                 else
 140                                         pLed->BlinkingLedState = RTW_LED_ON;
 141                                 mod_timer(&pLed->BlinkTimer, jiffies +
 142                                           msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
 143                                 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
 144                         } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
 145                                 pLed->bLedNoLinkBlinkInProgress = true;
 146                                 pLed->CurrLedState = LED_BLINK_SLOWLY;
 147                                 if (pLed->bLedOn)
 148                                         pLed->BlinkingLedState = RTW_LED_OFF;
 149                                 else
 150                                         pLed->BlinkingLedState = RTW_LED_ON;
 151                                 mod_timer(&pLed->BlinkTimer, jiffies +
 152                                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
 153                                 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
 154                         }
 155                         pLed->bLedScanBlinkInProgress = false;
 156                 } else {
 157                         if (pLed->bLedOn)
 158                                 pLed->BlinkingLedState = RTW_LED_OFF;
 159                         else
 160                                 pLed->BlinkingLedState = RTW_LED_ON;
 161                         mod_timer(&pLed->BlinkTimer, jiffies +
 162                                   msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
 163                 }
 164                 break;
 165         case LED_BLINK_TXRX:
 166                 pLed->BlinkTimes--;
 167                 if (pLed->BlinkTimes == 0)
 168                         bStopBlinking = true;
 169                 if (bStopBlinking) {
 170                         if (check_fwstate(pmlmepriv, _FW_LINKED)) {
 171                                 pLed->bLedLinkBlinkInProgress = true;
 172                                 pLed->CurrLedState = LED_BLINK_NORMAL;
 173                                 if (pLed->bLedOn)
 174                                         pLed->BlinkingLedState = RTW_LED_OFF;
 175                                 else
 176                                         pLed->BlinkingLedState = RTW_LED_ON;
 177                                 mod_timer(&pLed->BlinkTimer, jiffies +
 178                                           msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
 179                                 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
 180                         } else if (!check_fwstate(pmlmepriv, _FW_LINKED)) {
 181                                 pLed->bLedNoLinkBlinkInProgress = true;
 182                                 pLed->CurrLedState = LED_BLINK_SLOWLY;
 183                                 if (pLed->bLedOn)
 184                                         pLed->BlinkingLedState = RTW_LED_OFF;
 185                                 else
 186                                         pLed->BlinkingLedState = RTW_LED_ON;
 187                                 mod_timer(&pLed->BlinkTimer, jiffies +
 188                                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
 189                                 RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
 190                         }
 191                         pLed->BlinkTimes = 0;
 192                         pLed->bLedBlinkInProgress = false;
 193                 } else {
 194                         if (pLed->bLedOn)
 195                                 pLed->BlinkingLedState = RTW_LED_OFF;
 196                         else
 197                                 pLed->BlinkingLedState = RTW_LED_ON;
 198                         mod_timer(&pLed->BlinkTimer, jiffies +
 199                                   msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
 200                 }
 201                 break;
 202         case LED_BLINK_WPS:
 203                 if (pLed->bLedOn)
 204                         pLed->BlinkingLedState = RTW_LED_OFF;
 205                 else
 206                         pLed->BlinkingLedState = RTW_LED_ON;
 207                 mod_timer(&pLed->BlinkTimer, jiffies +
 208                           msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
 209                 break;
 210         case LED_BLINK_WPS_STOP:        /* WPS success */
 211                 if (pLed->BlinkingLedState == RTW_LED_ON)
 212                         bStopBlinking = false;
 213                 else
 214                         bStopBlinking = true;
 215 
 216                 if (bStopBlinking) {
 217                         pLed->bLedLinkBlinkInProgress = true;
 218                         pLed->CurrLedState = LED_BLINK_NORMAL;
 219                         if (pLed->bLedOn)
 220                                 pLed->BlinkingLedState = RTW_LED_OFF;
 221                         else
 222                                 pLed->BlinkingLedState = RTW_LED_ON;
 223                         mod_timer(&pLed->BlinkTimer, jiffies +
 224                                   msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
 225                         RT_TRACE(_module_rtl8712_led_c_, _drv_info_, ("CurrLedState %d\n", pLed->CurrLedState));
 226 
 227                         pLed->bLedWPSBlinkInProgress = false;
 228                 } else {
 229                         pLed->BlinkingLedState = RTW_LED_OFF;
 230                         mod_timer(&pLed->BlinkTimer, jiffies +
 231                                   msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
 232                 }
 233                 break;
 234         default:
 235                 break;
 236         }
 237 }
 238 
 239  /* ALPHA, added by chiyoko, 20090106 */
 240 static void SwLedControlMode1(struct adapter *padapter, enum LED_CTL_MODE LedAction)
 241 {
 242         struct led_priv *ledpriv = &padapter->ledpriv;
 243         struct LED_871x *pLed = &ledpriv->sw_led;
 244         struct mlme_priv *pmlmepriv = &padapter->mlmepriv;
 245 
 246         switch (LedAction) {
 247         case LED_CTL_POWER_ON:
 248         case LED_CTL_START_TO_LINK:
 249         case LED_CTL_NO_LINK:
 250                 if (pLed->bLedNoLinkBlinkInProgress)
 251                         break;
 252                 if (pLed->CurrLedState == LED_BLINK_SCAN ||
 253                     IS_LED_WPS_BLINKING(pLed))
 254                         return;
 255                 if (pLed->bLedLinkBlinkInProgress) {
 256                         del_timer_sync(&pLed->BlinkTimer);
 257                         pLed->bLedLinkBlinkInProgress = false;
 258                 }
 259                 if (pLed->bLedBlinkInProgress) {
 260                         del_timer_sync(&pLed->BlinkTimer);
 261                         pLed->bLedBlinkInProgress = false;
 262                 }
 263                 pLed->bLedNoLinkBlinkInProgress = true;
 264                 pLed->CurrLedState = LED_BLINK_SLOWLY;
 265                 if (pLed->bLedOn)
 266                         pLed->BlinkingLedState = RTW_LED_OFF;
 267                 else
 268                         pLed->BlinkingLedState = RTW_LED_ON;
 269                 mod_timer(&pLed->BlinkTimer, jiffies +
 270                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
 271                 break;
 272         case LED_CTL_LINK:
 273                 if (pLed->bLedLinkBlinkInProgress)
 274                         break;
 275                 if (pLed->CurrLedState == LED_BLINK_SCAN ||
 276                     IS_LED_WPS_BLINKING(pLed))
 277                         return;
 278                 if (pLed->bLedNoLinkBlinkInProgress) {
 279                         del_timer_sync(&pLed->BlinkTimer);
 280                         pLed->bLedNoLinkBlinkInProgress = false;
 281                 }
 282                 if (pLed->bLedBlinkInProgress) {
 283                         del_timer_sync(&pLed->BlinkTimer);
 284                         pLed->bLedBlinkInProgress = false;
 285                 }
 286                 pLed->bLedLinkBlinkInProgress = true;
 287                 pLed->CurrLedState = LED_BLINK_NORMAL;
 288                 if (pLed->bLedOn)
 289                         pLed->BlinkingLedState = RTW_LED_OFF;
 290                 else
 291                         pLed->BlinkingLedState = RTW_LED_ON;
 292                 mod_timer(&pLed->BlinkTimer, jiffies +
 293                           msecs_to_jiffies(LED_BLINK_LINK_INTERVAL_ALPHA));
 294                 break;
 295         case LED_CTL_SITE_SURVEY:
 296                 if (pmlmepriv->LinkDetectInfo.bBusyTraffic &&
 297                     check_fwstate(pmlmepriv, _FW_LINKED))
 298                         break;
 299                 if (pLed->bLedScanBlinkInProgress)
 300                         break;
 301                 if (IS_LED_WPS_BLINKING(pLed))
 302                         return;
 303                 if (pLed->bLedNoLinkBlinkInProgress) {
 304                         del_timer_sync(&pLed->BlinkTimer);
 305                         pLed->bLedNoLinkBlinkInProgress = false;
 306                 }
 307                 if (pLed->bLedLinkBlinkInProgress) {
 308                         del_timer_sync(&pLed->BlinkTimer);
 309                         pLed->bLedLinkBlinkInProgress = false;
 310                 }
 311                 if (pLed->bLedBlinkInProgress) {
 312                         del_timer_sync(&pLed->BlinkTimer);
 313                         pLed->bLedBlinkInProgress = false;
 314                 }
 315                 pLed->bLedScanBlinkInProgress = true;
 316                 pLed->CurrLedState = LED_BLINK_SCAN;
 317                 pLed->BlinkTimes = 24;
 318                 if (pLed->bLedOn)
 319                         pLed->BlinkingLedState = RTW_LED_OFF;
 320                 else
 321                         pLed->BlinkingLedState = RTW_LED_ON;
 322                 mod_timer(&pLed->BlinkTimer, jiffies +
 323                           msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
 324                 break;
 325         case LED_CTL_TX:
 326         case LED_CTL_RX:
 327                 if (pLed->bLedBlinkInProgress)
 328                         break;
 329                 if (pLed->CurrLedState == LED_BLINK_SCAN ||
 330                     IS_LED_WPS_BLINKING(pLed))
 331                         return;
 332                 if (pLed->bLedNoLinkBlinkInProgress) {
 333                         del_timer_sync(&pLed->BlinkTimer);
 334                         pLed->bLedNoLinkBlinkInProgress = false;
 335                 }
 336                 if (pLed->bLedLinkBlinkInProgress) {
 337                         del_timer_sync(&pLed->BlinkTimer);
 338                         pLed->bLedLinkBlinkInProgress = false;
 339                 }
 340                 pLed->bLedBlinkInProgress = true;
 341                 pLed->CurrLedState = LED_BLINK_TXRX;
 342                 pLed->BlinkTimes = 2;
 343                 if (pLed->bLedOn)
 344                         pLed->BlinkingLedState = RTW_LED_OFF;
 345                 else
 346                         pLed->BlinkingLedState = RTW_LED_ON;
 347                 mod_timer(&pLed->BlinkTimer, jiffies +
 348                           msecs_to_jiffies(LED_BLINK_FASTER_INTERVAL_ALPHA));
 349                 break;
 350         case LED_CTL_START_WPS: /* wait until xinpin finish */
 351         case LED_CTL_START_WPS_BOTTON:
 352                 if (pLed->bLedWPSBlinkInProgress)
 353                         break;
 354                 if (pLed->bLedNoLinkBlinkInProgress) {
 355                         del_timer_sync(&pLed->BlinkTimer);
 356                         pLed->bLedNoLinkBlinkInProgress = false;
 357                 }
 358                 if (pLed->bLedLinkBlinkInProgress) {
 359                         del_timer_sync(&pLed->BlinkTimer);
 360                         pLed->bLedLinkBlinkInProgress = false;
 361                 }
 362                 if (pLed->bLedBlinkInProgress) {
 363                         del_timer_sync(&pLed->BlinkTimer);
 364                         pLed->bLedBlinkInProgress = false;
 365                 }
 366                 if (pLed->bLedScanBlinkInProgress) {
 367                         del_timer_sync(&pLed->BlinkTimer);
 368                         pLed->bLedScanBlinkInProgress = false;
 369                 }
 370                 pLed->bLedWPSBlinkInProgress = true;
 371                 pLed->CurrLedState = LED_BLINK_WPS;
 372                 if (pLed->bLedOn)
 373                         pLed->BlinkingLedState = RTW_LED_OFF;
 374                 else
 375                         pLed->BlinkingLedState = RTW_LED_ON;
 376                 mod_timer(&pLed->BlinkTimer, jiffies +
 377                           msecs_to_jiffies(LED_BLINK_SCAN_INTERVAL_ALPHA));
 378                 break;
 379         case LED_CTL_STOP_WPS:
 380                 if (pLed->bLedNoLinkBlinkInProgress) {
 381                         del_timer_sync(&pLed->BlinkTimer);
 382                         pLed->bLedNoLinkBlinkInProgress = false;
 383                 }
 384                 if (pLed->bLedLinkBlinkInProgress) {
 385                         del_timer_sync(&pLed->BlinkTimer);
 386                         pLed->bLedLinkBlinkInProgress = false;
 387                 }
 388                 if (pLed->bLedBlinkInProgress) {
 389                         del_timer_sync(&pLed->BlinkTimer);
 390                         pLed->bLedBlinkInProgress = false;
 391                 }
 392                 if (pLed->bLedScanBlinkInProgress) {
 393                         del_timer_sync(&pLed->BlinkTimer);
 394                         pLed->bLedScanBlinkInProgress = false;
 395                 }
 396                 if (pLed->bLedWPSBlinkInProgress)
 397                         del_timer_sync(&pLed->BlinkTimer);
 398                 else
 399                         pLed->bLedWPSBlinkInProgress = true;
 400                 pLed->CurrLedState = LED_BLINK_WPS_STOP;
 401                 if (pLed->bLedOn) {
 402                         pLed->BlinkingLedState = RTW_LED_OFF;
 403                         mod_timer(&pLed->BlinkTimer, jiffies +
 404                                   msecs_to_jiffies(LED_BLINK_WPS_SUCCESS_INTERVAL_ALPHA));
 405                 } else {
 406                         pLed->BlinkingLedState = RTW_LED_ON;
 407                         mod_timer(&pLed->BlinkTimer,
 408                                   jiffies + msecs_to_jiffies(0));
 409                 }
 410                 break;
 411         case LED_CTL_STOP_WPS_FAIL:
 412                 if (pLed->bLedWPSBlinkInProgress) {
 413                         del_timer_sync(&pLed->BlinkTimer);
 414                         pLed->bLedWPSBlinkInProgress = false;
 415                 }
 416                 pLed->bLedNoLinkBlinkInProgress = true;
 417                 pLed->CurrLedState = LED_BLINK_SLOWLY;
 418                 if (pLed->bLedOn)
 419                         pLed->BlinkingLedState = RTW_LED_OFF;
 420                 else
 421                         pLed->BlinkingLedState = RTW_LED_ON;
 422                 mod_timer(&pLed->BlinkTimer, jiffies +
 423                           msecs_to_jiffies(LED_BLINK_NO_LINK_INTERVAL_ALPHA));
 424                 break;
 425         case LED_CTL_POWER_OFF:
 426                 pLed->CurrLedState = RTW_LED_OFF;
 427                 pLed->BlinkingLedState = RTW_LED_OFF;
 428                 if (pLed->bLedNoLinkBlinkInProgress) {
 429                         del_timer_sync(&pLed->BlinkTimer);
 430                         pLed->bLedNoLinkBlinkInProgress = false;
 431                 }
 432                 if (pLed->bLedLinkBlinkInProgress) {
 433                         del_timer_sync(&pLed->BlinkTimer);
 434                         pLed->bLedLinkBlinkInProgress = false;
 435                 }
 436                 if (pLed->bLedBlinkInProgress) {
 437                         del_timer_sync(&pLed->BlinkTimer);
 438                         pLed->bLedBlinkInProgress = false;
 439                 }
 440                 if (pLed->bLedWPSBlinkInProgress) {
 441                         del_timer_sync(&pLed->BlinkTimer);
 442                         pLed->bLedWPSBlinkInProgress = false;
 443                 }
 444                 if (pLed->bLedScanBlinkInProgress) {
 445                         del_timer_sync(&pLed->BlinkTimer);
 446                         pLed->bLedScanBlinkInProgress = false;
 447                 }
 448                 sw_led_off(padapter, pLed);
 449                 break;
 450         default:
 451                 break;
 452         }
 453 
 454         RT_TRACE(_module_rtl8712_led_c_, _drv_info_,
 455                  ("Led %d\n", pLed->CurrLedState));
 456 }
 457 
 458 void blink_handler(struct LED_871x *pLed)
 459 {
 460         struct adapter *padapter = pLed->padapter;
 461 
 462         if (padapter->bSurpriseRemoved || padapter->bDriverStopped)
 463                 return;
 464 
 465         SwLedBlink1(pLed);
 466 }
 467 
 468 void led_control_8188eu(struct adapter *padapter, enum LED_CTL_MODE LedAction)
 469 {
 470         if (padapter->bSurpriseRemoved || padapter->bDriverStopped ||
 471             !padapter->hw_init_completed)
 472                 return;
 473 
 474         if ((padapter->pwrctrlpriv.rf_pwrstate != rf_on &&
 475              padapter->pwrctrlpriv.rfoff_reason > RF_CHANGE_BY_PS) &&
 476             (LedAction == LED_CTL_TX || LedAction == LED_CTL_RX ||
 477              LedAction == LED_CTL_SITE_SURVEY ||
 478              LedAction == LED_CTL_LINK ||
 479              LedAction == LED_CTL_NO_LINK ||
 480              LedAction == LED_CTL_POWER_ON))
 481                 return;
 482 
 483         SwLedControlMode1(padapter, LedAction);
 484 }

/* [<][>][^][v][top][bottom][index][help] */