linux/drivers/staging/otus/80211core/ledmgr.c
<<
>>
Prefs
   1/*
   2 * Copyright (c) 2007-2008 Atheros Communications Inc.
   3 *
   4 * Permission to use, copy, modify, and/or distribute this software for any
   5 * purpose with or without fee is hereby granted, provided that the above
   6 * copyright notice and this permission notice appear in all copies.
   7 *
   8 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
   9 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  10 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  11 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  12 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  13 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  14 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  15 */
  16
  17#include "cprecomp.h"
  18
  19/************************************************************************/
  20/*                                                                      */
  21/*    FUNCTION DESCRIPTION                  zfLedCtrlType1              */
  22/*      Traditional single-LED state                                    */
  23/*                                                                      */
  24/*    INPUTS                                                            */
  25/*      dev : device pointer                                            */
  26/*                                                                      */
  27/*    OUTPUTS                                                           */
  28/*      None                                                            */
  29/*                                                                      */
  30/*    AUTHOR                                                            */
  31/*      Stephen Chen        Atheros Communications, INC.    2007.6      */
  32/*                                                                      */
  33/************************************************************************/
  34// bit 15-12 : Toff for Scan state
  35//     11-8 : Ton for Scan state
  36//     7 : Reserved
  37//     6 : mode
  38//--------------------------------------
  39//     bit 6 = 0
  40//     5-4 : Connect state
  41//           00 => always off
  42//           01 => always on
  43//           10 => Idle off, acitve on
  44//           11 => Idle on, active off
  45//--------------------------------------
  46//     bit 6 = 1
  47//     5-4 : freq
  48//           00 => 1Hz
  49//           01 => 0.5Hz
  50//           10 => 0.25Hz
  51//           11 => 0.125Hz
  52//--------------------------------------
  53//     3 : Power save state
  54//         0 => always off in power save state
  55//         1 => works as connect state
  56//     2 : Disable state
  57//     1 : Reserved
  58//     0 : Power-on state
  59void zfLedCtrlType1(zdev_t* dev)
  60{
  61    u16_t i;
  62    u32_t ton, toff, tmp, period;
  63    zmw_get_wlan_dev(dev);
  64
  65    for (i=0; i<ZM_MAX_LED_NUMBER; i++)
  66    {
  67        if (zfStaIsConnected(dev) != TRUE)
  68        {
  69            //Scan state
  70            ton = ((wd->ledStruct.ledMode[i] & 0xf00) >> 8) * 5;
  71            toff = ((wd->ledStruct.ledMode[i] & 0xf000) >> 12) * 5;
  72
  73            if ((ton + toff) != 0)
  74            {
  75                tmp = wd->ledStruct.counter / (ton+toff);
  76                tmp = wd->ledStruct.counter - (tmp * (ton+toff));
  77                if (tmp < ton)
  78                {
  79                    zfHpLedCtrl(dev, i, 1);
  80                }
  81                else
  82                {
  83                    zfHpLedCtrl(dev, i, 0);
  84                }
  85            }
  86        }
  87        else
  88        {
  89            if ((zfPowerSavingMgrIsSleeping(dev)) && ((wd->ledStruct.ledMode[i] & 0x8) == 0))
  90            {
  91                zfHpLedCtrl(dev, i, 0);
  92            }
  93            else
  94            {
  95                //Connect state
  96                if ((wd->ledStruct.ledMode[i] & 0x40) == 0)
  97                {
  98                    if ((wd->ledStruct.counter & 1) == 0)
  99                    {
 100                        zfHpLedCtrl(dev, i, (wd->ledStruct.ledMode[i] & 0x10) >> 4);
 101                    }
 102                    else
 103                    {
 104                        if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
 105                        {
 106                            wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
 107                            if ((wd->ledStruct.ledMode[i] & 0x20) != 0)
 108                            {
 109                                zfHpLedCtrl(dev, i, ((wd->ledStruct.ledMode[i] & 0x10) >> 4)^1);
 110                            }
 111                        }
 112                    }
 113                }// if ((wd->ledStruct.ledMode[i] & 0x40) == 0)
 114                else
 115                {
 116                    period = 5 * (1 << ((wd->ledStruct.ledMode[i] & 0x30) >> 4));
 117                    tmp = wd->ledStruct.counter / (period*2);
 118                    tmp = wd->ledStruct.counter - (tmp * (period*2));
 119                    if (tmp < period)
 120                    {
 121                        if ((wd->ledStruct.counter & 1) == 0)
 122                        {
 123                            zfHpLedCtrl(dev, i, 0);
 124                        }
 125                        else
 126                        {
 127                            if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
 128                            {
 129                                wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
 130                                zfHpLedCtrl(dev, i, 1);
 131                            }
 132                        }
 133                    }
 134                    else
 135                    {
 136                        if ((wd->ledStruct.counter & 1) == 0)
 137                        {
 138                            zfHpLedCtrl(dev, i, 1);
 139                        }
 140                        else
 141                        {
 142                            if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
 143                            {
 144                                wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
 145                                zfHpLedCtrl(dev, i, 0);
 146                            }
 147                        }
 148                    }
 149                } //else, if ((wd->ledStruct.ledMode[i] & 0x40) == 0)
 150            } //else, if (zfPowerSavingMgrIsSleeping(dev))
 151        } //else : if (zfStaIsConnected(dev) != TRUE)
 152    } //for (i=0; i<ZM_MAX_LED_NUMBER; i++)
 153}
 154
 155/******************************************************************************/
 156/*                                                                            */
 157/*    FUNCTION DESCRIPTION                  zfLedCtrlType2                    */
 158/*      Customize for Netgear Dual-LED state ((bug#31292))                    */
 159/*                                                                            */
 160/*      1. Status:  When dongle does not connect to 2.4G or 5G but in site    */
 161/*                  survey/association                                        */
 162/*         LED status: Slow blinking, Amber then Blue per 500ms               */
 163/*      2. Status:      Connection at 2.4G in site survey/association             */
 164/*         LED status: Slow blinking, Amber/off per 500ms                     */
 165/*      3. Status:      Connection at 5G in site survey/association               */
 166/*         LED status: Slow blinking, Blue/off per 500ms                      */
 167/*      4. Status:      When transfer the packet                                  */
 168/*         LED status: Blink per packet, including TX and RX                  */
 169/*      5. Status:      When linking is established but no traffic                */
 170/*         LED status: Always on                                              */
 171/*      6. Status:      When linking is dropped but no re-connection              */
 172/*         LED status: Always off                                             */
 173/*      7. Status:      From one connection(2.4G or 5G) to change to another band */
 174/*         LED status: Amber/Blue =>Slow blinking, Amber then Blue per 500ms  */
 175/*                                                                            */
 176/*    INPUTS                                                                  */
 177/*      dev : device pointer                                                  */
 178/*                                                                            */
 179/*    OUTPUTS                                                                 */
 180/*      None                                                                  */
 181/*                                                                            */
 182/*    AUTHOR                                                                  */
 183/*      Shang-Chun Liu        Atheros Communications, INC.    2007.11         */
 184/*                                                                            */
 185/******************************************************************************/
 186void zfLedCtrlType2_scan(zdev_t* dev);
 187
 188void zfLedCtrlType2(zdev_t* dev)
 189{
 190    u32_t ton, toff, tmp, period;
 191    u16_t OperateLED;
 192    zmw_get_wlan_dev(dev);
 193
 194    if (zfStaIsConnected(dev) != TRUE)
 195    {
 196        // Disconnect state
 197        if(wd->ledStruct.counter % 4 != 0)
 198        {
 199            // Update LED each 400ms(4*100)
 200            // Prevent this situation
 201            //              _______         ___
 202            // LED[0] ON   |       |       | x |
 203            // ------ OFF->+-+-+-+-+-+-+-+-+-+-+-+->>>...
 204            // LED[1] ON
 205            //
 206            return;
 207        }
 208
 209        if (((wd->state == ZM_WLAN_STATE_DISABLED) && (wd->sta.bChannelScan))
 210            || ((wd->state != ZM_WLAN_STATE_DISABLED) && (wd->sta.bAutoReconnect)))
 211        {
 212            // Scan/AutoReconnect state
 213            zfLedCtrlType2_scan(dev);
 214        }
 215        else
 216        {
 217            // Neither Connected nor Scan
 218            zfHpLedCtrl(dev, 0, 0);
 219            zfHpLedCtrl(dev, 1, 0);
 220        }
 221    }
 222    else
 223    {
 224        if( wd->sta.bChannelScan )
 225        {
 226            // Scan state
 227            if(wd->ledStruct.counter % 4 != 0)
 228                return;
 229            zfLedCtrlType2_scan(dev);
 230            return;
 231        }
 232
 233        if(wd->frequency < 3000)
 234        {
 235            OperateLED = 0;     // LED[0]: work on 2.4G (b/g band)
 236            zfHpLedCtrl(dev, 1, 0);
 237        }
 238        else
 239        {
 240            OperateLED = 1;     // LED[1]: work on 5G (a band)
 241            zfHpLedCtrl(dev, 0, 0);
 242        }
 243
 244        if ((zfPowerSavingMgrIsSleeping(dev)) && ((wd->ledStruct.ledMode[OperateLED] & 0x8) == 0))
 245        {
 246            // If Sleeping, turn OFF
 247            zfHpLedCtrl(dev, OperateLED, 0);
 248        }
 249        else
 250        {
 251            //Connect state
 252            if ((wd->ledStruct.counter & 1) == 0)   // even
 253            {
 254                // No traffic, always ON
 255                zfHpLedCtrl(dev, OperateLED, 1);
 256            }
 257            else       // odd
 258            {
 259                if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
 260                {
 261                    // If have traffic, turn OFF
 262                            //                   _____   _   _   _   _____
 263                            // LED[Operate] ON        | | | | | | | |
 264                            // ------------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
 265                            //
 266                    wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
 267                    zfHpLedCtrl(dev, OperateLED, 0);
 268                }
 269            }
 270        }
 271    }
 272}
 273
 274void zfLedCtrlType2_scan(zdev_t* dev)
 275{
 276    zmw_get_wlan_dev(dev);
 277
 278    // When doing scan, blink(Amber/Blue) and off per 500ms (about 400ms in our driver)
 279    //               _______                         _______
 280    // LED[0] ON    |       |       8       12      |       |
 281    // ------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
 282    // LED[1] ON    0       4       |_______|       0       3
 283    //
 284
 285    switch(wd->ledStruct.counter % 16)
 286    {
 287        case 0:   // case 0~3, LED[0] on
 288            if(wd->supportMode & ZM_WIRELESS_MODE_24)
 289            {
 290                zfHpLedCtrl(dev, 0, 1);
 291                zfHpLedCtrl(dev, 1, 0);
 292            }
 293            else
 294            {
 295                zfHpLedCtrl(dev, 1, 1);
 296                zfHpLedCtrl(dev, 0, 0);
 297            }
 298            break;
 299
 300        case 8:   // case 8~11, LED[1] on
 301            if(wd->supportMode & ZM_WIRELESS_MODE_5)
 302            {
 303                zfHpLedCtrl(dev, 1, 1);
 304                zfHpLedCtrl(dev, 0, 0);
 305            }
 306            else
 307            {
 308                zfHpLedCtrl(dev, 0, 1);
 309                zfHpLedCtrl(dev, 1, 0);
 310            }
 311            break;
 312
 313        default:  // others, all off
 314            zfHpLedCtrl(dev, 0, 0);
 315            zfHpLedCtrl(dev, 1, 0);
 316            break;
 317    }
 318}
 319
 320/**********************************************************************************/
 321/*                                                                                */
 322/*    FUNCTION DESCRIPTION                  zfLedCtrlType3                        */
 323/*      Customize for Netgear Single-LED state ((bug#32243))                      */
 324/*                                                                                */
 325/*  ¡EOff: when the adapter is disabled or hasn't started to associate with AP    */
 326/*         yet.                                                                          */
 327/*  ¡EOn: Once adpater associate with AP successfully                             */
 328/*  ¡ESlow blinking: whenever adapters do site-survey or try to associate with AP */
 329/*    - If there is a connection already, and adapters do site-survey or          */
 330/*      re-associate action, the LED should keep LED backgraoud as ON, thus       */
 331/*      the blinking behavior SHOULD be OFF (200ms) - ON (800ms) and continue this*/
 332/*      cycle.                                                                    */
 333/*    - If there is no connection yet, and adapters start to do site-survey or    */
 334/*      associate action, the LED should keep LED background as OFF, thus the     */
 335/*      blinking behavior SHOULD be ON (200ms) - OFF (800ms) and continue this    */
 336/*      cycle.                                                                    */
 337/*    - For the case that associate fail, adpater should keep associating, and the*/
 338/*      LED should also keep slow blinking.                                       */
 339/*  ¡EQuick blinking: to blink OFF-ON cycle for each time that traffic packet is  */
 340/*    received or is transmitted.                                                 */
 341/*                                                                                */
 342/*    INPUTS                                                                      */
 343/*      dev : device pointer                                                      */
 344/*                                                                                */
 345/*    OUTPUTS                                                                     */
 346/*      None                                                                      */
 347/*                                                                                */
 348/*    AUTHOR                                                                      */
 349/*      Shang-Chun Liu        Atheros Communications, INC.    2008.01             */
 350/*                                                                                */
 351/**********************************************************************************/
 352void zfLedCtrlType3_scan(zdev_t* dev, u16_t isConnect);
 353
 354void zfLedCtrlType3(zdev_t* dev)
 355{
 356    zmw_get_wlan_dev(dev);
 357
 358    if (zfStaIsConnected(dev) != TRUE)
 359    {
 360        // Disconnect state
 361        if(wd->ledStruct.counter % 2 != 0)
 362        {
 363            // Update LED each 200ms(2*100)
 364            // Prevent this situation
 365            //              ___     _
 366            // LED[0] ON   |   |   |x|
 367            // ------ OFF->+-+-+-+-+-+-+->>>...
 368            //
 369            return;
 370        }
 371
 372        if (((wd->state == ZM_WLAN_STATE_DISABLED) && (wd->sta.bChannelScan))
 373            || ((wd->state != ZM_WLAN_STATE_DISABLED) && (wd->sta.bAutoReconnect)))
 374        {
 375            // Scan/AutoReconnect state
 376            zfLedCtrlType3_scan(dev, 0);
 377        }
 378        else
 379        {
 380            // Neither Connected nor Scan
 381            zfHpLedCtrl(dev, 0, 0);
 382            zfHpLedCtrl(dev, 1, 0);
 383        }
 384    }
 385    else
 386    {
 387        if( wd->sta.bChannelScan )
 388        {
 389            // Scan state
 390            if(wd->ledStruct.counter % 2 != 0)
 391                return;
 392            zfLedCtrlType3_scan(dev, 1);
 393            return;
 394        }
 395
 396        if ((zfPowerSavingMgrIsSleeping(dev)) && ((wd->ledStruct.ledMode[0] & 0x8) == 0))
 397        {
 398            // If Sleeping, turn OFF
 399            zfHpLedCtrl(dev, 0, 0);
 400            zfHpLedCtrl(dev, 1, 0);
 401        }
 402        else
 403        {
 404            //Connect state
 405            if ((wd->ledStruct.counter & 1) == 0)   // even
 406            {
 407                // No traffic, always ON
 408                zfHpLedCtrl(dev, 0, 1);
 409                zfHpLedCtrl(dev, 1, 1);
 410            }
 411            else       // odd
 412            {
 413                if ((wd->ledStruct.txTraffic > 0) || (wd->ledStruct.rxTraffic > 0))
 414                {
 415                    // If have traffic, turn OFF
 416                            //                   _____   _   _   _   _____
 417                            // LED[Operate] ON        | | | | | | | |
 418                            // ------------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
 419                            //
 420                    wd->ledStruct.txTraffic = wd->ledStruct.rxTraffic = 0;
 421                    zfHpLedCtrl(dev, 0, 0);
 422                    zfHpLedCtrl(dev, 1, 0);
 423                }
 424            }
 425        }
 426    }
 427}
 428
 429void zfLedCtrlType3_scan(zdev_t* dev, u16_t isConnect)
 430{
 431    u32_t ton, toff, tmp;
 432    zmw_get_wlan_dev(dev);
 433
 434    // Doing scan when :
 435    // 1. Disconnected: ON (200ms) - OFF (800ms) (200ms-600ms in our driver)
 436    //               ___             ___             ___
 437    // LED[0] ON    |   |           |   |           |   |
 438    // ------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
 439    //              0   2   4   6   8  10  12  14  16
 440    // 2. Connected:   ON (800ms) - OFF (200ms) (600ms-200ms in our driver)
 441    //               ___________     ___________     ______
 442    // LED[0] ON    |           |   |           |   |
 443    // ------ OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+->>>...
 444    //              0   2   4   6   8  10  12  14  16
 445
 446    //Scan state
 447    if(!isConnect)
 448        ton = 2, toff = 6;
 449    else
 450        ton = 6, toff = 2;
 451
 452    if ((ton + toff) != 0)
 453    {
 454        tmp = wd->ledStruct.counter % (ton+toff);
 455       if (tmp < ton)
 456        {
 457            zfHpLedCtrl(dev, 0, 1);
 458            zfHpLedCtrl(dev, 1, 1);
 459        }
 460        else
 461        {
 462            zfHpLedCtrl(dev, 0, 0);
 463            zfHpLedCtrl(dev, 1, 0);
 464        }
 465    }
 466}
 467
 468/******************************************************************************/
 469/*                                                                            */
 470/*    FUNCTION DESCRIPTION                  zfLedCtrl_BlinkWhenScan_Alpha     */
 471/*      Customize for Alpha/DLink LED                                         */
 472/*      - Blink LED 12 times within 3 seconds when doing Active Scan          */
 473/*                            ___   ___   ___   ___                               */
 474/*            LED[0] ON      |   | |   | |   | |   |                              */
 475/*            -------OFF->-+-+-+-+-+-+-+-+-+-+-+-+-+--+-->>>...                   */
 476/*                                                                            */
 477/*    INPUTS                                                                  */
 478/*      dev : device pointer                                                  */
 479/*                                                                            */
 480/*    OUTPUTS                                                                 */
 481/*      None                                                                  */
 482/*                                                                            */
 483/*    AUTHOR                                                                  */
 484/*      Shang-Chun Liu        Atheros Communications, INC.    2007.11         */
 485/*                                                                            */
 486/******************************************************************************/
 487void zfLedCtrl_BlinkWhenScan_Alpha(zdev_t* dev)
 488{
 489    static u32_t counter = 0;
 490    zmw_get_wlan_dev(dev);
 491
 492    if(counter > 34)        // counter for 3 sec
 493    {
 494        wd->ledStruct.LEDCtrlFlag &= ~(u8_t)ZM_LED_CTRL_FLAG_ALPHA;
 495        counter = 0;
 496    }
 497
 498    if( (counter % 3) < 2)
 499        zfHpLedCtrl(dev, 0, 1);
 500    else
 501        zfHpLedCtrl(dev, 0, 0);
 502
 503    counter++;
 504}
 505
 506
 507/************************************************************************/
 508/*                                                                      */
 509/*    FUNCTION DESCRIPTION                  zfLed100msCtrl              */
 510/*      LED 100 milliseconds timer.                                     */
 511/*                                                                      */
 512/*    INPUTS                                                            */
 513/*      dev : device pointer                                            */
 514/*                                                                      */
 515/*    OUTPUTS                                                           */
 516/*      None                                                            */
 517/*                                                                      */
 518/*    AUTHOR                                                            */
 519/*      Stephen Chen        Atheros Communications, INC.    2007.6      */
 520/*                                                                      */
 521/************************************************************************/
 522void zfLed100msCtrl(zdev_t* dev)
 523{
 524    zmw_get_wlan_dev(dev);
 525
 526    wd->ledStruct.counter++;
 527
 528    if(wd->ledStruct.LEDCtrlFlag)
 529    {
 530        switch(wd->ledStruct.LEDCtrlFlag) {
 531        case ZM_LED_CTRL_FLAG_ALPHA:
 532            zfLedCtrl_BlinkWhenScan_Alpha(dev);
 533        break;
 534        }
 535    }
 536    else
 537    {
 538        switch(wd->ledStruct.LEDCtrlType) {
 539        case 1:                 // Traditional 1 LED
 540            zfLedCtrlType1(dev);
 541        break;
 542
 543        case 2:                 // Dual-LEDs for Netgear
 544            zfLedCtrlType2(dev);
 545        break;
 546
 547        case 3:                 // Single-LED for Netgear (WN111v2)
 548            zfLedCtrlType3(dev);
 549        break;
 550
 551        default:
 552            zfLedCtrlType1(dev);
 553        break;
 554        }
 555    }
 556}
 557
 558