linux/drivers/staging/rtl8192e/r8190_rtl8256.c
<<
>>
Prefs
   1/*
   2  This is part of the rtl8192 driver
   3  released under the GPL (See file COPYING for details).
   4
   5  This files contains programming code for the rtl8256
   6  radio frontend.
   7
   8  *Many* thanks to Realtek Corp. for their great support!
   9
  10*/
  11
  12#include "r8192E.h"
  13#include "r8192E_hw.h"
  14#include "r819xE_phyreg.h"
  15#include "r819xE_phy.h"
  16#include "r8190_rtl8256.h"
  17
  18/*--------------------------------------------------------------------------
  19 * Overview:    set RF band width (20M or 40M)
  20 * Input:       struct net_device*      dev
  21 *              WIRELESS_BANDWIDTH_E    Bandwidth       //20M or 40M
  22 * Output:      NONE
  23 * Return:      NONE
  24 * Note:        8226 support both 20M  and 40 MHz
  25 *---------------------------------------------------------------------------*/
  26void PHY_SetRF8256Bandwidth(struct net_device* dev , HT_CHANNEL_WIDTH Bandwidth)        //20M or 40M
  27{
  28        u8      eRFPath;
  29        struct r8192_priv *priv = ieee80211_priv(dev);
  30
  31        //for(eRFPath = RF90_PATH_A; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
  32        for(eRFPath = 0; eRFPath <priv->NumTotalRFPath; eRFPath++)
  33        {
  34                if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
  35                                continue;
  36
  37                switch(Bandwidth)
  38                {
  39                        case HT_CHANNEL_WIDTH_20:
  40                                if(priv->card_8192_version == VERSION_8190_BD || priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later!
  41                                {
  42                                        rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x100); //phy para:1ba
  43                                        rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3d7);
  44                                        rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x021);
  45
  46                                        //cosa add for sd3's request 01/23/2008
  47                                        //rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
  48                                }
  49                                else
  50                                {
  51                                        RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
  52                                }
  53
  54                                break;
  55                        case HT_CHANNEL_WIDTH_20_40:
  56                                if(priv->card_8192_version == VERSION_8190_BD ||priv->card_8192_version == VERSION_8190_BE)// 8256 D-cut, E-cut, xiong: consider it later!
  57                                {
  58                                        rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0b, bMask12Bits, 0x300); //phy para:3ba
  59                                        rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x2c, bMask12Bits, 0x3ff);
  60                                        rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x0e, bMask12Bits, 0x0e1);
  61
  62                                        //cosa add for sd3's request 01/23/2008
  63                                        #if 0
  64                                        if(priv->chan == 3 || priv->chan == 9) //I need to set priv->chan whenever current channel changes
  65                                                rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x59b);
  66                                        else
  67                                                rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, 0x14, bMask12Bits, 0x5ab);
  68                                        #endif
  69                                }
  70                                else
  71                                {
  72                                        RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown hardware version\n");
  73                                }
  74
  75
  76                                break;
  77                        default:
  78                                RT_TRACE(COMP_ERR, "PHY_SetRF8256Bandwidth(): unknown Bandwidth: %#X\n",Bandwidth );
  79                                break;
  80
  81                }
  82        }
  83        return;
  84}
  85/*--------------------------------------------------------------------------
  86 * Overview:    Interface to config 8256
  87 * Input:       struct net_device*      dev
  88 * Output:      NONE
  89 * Return:      NONE
  90 *---------------------------------------------------------------------------*/
  91RT_STATUS PHY_RF8256_Config(struct net_device* dev)
  92{
  93        struct r8192_priv *priv = ieee80211_priv(dev);
  94        // Initialize general global value
  95        //
  96        RT_STATUS rtStatus = RT_STATUS_SUCCESS;
  97        // TODO: Extend RF_PATH_C and RF_PATH_D in the future
  98        priv->NumTotalRFPath = RTL819X_TOTAL_RF_PATH;
  99        // Config BB and RF
 100        rtStatus = phy_RF8256_Config_ParaFile(dev);
 101
 102        return rtStatus;
 103}
 104/*--------------------------------------------------------------------------
 105 * Overview:    Interface to config 8256
 106 * Input:       struct net_device*      dev
 107 * Output:      NONE
 108 * Return:      NONE
 109 *---------------------------------------------------------------------------*/
 110RT_STATUS phy_RF8256_Config_ParaFile(struct net_device* dev)
 111{
 112        u32     u4RegValue = 0;
 113        u8      eRFPath;
 114        RT_STATUS                               rtStatus = RT_STATUS_SUCCESS;
 115        BB_REGISTER_DEFINITION_T        *pPhyReg;
 116        struct r8192_priv *priv = ieee80211_priv(dev);
 117        u32     RegOffSetToBeCheck = 0x3;
 118        u32     RegValueToBeCheck = 0x7f1;
 119        u32     RF3_Final_Value = 0;
 120        u8      ConstRetryTimes = 5, RetryTimes = 5;
 121        u8 ret = 0;
 122        //3//-----------------------------------------------------------------
 123        //3// <2> Initialize RF
 124        //3//-----------------------------------------------------------------
 125        for(eRFPath = (RF90_RADIO_PATH_E)RF90_PATH_A; eRFPath <priv->NumTotalRFPath; eRFPath++)
 126        {
 127                if (!rtl8192_phy_CheckIsLegalRFPath(dev, eRFPath))
 128                                continue;
 129
 130                pPhyReg = &priv->PHYRegDef[eRFPath];
 131
 132                // Joseph test for shorten RF config
 133        //      pHalData->RfReg0Value[eRFPath] =  rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, rGlobalCtrl, bMaskDWord);
 134
 135                /*----Store original RFENV control type----*/
 136                switch(eRFPath)
 137                {
 138                case RF90_PATH_A:
 139                case RF90_PATH_C:
 140                        u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV);
 141                        break;
 142                case RF90_PATH_B :
 143                case RF90_PATH_D:
 144                        u4RegValue = rtl8192_QueryBBReg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16);
 145                        break;
 146                }
 147
 148                /*----Set RF_ENV enable----*/
 149                rtl8192_setBBreg(dev, pPhyReg->rfintfe, bRFSI_RFENV<<16, 0x1);
 150
 151                /*----Set RF_ENV output high----*/
 152                rtl8192_setBBreg(dev, pPhyReg->rfintfo, bRFSI_RFENV, 0x1);
 153
 154                /* Set bit number of Address and Data for RF register */
 155                rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireAddressLength, 0x0);  // Set 0 to 4 bits for Z-serial and set 1 to 6 bits for 8258
 156                rtl8192_setBBreg(dev, pPhyReg->rfHSSIPara2, b3WireDataLength, 0x0);     // Set 0 to 12 bits for Z-serial and 8258, and set 1 to 14 bits for ???
 157
 158                rtl8192_phy_SetRFReg(dev, (RF90_RADIO_PATH_E) eRFPath, 0x0, bMask12Bits, 0xbf);
 159
 160                /*----Check RF block (for FPGA platform only)----*/
 161                // TODO: this function should be removed on ASIC , Emily 2007.2.2
 162                rtStatus = rtl8192_phy_checkBBAndRF(dev, HW90_BLOCK_RF, (RF90_RADIO_PATH_E)eRFPath);
 163                if(rtStatus!= RT_STATUS_SUCCESS)
 164                {
 165                        RT_TRACE(COMP_ERR, "PHY_RF8256_Config():Check Radio[%d] Fail!!\n", eRFPath);
 166                        goto phy_RF8256_Config_ParaFile_Fail;
 167                }
 168
 169                RetryTimes = ConstRetryTimes;
 170                RF3_Final_Value = 0;
 171                /*----Initialize RF fom connfiguration file----*/
 172                switch(eRFPath)
 173                {
 174                case RF90_PATH_A:
 175                        while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
 176                        {
 177                                ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
 178                                RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
 179                                RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
 180                                RetryTimes--;
 181                        }
 182                        break;
 183                case RF90_PATH_B:
 184                        while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
 185                        {
 186                                ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
 187                                RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
 188                                RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
 189                                RetryTimes--;
 190                        }
 191                        break;
 192                case RF90_PATH_C:
 193                        while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
 194                        {
 195                                ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
 196                                RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
 197                                RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
 198                                RetryTimes--;
 199                        }
 200                        break;
 201                case RF90_PATH_D:
 202                        while(RF3_Final_Value!=RegValueToBeCheck && RetryTimes!=0)
 203                        {
 204                                ret = rtl8192_phy_ConfigRFWithHeaderFile(dev,(RF90_RADIO_PATH_E)eRFPath);
 205                                RF3_Final_Value = rtl8192_phy_QueryRFReg(dev, (RF90_RADIO_PATH_E)eRFPath, RegOffSetToBeCheck, bMask12Bits);
 206                                RT_TRACE(COMP_RF, "RF %d %d register final value: %x\n", eRFPath, RegOffSetToBeCheck, RF3_Final_Value);
 207                                RetryTimes--;
 208                        }
 209                        break;
 210                }
 211
 212                /*----Restore RFENV control type----*/;
 213                switch(eRFPath)
 214                {
 215                case RF90_PATH_A:
 216                case RF90_PATH_C:
 217                        rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV, u4RegValue);
 218                        break;
 219                case RF90_PATH_B :
 220                case RF90_PATH_D:
 221                        rtl8192_setBBreg(dev, pPhyReg->rfintfs, bRFSI_RFENV<<16, u4RegValue);
 222                        break;
 223                }
 224
 225                if(ret){
 226                        RT_TRACE(COMP_ERR, "phy_RF8256_Config_ParaFile():Radio[%d] Fail!!", eRFPath);
 227                        goto phy_RF8256_Config_ParaFile_Fail;
 228                }
 229
 230        }
 231
 232        RT_TRACE(COMP_PHY, "PHY Initialization Success\n") ;
 233        return RT_STATUS_SUCCESS;
 234
 235phy_RF8256_Config_ParaFile_Fail:
 236        RT_TRACE(COMP_ERR, "PHY Initialization failed\n") ;
 237        return RT_STATUS_FAILURE;
 238}
 239
 240
 241void PHY_SetRF8256CCKTxPower(struct net_device* dev, u8 powerlevel)
 242{
 243        u32     TxAGC=0;
 244        struct r8192_priv *priv = ieee80211_priv(dev);
 245#ifdef RTL8190P
 246        u8                              byte0, byte1;
 247
 248        TxAGC |= ((powerlevel<<8)|powerlevel);
 249        TxAGC += priv->CCKTxPowerLevelOriginalOffset;
 250
 251        if(priv->bDynamicTxLowPower == true  //cosa 04282008 for cck long range
 252                /*pMgntInfo->bScanInProgress == TRUE*/ ) //cosa 05/22/2008 for scan
 253        {
 254                if(priv->CustomerID == RT_CID_819x_Netcore)
 255                        TxAGC = 0x2222;
 256                else
 257                TxAGC += ((priv->CckPwEnl<<8)|priv->CckPwEnl);
 258        }
 259
 260        byte0 = (u8)(TxAGC & 0xff);
 261        byte1 = (u8)((TxAGC & 0xff00)>>8);
 262        if(byte0 > 0x24)
 263                byte0 = 0x24;
 264        if(byte1 > 0x24)
 265                byte1 = 0x24;
 266        if(priv->rf_type == RF_2T4R)    //Only 2T4R you have to care the Antenna Tx Power offset
 267        {       // check antenna C over the max index 0x24
 268                        if(priv->RF_C_TxPwDiff > 0)
 269                        {
 270                                if( (byte0 + (u8)priv->RF_C_TxPwDiff) > 0x24)
 271                                        byte0 = 0x24 - priv->RF_C_TxPwDiff;
 272                                if( (byte1 + (u8)priv->RF_C_TxPwDiff) > 0x24)
 273                                        byte1 = 0x24 - priv->RF_C_TxPwDiff;
 274                        }
 275                }
 276        TxAGC = (byte1<<8) |byte0;
 277        write_nic_dword(dev, CCK_TXAGC, TxAGC);
 278#else
 279        #ifdef RTL8192E
 280
 281        TxAGC = powerlevel;
 282        if(priv->bDynamicTxLowPower == true)//cosa 04282008 for cck long range
 283        {
 284                if(priv->CustomerID == RT_CID_819x_Netcore)
 285                TxAGC = 0x22;
 286        else
 287                TxAGC += priv->CckPwEnl;
 288        }
 289        if(TxAGC > 0x24)
 290                TxAGC = 0x24;
 291        rtl8192_setBBreg(dev, rTxAGC_CCK_Mcs32, bTxAGCRateCCK, TxAGC);
 292        #endif
 293#endif
 294}
 295
 296
 297void PHY_SetRF8256OFDMTxPower(struct net_device* dev, u8 powerlevel)
 298{
 299        struct r8192_priv *priv = ieee80211_priv(dev);
 300        //Joseph TxPower for 8192 testing
 301#ifdef RTL8190P
 302        u32                             TxAGC1=0, TxAGC2=0, TxAGC2_tmp = 0;
 303        u8                              i, byteVal1[4], byteVal2[4], byteVal3[4];
 304
 305        if(priv->bDynamicTxHighPower == true)     //Add by Jacken 2008/03/06
 306        {
 307                TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel);
 308                //for tx power track
 309                TxAGC2_tmp = TxAGC1;
 310
 311                TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0];
 312                TxAGC2 =0x03030303;
 313
 314                //for tx power track
 315                TxAGC2_tmp += priv->MCSTxPowerLevelOriginalOffset[1];
 316        }
 317        else
 318        {
 319                TxAGC1 |= ((powerlevel<<24)|(powerlevel<<16)|(powerlevel<<8)|powerlevel);
 320                TxAGC2 = TxAGC1;
 321
 322                TxAGC1 += priv->MCSTxPowerLevelOriginalOffset[0];
 323                TxAGC2 += priv->MCSTxPowerLevelOriginalOffset[1];
 324
 325                TxAGC2_tmp = TxAGC2;
 326
 327        }
 328        for(i=0; i<4; i++)
 329        {
 330                byteVal1[i] = (u8)(  (TxAGC1 & (0xff<<(i*8))) >>(i*8) );
 331                if(byteVal1[i] > 0x24)
 332                        byteVal1[i] = 0x24;
 333                byteVal2[i] = (u8)(  (TxAGC2 & (0xff<<(i*8))) >>(i*8) );
 334                if(byteVal2[i] > 0x24)
 335                        byteVal2[i] = 0x24;
 336
 337                //for tx power track
 338                byteVal3[i] = (u8)(  (TxAGC2_tmp & (0xff<<(i*8))) >>(i*8) );
 339                if(byteVal3[i] > 0x24)
 340                        byteVal3[i] = 0x24;
 341        }
 342
 343        if(priv->rf_type == RF_2T4R)    //Only 2T4R you have to care the Antenna Tx Power offset
 344        {       // check antenna C over the max index 0x24
 345                if(priv->RF_C_TxPwDiff > 0)
 346                {
 347                        for(i=0; i<4; i++)
 348                        {
 349                                if( (byteVal1[i] + (u8)priv->RF_C_TxPwDiff) > 0x24)
 350                                        byteVal1[i] = 0x24 - priv->RF_C_TxPwDiff;
 351                                if( (byteVal2[i] + (u8)priv->RF_C_TxPwDiff) > 0x24)
 352                                        byteVal2[i] = 0x24 - priv->RF_C_TxPwDiff;
 353                                if( (byteVal3[i] + (u8)priv->RF_C_TxPwDiff) > 0x24)
 354                                        byteVal3[i] = 0x24 - priv->RF_C_TxPwDiff;
 355                        }
 356                }
 357        }
 358
 359        TxAGC1 = (byteVal1[3]<<24) | (byteVal1[2]<<16) |(byteVal1[1]<<8) |byteVal1[0];
 360        TxAGC2 = (byteVal2[3]<<24) | (byteVal2[2]<<16) |(byteVal2[1]<<8) |byteVal2[0];
 361
 362        //for tx power track
 363        TxAGC2_tmp = (byteVal3[3]<<24) | (byteVal3[2]<<16) |(byteVal3[1]<<8) |byteVal3[0];
 364        priv->Pwr_Track = TxAGC2_tmp;
 365        //DbgPrint("TxAGC2_tmp = 0x%x\n", TxAGC2_tmp);
 366
 367        //DbgPrint("TxAGC1/TxAGC2 = 0x%x/0x%x\n", TxAGC1, TxAGC2);
 368        write_nic_dword(dev, MCS_TXAGC, TxAGC1);
 369        write_nic_dword(dev, MCS_TXAGC+4, TxAGC2);
 370#else
 371#ifdef RTL8192E
 372        u32 writeVal, powerBase0, powerBase1, writeVal_tmp;
 373        u8 index = 0;
 374        u16 RegOffset[6] = {0xe00, 0xe04, 0xe10, 0xe14, 0xe18, 0xe1c};
 375        u8 byte0, byte1, byte2, byte3;
 376
 377        powerBase0 = powerlevel + priv->LegacyHTTxPowerDiff;    //OFDM rates
 378        powerBase0 = (powerBase0<<24) | (powerBase0<<16) |(powerBase0<<8) |powerBase0;
 379        powerBase1 = powerlevel;                                                        //MCS rates
 380        powerBase1 = (powerBase1<<24) | (powerBase1<<16) |(powerBase1<<8) |powerBase1;
 381
 382        for(index=0; index<6; index++)
 383        {
 384                writeVal = priv->MCSTxPowerLevelOriginalOffset[index] + ((index<2)?powerBase0:powerBase1);
 385                byte0 = (u8)(writeVal & 0x7f);
 386                byte1 = (u8)((writeVal & 0x7f00)>>8);
 387                byte2 = (u8)((writeVal & 0x7f0000)>>16);
 388                byte3 = (u8)((writeVal & 0x7f000000)>>24);
 389                if(byte0 > 0x24)        // Max power index = 0x24
 390                        byte0 = 0x24;
 391                if(byte1 > 0x24)
 392                        byte1 = 0x24;
 393                if(byte2 > 0x24)
 394                        byte2 = 0x24;
 395                if(byte3 > 0x24)
 396                        byte3 = 0x24;
 397
 398                if(index == 3)
 399                {
 400                        writeVal_tmp = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
 401                        priv->Pwr_Track = writeVal_tmp;
 402                }
 403
 404                if(priv->bDynamicTxHighPower == true)     //Add by Jacken 2008/03/06  //when DM implement, add this
 405                {
 406                        writeVal = 0x03030303;
 407                }
 408                else
 409                {
 410                        writeVal = (byte3<<24) | (byte2<<16) |(byte1<<8) |byte0;
 411                }
 412                rtl8192_setBBreg(dev, RegOffset[index], 0x7f7f7f7f, writeVal);
 413        }
 414
 415#endif
 416#endif
 417        return;
 418}
 419
 420#define MAX_DOZE_WAITING_TIMES_9x 64
 421static bool
 422SetRFPowerState8190(
 423        struct net_device* dev,
 424        RT_RF_POWER_STATE       eRFPowerState
 425        )
 426{
 427        struct r8192_priv *priv = ieee80211_priv(dev);
 428        PRT_POWER_SAVE_CONTROL  pPSC = (PRT_POWER_SAVE_CONTROL)(&(priv->ieee80211->PowerSaveControl));
 429        bool bResult = true;
 430        //u8 eRFPath;
 431        u8      i = 0, QueueID = 0;
 432        ptx_ring        head=NULL,tail=NULL;
 433
 434        if(priv->SetRFPowerStateInProgress == true)
 435                return false;
 436        RT_TRACE(COMP_POWER, "===========> SetRFPowerState8190()!\n");
 437        priv->SetRFPowerStateInProgress = true;
 438
 439        switch(priv->rf_chip)
 440        {
 441                case RF_8256:
 442                switch( eRFPowerState )
 443                {
 444                        case eRfOn:
 445                                RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOn !\n");
 446                                                //RXTX enable control: On
 447                                        //for(eRFPath = 0; eRFPath <pHalData->NumTotalRFPath; eRFPath++)
 448                                        //      PHY_SetRFReg(Adapter, (RF90_RADIO_PATH_E)eRFPath, 0x4, 0xC00, 0x2);
 449                                #ifdef RTL8190P
 450                                if(priv->rf_type == RF_2T4R)
 451                                {
 452                                        //enable RF-Chip A/B
 453                                        rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1); // 0x860[4]
 454                                        //enable RF-Chip C/D
 455                                        rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4]
 456                                        //analog to digital on
 457                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0xf);// 0x88c[11:8]
 458                                        //digital to analog on
 459                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0xf); // 0x880[8:5]
 460                                        //rx antenna on
 461                                        rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0xf);// 0xc04[3:0]
 462                                        //rx antenna on
 463                                        rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0xf);// 0xd04[3:0]
 464                                        //analog to digital part2 on
 465                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0xf); // 0x880[12:9]
 466                                }
 467                                else if(priv->rf_type == RF_1T2R)       //RF-C, RF-D
 468                                {
 469                                        //enable RF-Chip C/D
 470                                        rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x1); // 0x868[4]
 471                                        //analog to digital on
 472                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xc00, 0x3);// 0x88c[11:10]
 473                                        //digital to analog on
 474                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x180, 0x3); // 0x880[8:7]
 475                                        //rx antenna on
 476                                        rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xc, 0x3);// 0xc04[3:2]
 477                                        //rx antenna on
 478                                        rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xc, 0x3);// 0xd04[3:2]
 479                                        //analog to digital part2 on
 480                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1800, 0x3); // 0x880[12:11]
 481                                }
 482                                #else
 483                                write_nic_byte(dev, ANAPAR, 0x37);//160MHz
 484                                write_nic_byte(dev, MacBlkCtrl, 0x17); // 0x403
 485                                mdelay(1);
 486                                //enable clock 80/88 MHz
 487
 488                                priv->bHwRfOffAction = 0;
 489                                //}
 490
 491                                // Baseband reset 2008.09.30 add
 492                                write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0));
 493
 494                                //2 AFE
 495                                // 2008.09.30 add
 496                                rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x1); // 0x884
 497                                //analog to digital part2 on
 498                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x3);              // 0x880[6:5]
 499                                //digital to analog on
 500                                rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x13); // 0x880[4:3]
 501                                //analog to digital on
 502                                rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0xf03);// 0x88c[9:8]
 503                                //rx antenna on
 504                                //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0x3, 0x3);// 0xc04[1:0]
 505                                //rx antenna on 2008.09.30 mark
 506                                //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0x3, 0x3);// 0xd04[1:0]
 507
 508                                //2 RF
 509                                //enable RF-Chip A/B
 510                                        rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x1);              // 0x860[4]
 511                                rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x1);              // 0x864[4]
 512                                #endif
 513                                                break;
 514
 515                                //
 516                                // In current solution, RFSleep=RFOff in order to save power under 802.11 power save.
 517                                // By Bruce, 2008-01-16.
 518                                //
 519                        case eRfSleep:
 520                        case eRfOff:
 521                                RT_TRACE(COMP_POWER, "SetRFPowerState8190() eRfOff/Sleep !\n");
 522                                if (pPSC->bLeisurePs)
 523                                {
 524                                        for(QueueID = 0, i = 0; QueueID < MAX_TX_QUEUE; )
 525                                        {
 526                                                switch(QueueID) {
 527                                                        case MGNT_QUEUE:
 528                                                                tail=priv->txmapringtail;
 529                                                                head=priv->txmapringhead;
 530                                                                break;
 531
 532                                                        case BK_QUEUE:
 533                                                                tail=priv->txbkpringtail;
 534                                                                head=priv->txbkpringhead;
 535                                                                break;
 536
 537                                                        case BE_QUEUE:
 538                                                                tail=priv->txbepringtail;
 539                                                                head=priv->txbepringhead;
 540                                                                break;
 541
 542                                                        case VI_QUEUE:
 543                                                                tail=priv->txvipringtail;
 544                                                                head=priv->txvipringhead;
 545                                                                break;
 546
 547                                                        case VO_QUEUE:
 548                                                                tail=priv->txvopringtail;
 549                                                                head=priv->txvopringhead;
 550                                                                break;
 551
 552                                                        default:
 553                                                                tail=head=NULL;
 554                                                                break;
 555                                                }
 556                                                if(tail == head)
 557                                                {
 558                                                        //DbgPrint("QueueID = %d", QueueID);
 559                                                        QueueID++;
 560                                                        continue;
 561                                                }
 562                                                else
 563                                                {
 564                                                        RT_TRACE(COMP_POWER, "eRf Off/Sleep: %d times BusyQueue[%d] !=0 before doze!\n", (i+1), QueueID);
 565                                                        udelay(10);
 566                                                        i++;
 567                                                }
 568
 569                                                if(i >= MAX_DOZE_WAITING_TIMES_9x)
 570                                                {
 571                                                        RT_TRACE(COMP_POWER, "\n\n\n TimeOut!! SetRFPowerState8190(): eRfOff: %d times BusyQueue[%d] != 0 !!!\n\n\n", MAX_DOZE_WAITING_TIMES_9x, QueueID);
 572                                                        break;
 573                                                }
 574                                        }
 575                                }
 576                                #ifdef RTL8190P
 577                                if(priv->rf_type == RF_2T4R)
 578                                {
 579                                        //disable RF-Chip A/B
 580                                        rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);              // 0x860[4]
 581                                }
 582                                //disable RF-Chip C/D
 583                                rtl8192_setBBreg(dev, rFPGA0_XC_RFInterfaceOE, BIT4, 0x0); // 0x868[4]
 584                                //analog to digital off, for power save
 585                                rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
 586                                //digital to analog off, for power save
 587                                rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e0, 0x0); // 0x880[8:5]
 588                                //rx antenna off
 589                                rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
 590                                //rx antenna off
 591                                rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
 592                                //analog to digital part2 off, for power save
 593                                rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x1e00, 0x0); // 0x880[12:9]
 594#else //8192E
 595                                        //2 RF
 596                                //disable RF-Chip A/B
 597                                rtl8192_setBBreg(dev, rFPGA0_XA_RFInterfaceOE, BIT4, 0x0);              // 0x860[4]
 598                                        rtl8192_setBBreg(dev, rFPGA0_XB_RFInterfaceOE, BIT4, 0x0);              // 0x864[4]
 599                                        //2 AFE
 600                                //analog to digital off, for power save
 601                                        //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter4, 0xf00, 0x0);// 0x88c[11:8]
 602                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter4, 0xf03, 0x0); //  2008.09.30 Modify
 603                                //digital to analog off, for power save
 604                                        //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x18, 0x0); // 0x880[4:3]
 605                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x98, 0x0); // 0x880 2008.09.30 Modify
 606                                        //rx antenna off  2008.09.30 mark
 607                                        //PHY_SetBBReg(Adapter, rOFDM0_TRxPathEnable, 0xf, 0x0);// 0xc04[3:0]
 608                                        //rx antenna off  2008.09.30 mark
 609                                        //PHY_SetBBReg(Adapter, rOFDM1_TRxPathEnable, 0xf, 0x0);// 0xd04[3:0]
 610                                //analog to digital part2 off, for power save
 611                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter1, 0x60, 0x0);              // 0x880[6:5]
 612                                        // 2008.09.30 add
 613                                        rtl8192_setBBreg(dev, rFPGA0_AnalogParameter2, 0x20000000, 0x0); // 0x884
 614
 615
 616                                        //disable clock 80/88 MHz 2008.09.30 mark
 617                                        //PHY_SetBBReg(Adapter, rFPGA0_AnalogParameter1, 0x4, 0x0); // 0x880[2]
 618                                        //2 BB
 619                                        // Baseband reset 2008.09.30 add
 620                                        write_nic_byte(dev, BB_RESET, (read_nic_byte(dev, BB_RESET)|BIT0)); // 0x101
 621                                        //MAC: off
 622                                        write_nic_byte(dev, MacBlkCtrl, 0x0); // 0x403
 623                                        //slow down cpu/lbus clock from 160MHz to Lower
 624                                        write_nic_byte(dev, ANAPAR, 0x07); // 0x 17 40MHz
 625                                priv->bHwRfOffAction = 0;
 626                                //}
 627                                #endif
 628                                        break;
 629
 630                        default:
 631                                        bResult = false;
 632                                        RT_TRACE(COMP_ERR, "SetRFPowerState8190(): unknow state to set: 0x%X!!!\n", eRFPowerState);
 633                                        break;
 634                }
 635
 636                break;
 637
 638                default:
 639                        RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n");
 640                        break;
 641        }
 642
 643        if(bResult)
 644        {
 645                // Update current RF state variable.
 646                priv->ieee80211->eRFPowerState = eRFPowerState;
 647
 648                switch(priv->rf_chip )
 649                {
 650                        case RF_8256:
 651                        switch(priv->ieee80211->eRFPowerState)
 652                        {
 653                                case eRfOff:
 654                                //
 655                                //If Rf off reason is from IPS, Led should blink with no link, by Maddest 071015
 656                                //
 657                                        if(priv->ieee80211->RfOffReason==RF_CHANGE_BY_IPS )
 658                                        {
 659                                                #ifdef TO_DO
 660                                                Adapter->HalFunc.LedControlHandler(Adapter,LED_CTL_NO_LINK);
 661                                                #endif
 662                                        }
 663                                        else
 664                                        {
 665                                        // Turn off LED if RF is not ON.
 666                                                #ifdef TO_DO
 667                                                Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_POWER_OFF);
 668                                                #endif
 669                                        }
 670                                        break;
 671
 672                                case eRfOn:
 673                                // Turn on RF we are still linked, which might happen when
 674                                // we quickly turn off and on HW RF. 2006.05.12, by rcnjko.
 675                                        if( priv->ieee80211->state == IEEE80211_LINKED)
 676                                        {
 677                                                #ifdef TO_DO
 678                                                Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_LINK);
 679                                                #endif
 680                                        }
 681                                        else
 682                                        {
 683                                        // Turn off LED if RF is not ON.
 684                                                #ifdef TO_DO
 685                                                Adapter->HalFunc.LedControlHandler(Adapter, LED_CTL_NO_LINK);
 686                                                #endif
 687                                        }
 688                                        break;
 689
 690                                default:
 691                        // do nothing.
 692                                        break;
 693                        }// Switch RF state
 694
 695                        break;
 696
 697                        default:
 698                                RT_TRACE(COMP_ERR, "SetRFPowerState8190(): Unknown RF type\n");
 699                                break;
 700                }// Switch RFChipID
 701        }
 702
 703        priv->SetRFPowerStateInProgress = false;
 704        RT_TRACE(COMP_POWER, "<=========== SetRFPowerState8190() bResult = %d!\n", bResult);
 705        return bResult;
 706}
 707
 708
 709
 710//
 711//      Description:
 712//              Change RF power state.
 713//
 714//      Assumption:
 715//              This function must be executed in re-schdulable context,
 716//              ie. PASSIVE_LEVEL.
 717//
 718//      050823, by rcnjko.
 719//
 720static bool
 721SetRFPowerState(
 722        struct net_device* dev,
 723        RT_RF_POWER_STATE       eRFPowerState
 724        )
 725{
 726        struct r8192_priv *priv = ieee80211_priv(dev);
 727
 728        bool bResult = false;
 729
 730        RT_TRACE(COMP_RF,"---------> SetRFPowerState(): eRFPowerState(%d)\n", eRFPowerState);
 731#ifdef RTL8192E
 732        if(eRFPowerState == priv->ieee80211->eRFPowerState && priv->bHwRfOffAction == 0)
 733#else
 734        if(eRFPowerState == priv->ieee80211->eRFPowerState)
 735#endif
 736        {
 737                RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): discard the request for eRFPowerState(%d) is the same.\n", eRFPowerState);
 738                return bResult;
 739        }
 740
 741        bResult = SetRFPowerState8190(dev, eRFPowerState);
 742
 743        RT_TRACE(COMP_POWER, "<--------- SetRFPowerState(): bResult(%d)\n", bResult);
 744
 745        return bResult;
 746}
 747
 748static void
 749MgntDisconnectIBSS(
 750        struct net_device* dev
 751)
 752{
 753        struct r8192_priv *priv = ieee80211_priv(dev);
 754        //RT_OP_MODE    OpMode;
 755        u8                      i;
 756        bool    bFilterOutNonAssociatedBSSID = false;
 757
 758        //IEEE80211_DEBUG(IEEE80211_DL_TRACE, "XXXXXXXXXX MgntDisconnect IBSS\n");
 759
 760        priv->ieee80211->state = IEEE80211_NOLINK;
 761
 762//      PlatformZeroMemory( pMgntInfo->Bssid, 6 );
 763        for(i=0;i<6;i++)  priv->ieee80211->current_network.bssid[i]= 0x55;
 764        priv->OpMode = RT_OP_MODE_NO_LINK;
 765        write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]);
 766        write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]);
 767        {
 768                        RT_OP_MODE      OpMode = priv->OpMode;
 769                        //LED_CTL_MODE  LedAction = LED_CTL_NO_LINK;
 770                        u8      btMsr = read_nic_byte(dev, MSR);
 771
 772                        btMsr &= 0xfc;
 773
 774                        switch(OpMode)
 775                        {
 776                        case RT_OP_MODE_INFRASTRUCTURE:
 777                                btMsr |= MSR_LINK_MANAGED;
 778                                //LedAction = LED_CTL_LINK;
 779                                break;
 780
 781                        case RT_OP_MODE_IBSS:
 782                                btMsr |= MSR_LINK_ADHOC;
 783                                // led link set seperate
 784                                break;
 785
 786                        case RT_OP_MODE_AP:
 787                                btMsr |= MSR_LINK_MASTER;
 788                                //LedAction = LED_CTL_LINK;
 789                                break;
 790
 791                        default:
 792                                btMsr |= MSR_LINK_NONE;
 793                                break;
 794                        }
 795
 796                        write_nic_byte(dev, MSR, btMsr);
 797
 798                        // LED control
 799                        //Adapter->HalFunc.LedControlHandler(Adapter, LedAction);
 800        }
 801        ieee80211_stop_send_beacons(priv->ieee80211);
 802
 803        // If disconnect, clear RCR CBSSID bit
 804        bFilterOutNonAssociatedBSSID = false;
 805        {
 806                        u32 RegRCR, Type;
 807                        Type = bFilterOutNonAssociatedBSSID;
 808                        RegRCR = read_nic_dword(dev,RCR);
 809                        priv->ReceiveConfig = RegRCR;
 810                        if (Type == true)
 811                                RegRCR |= (RCR_CBSSID);
 812                        else if (Type == false)
 813                                RegRCR &= (~RCR_CBSSID);
 814
 815                        {
 816                                write_nic_dword(dev, RCR,RegRCR);
 817                                priv->ReceiveConfig = RegRCR;
 818                        }
 819
 820                }
 821        //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE );
 822        notify_wx_assoc_event(priv->ieee80211);
 823
 824}
 825
 826static void
 827MlmeDisassociateRequest(
 828        struct net_device* dev,
 829        u8*             asSta,
 830        u8                      asRsn
 831        )
 832{
 833        struct r8192_priv *priv = ieee80211_priv(dev);
 834        u8 i;
 835
 836        RemovePeerTS(priv->ieee80211, asSta);
 837
 838        SendDisassociation( priv->ieee80211, asSta, asRsn );
 839
 840        if(memcpy(priv->ieee80211->current_network.bssid,asSta,6) == NULL)
 841        {
 842                //ShuChen TODO: change media status.
 843                //ShuChen TODO: What to do when disassociate.
 844                priv->ieee80211->state = IEEE80211_NOLINK;
 845                //pMgntInfo->AsocTimestamp = 0;
 846                for(i=0;i<6;i++)  priv->ieee80211->current_network.bssid[i] = 0x22;
 847//              pMgntInfo->mBrates.Length = 0;
 848//              Adapter->HalFunc.SetHwRegHandler( Adapter, HW_VAR_BASIC_RATE, (pu1Byte)(&pMgntInfo->mBrates) );
 849                priv->OpMode = RT_OP_MODE_NO_LINK;
 850                {
 851                        RT_OP_MODE      OpMode = priv->OpMode;
 852                        //LED_CTL_MODE  LedAction = LED_CTL_NO_LINK;
 853                        u8 btMsr = read_nic_byte(dev, MSR);
 854
 855                        btMsr &= 0xfc;
 856
 857                        switch(OpMode)
 858                        {
 859                        case RT_OP_MODE_INFRASTRUCTURE:
 860                                btMsr |= MSR_LINK_MANAGED;
 861                                //LedAction = LED_CTL_LINK;
 862                                break;
 863
 864                        case RT_OP_MODE_IBSS:
 865                                btMsr |= MSR_LINK_ADHOC;
 866                                // led link set seperate
 867                                break;
 868
 869                        case RT_OP_MODE_AP:
 870                                btMsr |= MSR_LINK_MASTER;
 871                                //LedAction = LED_CTL_LINK;
 872                                break;
 873
 874                        default:
 875                                btMsr |= MSR_LINK_NONE;
 876                                break;
 877                        }
 878
 879                        write_nic_byte(dev, MSR, btMsr);
 880
 881                        // LED control
 882                        //Adapter->HalFunc.LedControlHandler(Adapter, LedAction);
 883                }
 884                ieee80211_disassociate(priv->ieee80211);
 885
 886                write_nic_word(dev, BSSIDR, ((u16*)priv->ieee80211->current_network.bssid)[0]);
 887                write_nic_dword(dev, BSSIDR+2, ((u32*)(priv->ieee80211->current_network.bssid+2))[0]);
 888
 889        }
 890
 891}
 892
 893
 894static void
 895MgntDisconnectAP(
 896        struct net_device* dev,
 897        u8 asRsn
 898)
 899{
 900        struct r8192_priv *priv = ieee80211_priv(dev);
 901        bool bFilterOutNonAssociatedBSSID = false;
 902
 903//
 904// Commented out by rcnjko, 2005.01.27:
 905// I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
 906//
 907//      //2004/09/15, kcwu, the key should be cleared, or the new handshaking will not success
 908//      SecClearAllKeys(Adapter);
 909
 910        // In WPA WPA2 need to Clear all key ... because new key will set after new handshaking.
 911#ifdef TO_DO
 912        if(   pMgntInfo->SecurityInfo.AuthMode > RT_802_11AuthModeAutoSwitch ||
 913                (pMgntInfo->bAPSuportCCKM && pMgntInfo->bCCX8021xenable) )      // In CCKM mode will Clear key
 914        {
 915                SecClearAllKeys(Adapter);
 916                RT_TRACE(COMP_SEC, DBG_LOUD,("======>CCKM clear key..."))
 917        }
 918#endif
 919        // If disconnect, clear RCR CBSSID bit
 920        bFilterOutNonAssociatedBSSID = false;
 921        {
 922                        u32 RegRCR, Type;
 923
 924                        Type = bFilterOutNonAssociatedBSSID;
 925                        //Adapter->HalFunc.GetHwRegHandler(Adapter, HW_VAR_RCR, (pu1Byte)(&RegRCR));
 926                        RegRCR = read_nic_dword(dev,RCR);
 927                        priv->ReceiveConfig = RegRCR;
 928
 929                        if (Type == true)
 930                                RegRCR |= (RCR_CBSSID);
 931                        else if (Type == false)
 932                                RegRCR &= (~RCR_CBSSID);
 933
 934                        write_nic_dword(dev, RCR,RegRCR);
 935                        priv->ReceiveConfig = RegRCR;
 936
 937
 938        }
 939        // 2004.10.11, by rcnjko.
 940        //MlmeDisassociateRequest( Adapter, pMgntInfo->Bssid, disas_lv_ss );
 941        MlmeDisassociateRequest( dev, priv->ieee80211->current_network.bssid, asRsn );
 942
 943        priv->ieee80211->state = IEEE80211_NOLINK;
 944        //pMgntInfo->AsocTimestamp = 0;
 945}
 946
 947
 948static bool
 949MgntDisconnect(
 950        struct net_device* dev,
 951        u8 asRsn
 952)
 953{
 954        struct r8192_priv *priv = ieee80211_priv(dev);
 955
 956        //
 957        // Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
 958        //
 959#ifdef TO_DO
 960        if(pMgntInfo->mPss != eAwake)
 961        {
 962                //
 963                // Using AwkaeTimer to prevent mismatch ps state.
 964                // In the timer the state will be changed according to the RF is being awoke or not. By Bruce, 2007-10-31.
 965                //
 966                // PlatformScheduleWorkItem( &(pMgntInfo->AwakeWorkItem) );
 967                PlatformSetTimer( Adapter, &(pMgntInfo->AwakeTimer), 0 );
 968        }
 969#endif
 970        // Follow 8180 AP mode, 2005.05.30, by rcnjko.
 971#ifdef TO_DO
 972        if(pMgntInfo->mActingAsAp)
 973        {
 974                RT_TRACE(COMP_MLME, DBG_LOUD, ("MgntDisconnect() ===> AP_DisassociateAllStation\n"));
 975                AP_DisassociateAllStation(Adapter, unspec_reason);
 976                return TRUE;
 977        }
 978#endif
 979        // Indication of disassociation event.
 980        //DrvIFIndicateDisassociation(Adapter, asRsn);
 981
 982        // In adhoc mode, update beacon frame.
 983        if( priv->ieee80211->state == IEEE80211_LINKED )
 984        {
 985                if( priv->ieee80211->iw_mode == IW_MODE_ADHOC )
 986                {
 987                        //RT_TRACE(COMP_MLME, "MgntDisconnect() ===> MgntDisconnectIBSS\n");
 988                        MgntDisconnectIBSS(dev);
 989                }
 990                if( priv->ieee80211->iw_mode == IW_MODE_INFRA )
 991                {
 992                        // We clear key here instead of MgntDisconnectAP() because that
 993                        // MgntActSet_802_11_DISASSOCIATE() is an interface called by OS,
 994                        // e.g. OID_802_11_DISASSOCIATE in Windows while as MgntDisconnectAP() is
 995                        // used to handle disassociation related things to AP, e.g. send Disassoc
 996                        // frame to AP.  2005.01.27, by rcnjko.
 997                        //IEEE80211_DEBUG(IEEE80211_DL_TRACE,"MgntDisconnect() ===> MgntDisconnectAP\n");
 998                        MgntDisconnectAP(dev, asRsn);
 999                }
1000
1001                // Inidicate Disconnect, 2005.02.23, by rcnjko.
1002                //MgntIndicateMediaStatus( Adapter, RT_MEDIA_DISCONNECT, GENERAL_INDICATE);
1003        }
1004
1005        return true;
1006}
1007
1008//
1009//      Description:
1010//              Chang RF Power State.
1011//              Note that, only MgntActSet_RF_State() is allowed to set HW_VAR_RF_STATE.
1012//
1013//      Assumption:
1014//              PASSIVE LEVEL.
1015//
1016bool
1017MgntActSet_RF_State(
1018        struct net_device* dev,
1019        RT_RF_POWER_STATE       StateToSet,
1020        RT_RF_CHANGE_SOURCE ChangeSource
1021        )
1022{
1023        struct r8192_priv *priv = ieee80211_priv(dev);
1024        bool                    bActionAllowed = false;
1025        bool                    bConnectBySSID = false;
1026        RT_RF_POWER_STATE       rtState;
1027        u16                                     RFWaitCounter = 0;
1028        unsigned long flag;
1029        RT_TRACE(COMP_POWER, "===>MgntActSet_RF_State(): StateToSet(%d)\n",StateToSet);
1030
1031        //1//
1032        //1//<1>Prevent the race condition of RF state change.
1033        //1//
1034        // Only one thread can change the RF state at one time, and others should wait to be executed. By Bruce, 2007-11-28.
1035
1036        while(true)
1037        {
1038                spin_lock_irqsave(&priv->rf_ps_lock,flag);
1039                if(priv->RFChangeInProgress)
1040                {
1041                        spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
1042                        RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): RF Change in progress! Wait to set..StateToSet(%d).\n", StateToSet);
1043
1044                        // Set RF after the previous action is done.
1045                        while(priv->RFChangeInProgress)
1046                        {
1047                                RFWaitCounter ++;
1048                                RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Wait 1 ms (%d times)...\n", RFWaitCounter);
1049                                udelay(1000); // 1 ms
1050
1051                                // Wait too long, return FALSE to avoid to be stuck here.
1052                                if(RFWaitCounter > 100)
1053                                {
1054                                        RT_TRACE(COMP_ERR, "MgntActSet_RF_State(): Wait too logn to set RF\n");
1055                                        // TODO: Reset RF state?
1056                                        return false;
1057                                }
1058                        }
1059                }
1060                else
1061                {
1062                        priv->RFChangeInProgress = true;
1063                        spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
1064                        break;
1065                }
1066        }
1067
1068        rtState = priv->ieee80211->eRFPowerState;
1069
1070        switch(StateToSet)
1071        {
1072        case eRfOn:
1073                //
1074                // Turn On RF no matter the IPS setting because we need to update the RF state to Ndis under Vista, or
1075                // the Windows does not allow the driver to perform site survey any more. By Bruce, 2007-10-02.
1076                //
1077
1078                priv->ieee80211->RfOffReason &= (~ChangeSource);
1079
1080                if(! priv->ieee80211->RfOffReason)
1081                {
1082                        priv->ieee80211->RfOffReason = 0;
1083                        bActionAllowed = true;
1084
1085
1086                        if(rtState == eRfOff && ChangeSource >=RF_CHANGE_BY_HW )
1087                        {
1088                                bConnectBySSID = true;
1089                        }
1090                }
1091                else
1092                        RT_TRACE(COMP_POWER, "MgntActSet_RF_State - eRfon reject pMgntInfo->RfOffReason= 0x%x, ChangeSource=0x%X\n", priv->ieee80211->RfOffReason, ChangeSource);
1093
1094                break;
1095
1096        case eRfOff:
1097
1098                        if (priv->ieee80211->RfOffReason > RF_CHANGE_BY_IPS)
1099                        {
1100                                //
1101                                // 060808, Annie:
1102                                // Disconnect to current BSS when radio off. Asked by QuanTa.
1103                                //
1104                                // Set all link status falg, by Bruce, 2007-06-26.
1105                                //MgntActSet_802_11_DISASSOCIATE( Adapter, disas_lv_ss );
1106                                MgntDisconnect(dev, disas_lv_ss);
1107
1108                                // Clear content of bssDesc[] and bssDesc4Query[] to avoid reporting old bss to UI.
1109                                // 2007.05.28, by shien chang.
1110
1111                        }
1112
1113
1114                priv->ieee80211->RfOffReason |= ChangeSource;
1115                bActionAllowed = true;
1116                break;
1117
1118        case eRfSleep:
1119                priv->ieee80211->RfOffReason |= ChangeSource;
1120                bActionAllowed = true;
1121                break;
1122
1123        default:
1124                break;
1125        }
1126
1127        if(bActionAllowed)
1128        {
1129                RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is allowed.... StateToSet(%d), RfOffReason(%#X)\n", StateToSet, priv->ieee80211->RfOffReason);
1130                                // Config HW to the specified mode.
1131                SetRFPowerState(dev, StateToSet);
1132                // Turn on RF.
1133                if(StateToSet == eRfOn)
1134                {
1135                        //Adapter->HalFunc.HalEnableRxHandler(Adapter);
1136                        if(bConnectBySSID)
1137                        {
1138                                //MgntActSet_802_11_SSID(Adapter, Adapter->MgntInfo.Ssid.Octet, Adapter->MgntInfo.Ssid.Length, TRUE );
1139                        }
1140                }
1141                // Turn off RF.
1142                else if(StateToSet == eRfOff)
1143                {
1144                        //Adapter->HalFunc.HalDisableRxHandler(Adapter);
1145                }
1146        }
1147        else
1148        {
1149                RT_TRACE(COMP_POWER, "MgntActSet_RF_State(): Action is rejected.... StateToSet(%d), ChangeSource(%#X), RfOffReason(%#X)\n", StateToSet, ChangeSource, priv->ieee80211->RfOffReason);
1150        }
1151
1152        // Release RF spinlock
1153        spin_lock_irqsave(&priv->rf_ps_lock,flag);
1154        priv->RFChangeInProgress = false;
1155        spin_unlock_irqrestore(&priv->rf_ps_lock,flag);
1156
1157        RT_TRACE(COMP_POWER, "<===MgntActSet_RF_State()\n");
1158        return bActionAllowed;
1159}
1160
1161
1162