linux/drivers/staging/rtl8192su/r8192U_dm.c
<<
>>
Prefs
   1/*++
   2Copyright-c Realtek Semiconductor Corp. All rights reserved.
   3
   4Module Name:
   5        r8192U_dm.c
   6
   7Abstract:
   8        HW dynamic mechanism.
   9
  10Major Change History:
  11        When            Who                             What
  12        ----------      --------------- -------------------------------
  13        2008-05-14      amy                     create version 0 porting from windows code.
  14
  15--*/
  16
  17
  18#include "r8192U.h"
  19#include "r8192U_dm.h"
  20#include "r819xU_cmdpkt.h"
  21#include "r8192S_hw.h"
  22#include "r8192S_phy.h"
  23#include "r8192S_phyreg.h"
  24
  25/*---------------------------Define Local Constant---------------------------*/
  26//
  27// Indicate different AP vendor for IOT issue.
  28//
  29#if 1
  30                static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
  31                // UNKNOWN      REALTEK_90      /*REALTEK_92SE*/        BROADCOM        RALINK          ATHEROS         CISCO           MARVELL         92U_AP          SELF_AP
  32                   { 0xa44f,    0x5ea44f,       0x5ea44f,               0xa44f,         0xa44f,                 0xa44f,                 0xa630,         0xa42b,         0x5e4322,       0x5e4322};
  33                static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
  34                // UNKNOWN      REALTEK         /*REALTEK_92SE*/        BROADCOM        RALINK          ATHEROS         CISCO           MARVELL         92U_AP          SELF_AP
  35                   { 0x5ea44f,  0xa44f,         0x5ea44f,               0x5e4322,       0x5ea422,       0x5e4322,       0x3ea44f,       0x5ea42b,       0x5e4322,       0x5e4322};
  36
  37#endif
  38
  39#define RTK_UL_EDCA 0xa44f
  40#define RTK_DL_EDCA 0x5e4322
  41/*---------------------------Define Local Constant---------------------------*/
  42
  43
  44/*------------------------Define global variable-----------------------------*/
  45// Debug variable ?
  46dig_t   dm_digtable;
  47// Store current shoftware write register content for MAC PHY.
  48u8              dm_shadow[16][256] = {{0}};
  49// For Dynamic Rx Path Selection by Signal Strength
  50DRxPathSel      DM_RxPathSelTable;
  51/*------------------------Define global variable-----------------------------*/
  52
  53
  54/*------------------------Define local variable------------------------------*/
  55/*------------------------Define local variable------------------------------*/
  56
  57
  58/*--------------------Define export function prototype-----------------------*/
  59#ifdef TO_DO_LIST
  60static  void dm_CheckProtection(struct net_device *dev);
  61#endif
  62extern  void    init_hal_dm(struct net_device *dev);
  63extern  void deinit_hal_dm(struct net_device *dev);
  64
  65extern void hal_dm_watchdog(struct net_device *dev);
  66
  67
  68extern  void    init_rate_adaptive(struct net_device *dev);
  69extern  void    dm_txpower_trackingcallback(struct work_struct *work);
  70extern  void    dm_cck_txpower_adjust(struct net_device *dev,bool  binch14);
  71extern  void    dm_restore_dynamic_mechanism_state(struct net_device *dev);
  72extern  void    dm_backup_dynamic_mechanism_state(struct net_device *dev);
  73extern  void    dm_change_dynamic_initgain_thresh(struct net_device *dev,
  74                                                                u32             dm_type,
  75                                                                u32             dm_value);
  76extern  void    DM_ChangeFsyncSetting(struct net_device *dev,
  77                                                                                                s32             DM_Type,
  78                                                                                                s32             DM_Value);
  79extern  void dm_force_tx_fw_info(struct net_device *dev,
  80                                                                                u32             force_type,
  81                                                                                u32             force_value);
  82extern  void    dm_init_edca_turbo(struct net_device *dev);
  83extern  void    dm_rf_operation_test_callback(unsigned long data);
  84extern  void    dm_rf_pathcheck_workitemcallback(struct work_struct *work);
  85extern  void dm_fsync_timer_callback(unsigned long data);
  86extern  void dm_check_fsync(struct net_device *dev);
  87extern  void    dm_shadow_init(struct net_device *dev);
  88
  89
  90/*--------------------Define export function prototype-----------------------*/
  91
  92
  93/*---------------------Define local function prototype-----------------------*/
  94// DM --> Rate Adaptive
  95static  void    dm_check_rate_adaptive(struct net_device *dev);
  96
  97// DM --> Bandwidth switch
  98static  void    dm_init_bandwidth_autoswitch(struct net_device *dev);
  99static  void    dm_bandwidth_autoswitch(        struct net_device *dev);
 100
 101// DM --> TX power control
 102//static        void    dm_initialize_txpower_tracking(struct net_device *dev);
 103
 104static  void    dm_check_txpower_tracking(struct net_device *dev);
 105
 106
 107
 108//static        void    dm_txpower_reset_recovery(struct net_device *dev);
 109
 110
 111// DM --> BB init gain restore
 112#ifndef RTL8192U
 113static  void    dm_bb_initialgain_restore(struct net_device *dev);
 114
 115
 116// DM --> BB init gain backup
 117static  void    dm_bb_initialgain_backup(struct net_device *dev);
 118#endif
 119// DM --> Dynamic Init Gain by RSSI
 120static  void    dm_dig_init(struct net_device *dev);
 121static  void    dm_ctrl_initgain_byrssi(struct net_device *dev);
 122static  void    dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
 123static  void    dm_ctrl_initgain_byrssi_by_driverrssi(  struct net_device *dev);
 124static  void    dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
 125static  void    dm_initial_gain(struct net_device *dev);
 126static  void    dm_pd_th(struct net_device *dev);
 127static  void    dm_cs_ratio(struct net_device *dev);
 128
 129static  void dm_init_ctstoself(struct net_device *dev);
 130// DM --> EDCA turboe mode control
 131static  void    dm_check_edca_turbo(struct net_device *dev);
 132
 133// DM --> HW RF control
 134static  void    dm_check_rfctrl_gpio(struct net_device *dev);
 135
 136#ifndef RTL8190P
 137//static        void    dm_gpio_change_rf(struct net_device *dev);
 138#endif
 139// DM --> Check PBC
 140static  void dm_check_pbc_gpio(struct net_device *dev);
 141
 142
 143// DM --> Check current RX RF path state
 144static  void    dm_check_rx_path_selection(struct net_device *dev);
 145static  void dm_init_rxpath_selection(struct net_device *dev);
 146static  void dm_rxpath_sel_byrssi(struct net_device *dev);
 147
 148
 149// DM --> Fsync for broadcom ap
 150static void dm_init_fsync(struct net_device *dev);
 151static void dm_deInit_fsync(struct net_device *dev);
 152
 153//Added by vivi, 20080522
 154static  void    dm_check_txrateandretrycount(struct net_device *dev);
 155
 156/*---------------------Define local function prototype-----------------------*/
 157
 158/*---------------------Define of Tx Power Control For Near/Far Range --------*/   //Add by Jacken 2008/02/18
 159static  void    dm_init_dynamic_txpower(struct net_device *dev);
 160static  void    dm_dynamic_txpower(struct net_device *dev);
 161
 162
 163// DM --> For rate adaptive and DIG, we must send RSSI to firmware
 164static  void dm_send_rssi_tofw(struct net_device *dev);
 165static  void    dm_ctstoself(struct net_device *dev);
 166/*---------------------------Define function prototype------------------------*/
 167//================================================================================
 168//      HW Dynamic mechanism interface.
 169//================================================================================
 170static void dm_CheckAggrPolicy(struct net_device *dev)
 171{
 172        struct r8192_priv *priv = ieee80211_priv(dev);
 173        PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
 174        //u8                    QueueId;
 175        //PRT_TCB                       pTcb;
 176        bool                    bAmsduEnable = false;
 177
 178        static u8               lastTxOkCnt = 0;
 179        static u8               lastRxOkCnt = 0;
 180        u8                      curTxOkCnt = 0;
 181        u8                      curRxOkCnt = 0;
 182
 183        // Determine if A-MSDU policy.
 184        if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_HYBRID_AGGREGATION)
 185        {
 186                if(read_nic_byte(dev, INIMCS_SEL) > DESC92S_RATE54M)
 187                        bAmsduEnable = true;
 188        }
 189        else if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE)
 190        {
 191                if(read_nic_byte(dev, INIMCS_SEL) > DESC92S_RATE54M)
 192                {
 193                        curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
 194                        curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
 195
 196                        if(curRxOkCnt <= 4*curTxOkCnt)
 197                                bAmsduEnable = true;
 198                }
 199        }
 200        else
 201        {
 202                // Do not need to switch aggregation policy.
 203                return;
 204        }
 205
 206        // Switch A-MSDU
 207        if(bAmsduEnable && !pHTInfo->bCurrent_AMSDU_Support)
 208        {
 209                pHTInfo->bCurrent_AMSDU_Support = true;
 210        }
 211        else if(!bAmsduEnable && pHTInfo->bCurrent_AMSDU_Support)
 212        {
 213#ifdef TO_DO_LIST
 214                //PlatformAcquireSpinLock(Adapter, RT_TX_SPINLOCK);
 215                for(QueueId = 0; QueueId < MAX_TX_QUEUE; QueueId++)
 216                {
 217                        while(!RTIsListEmpty(&dev->TcbAggrQueue[QueueId]))
 218                        {
 219                                pTcb = (PRT_TCB)RTRemoveHeadList(&dev->TcbAggrQueue[QueueId]);
 220                                dev->TcbCountInAggrQueue[QueueId]--;
 221                                PreTransmitTCB(dev, pTcb);
 222                        }
 223                }
 224                //PlatformReleaseSpinLock(Adapter, RT_TX_SPINLOCK);
 225                pHTInfo->bCurrent_AMSDU_Support = false;
 226#endif
 227        }
 228
 229        // Determine A-MPDU policy
 230        if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_AMSDU_ENABLE)
 231        {
 232                if(!bAmsduEnable)
 233                        pHTInfo->bCurrentAMPDUEnable = true;
 234        }
 235
 236        // Update local static variables.
 237        lastTxOkCnt = priv->stats.txbytesunicast;
 238        lastRxOkCnt = priv->stats.rxbytesunicast;
 239}
 240//
 241//      Description:
 242//              Prepare SW resource for HW dynamic mechanism.
 243//
 244//      Assumption:
 245//              This function is only invoked at driver intialization once.
 246//
 247//
 248extern  void
 249init_hal_dm(struct net_device *dev)
 250{
 251        struct r8192_priv *priv = ieee80211_priv(dev);
 252
 253        // Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism.
 254        priv->undecorated_smoothed_pwdb = -1;
 255
 256        //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
 257        dm_init_dynamic_txpower(dev);
 258        init_rate_adaptive(dev);
 259        dm_initialize_txpower_tracking(dev);
 260        dm_dig_init(dev);
 261        dm_init_edca_turbo(dev);
 262        dm_init_bandwidth_autoswitch(dev);
 263        dm_init_fsync(dev);
 264        dm_init_rxpath_selection(dev);
 265        dm_init_ctstoself(dev);
 266
 267}       // InitHalDm
 268
 269extern void deinit_hal_dm(struct net_device *dev)
 270{
 271
 272        dm_deInit_fsync(dev);
 273
 274}
 275
 276
 277
 278
 279//#if 0
 280extern  void    hal_dm_watchdog(struct net_device *dev)
 281{
 282        struct r8192_priv *priv = ieee80211_priv(dev);
 283
 284        if(priv->bInHctTest)
 285                return;
 286
 287
 288        dm_check_rfctrl_gpio(dev);
 289
 290        // Add by hpfan 2008-03-11
 291        dm_check_pbc_gpio(dev);
 292        dm_check_txrateandretrycount(dev); //moved by tynli
 293        dm_check_edca_turbo(dev);
 294
 295        dm_CheckAggrPolicy(dev);
 296
 297#ifdef TO_DO_LIST
 298        dm_CheckProtection(dev);
 299#endif
 300
 301        // ====================================================
 302        // If any dynamic mechanism is ready, put it above this return;
 303        // ====================================================
 304        //if (IS_HARDWARE_TYPE_8192S(dev))
 305        return;
 306
 307#ifdef TO_DO_LIST
 308        if(Adapter->MgntInfo.mActingAsAp)
 309        {
 310                AP_dm_CheckRateAdaptive(dev);
 311                //return;
 312        }
 313        else
 314#endif
 315        {
 316                dm_check_rate_adaptive(dev);
 317        }
 318        dm_dynamic_txpower(dev);
 319
 320        dm_check_txpower_tracking(dev);
 321        dm_ctrl_initgain_byrssi(dev);//LZM TMP 090302
 322
 323        dm_bandwidth_autoswitch(dev);
 324
 325        dm_check_rx_path_selection(dev);//LZM TMP 090302
 326        dm_check_fsync(dev);
 327
 328        dm_send_rssi_tofw(dev);
 329
 330        dm_ctstoself(dev);
 331
 332}       //HalDmWatchDog
 333
 334/*
 335  * Decide Rate Adaptive Set according to distance (signal strength)
 336  *     01/11/2008      MHC             Modify input arguments and RATR table level.
 337  *     01/16/2008      MHC             RF_Type is assigned in ReadAdapterInfo(). We must call
 338  *                                             the function after making sure RF_Type.
 339  */
 340extern void init_rate_adaptive(struct net_device * dev)
 341{
 342
 343        struct r8192_priv *priv = ieee80211_priv(dev);
 344        prate_adaptive  pra = (prate_adaptive)&priv->rate_adaptive;
 345
 346        pra->ratr_state = DM_RATR_STA_MAX;
 347        pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
 348        pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
 349        pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
 350
 351        pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
 352        pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
 353        pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
 354
 355        if(priv->CustomerID == RT_CID_819x_Netcore)
 356                pra->ping_rssi_enable = 1;
 357        else
 358                pra->ping_rssi_enable = 0;
 359        pra->ping_rssi_thresh_for_ra = 15;
 360
 361
 362        if (priv->rf_type == RF_2T4R)
 363        {
 364                // 07/10/08 MH Modify for RA smooth scheme.
 365                /* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/
 366                pra->upper_rssi_threshold_ratr          =       0x8f0f0000;
 367                pra->middle_rssi_threshold_ratr         =       0x8f0ff000;
 368                pra->low_rssi_threshold_ratr            =       0x8f0ff001;
 369                pra->low_rssi_threshold_ratr_40M        =       0x8f0ff005;
 370                pra->low_rssi_threshold_ratr_20M        =       0x8f0ff001;
 371                pra->ping_rssi_ratr     =       0x0000000d;//cosa add for test
 372        }
 373        else if (priv->rf_type == RF_1T2R)
 374        {
 375                pra->upper_rssi_threshold_ratr          =       0x000f0000;
 376                pra->middle_rssi_threshold_ratr         =       0x000ff000;
 377                pra->low_rssi_threshold_ratr            =       0x000ff001;
 378                pra->low_rssi_threshold_ratr_40M        =       0x000ff005;
 379                pra->low_rssi_threshold_ratr_20M        =       0x000ff001;
 380                pra->ping_rssi_ratr     =       0x0000000d;//cosa add for test
 381        }
 382
 383}       // InitRateAdaptive
 384
 385
 386/*-----------------------------------------------------------------------------
 387 * Function:    dm_check_rate_adaptive()
 388 *
 389 * Overview:
 390 *
 391 * Input:               NONE
 392 *
 393 * Output:              NONE
 394 *
 395 * Return:              NONE
 396 *
 397 * Revised History:
 398 *      When            Who             Remark
 399 *      05/26/08        amy     Create version 0 proting from windows code.
 400 *
 401 *---------------------------------------------------------------------------*/
 402static void dm_check_rate_adaptive(struct net_device * dev)
 403{
 404        struct r8192_priv *priv = ieee80211_priv(dev);
 405        PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
 406        prate_adaptive                  pra = (prate_adaptive)&priv->rate_adaptive;
 407        u32                                             currentRATR, targetRATR = 0;
 408        u32                                             LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
 409        bool                                            bshort_gi_enabled = false;
 410        static u8                                       ping_rssi_state=0;
 411
 412
 413        if(!priv->up)
 414        {
 415                RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
 416                return;
 417        }
 418
 419        if(pra->rate_adaptive_disabled)//this variable is set by ioctl.
 420                return;
 421
 422        // TODO: Only 11n mode is implemented currently,
 423        if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
 424                 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
 425                 return;
 426
 427        if( priv->ieee80211->state == IEEE80211_LINKED )
 428        {
 429        //      RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
 430
 431                //
 432                // Check whether Short GI is enabled
 433                //
 434                bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
 435                        (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
 436
 437
 438                pra->upper_rssi_threshold_ratr =
 439                                (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
 440
 441                pra->middle_rssi_threshold_ratr =
 442                                (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
 443
 444                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
 445                {
 446                        pra->low_rssi_threshold_ratr =
 447                                (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
 448                }
 449                else
 450                {
 451                        pra->low_rssi_threshold_ratr =
 452                        (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
 453                }
 454                //cosa add for test
 455                pra->ping_rssi_ratr =
 456                                (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
 457
 458                /* 2007/10/08 MH We support RA smooth scheme now. When it is the first
 459                   time to link with AP. We will not change upper/lower threshold. If
 460                   STA stay in high or low level, we must change two different threshold
 461                   to prevent jumping frequently. */
 462                if (pra->ratr_state == DM_RATR_STA_HIGH)
 463                {
 464                        HighRSSIThreshForRA     = pra->high2low_rssi_thresh_for_ra;
 465                        LowRSSIThreshForRA      = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
 466                                        (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
 467                }
 468                else if (pra->ratr_state == DM_RATR_STA_LOW)
 469                {
 470                        HighRSSIThreshForRA     = pra->high_rssi_thresh_for_ra;
 471                        LowRSSIThreshForRA      = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
 472                                        (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
 473                }
 474                else
 475                {
 476                        HighRSSIThreshForRA     = pra->high_rssi_thresh_for_ra;
 477                        LowRSSIThreshForRA      = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
 478                                        (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
 479                }
 480
 481                //DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);
 482                if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
 483                {
 484                        //DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);
 485                        pra->ratr_state = DM_RATR_STA_HIGH;
 486                        targetRATR = pra->upper_rssi_threshold_ratr;
 487                }else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA)
 488                {
 489                        //DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);
 490                        pra->ratr_state = DM_RATR_STA_MIDDLE;
 491                        targetRATR = pra->middle_rssi_threshold_ratr;
 492                }else
 493                {
 494                        //DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);
 495                        pra->ratr_state = DM_RATR_STA_LOW;
 496                        targetRATR = pra->low_rssi_threshold_ratr;
 497                }
 498
 499                        //cosa add for test
 500                if(pra->ping_rssi_enable)
 501                {
 502                        //pHalData->UndecoratedSmoothedPWDB = 19;
 503                        if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5))
 504                        {
 505                                if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
 506                                        ping_rssi_state )
 507                                {
 508                                        //DbgPrint("TestRSSI = %d, set RATR to 0x%x \n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);
 509                                        pra->ratr_state = DM_RATR_STA_LOW;
 510                                        targetRATR = pra->ping_rssi_ratr;
 511                                        ping_rssi_state = 1;
 512                                }
 513                                //else
 514                                //      DbgPrint("TestRSSI is between the range. \n");
 515                        }
 516                        else
 517                        {
 518                                //DbgPrint("TestRSSI Recover to 0x%x \n", targetRATR);
 519                                ping_rssi_state = 0;
 520                        }
 521                }
 522
 523                // 2008.04.01
 524#if 1
 525                // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
 526                if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
 527                        targetRATR &=  0xf00fffff;
 528#endif
 529
 530                //
 531                // Check whether updating of RATR0 is required
 532                //
 533                currentRATR = read_nic_dword(dev, RATR0);
 534                if( targetRATR !=  currentRATR )
 535                {
 536                        u32 ratr_value;
 537                        ratr_value = targetRATR;
 538                        RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
 539                        if(priv->rf_type == RF_1T2R)
 540                        {
 541                                ratr_value &= ~(RATE_ALL_OFDM_2SS);
 542                        }
 543                        write_nic_dword(dev, RATR0, ratr_value);
 544                        write_nic_byte(dev, UFWP, 1);
 545
 546                        pra->last_ratr = targetRATR;
 547                }
 548
 549        }
 550        else
 551        {
 552                pra->ratr_state = DM_RATR_STA_MAX;
 553        }
 554
 555}       // dm_CheckRateAdaptive
 556
 557
 558static void dm_init_bandwidth_autoswitch(struct net_device * dev)
 559{
 560        struct r8192_priv *priv = ieee80211_priv(dev);
 561
 562        priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
 563        priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
 564        priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
 565        priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
 566
 567}       // dm_init_bandwidth_autoswitch
 568
 569
 570static void dm_bandwidth_autoswitch(struct net_device * dev)
 571{
 572        struct r8192_priv *priv = ieee80211_priv(dev);
 573
 574        if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){
 575                return;
 576        }else{
 577                if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40
 578                        if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
 579                                priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
 580                }else{//in force send packets in 20 Mhz in 20/40
 581                        if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
 582                                priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
 583
 584                }
 585        }
 586}       // dm_BandwidthAutoSwitch
 587
 588//OFDM default at 0db, index=6.
 589static u32 OFDMSwingTable[OFDM_Table_Length] = {
 590        0x7f8001fe,     // 0, +6db
 591        0x71c001c7,     // 1, +5db
 592        0x65400195,     // 2, +4db
 593        0x5a400169,     // 3, +3db
 594        0x50800142,     // 4, +2db
 595        0x47c0011f,     // 5, +1db
 596        0x40000100,     // 6, +0db ===> default, upper for higher temprature, lower for low temprature
 597        0x390000e4,     // 7, -1db
 598        0x32c000cb,     // 8, -2db
 599        0x2d4000b5,     // 9, -3db
 600        0x288000a2,     // 10, -4db
 601        0x24000090,     // 11, -5db
 602        0x20000080,     // 12, -6db
 603        0x1c800072,     // 13, -7db
 604        0x19800066,     // 14, -8db
 605        0x26c0005b,     // 15, -9db
 606        0x24400051,     // 16, -10db
 607        0x12000048,     // 17, -11db
 608        0x10000040      // 18, -12db
 609};
 610
 611static u8       CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
 612        {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},       // 0, +0db ===> CCK40M default
 613        {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},       // 1, -1db
 614        {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},       // 2, -2db
 615        {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},       // 3, -3db
 616        {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},       // 4, -4db
 617        {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},       // 5, -5db
 618        {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},       // 6, -6db ===> CCK20M default
 619        {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},       // 7, -7db
 620        {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},       // 8, -8db
 621        {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},       // 9, -9db
 622        {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},       // 10, -10db
 623        {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}        // 11, -11db
 624};
 625
 626static u8       CCKSwingTable_Ch14[CCK_Table_length][8] = {
 627        {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},       // 0, +0db  ===> CCK40M default
 628        {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},       // 1, -1db
 629        {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},       // 2, -2db
 630        {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},       // 3, -3db
 631        {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},       // 4, -4db
 632        {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},       // 5, -5db
 633        {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},       // 6, -6db  ===> CCK20M default
 634        {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},       // 7, -7db
 635        {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},       // 8, -8db
 636        {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},       // 9, -9db
 637        {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},       // 10, -10db
 638        {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}        // 11, -11db
 639};
 640
 641static void dm_TXPowerTrackingCallback_TSSI(struct net_device * dev)
 642{
 643        struct r8192_priv *priv = ieee80211_priv(dev);
 644        bool                                            bHighpowerstate, viviflag = FALSE;
 645        DCMD_TXCMD_T                    tx_cmd;
 646        u8                                              powerlevelOFDM24G;
 647        int                                             i =0, j = 0, k = 0;
 648        u8                                              RF_Type, tmp_report[5]={0, 0, 0, 0, 0};
 649        u32                                             Value;
 650        u8                                              Pwr_Flag;
 651        u16                                             Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0;
 652        //RT_STATUS                             rtStatus = RT_STATUS_SUCCESS;
 653#ifdef RTL8192U
 654        bool rtStatus = true;
 655#endif
 656        u32                                             delta=0;
 657
 658        write_nic_byte(dev, 0x1ba, 0);
 659
 660        priv->ieee80211->bdynamic_txpower_enable = false;
 661        bHighpowerstate = priv->bDynamicTxHighPower;
 662
 663        powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
 664        RF_Type = priv->rf_type;
 665        Value = (RF_Type<<8) | powerlevelOFDM24G;
 666
 667        RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
 668
 669        for(j = 0; j<=30; j++)
 670{       //fill tx_cmd
 671
 672        tx_cmd.Op               = TXCMD_SET_TX_PWR_TRACKING;
 673        tx_cmd.Length   = 4;
 674        tx_cmd.Value            = Value;
 675#ifdef RTL8192U
 676        rtStatus = SendTxCommandPacket(dev, &tx_cmd, 12);
 677        if (rtStatus == false)
 678        {
 679                RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
 680        }
 681#else
 682        cmpk_message_handle_tx(dev, (u8*)&tx_cmd,
 683                                                                DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
 684#endif
 685        mdelay(1);
 686        //DbgPrint("hi, vivi, strange\n");
 687        for(i = 0;i <= 30; i++)
 688        {
 689                Pwr_Flag = read_nic_byte(dev, 0x1ba);
 690
 691                if (Pwr_Flag == 0)
 692                {
 693                        mdelay(1);
 694                        continue;
 695                }
 696#ifdef RTL8190P
 697                Avg_TSSI_Meas = read_nic_word(dev, 0x1bc);
 698#else
 699                Avg_TSSI_Meas = read_nic_word(dev, 0x13c);
 700#endif
 701                if(Avg_TSSI_Meas == 0)
 702                {
 703                        write_nic_byte(dev, 0x1ba, 0);
 704                        break;
 705                }
 706
 707                for(k = 0;k < 5; k++)
 708                {
 709#ifdef RTL8190P
 710                        tmp_report[k] = read_nic_byte(dev, 0x1d8+k);
 711#else
 712                        if(k !=4)
 713                                tmp_report[k] = read_nic_byte(dev, 0x134+k);
 714                        else
 715                                tmp_report[k] = read_nic_byte(dev, 0x13e);
 716#endif
 717                        RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
 718                }
 719
 720                //check if the report value is right
 721                for(k = 0;k < 5; k++)
 722                {
 723                        if(tmp_report[k] <= 20)
 724                        {
 725                                viviflag =TRUE;
 726                                break;
 727                        }
 728                }
 729                if(viviflag ==TRUE)
 730                {
 731                        write_nic_byte(dev, 0x1ba, 0);
 732                        viviflag = FALSE;
 733                        RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
 734                        for(k = 0;k < 5; k++)
 735                                tmp_report[k] = 0;
 736                        break;
 737                }
 738
 739                for(k = 0;k < 5; k++)
 740                {
 741                        Avg_TSSI_Meas_from_driver += tmp_report[k];
 742                }
 743
 744                Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
 745                RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
 746                TSSI_13dBm = priv->TSSI_13dBm;
 747                RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
 748
 749                //if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)
 750                // For MacOS-compatible
 751                if(Avg_TSSI_Meas_from_driver > TSSI_13dBm)
 752                        delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
 753                else
 754                        delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
 755
 756                if(delta <= E_FOR_TX_POWER_TRACK)
 757                {
 758                        priv->ieee80211->bdynamic_txpower_enable = TRUE;
 759                        write_nic_byte(dev, 0x1ba, 0);
 760                        RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
 761                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
 762                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
 763#ifdef RTL8190P
 764                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
 765                        RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
 766#endif
 767                        RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
 768                        RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
 769                        return;
 770                }
 771                else
 772                {
 773                        if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
 774                        {
 775                                if((priv->rfa_txpowertrackingindex > 0)
 776#ifdef RTL8190P
 777                                        &&(priv->rfc_txpowertrackingindex > 0)
 778#endif
 779                                )
 780                                {
 781                                        priv->rfa_txpowertrackingindex--;
 782                                        if(priv->rfa_txpowertrackingindex_real > 4)
 783                                        {
 784                                                priv->rfa_txpowertrackingindex_real--;
 785                                                rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
 786                                        }
 787#ifdef RTL8190P
 788                                        priv->rfc_txpowertrackingindex--;
 789                                        if(priv->rfc_txpowertrackingindex_real > 4)
 790                                        {
 791                                                priv->rfc_txpowertrackingindex_real--;
 792                                                rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
 793                                        }
 794#endif
 795                                }
 796                        }
 797                        else
 798                        {
 799                                if((priv->rfa_txpowertrackingindex < 36)
 800#ifdef RTL8190P
 801                                        &&(priv->rfc_txpowertrackingindex < 36)
 802#endif
 803                                        )
 804                                {
 805                                        priv->rfa_txpowertrackingindex++;
 806                                        priv->rfa_txpowertrackingindex_real++;
 807                                        rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
 808
 809#ifdef RTL8190P
 810                                        priv->rfc_txpowertrackingindex++;
 811                                        priv->rfc_txpowertrackingindex_real++;
 812                                        rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
 813#endif
 814                                }
 815                        }
 816                        priv->cck_present_attentuation_difference
 817                                = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
 818
 819                        if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
 820                                priv->cck_present_attentuation
 821                                = priv->cck_present_attentuation_20Mdefault + priv->cck_present_attentuation_difference;
 822                        else
 823                                priv->cck_present_attentuation
 824                                = priv->cck_present_attentuation_40Mdefault + priv->cck_present_attentuation_difference;
 825
 826                        if(priv->cck_present_attentuation > -1&&priv->cck_present_attentuation <23)
 827                        {
 828                                if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
 829                                {
 830                                        priv->bcck_in_ch14 = TRUE;
 831                                        dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
 832                                }
 833                                else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
 834                                {
 835                                        priv->bcck_in_ch14 = FALSE;
 836                                        dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
 837                                }
 838                                else
 839                                        dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
 840                        }
 841                RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
 842                RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
 843#ifdef RTL8190P
 844                RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex = %d\n", priv->rfc_txpowertrackingindex);
 845                RT_TRACE(COMP_POWER_TRACKING, "priv->rfc_txpowertrackingindex_real = %d\n", priv->rfc_txpowertrackingindex_real);
 846#endif
 847                RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation_difference = %d\n", priv->cck_present_attentuation_difference);
 848                RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attentuation = %d\n", priv->cck_present_attentuation);
 849
 850                if (priv->cck_present_attentuation_difference <= -12||priv->cck_present_attentuation_difference >= 24)
 851                {
 852                        priv->ieee80211->bdynamic_txpower_enable = TRUE;
 853                        write_nic_byte(dev, 0x1ba, 0);
 854                        RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
 855                        return;
 856                }
 857
 858
 859        }
 860                write_nic_byte(dev, 0x1ba, 0);
 861                Avg_TSSI_Meas_from_driver = 0;
 862                for(k = 0;k < 5; k++)
 863                        tmp_report[k] = 0;
 864                break;
 865        }
 866}
 867                priv->ieee80211->bdynamic_txpower_enable = TRUE;
 868                write_nic_byte(dev, 0x1ba, 0);
 869}
 870
 871static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device * dev)
 872{
 873#define ThermalMeterVal 9
 874        struct r8192_priv *priv = ieee80211_priv(dev);
 875        u32 tmpRegA, TempCCk;
 876        u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
 877        int i =0, CCKSwingNeedUpdate=0;
 878
 879        if(!priv->btxpower_trackingInit)
 880        {
 881                //Query OFDM default setting
 882                tmpRegA= rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
 883                for(i=0; i<OFDM_Table_Length; i++)      //find the index
 884                {
 885                        if(tmpRegA == OFDMSwingTable[i])
 886                        {
 887                                priv->OFDM_index= (u8)i;
 888                                RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
 889                                        rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
 890                        }
 891                }
 892
 893                //Query CCK default setting From 0xa22
 894                TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
 895                for(i=0 ; i<CCK_Table_length ; i++)
 896                {
 897                        if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0])
 898                        {
 899                                priv->CCK_index =(u8) i;
 900                                RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
 901                                        rCCK0_TxFilter1, TempCCk, priv->CCK_index);
 902                                break;
 903                        }
 904                }
 905                priv->btxpower_trackingInit = TRUE;
 906                //pHalData->TXPowercount = 0;
 907                return;
 908        }
 909
 910        // read and filter out unreasonable value
 911        tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);        // 0x12: RF Reg[10:7]
 912        RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d \n", tmpRegA);
 913        if(tmpRegA < 3 || tmpRegA > 13)
 914                return;
 915        if(tmpRegA >= 12)       // if over 12, TP will be bad when high temprature
 916                tmpRegA = 12;
 917        RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d \n", tmpRegA);
 918        priv->ThermalMeter[0] = ThermalMeterVal;        //We use fixed value by Bryant's suggestion
 919        priv->ThermalMeter[1] = ThermalMeterVal;        //We use fixed value by Bryant's suggestion
 920
 921        //Get current RF-A temprature index
 922        if(priv->ThermalMeter[0] >= (u8)tmpRegA)        //lower temprature
 923        {
 924                tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
 925                tmpCCK40Mindex = tmpCCK20Mindex - 6;
 926                if(tmpOFDMindex >= OFDM_Table_Length)
 927                        tmpOFDMindex = OFDM_Table_Length-1;
 928                if(tmpCCK20Mindex >= CCK_Table_length)
 929                        tmpCCK20Mindex = CCK_Table_length-1;
 930                if(tmpCCK40Mindex >= CCK_Table_length)
 931                        tmpCCK40Mindex = CCK_Table_length-1;
 932        }
 933        else
 934        {
 935                tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
 936                if(tmpval >= 6)                                                         // higher temprature
 937                        tmpOFDMindex = tmpCCK20Mindex = 0;              // max to +6dB
 938                else
 939                        tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
 940                tmpCCK40Mindex = 0;
 941        }
 942        //DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
 943                //((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
 944                //tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);
 945        if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)       //40M
 946                tmpCCKindex = tmpCCK40Mindex;
 947        else
 948                tmpCCKindex = tmpCCK20Mindex;
 949
 950        if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
 951        {
 952                priv->bcck_in_ch14 = TRUE;
 953                CCKSwingNeedUpdate = 1;
 954        }
 955        else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
 956        {
 957                priv->bcck_in_ch14 = FALSE;
 958                CCKSwingNeedUpdate = 1;
 959        }
 960
 961        if(priv->CCK_index != tmpCCKindex)
 962        {
 963                priv->CCK_index = tmpCCKindex;
 964                CCKSwingNeedUpdate = 1;
 965        }
 966
 967        if(CCKSwingNeedUpdate)
 968        {
 969                //DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);
 970                dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
 971        }
 972        if(priv->OFDM_index != tmpOFDMindex)
 973        {
 974                priv->OFDM_index = tmpOFDMindex;
 975                rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
 976                RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
 977                        priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
 978        }
 979        priv->txpower_count = 0;
 980}
 981
 982extern  void    dm_txpower_trackingcallback(struct work_struct *work)
 983{
 984        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
 985       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
 986       struct net_device *dev = priv->ieee80211->dev;
 987
 988#ifdef RTL8190P
 989        dm_TXPowerTrackingCallback_TSSI(dev);
 990#else
 991        if(priv->bDcut == TRUE)
 992                dm_TXPowerTrackingCallback_TSSI(dev);
 993        else
 994                dm_TXPowerTrackingCallback_ThermalMeter(dev);
 995#endif
 996}
 997
 998
 999static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
1000{
1001
1002        struct r8192_priv *priv = ieee80211_priv(dev);
1003
1004        //Initial the Tx BB index and mapping value
1005        priv->txbbgain_table[0].txbb_iq_amplifygain =                   12;
1006        priv->txbbgain_table[0].txbbgain_value=0x7f8001fe;
1007        priv->txbbgain_table[1].txbb_iq_amplifygain =                   11;
1008        priv->txbbgain_table[1].txbbgain_value=0x788001e2;
1009        priv->txbbgain_table[2].txbb_iq_amplifygain =                   10;
1010        priv->txbbgain_table[2].txbbgain_value=0x71c001c7;
1011        priv->txbbgain_table[3].txbb_iq_amplifygain =                   9;
1012        priv->txbbgain_table[3].txbbgain_value=0x6b8001ae;
1013        priv->txbbgain_table[4].txbb_iq_amplifygain =                  8;
1014        priv->txbbgain_table[4].txbbgain_value=0x65400195;
1015        priv->txbbgain_table[5].txbb_iq_amplifygain =                  7;
1016        priv->txbbgain_table[5].txbbgain_value=0x5fc0017f;
1017        priv->txbbgain_table[6].txbb_iq_amplifygain =                  6;
1018        priv->txbbgain_table[6].txbbgain_value=0x5a400169;
1019        priv->txbbgain_table[7].txbb_iq_amplifygain =                  5;
1020        priv->txbbgain_table[7].txbbgain_value=0x55400155;
1021        priv->txbbgain_table[8].txbb_iq_amplifygain =                  4;
1022        priv->txbbgain_table[8].txbbgain_value=0x50800142;
1023        priv->txbbgain_table[9].txbb_iq_amplifygain =                  3;
1024        priv->txbbgain_table[9].txbbgain_value=0x4c000130;
1025        priv->txbbgain_table[10].txbb_iq_amplifygain =                 2;
1026        priv->txbbgain_table[10].txbbgain_value=0x47c0011f;
1027        priv->txbbgain_table[11].txbb_iq_amplifygain =                 1;
1028        priv->txbbgain_table[11].txbbgain_value=0x43c0010f;
1029        priv->txbbgain_table[12].txbb_iq_amplifygain =                 0;
1030        priv->txbbgain_table[12].txbbgain_value=0x40000100;
1031        priv->txbbgain_table[13].txbb_iq_amplifygain =                 -1;
1032        priv->txbbgain_table[13].txbbgain_value=0x3c8000f2;
1033        priv->txbbgain_table[14].txbb_iq_amplifygain =               -2;
1034        priv->txbbgain_table[14].txbbgain_value=0x390000e4;
1035        priv->txbbgain_table[15].txbb_iq_amplifygain =               -3;
1036        priv->txbbgain_table[15].txbbgain_value=0x35c000d7;
1037        priv->txbbgain_table[16].txbb_iq_amplifygain =               -4;
1038        priv->txbbgain_table[16].txbbgain_value=0x32c000cb;
1039        priv->txbbgain_table[17].txbb_iq_amplifygain =               -5;
1040        priv->txbbgain_table[17].txbbgain_value=0x300000c0;
1041        priv->txbbgain_table[18].txbb_iq_amplifygain =                      -6;
1042        priv->txbbgain_table[18].txbbgain_value=0x2d4000b5;
1043        priv->txbbgain_table[19].txbb_iq_amplifygain =               -7;
1044        priv->txbbgain_table[19].txbbgain_value=0x2ac000ab;
1045        priv->txbbgain_table[20].txbb_iq_amplifygain =               -8;
1046        priv->txbbgain_table[20].txbbgain_value=0x288000a2;
1047        priv->txbbgain_table[21].txbb_iq_amplifygain =               -9;
1048        priv->txbbgain_table[21].txbbgain_value=0x26000098;
1049        priv->txbbgain_table[22].txbb_iq_amplifygain =               -10;
1050        priv->txbbgain_table[22].txbbgain_value=0x24000090;
1051        priv->txbbgain_table[23].txbb_iq_amplifygain =               -11;
1052        priv->txbbgain_table[23].txbbgain_value=0x22000088;
1053        priv->txbbgain_table[24].txbb_iq_amplifygain =               -12;
1054        priv->txbbgain_table[24].txbbgain_value=0x20000080;
1055        priv->txbbgain_table[25].txbb_iq_amplifygain =               -13;
1056        priv->txbbgain_table[25].txbbgain_value=0x1a00006c;
1057        priv->txbbgain_table[26].txbb_iq_amplifygain =               -14;
1058        priv->txbbgain_table[26].txbbgain_value=0x1c800072;
1059        priv->txbbgain_table[27].txbb_iq_amplifygain =               -15;
1060        priv->txbbgain_table[27].txbbgain_value=0x18000060;
1061        priv->txbbgain_table[28].txbb_iq_amplifygain =               -16;
1062        priv->txbbgain_table[28].txbbgain_value=0x19800066;
1063        priv->txbbgain_table[29].txbb_iq_amplifygain =               -17;
1064        priv->txbbgain_table[29].txbbgain_value=0x15800056;
1065        priv->txbbgain_table[30].txbb_iq_amplifygain =               -18;
1066        priv->txbbgain_table[30].txbbgain_value=0x26c0005b;
1067        priv->txbbgain_table[31].txbb_iq_amplifygain =               -19;
1068        priv->txbbgain_table[31].txbbgain_value=0x14400051;
1069        priv->txbbgain_table[32].txbb_iq_amplifygain =               -20;
1070        priv->txbbgain_table[32].txbbgain_value=0x24400051;
1071        priv->txbbgain_table[33].txbb_iq_amplifygain =               -21;
1072        priv->txbbgain_table[33].txbbgain_value=0x1300004c;
1073        priv->txbbgain_table[34].txbb_iq_amplifygain =               -22;
1074        priv->txbbgain_table[34].txbbgain_value=0x12000048;
1075        priv->txbbgain_table[35].txbb_iq_amplifygain =               -23;
1076        priv->txbbgain_table[35].txbbgain_value=0x11000044;
1077        priv->txbbgain_table[36].txbb_iq_amplifygain =               -24;
1078        priv->txbbgain_table[36].txbbgain_value=0x10000040;
1079
1080        //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
1081        //This Table is for CH1~CH13
1082        priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
1083        priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
1084        priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
1085        priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25;
1086        priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c;
1087        priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12;
1088        priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09;
1089        priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04;
1090
1091        priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33;
1092        priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32;
1093        priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b;
1094        priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23;
1095        priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a;
1096        priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11;
1097        priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08;
1098        priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04;
1099
1100        priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30;
1101        priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f;
1102        priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29;
1103        priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21;
1104        priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19;
1105        priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10;
1106        priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08;
1107        priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03;
1108
1109        priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d;
1110        priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d;
1111        priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27;
1112        priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f;
1113        priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18;
1114        priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f;
1115        priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08;
1116        priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03;
1117
1118        priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b;
1119        priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a;
1120        priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25;
1121        priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e;
1122        priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16;
1123        priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e;
1124        priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07;
1125        priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03;
1126
1127        priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28;
1128        priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28;
1129        priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22;
1130        priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c;
1131        priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15;
1132        priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d;
1133        priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07;
1134        priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03;
1135
1136        priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26;
1137        priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25;
1138        priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21;
1139        priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b;
1140        priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14;
1141        priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d;
1142        priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06;
1143        priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03;
1144
1145        priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24;
1146        priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23;
1147        priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f;
1148        priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19;
1149        priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13;
1150        priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c;
1151        priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06;
1152        priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03;
1153
1154        priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22;
1155        priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21;
1156        priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d;
1157        priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18;
1158        priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11;
1159        priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b;
1160        priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06;
1161        priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02;
1162
1163        priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20;
1164        priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20;
1165        priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b;
1166        priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16;
1167        priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11;
1168        priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08;
1169        priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05;
1170        priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02;
1171
1172        priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f;
1173        priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e;
1174        priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a;
1175        priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15;
1176        priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10;
1177        priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a;
1178        priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05;
1179        priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02;
1180
1181        priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d;
1182        priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c;
1183        priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18;
1184        priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14;
1185        priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f;
1186        priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a;
1187        priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05;
1188        priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02;
1189
1190        priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b;
1191        priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a;
1192        priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17;
1193        priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13;
1194        priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e;
1195        priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09;
1196        priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04;
1197        priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02;
1198
1199        priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a;
1200        priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19;
1201        priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16;
1202        priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12;
1203        priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d;
1204        priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09;
1205        priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04;
1206        priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02;
1207
1208        priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18;
1209        priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17;
1210        priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15;
1211        priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11;
1212        priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c;
1213        priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08;
1214        priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04;
1215        priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02;
1216
1217        priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17;
1218        priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16;
1219        priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13;
1220        priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10;
1221        priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c;
1222        priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08;
1223        priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04;
1224        priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02;
1225
1226        priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16;
1227        priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15;
1228        priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12;
1229        priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f;
1230        priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b;
1231        priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07;
1232        priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04;
1233        priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01;
1234
1235        priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14;
1236        priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14;
1237        priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11;
1238        priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e;
1239        priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b;
1240        priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07;
1241        priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03;
1242        priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02;
1243
1244        priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13;
1245        priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13;
1246        priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10;
1247        priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d;
1248        priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a;
1249        priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06;
1250        priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03;
1251        priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01;
1252
1253        priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12;
1254        priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12;
1255        priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f;
1256        priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c;
1257        priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09;
1258        priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06;
1259        priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03;
1260        priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01;
1261
1262        priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11;
1263        priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11;
1264        priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f;
1265        priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c;
1266        priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09;
1267        priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06;
1268        priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03;
1269        priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01;
1270
1271        priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10;
1272        priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10;
1273        priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e;
1274        priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b;
1275        priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08;
1276        priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05;
1277        priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03;
1278        priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01;
1279
1280        priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f;
1281        priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f;
1282        priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d;
1283        priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b;
1284        priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08;
1285        priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05;
1286        priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
1287        priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
1288
1289        //ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
1290        //This Table is for CH14
1291        priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
1292        priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
1293        priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
1294        priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b;
1295        priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00;
1296        priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00;
1297        priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00;
1298        priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00;
1299
1300        priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33;
1301        priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32;
1302        priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b;
1303        priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19;
1304        priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00;
1305        priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00;
1306        priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00;
1307        priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00;
1308
1309        priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30;
1310        priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f;
1311        priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29;
1312        priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18;
1313        priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00;
1314        priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00;
1315        priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00;
1316        priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00;
1317
1318        priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d;
1319        priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d;
1320        priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27;
1321        priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17;
1322        priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00;
1323        priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00;
1324        priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00;
1325        priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00;
1326
1327        priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b;
1328        priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a;
1329        priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25;
1330        priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15;
1331        priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00;
1332        priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00;
1333        priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00;
1334        priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00;
1335
1336        priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28;
1337        priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28;
1338        priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22;
1339        priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14;
1340        priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00;
1341        priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00;
1342        priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00;
1343        priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00;
1344
1345        priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26;
1346        priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25;
1347        priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21;
1348        priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13;
1349        priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00;
1350        priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00;
1351        priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00;
1352        priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00;
1353
1354        priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24;
1355        priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23;
1356        priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f;
1357        priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12;
1358        priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00;
1359        priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00;
1360        priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00;
1361        priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00;
1362
1363        priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22;
1364        priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21;
1365        priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d;
1366        priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11;
1367        priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00;
1368        priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00;
1369        priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00;
1370        priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00;
1371
1372        priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20;
1373        priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20;
1374        priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b;
1375        priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10;
1376        priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00;
1377        priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00;
1378        priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00;
1379        priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00;
1380
1381        priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f;
1382        priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e;
1383        priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a;
1384        priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f;
1385        priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00;
1386        priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00;
1387        priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00;
1388        priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00;
1389
1390        priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d;
1391        priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c;
1392        priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18;
1393        priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e;
1394        priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00;
1395        priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00;
1396        priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00;
1397        priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00;
1398
1399        priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b;
1400        priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a;
1401        priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17;
1402        priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e;
1403        priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00;
1404        priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00;
1405        priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00;
1406        priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00;
1407
1408        priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a;
1409        priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19;
1410        priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16;
1411        priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d;
1412        priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00;
1413        priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00;
1414        priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00;
1415        priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00;
1416
1417        priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18;
1418        priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17;
1419        priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15;
1420        priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c;
1421        priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00;
1422        priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00;
1423        priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00;
1424        priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00;
1425
1426        priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17;
1427        priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16;
1428        priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13;
1429        priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b;
1430        priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00;
1431        priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00;
1432        priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00;
1433        priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00;
1434
1435        priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16;
1436        priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15;
1437        priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12;
1438        priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b;
1439        priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00;
1440        priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00;
1441        priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00;
1442        priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00;
1443
1444        priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14;
1445        priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14;
1446        priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11;
1447        priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a;
1448        priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00;
1449        priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00;
1450        priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00;
1451        priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00;
1452
1453        priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13;
1454        priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13;
1455        priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10;
1456        priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a;
1457        priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00;
1458        priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00;
1459        priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00;
1460        priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00;
1461
1462        priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12;
1463        priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12;
1464        priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f;
1465        priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09;
1466        priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00;
1467        priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00;
1468        priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00;
1469        priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00;
1470
1471        priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11;
1472        priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11;
1473        priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f;
1474        priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09;
1475        priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00;
1476        priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00;
1477        priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00;
1478        priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00;
1479
1480        priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10;
1481        priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10;
1482        priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e;
1483        priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08;
1484        priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00;
1485        priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00;
1486        priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00;
1487        priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00;
1488
1489        priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f;
1490        priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f;
1491        priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d;
1492        priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08;
1493        priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00;
1494        priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00;
1495        priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00;
1496        priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00;
1497
1498        priv->btxpower_tracking = TRUE;
1499        priv->txpower_count       = 0;
1500        priv->btxpower_trackingInit = FALSE;
1501
1502}
1503
1504
1505void dm_initialize_txpower_tracking(struct net_device *dev)
1506{
1507#if (defined RTL8190P)
1508        dm_InitializeTXPowerTracking_TSSI(dev);
1509#else
1510        // 2009/01/12 MH Enable for 92S series channel 1-14 CCK tx pwer setting for MP.
1511        //
1512        dm_InitializeTXPowerTracking_TSSI(dev);
1513#endif
1514}// dm_InitializeTXPowerTracking
1515
1516
1517static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
1518{
1519        struct r8192_priv *priv = ieee80211_priv(dev);
1520        static u32 tx_power_track_counter = 0;
1521
1522        if(!priv->btxpower_tracking)
1523                return;
1524        else
1525        {
1526                if((tx_power_track_counter % 30 == 0)&&(tx_power_track_counter != 0))
1527                {
1528                                queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
1529                }
1530                tx_power_track_counter++;
1531        }
1532
1533}
1534
1535
1536static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1537{
1538        struct r8192_priv *priv = ieee80211_priv(dev);
1539        static u8       TM_Trigger=0;
1540
1541        //DbgPrint("dm_CheckTXPowerTracking() \n");
1542        if(!priv->btxpower_tracking)
1543                return;
1544        else
1545        {
1546                if(priv->txpower_count  <= 2)
1547                {
1548                        priv->txpower_count++;
1549                        return;
1550                }
1551        }
1552
1553        if(!TM_Trigger)
1554        {
1555                //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash
1556                //actually write reg0x02 bit1=0, then bit1=1.
1557                //DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
1558                rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4d);
1559                rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4f);
1560                rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4d);
1561                rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bRFRegOffsetMask, 0x4f);
1562                TM_Trigger = 1;
1563                return;
1564        }
1565        else
1566        {
1567                //DbgPrint("Schedule TxPowerTrackingWorkItem\n");
1568                        queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
1569                TM_Trigger = 0;
1570        }
1571}
1572
1573
1574static void dm_check_txpower_tracking(struct net_device *dev)
1575{
1576        struct r8192_priv *priv = ieee80211_priv(dev);
1577        //static u32 tx_power_track_counter = 0;
1578
1579#ifdef  RTL8190P
1580        dm_CheckTXPowerTracking_TSSI(dev);
1581#else
1582        if(priv->bDcut == TRUE)
1583                dm_CheckTXPowerTracking_TSSI(dev);
1584        else
1585                dm_CheckTXPowerTracking_ThermalMeter(dev);
1586#endif
1587
1588}       // dm_CheckTXPowerTracking
1589
1590
1591static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool  bInCH14)
1592{
1593        u32 TempVal;
1594        struct r8192_priv *priv = ieee80211_priv(dev);
1595        //Write 0xa22 0xa23
1596        TempVal = 0;
1597        if(!bInCH14){
1598                //Write 0xa22 0xa23
1599                TempVal =       priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
1600                                        (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ;
1601
1602                rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
1603                //Write 0xa24 ~ 0xa27
1604                TempVal = 0;
1605                TempVal =       priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
1606                                        (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
1607                                        (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16 )+
1608                                        (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
1609                rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
1610                //Write 0xa28  0xa29
1611                TempVal = 0;
1612                TempVal =       priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
1613                                        (priv->cck_txbbgain_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ;
1614
1615                rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
1616        }
1617        else
1618        {
1619                TempVal =       priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[0] +
1620                                        (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[1]<<8) ;
1621
1622                rtl8192_setBBreg(dev, rCCK0_TxFilter1,bMaskHWord, TempVal);
1623                //Write 0xa24 ~ 0xa27
1624                TempVal = 0;
1625                TempVal =       priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[2] +
1626                                        (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[3]<<8) +
1627                                        (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[4]<<16 )+
1628                                        (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[5]<<24);
1629                rtl8192_setBBreg(dev, rCCK0_TxFilter2,bMaskDWord, TempVal);
1630                //Write 0xa28  0xa29
1631                TempVal = 0;
1632                TempVal =       priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[6] +
1633                                        (priv->cck_txbbgain_ch14_table[priv->cck_present_attentuation].ccktxbb_valuearray[7]<<8) ;
1634
1635                rtl8192_setBBreg(dev, rCCK0_DebugPort,bMaskLWord, TempVal);
1636        }
1637
1638
1639}
1640
1641static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev,    bool  bInCH14)
1642{
1643        u32 TempVal;
1644        struct r8192_priv *priv = ieee80211_priv(dev);
1645
1646        TempVal = 0;
1647        if(!bInCH14)
1648        {
1649                //Write 0xa22 0xa23
1650                TempVal =       CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1651                                        (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
1652                rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1653                RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1654                        rCCK0_TxFilter1, TempVal);
1655                //Write 0xa24 ~ 0xa27
1656                TempVal = 0;
1657                TempVal =       CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1658                                        (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1659                                        (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+
1660                                        (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1661                rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1662                RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1663                        rCCK0_TxFilter2, TempVal);
1664                //Write 0xa28  0xa29
1665                TempVal = 0;
1666                TempVal =       CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1667                                        (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
1668
1669                rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1670                RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1671                        rCCK0_DebugPort, TempVal);
1672        }
1673        else
1674        {
1675//              priv->CCKTxPowerAdjustCntNotCh14++;     //cosa add for debug.
1676                //Write 0xa22 0xa23
1677                TempVal =       CCKSwingTable_Ch14[priv->CCK_index][0] +
1678                                        (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
1679
1680                rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1681                RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1682                        rCCK0_TxFilter1, TempVal);
1683                //Write 0xa24 ~ 0xa27
1684                TempVal = 0;
1685                TempVal =       CCKSwingTable_Ch14[priv->CCK_index][2] +
1686                                        (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1687                                        (CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+
1688                                        (CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1689                rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1690                RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1691                        rCCK0_TxFilter2, TempVal);
1692                //Write 0xa28  0xa29
1693                TempVal = 0;
1694                TempVal =       CCKSwingTable_Ch14[priv->CCK_index][6] +
1695                                        (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
1696
1697                rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1698                RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n",
1699                        rCCK0_DebugPort, TempVal);
1700        }
1701}
1702
1703
1704
1705extern void dm_cck_txpower_adjust(
1706        struct net_device *dev,
1707        bool  binch14
1708)
1709{       // dm_CCKTxPowerAdjust
1710
1711        struct r8192_priv *priv = ieee80211_priv(dev);
1712#ifdef RTL8190P
1713        dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1714#else
1715        if(priv->bDcut == TRUE)
1716                dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1717        else
1718                dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
1719#endif
1720}
1721
1722
1723#ifndef  RTL8192U
1724static void dm_txpower_reset_recovery(
1725        struct net_device *dev
1726)
1727{
1728        struct r8192_priv *priv = ieee80211_priv(dev);
1729
1730        RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1731        rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1732        RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1733        RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",priv->rfa_txpowertrackingindex);
1734        RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF A I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbb_iq_amplifygain);
1735        RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n",priv->cck_present_attentuation);
1736        dm_cck_txpower_adjust(dev,priv->bcck_in_ch14);
1737
1738        rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1739        RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1740        RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",priv->rfc_txpowertrackingindex);
1741        RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery : RF C I/Q Amplify Gain is %ld\n",priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbb_iq_amplifygain);
1742
1743}       // dm_TXPowerResetRecovery
1744
1745extern void dm_restore_dynamic_mechanism_state(struct net_device *dev)
1746{
1747        struct r8192_priv *priv = ieee80211_priv(dev);
1748        u32     reg_ratr = priv->rate_adaptive.last_ratr;
1749
1750        if(!priv->up)
1751        {
1752                RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
1753                return;
1754        }
1755
1756        //
1757        // Restore previous state for rate adaptive
1758        //
1759        if(priv->rate_adaptive.rate_adaptive_disabled)
1760                return;
1761        // TODO: Only 11n mode is implemented currently,
1762        if( !(priv->ieee80211->mode==WIRELESS_MODE_N_24G ||
1763                 priv->ieee80211->mode==WIRELESS_MODE_N_5G))
1764                 return;
1765        {
1766                        /* 2007/11/15 MH Copy from 8190PCI. */
1767                        u32 ratr_value;
1768                        ratr_value = reg_ratr;
1769                        if(priv->rf_type == RF_1T2R)    // 1T2R, Spatial Stream 2 should be disabled
1770                        {
1771                                ratr_value &=~ (RATE_ALL_OFDM_2SS);
1772                                //DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);
1773                        }
1774                        //DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);
1775                        //cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);
1776                        write_nic_dword(dev, RATR0, ratr_value);
1777                        write_nic_byte(dev, UFWP, 1);
1778        }
1779        //Resore TX Power Tracking Index
1780        if(priv->btxpower_trackingInit && priv->btxpower_tracking){
1781                dm_txpower_reset_recovery(dev);
1782        }
1783
1784        //
1785        //Restore BB Initial Gain
1786        //
1787        dm_bb_initialgain_restore(dev);
1788
1789}       // DM_RestoreDynamicMechanismState
1790
1791static void dm_bb_initialgain_restore(struct net_device *dev)
1792{
1793        struct r8192_priv *priv = ieee80211_priv(dev);
1794        u32 bit_mask = 0x7f; //Bit0~ Bit6
1795
1796        if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1797                return;
1798
1799        //Disable Initial Gain
1800        //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
1801        rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   // Only clear byte 1 and rewrite.
1802        rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
1803        rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
1804        rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
1805        rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
1806        bit_mask  = bMaskByte2;
1807        rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
1808
1809        RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
1810        RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
1811        RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
1812        RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
1813        RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",priv->initgain_backup.cca);
1814        //Enable Initial Gain
1815        //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);
1816        rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);   // Only clear byte 1 and rewrite.
1817
1818}       // dm_BBInitialGainRestore
1819
1820
1821extern void dm_backup_dynamic_mechanism_state(struct net_device *dev)
1822{
1823        struct r8192_priv *priv = ieee80211_priv(dev);
1824
1825        // Fsync to avoid reset
1826        priv->bswitch_fsync  = false;
1827        priv->bfsync_processing = false;
1828        //Backup BB InitialGain
1829        dm_bb_initialgain_backup(dev);
1830
1831}       // DM_BackupDynamicMechanismState
1832
1833
1834static void dm_bb_initialgain_backup(struct net_device *dev)
1835{
1836        struct r8192_priv *priv = ieee80211_priv(dev);
1837        u32 bit_mask = bMaskByte0; //Bit0~ Bit6
1838
1839        if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1840                return;
1841
1842        //PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);
1843        rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   // Only clear byte 1 and rewrite.
1844        priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
1845        priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
1846        priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
1847        priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
1848        bit_mask  = bMaskByte2;
1849        priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
1850
1851        RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",priv->initgain_backup.xaagccore1);
1852        RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",priv->initgain_backup.xbagccore1);
1853        RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",priv->initgain_backup.xcagccore1);
1854        RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",priv->initgain_backup.xdagccore1);
1855        RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",priv->initgain_backup.cca);
1856
1857}   // dm_BBInitialGainBakcup
1858
1859#endif
1860/*-----------------------------------------------------------------------------
1861 * Function:    dm_change_dynamic_initgain_thresh()
1862 *
1863 * Overview:
1864 *
1865 * Input:               NONE
1866 *
1867 * Output:              NONE
1868 *
1869 * Return:              NONE
1870 *
1871 * Revised History:
1872 *      When            Who             Remark
1873 *      05/29/2008      amy             Create Version 0 porting from windows code.
1874 *
1875 *---------------------------------------------------------------------------*/
1876extern void dm_change_dynamic_initgain_thresh(struct net_device *dev,
1877                                                                u32             dm_type,
1878                                                                u32             dm_value)
1879{
1880        struct r8192_priv *priv = ieee80211_priv(dev);
1881        if(dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
1882                priv->MidHighPwrTHR_L2 = (u8)dm_value;
1883        else if(dm_type == DIG_TYPE_THRESH_HIGHPWR_LOW)
1884                priv->MidHighPwrTHR_L1 = (u8)dm_value;
1885        return;
1886        if (dm_type == DIG_TYPE_THRESH_HIGH)
1887        {
1888                dm_digtable.rssi_high_thresh = dm_value;
1889        }
1890        else if (dm_type == DIG_TYPE_THRESH_LOW)
1891        {
1892                dm_digtable.rssi_low_thresh = dm_value;
1893        }
1894        else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
1895        {
1896                dm_digtable.rssi_high_power_highthresh = dm_value;
1897        }
1898        else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH)
1899        {
1900                dm_digtable.rssi_high_power_highthresh = dm_value;
1901        }
1902        else if (dm_type == DIG_TYPE_ENABLE)
1903        {
1904                dm_digtable.dig_state           = DM_STA_DIG_MAX;
1905                dm_digtable.dig_enable_flag     = true;
1906        }
1907        else if (dm_type == DIG_TYPE_DISABLE)
1908        {
1909                dm_digtable.dig_state           = DM_STA_DIG_MAX;
1910                dm_digtable.dig_enable_flag     = false;
1911        }
1912        else if (dm_type == DIG_TYPE_DBG_MODE)
1913        {
1914                if(dm_value >= DM_DBG_MAX)
1915                        dm_value = DM_DBG_OFF;
1916                dm_digtable.dbg_mode            = (u8)dm_value;
1917        }
1918        else if (dm_type == DIG_TYPE_RSSI)
1919        {
1920                if(dm_value > 100)
1921                        dm_value = 30;
1922                dm_digtable.rssi_val                    = (long)dm_value;
1923        }
1924        else if (dm_type == DIG_TYPE_ALGORITHM)
1925        {
1926                if (dm_value >= DIG_ALGO_MAX)
1927                        dm_value = DIG_ALGO_BY_FALSE_ALARM;
1928                if(dm_digtable.dig_algorithm != (u8)dm_value)
1929                        dm_digtable.dig_algorithm_switch = 1;
1930                dm_digtable.dig_algorithm       = (u8)dm_value;
1931        }
1932        else if (dm_type == DIG_TYPE_BACKOFF)
1933        {
1934                if(dm_value > 30)
1935                        dm_value = 30;
1936                dm_digtable.backoff_val         = (u8)dm_value;
1937        }
1938        else if(dm_type == DIG_TYPE_RX_GAIN_MIN)
1939        {
1940                if(dm_value == 0)
1941                        dm_value = 0x1;
1942                dm_digtable.rx_gain_range_min = (u8)dm_value;
1943        }
1944        else if(dm_type == DIG_TYPE_RX_GAIN_MAX)
1945        {
1946                if(dm_value > 0x50)
1947                        dm_value = 0x50;
1948                dm_digtable.rx_gain_range_max = (u8)dm_value;
1949        }
1950}       /* DM_ChangeDynamicInitGainThresh */
1951extern  void
1952dm_change_fsync_setting(
1953        struct net_device *dev,
1954        s32             DM_Type,
1955        s32             DM_Value)
1956{
1957        struct r8192_priv *priv = ieee80211_priv(dev);
1958
1959        if (DM_Type == 0)       // monitor 0xc38 register
1960        {
1961                if(DM_Value > 1)
1962                        DM_Value = 1;
1963                priv->framesyncMonitor = (u8)DM_Value;
1964                //DbgPrint("pHalData->framesyncMonitor = %d", pHalData->framesyncMonitor);
1965        }
1966}
1967
1968extern void
1969dm_change_rxpath_selection_setting(
1970        struct net_device *dev,
1971        s32             DM_Type,
1972        s32             DM_Value)
1973{
1974        struct r8192_priv *priv = ieee80211_priv(dev);
1975        prate_adaptive  pRA = (prate_adaptive)&(priv->rate_adaptive);
1976
1977
1978        if(DM_Type == 0)
1979        {
1980                if(DM_Value > 1)
1981                        DM_Value = 1;
1982                DM_RxPathSelTable.Enable = (u8)DM_Value;
1983        }
1984        else if(DM_Type == 1)
1985        {
1986                if(DM_Value > 1)
1987                        DM_Value = 1;
1988                DM_RxPathSelTable.DbgMode = (u8)DM_Value;
1989        }
1990        else if(DM_Type == 2)
1991        {
1992                if(DM_Value > 40)
1993                        DM_Value = 40;
1994                DM_RxPathSelTable.SS_TH_low = (u8)DM_Value;
1995        }
1996        else if(DM_Type == 3)
1997        {
1998                if(DM_Value > 25)
1999                        DM_Value = 25;
2000                DM_RxPathSelTable.diff_TH = (u8)DM_Value;
2001        }
2002        else if(DM_Type == 4)
2003        {
2004                if(DM_Value >= CCK_Rx_Version_MAX)
2005                        DM_Value = CCK_Rx_Version_1;
2006                DM_RxPathSelTable.cck_method= (u8)DM_Value;
2007        }
2008        else if(DM_Type == 10)
2009        {
2010                if(DM_Value > 100)
2011                        DM_Value = 50;
2012                DM_RxPathSelTable.rf_rssi[0] = (u8)DM_Value;
2013        }
2014        else if(DM_Type == 11)
2015        {
2016                if(DM_Value > 100)
2017                        DM_Value = 50;
2018                DM_RxPathSelTable.rf_rssi[1] = (u8)DM_Value;
2019        }
2020        else if(DM_Type == 12)
2021        {
2022                if(DM_Value > 100)
2023                        DM_Value = 50;
2024                DM_RxPathSelTable.rf_rssi[2] = (u8)DM_Value;
2025        }
2026        else if(DM_Type == 13)
2027        {
2028                if(DM_Value > 100)
2029                        DM_Value = 50;
2030                DM_RxPathSelTable.rf_rssi[3] = (u8)DM_Value;
2031        }
2032        else if(DM_Type == 20)
2033        {
2034                if(DM_Value > 1)
2035                        DM_Value = 1;
2036                pRA->ping_rssi_enable = (u8)DM_Value;
2037        }
2038        else if(DM_Type == 21)
2039        {
2040                if(DM_Value > 30)
2041                        DM_Value = 30;
2042                pRA->ping_rssi_thresh_for_ra = DM_Value;
2043        }
2044}
2045
2046/*-----------------------------------------------------------------------------
2047 * Function:    dm_dig_init()
2048 *
2049 * Overview:    Set DIG scheme init value.
2050 *
2051 * Input:               NONE
2052 *
2053 * Output:              NONE
2054 *
2055 * Return:              NONE
2056 *
2057 * Revised History:
2058 *      When            Who             Remark
2059 *      05/15/2008      amy             Create Version 0 porting from windows code.
2060 *
2061 *---------------------------------------------------------------------------*/
2062static void dm_dig_init(struct net_device *dev)
2063{
2064        struct r8192_priv *priv = ieee80211_priv(dev);
2065        /* 2007/10/05 MH Disable DIG scheme now. Not tested. */
2066        dm_digtable.dig_enable_flag     = true;
2067        dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
2068        dm_digtable.dbg_mode = DM_DBG_OFF;      //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
2069        dm_digtable.dig_algorithm_switch = 0;
2070
2071        /* 2007/10/04 MH Define init gain threshol. */
2072        dm_digtable.dig_state           = DM_STA_DIG_MAX;
2073        dm_digtable.dig_highpwr_state   = DM_STA_DIG_MAX;
2074        dm_digtable.initialgain_lowerbound_state = false;
2075
2076        dm_digtable.rssi_low_thresh     = DM_DIG_THRESH_LOW;
2077        dm_digtable.rssi_high_thresh    = DM_DIG_THRESH_HIGH;
2078
2079        dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
2080        dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
2081
2082        dm_digtable.rssi_val = 50;      //for new dig debug rssi value
2083        dm_digtable.backoff_val = DM_DIG_BACKOFF;
2084        dm_digtable.rx_gain_range_max = DM_DIG_MAX;
2085        if(priv->CustomerID == RT_CID_819x_Netcore)
2086                dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
2087        else
2088                dm_digtable.rx_gain_range_min = DM_DIG_MIN;
2089
2090}       /* dm_dig_init */
2091
2092
2093/*-----------------------------------------------------------------------------
2094 * Function:    dm_ctrl_initgain_byrssi()
2095 *
2096 * Overview:    Driver must monitor RSSI and notify firmware to change initial
2097 *                              gain according to different threshold. BB team provide the
2098 *                              suggested solution.
2099 *
2100 * Input:                       struct net_device *dev
2101 *
2102 * Output:              NONE
2103 *
2104 * Return:              NONE
2105 *
2106 * Revised History:
2107 *      When            Who             Remark
2108 *      05/27/2008      amy             Create Version 0 porting from windows code.
2109 *---------------------------------------------------------------------------*/
2110static void dm_ctrl_initgain_byrssi(struct net_device *dev)
2111{
2112
2113        if (dm_digtable.dig_enable_flag == false)
2114                return;
2115
2116        if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
2117                dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
2118        else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
2119                dm_ctrl_initgain_byrssi_by_driverrssi(dev);
2120//              ;
2121        else
2122                return;
2123}
2124
2125
2126static void dm_ctrl_initgain_byrssi_by_driverrssi(
2127        struct net_device *dev)
2128{
2129        struct r8192_priv *priv = ieee80211_priv(dev);
2130        u8 i;
2131        static u8       fw_dig=0;
2132
2133        if (dm_digtable.dig_enable_flag == false)
2134                return;
2135
2136        //DbgPrint("Dig by Sw Rssi \n");
2137        if(dm_digtable.dig_algorithm_switch)    // if swithed algorithm, we have to disable FW Dig.
2138                fw_dig = 0;
2139        if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled
2140        {// FW DIG Off
2141                for(i=0; i<3; i++)
2142                        rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   // Only clear byte 1 and rewrite.
2143                fw_dig++;
2144                dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off.
2145        }
2146
2147        if(priv->ieee80211->state == IEEE80211_LINKED)
2148                dm_digtable.cur_connect_state = DIG_CONNECT;
2149        else
2150                dm_digtable.cur_connect_state = DIG_DISCONNECT;
2151
2152        //DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n",
2153                //DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);
2154
2155        if(dm_digtable.dbg_mode == DM_DBG_OFF)
2156                dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
2157        //DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val);
2158        dm_initial_gain(dev);
2159        dm_pd_th(dev);
2160        dm_cs_ratio(dev);
2161        if(dm_digtable.dig_algorithm_switch)
2162                dm_digtable.dig_algorithm_switch = 0;
2163        dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
2164
2165}       /* dm_CtrlInitGainByRssi */
2166
2167static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
2168        struct net_device *dev)
2169{
2170        struct r8192_priv *priv = ieee80211_priv(dev);
2171        static u32 reset_cnt = 0;
2172        u8 i;
2173
2174        if (dm_digtable.dig_enable_flag == false)
2175                return;
2176
2177        if(dm_digtable.dig_algorithm_switch)
2178        {
2179                dm_digtable.dig_state = DM_STA_DIG_MAX;
2180                // Fw DIG On.
2181                for(i=0; i<3; i++)
2182                        rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);   // Only clear byte 1 and rewrite.
2183                dm_digtable.dig_algorithm_switch = 0;
2184        }
2185
2186        if (priv->ieee80211->state != IEEE80211_LINKED)
2187                return;
2188
2189        // For smooth, we can not change DIG state.
2190        if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
2191                (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
2192        {
2193                return;
2194        }
2195        //DbgPrint("Dig by Fw False Alarm\n");
2196        //if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)
2197        /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
2198        pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
2199        DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
2200        /* 1. When RSSI decrease, We have to judge if it is smaller than a treshold
2201                  and then execute below step. */
2202        if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
2203        {
2204                /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
2205                   will be reset to init value. We must prevent the condition. */
2206                if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
2207                        (priv->reset_count == reset_cnt))
2208                {
2209                        return;
2210                }
2211                else
2212                {
2213                        reset_cnt = priv->reset_count;
2214                }
2215
2216                // If DIG is off, DIG high power state must reset.
2217                dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
2218                dm_digtable.dig_state = DM_STA_DIG_OFF;
2219
2220                // 1.1 DIG Off.
2221                rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   // Only clear byte 1 and rewrite.
2222
2223                // 1.2 Set initial gain.
2224                write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
2225                write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
2226                write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
2227                write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
2228
2229                // 1.3 Lower PD_TH for OFDM.
2230                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2231                {
2232                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2233                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2234                        rtl8192_setBBreg(dev, (rOFDM0_XATxAFE+3), bMaskByte0, 0x00);
2235                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2236                                write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
2237                        */
2238                        //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
2239
2240
2241                        //else
2242                                //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
2243                }
2244                else
2245                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2246
2247                // 1.4 Lower CS ratio for CCK.
2248                write_nic_byte(dev, 0xa0a, 0x08);
2249
2250                // 1.5 Higher EDCCA.
2251                //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
2252                return;
2253
2254        }
2255
2256        /* 2. When RSSI increase, We have to judge if it is larger than a treshold
2257                  and then execute below step.  */
2258        if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
2259        {
2260                u8 reset_flag = 0;
2261
2262                if (dm_digtable.dig_state == DM_STA_DIG_ON &&
2263                        (priv->reset_count == reset_cnt))
2264                {
2265                        dm_ctrl_initgain_byrssi_highpwr(dev);
2266                        return;
2267                }
2268                else
2269                {
2270                        if (priv->reset_count != reset_cnt)
2271                                reset_flag = 1;
2272
2273                        reset_cnt = priv->reset_count;
2274                }
2275
2276                dm_digtable.dig_state = DM_STA_DIG_ON;
2277                //DbgPrint("DIG ON\n\r");
2278
2279                // 2.1 Set initial gain.
2280                // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
2281                if (reset_flag == 1)
2282                {
2283                        write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
2284                        write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
2285                        write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
2286                        write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
2287                }
2288                else
2289                {
2290                        write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
2291                        write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
2292                        write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
2293                        write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
2294                }
2295
2296                // 2.2 Higher PD_TH for OFDM.
2297                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2298                {
2299                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2300                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2301                        #ifdef RTL8190P
2302                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2303                        #else
2304                                write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2305                        #endif
2306                        /*
2307                        else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2308                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2309                        */
2310                        //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
2311
2312                        //else
2313                                //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
2314                }
2315                else
2316                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2317
2318                // 2.3 Higher CS ratio for CCK.
2319                write_nic_byte(dev, 0xa0a, 0xcd);
2320
2321                // 2.4 Lower EDCCA.
2322                /* 2008/01/11 MH 90/92 series are the same. */
2323                //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
2324
2325                // 2.5 DIG On.
2326                rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);   // Only clear byte 1 and rewrite.
2327
2328        }
2329
2330        dm_ctrl_initgain_byrssi_highpwr(dev);
2331
2332}       /* dm_CtrlInitGainByRssi */
2333
2334
2335/*-----------------------------------------------------------------------------
2336 * Function:    dm_ctrl_initgain_byrssi_highpwr()
2337 *
2338 * Overview:
2339 *
2340 * Input:               NONE
2341 *
2342 * Output:              NONE
2343 *
2344 * Return:              NONE
2345 *
2346 * Revised History:
2347 *      When            Who             Remark
2348 *      05/28/2008      amy             Create Version 0 porting from windows code.
2349 *
2350 *---------------------------------------------------------------------------*/
2351static void dm_ctrl_initgain_byrssi_highpwr(
2352        struct net_device * dev)
2353{
2354        struct r8192_priv *priv = ieee80211_priv(dev);
2355        static u32 reset_cnt_highpwr = 0;
2356
2357        // For smooth, we can not change high power DIG state in the range.
2358        if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
2359                (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
2360        {
2361                return;
2362        }
2363
2364        /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
2365                  it is larger than a treshold and then execute below step.  */
2366        // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
2367        if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
2368        {
2369                if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
2370                        (priv->reset_count == reset_cnt_highpwr))
2371                        return;
2372                else
2373                        dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
2374
2375                // 3.1 Higher PD_TH for OFDM for high power state.
2376                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2377                {
2378                        rtl8192_setBBreg(dev, (rOFDM0_XATxAFE+3), bMaskByte0, 0x10);
2379                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2380                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2381                        */
2382
2383                }
2384                else
2385                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2386        }
2387        else
2388        {
2389                if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
2390                        (priv->reset_count == reset_cnt_highpwr))
2391                        return;
2392                else
2393                        dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
2394
2395                if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
2396                         priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
2397                {
2398                        // 3.2 Recover PD_TH for OFDM for normal power region.
2399                        if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2400                        {
2401                                #ifdef RTL8190P
2402                                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2403                                #else
2404                                        write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2405                                #endif
2406                                /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2407                                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2408                                */
2409
2410                        }
2411                        else
2412                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2413                }
2414        }
2415
2416        reset_cnt_highpwr = priv->reset_count;
2417
2418}       /* dm_CtrlInitGainByRssiHighPwr */
2419
2420
2421static void dm_initial_gain(
2422        struct net_device * dev)
2423{
2424        struct r8192_priv *priv = ieee80211_priv(dev);
2425        u8                                      initial_gain=0;
2426        static u8                               initialized=0, force_write=0;
2427        static u32                      reset_cnt=0;
2428
2429        if(dm_digtable.dig_algorithm_switch)
2430        {
2431                initialized = 0;
2432                reset_cnt = 0;
2433        }
2434
2435        if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
2436        {
2437                if(dm_digtable.cur_connect_state == DIG_CONNECT)
2438                {
2439                        if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
2440                                dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
2441                        else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
2442                                dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
2443                        else
2444                                dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
2445                }
2446                else            //current state is disconnected
2447                {
2448                        if(dm_digtable.cur_ig_value == 0)
2449                                dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2450                        else
2451                                dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
2452                }
2453        }
2454        else    // disconnected -> connected or connected -> disconnected
2455        {
2456                dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2457                dm_digtable.pre_ig_value = 0;
2458        }
2459        //DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);
2460
2461        // if silent reset happened, we should rewrite the values back
2462        if(priv->reset_count != reset_cnt)
2463        {
2464                force_write = 1;
2465                reset_cnt = priv->reset_count;
2466        }
2467
2468        if(dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1))
2469                force_write = 1;
2470
2471        {
2472                if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
2473                        || !initialized || force_write)
2474                {
2475                        initial_gain = (u8)dm_digtable.cur_ig_value;
2476                        //DbgPrint("Write initial gain = 0x%x\n", initial_gain);
2477                        // Set initial gain.
2478                        write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
2479                        write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
2480                        write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
2481                        write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
2482                        dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
2483                        initialized = 1;
2484                        force_write = 0;
2485                }
2486        }
2487}
2488
2489static void dm_pd_th(
2490        struct net_device * dev)
2491{
2492        struct r8192_priv *priv = ieee80211_priv(dev);
2493        static u8                               initialized=0, force_write=0;
2494        static u32                      reset_cnt = 0;
2495
2496        if(dm_digtable.dig_algorithm_switch)
2497        {
2498                initialized = 0;
2499                reset_cnt = 0;
2500        }
2501
2502        if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
2503        {
2504                if(dm_digtable.cur_connect_state == DIG_CONNECT)
2505                {
2506                        if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
2507                                dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
2508                        else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2509                                dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2510                        else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
2511                                        (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
2512                                dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
2513                        else
2514                                dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
2515                }
2516                else
2517                {
2518                        dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2519                }
2520        }
2521        else    // disconnected -> connected or connected -> disconnected
2522        {
2523                dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2524        }
2525
2526        // if silent reset happened, we should rewrite the values back
2527        if(priv->reset_count != reset_cnt)
2528        {
2529                force_write = 1;
2530                reset_cnt = priv->reset_count;
2531        }
2532
2533        {
2534                if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
2535                        (initialized<=3) || force_write)
2536                {
2537                        //DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);
2538                        if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
2539                        {
2540                                // Lower PD_TH for OFDM.
2541                                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2542                                {
2543                                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2544                                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2545                                        rtl8192_setBBreg(dev, (rOFDM0_XATxAFE+3), bMaskByte0, 0x00);
2546                                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2547                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2548                                        */
2549                                }
2550                                else
2551                                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2552                        }
2553                        else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
2554                        {
2555                                // Higher PD_TH for OFDM.
2556                                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2557                                {
2558                                        /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2559                                        // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2560                                        #ifdef RTL8190P
2561                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2562                                        #else
2563                                                write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2564                                        #endif
2565                                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2566                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2567                                        */
2568                                }
2569                                else
2570                                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2571                        }
2572                        else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
2573                        {
2574                                // Higher PD_TH for OFDM for high power state.
2575                                if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2576                                {
2577                                        #ifdef RTL8190P
2578                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2579                                        #else
2580                                                write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2581                                        #endif
2582                                        /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2583                                                write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2584                                        */
2585                                }
2586                                else
2587                                        write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2588                        }
2589                        dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
2590                        if(initialized <= 3)
2591                                initialized++;
2592                        force_write = 0;
2593                }
2594        }
2595}
2596
2597static  void dm_cs_ratio(
2598        struct net_device * dev)
2599{
2600        struct r8192_priv *priv = ieee80211_priv(dev);
2601        static u8                               initialized=0,force_write=0;
2602        static u32                      reset_cnt = 0;
2603
2604        if(dm_digtable.dig_algorithm_switch)
2605        {
2606                initialized = 0;
2607                reset_cnt = 0;
2608        }
2609
2610        if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
2611        {
2612                if(dm_digtable.cur_connect_state == DIG_CONNECT)
2613                {
2614                        if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2615                                dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2616                        else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) )
2617                                dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
2618                        else
2619                                dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
2620                }
2621                else
2622                {
2623                        dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2624                }
2625        }
2626        else    // disconnected -> connected or connected -> disconnected
2627        {
2628                dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2629        }
2630
2631        // if silent reset happened, we should rewrite the values back
2632        if(priv->reset_count != reset_cnt)
2633        {
2634                force_write = 1;
2635                reset_cnt = priv->reset_count;
2636        }
2637
2638
2639        {
2640                if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
2641                        !initialized || force_write)
2642                {
2643                        //DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);
2644                        if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
2645                        {
2646                                // Lower CS ratio for CCK.
2647                                write_nic_byte(dev, 0xa0a, 0x08);
2648                        }
2649                        else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
2650                        {
2651                                // Higher CS ratio for CCK.
2652                                write_nic_byte(dev, 0xa0a, 0xcd);
2653                        }
2654                        dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
2655                        initialized = 1;
2656                        force_write = 0;
2657                }
2658        }
2659}
2660
2661extern void dm_init_edca_turbo(struct net_device * dev)
2662{
2663        struct r8192_priv *priv = ieee80211_priv(dev);
2664
2665        priv->bcurrent_turbo_EDCA = false;
2666        priv->ieee80211->bis_any_nonbepkts = false;
2667        priv->bis_cur_rdlstate = false;
2668}       // dm_init_edca_turbo
2669
2670#if 1
2671static void dm_check_edca_turbo(
2672        struct net_device * dev)
2673{
2674        struct r8192_priv *priv = ieee80211_priv(dev);
2675        PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
2676        //PSTA_QOS                      pStaQos = pMgntInfo->pStaQos;
2677
2678        // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
2679        static unsigned long                    lastTxOkCnt = 0;
2680        static unsigned long                    lastRxOkCnt = 0;
2681        unsigned long                           curTxOkCnt = 0;
2682        unsigned long                           curRxOkCnt = 0;
2683
2684        //
2685        // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
2686        // should follow the settings from QAP. By Bruce, 2007-12-07.
2687        //
2688        #if 1
2689        if(priv->ieee80211->state != IEEE80211_LINKED)
2690                goto dm_CheckEdcaTurbo_EXIT;
2691        #endif
2692        // We do not turn on EDCA turbo mode for some AP that has IOT issue
2693        if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
2694                goto dm_CheckEdcaTurbo_EXIT;
2695
2696        {
2697                u8* peername[11] = {"unknown", "realtek", "realtek_92se", "broadcom", "ralink", "atheros", "cisco", "marvell", "92u_softap", "self_softap"};
2698                static int wb_tmp = 0;
2699                if (wb_tmp == 0){
2700                        printk("%s():iot peer is %#x:%s, bssid:"MAC_FMT"\n",__FUNCTION__,pHTInfo->IOTPeer,peername[pHTInfo->IOTPeer], MAC_ARG(priv->ieee80211->current_network.bssid));
2701                        wb_tmp = 1;
2702                }
2703        }
2704        // Check the status for current condition.
2705        if(!priv->ieee80211->bis_any_nonbepkts)
2706        {
2707                curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2708                curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2709                // Modify EDCA parameters selection bias
2710                // For some APs, use downlink EDCA parameters for uplink+downlink
2711                if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX)
2712                {
2713                        if(curTxOkCnt > 4*curRxOkCnt)
2714                        {
2715                                if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2716                                {
2717                                        write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
2718                                        priv->bis_cur_rdlstate = false;
2719                                }
2720                        }
2721                        else
2722                        {
2723                                if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2724                                {
2725                                        write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
2726                                        priv->bis_cur_rdlstate = true;
2727                                }
2728                        }
2729                        priv->bcurrent_turbo_EDCA = true;
2730                }
2731                else
2732                {
2733                        if(curRxOkCnt > 4*curTxOkCnt)
2734                        {
2735                                if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2736                                {
2737                                        write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
2738                                        priv->bis_cur_rdlstate = true;
2739                                }
2740                        }
2741                        else
2742                        {
2743                                if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2744                                {
2745                                        write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
2746                                        priv->bis_cur_rdlstate = false;
2747                                }
2748                        }
2749                        priv->bcurrent_turbo_EDCA = true;
2750                }
2751        }
2752        else
2753        {
2754                //
2755                // Turn Off EDCA turbo here.
2756                // Restore original EDCA according to the declaration of AP.
2757                //
2758                 if(priv->bcurrent_turbo_EDCA)
2759                {
2760
2761                        {
2762                                u8              u1bAIFS;
2763                                u32             u4bAcParam;
2764                                struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2765                                u8 mode = priv->ieee80211->mode;
2766
2767                        // For Each time updating EDCA parameter, reset EDCA turbo mode status.
2768                                dm_init_edca_turbo(dev);
2769                                u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2770                                u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2771                                        (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
2772                                        (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
2773                                        ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2774                        //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2775                                write_nic_dword(dev, EDCAPARA_BE,  u4bAcParam);
2776
2777                        // Check ACM bit.
2778                        // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
2779                                {
2780                        // TODO:  Modified this part and try to set acm control in only 1 IO processing!!
2781
2782                                        PACI_AIFSN      pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
2783                                        u8              AcmCtrl = read_nic_byte( dev, AcmHwCtrl );
2784                                        if( pAciAifsn->f.ACM )
2785                                        { // ACM bit is 1.
2786                                                AcmCtrl |= AcmHw_BeqEn;
2787                                        }
2788                                        else
2789                                        { // ACM bit is 0.
2790                                                AcmCtrl &= (~AcmHw_BeqEn);
2791                                        }
2792
2793                                        RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ;
2794                                        write_nic_byte(dev, AcmHwCtrl, AcmCtrl );
2795                                }
2796                        }
2797                        priv->bcurrent_turbo_EDCA = false;
2798                }
2799        }
2800
2801
2802dm_CheckEdcaTurbo_EXIT:
2803        // Set variables for next time.
2804        priv->ieee80211->bis_any_nonbepkts = false;
2805        lastTxOkCnt = priv->stats.txbytesunicast;
2806        lastRxOkCnt = priv->stats.rxbytesunicast;
2807}       // dm_CheckEdcaTurbo
2808#endif
2809
2810extern void DM_CTSToSelfSetting(struct net_device * dev,u32 DM_Type, u32 DM_Value)
2811{
2812        struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
2813
2814        if (DM_Type == 0)       // CTS to self disable/enable
2815        {
2816                if(DM_Value > 1)
2817                        DM_Value = 1;
2818                priv->ieee80211->bCTSToSelfEnable = (bool)DM_Value;
2819                //DbgPrint("pMgntInfo->bCTSToSelfEnable = %d\n", pMgntInfo->bCTSToSelfEnable);
2820        }
2821        else if(DM_Type == 1) //CTS to self Th
2822        {
2823                if(DM_Value >= 50)
2824                        DM_Value = 50;
2825                priv->ieee80211->CTSToSelfTH = (u8)DM_Value;
2826                //DbgPrint("pMgntInfo->CTSToSelfTH = %d\n", pMgntInfo->CTSToSelfTH);
2827        }
2828}
2829
2830static void dm_init_ctstoself(struct net_device * dev)
2831{
2832        struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
2833
2834        priv->ieee80211->bCTSToSelfEnable = TRUE;
2835        priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
2836}
2837
2838static void dm_ctstoself(struct net_device *dev)
2839{
2840        struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
2841        PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
2842        static unsigned long                            lastTxOkCnt = 0;
2843        static unsigned long                            lastRxOkCnt = 0;
2844        unsigned long                                           curTxOkCnt = 0;
2845        unsigned long                                           curRxOkCnt = 0;
2846
2847        if(priv->ieee80211->bCTSToSelfEnable != TRUE)
2848        {
2849                pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2850                return;
2851        }
2852        /*
2853        1. Uplink
2854        2. Linksys350/Linksys300N
2855        3. <50 disable, >55 enable
2856        */
2857
2858        if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
2859        {
2860                curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2861                curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2862                if(curRxOkCnt > 4*curTxOkCnt)   //downlink, disable CTS to self
2863                {
2864                        pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2865                        //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");
2866                }
2867                else    //uplink
2868                {
2869                #if 1
2870                        pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2871                #else
2872                        if(priv->undecorated_smoothed_pwdb < priv->ieee80211->CTSToSelfTH)      // disable CTS to self
2873                        {
2874                                pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2875                                //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled\n");
2876                        }
2877                        else if(priv->undecorated_smoothed_pwdb >= (priv->ieee80211->CTSToSelfTH+5))    // enable CTS to self
2878                        {
2879                                pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2880                                //DbgPrint("dm_CTSToSelf() ==> CTS to self enabled\n");
2881                        }
2882                #endif
2883                }
2884
2885                lastTxOkCnt = priv->stats.txbytesunicast;
2886                lastRxOkCnt = priv->stats.rxbytesunicast;
2887        }
2888}
2889
2890/*-----------------------------------------------------------------------------
2891 * Function:    dm_check_rfctrl_gpio()
2892 *
2893 * Overview:    Copy 8187B template for 9xseries.
2894 *
2895 * Input:               NONE
2896 *
2897 * Output:              NONE
2898 *
2899 * Return:              NONE
2900 *
2901 * Revised History:
2902 *      When            Who             Remark
2903 *      05/28/2008      amy             Create Version 0 porting from windows code.
2904 *
2905 *---------------------------------------------------------------------------*/
2906#if 1
2907static void dm_check_rfctrl_gpio(struct net_device * dev)
2908{
2909        //struct r8192_priv *priv = ieee80211_priv(dev);
2910
2911        // Walk around for DTM test, we will not enable HW - radio on/off because r/w
2912        // page 1 register before Lextra bus is enabled cause system fails when resuming
2913        // from S4. 20080218, Emily
2914
2915        // Stop to execute workitem to prevent S3/S4 bug.
2916#ifdef RTL8190P
2917        return;
2918#endif
2919#ifdef RTL8192U
2920        return;
2921#endif
2922        return;
2923#ifdef RTL8192E
2924                queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
2925#endif
2926
2927}       /* dm_CheckRfCtrlGPIO */
2928
2929#endif
2930/*-----------------------------------------------------------------------------
2931 * Function:    dm_check_pbc_gpio()
2932 *
2933 * Overview:    Check if PBC button is pressed.
2934 *
2935 * Input:               NONE
2936 *
2937 * Output:              NONE
2938 *
2939 * Return:              NONE
2940 *
2941 * Revised History:
2942 *      When            Who             Remark
2943 *      05/28/2008      amy     Create Version 0 porting from windows code.
2944 *
2945 *---------------------------------------------------------------------------*/
2946static  void    dm_check_pbc_gpio(struct net_device *dev)
2947{
2948#ifdef RTL8192U
2949        struct r8192_priv *priv = ieee80211_priv(dev);
2950        u8 tmp1byte;
2951
2952
2953        tmp1byte = read_nic_byte(dev,GPI);
2954        if(tmp1byte == 0xff)
2955                return;
2956
2957        if (tmp1byte&BIT6 || tmp1byte&BIT0)
2958        {
2959                // Here we only set bPbcPressed to TRUE
2960                // After trigger PBC, the variable will be set to FALSE
2961                RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
2962                priv->bpbc_pressed = true;
2963        }
2964#endif
2965        struct r8192_priv *priv = ieee80211_priv(dev);
2966        u8      tmp1byte;
2967
2968        write_nic_byte(dev, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO));
2969
2970        tmp1byte = read_nic_byte(dev, GPIO_IO_SEL);
2971        tmp1byte &= ~(HAL_8192S_HW_GPIO_WPS_BIT);
2972        write_nic_byte(dev, GPIO_IO_SEL, tmp1byte);
2973
2974        tmp1byte = read_nic_byte(dev, GPIO_IN);
2975
2976        RT_TRACE(COMP_IO, "CheckPbcGPIO - %x\n", tmp1byte);
2977
2978        // Add by hpfan 2008.07.07 to fix read GPIO error from S3
2979        if (tmp1byte == 0xff)
2980                return ;
2981
2982        if (tmp1byte&HAL_8192S_HW_GPIO_WPS_BIT)
2983        {
2984                // Here we only set bPbcPressed to TRUE
2985                // After trigger PBC, the variable will be set to FALSE
2986                RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
2987                priv->bpbc_pressed = true;
2988        }
2989
2990
2991
2992}
2993
2994#ifdef RTL8192E
2995
2996/*-----------------------------------------------------------------------------
2997 * Function:    dm_GPIOChangeRF
2998 * Overview:    PCI will not support workitem call back HW radio on-off control.
2999 *
3000 * Input:               NONE
3001 *
3002 * Output:              NONE
3003 *
3004 * Return:              NONE
3005 *
3006 * Revised History:
3007 *      When            Who             Remark
3008 *      02/21/2008      MHC             Create Version 0.
3009 *
3010 *---------------------------------------------------------------------------*/
3011extern  void    dm_gpio_change_rf_callback(struct work_struct *work)
3012{
3013        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3014       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
3015       struct net_device *dev = priv->ieee80211->dev;
3016        u8 tmp1byte;
3017        RT_RF_POWER_STATE       eRfPowerStateToSet;
3018        bool bActuallySet = false;
3019
3020        do{
3021                bActuallySet=false;
3022
3023                if(!priv->up)
3024                {
3025                        RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
3026                }
3027                else
3028                {
3029                        // 0x108 GPIO input register is read only
3030                        //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
3031                        tmp1byte = read_nic_byte(dev,GPI);
3032
3033                        eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
3034
3035                        if( (priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
3036                        {
3037                                RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
3038
3039                                priv->bHwRadioOff = false;
3040                                bActuallySet = true;
3041                        }
3042                        else if ( (priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
3043                        {
3044                                RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
3045                                priv->bHwRadioOff = true;
3046                                bActuallySet = true;
3047                        }
3048
3049                        if(bActuallySet)
3050                        {
3051                                #ifdef TO_DO
3052                                MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
3053                                //DrvIFIndicateCurrentPhyStatus(pAdapter);
3054                                #endif
3055                        }
3056                        else
3057                        {
3058                                msleep(2000);
3059                        }
3060
3061                }
3062        }while(TRUE)
3063
3064}       /* dm_GPIOChangeRF */
3065
3066#endif
3067/*-----------------------------------------------------------------------------
3068 * Function:    DM_RFPathCheckWorkItemCallBack()
3069 *
3070 * Overview:    Check if Current RF RX path is enabled
3071 *
3072 * Input:               NONE
3073 *
3074 * Output:              NONE
3075 *
3076 * Return:              NONE
3077 *
3078 * Revised History:
3079 *      When            Who             Remark
3080 *      01/30/2008      MHC             Create Version 0.
3081 *
3082 *---------------------------------------------------------------------------*/
3083extern  void    dm_rf_pathcheck_workitemcallback(struct work_struct *work)
3084{
3085        struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3086       struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
3087       struct net_device *dev =priv->ieee80211->dev;
3088        //bool bactually_set = false;
3089        u8 rfpath = 0, i;
3090
3091
3092        /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
3093           always be the same. We only read 0xc04 now. */
3094        rfpath = read_nic_byte(dev, 0xc04);
3095
3096        // Check Bit 0-3, it means if RF A-D is enabled.
3097        for (i = 0; i < RF90_PATH_MAX; i++)
3098        {
3099                if (rfpath & (0x01<<i))
3100                        priv->brfpath_rxenable[i] = 1;
3101                else
3102                        priv->brfpath_rxenable[i] = 0;
3103        }
3104        if(!DM_RxPathSelTable.Enable)
3105                return;
3106
3107        dm_rxpath_sel_byrssi(dev);
3108}       /* DM_RFPathCheckWorkItemCallBack */
3109
3110static void dm_init_rxpath_selection(struct net_device * dev)
3111{
3112        u8 i;
3113        struct r8192_priv *priv = ieee80211_priv(dev);
3114        DM_RxPathSelTable.Enable = 1;   //default enabled
3115        DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
3116        DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
3117        if(priv->CustomerID == RT_CID_819x_Netcore)
3118                DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
3119        else
3120                DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
3121        DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
3122        DM_RxPathSelTable.disabledRF = 0;
3123        for(i=0; i<4; i++)
3124        {
3125                DM_RxPathSelTable.rf_rssi[i] = 50;
3126                DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
3127                DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
3128        }
3129}
3130
3131static void dm_rxpath_sel_byrssi(struct net_device * dev)
3132{
3133        struct r8192_priv *priv = ieee80211_priv(dev);
3134        u8                              i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
3135        u8                              tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
3136        u8                              cck_default_Rx=0x2;     //RF-C
3137        u8                              cck_optional_Rx=0x3;//RF-D
3138        long                            tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
3139        u8                              cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
3140        u8                              cur_rf_rssi;
3141        long                            cur_cck_pwdb;
3142        static u8                       disabled_rf_cnt=0, cck_Rx_Path_initialized=0;
3143        u8                              update_cck_rx_path;
3144
3145        if(priv->rf_type != RF_2T4R)
3146                return;
3147
3148        if(!cck_Rx_Path_initialized)
3149        {
3150                DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf);
3151                cck_Rx_Path_initialized = 1;
3152        }
3153
3154        DM_RxPathSelTable.disabledRF = 0xf;
3155        DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(dev, 0xc04));
3156
3157        if(priv->ieee80211->mode == WIRELESS_MODE_B)
3158        {
3159                DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;        //pure B mode, fixed cck version2
3160                //DbgPrint("Pure B mode, use cck rx version2 \n");
3161        }
3162
3163        //decide max/sec/min rssi index
3164        for (i=0; i<RF90_PATH_MAX; i++)
3165        {
3166                if(!DM_RxPathSelTable.DbgMode)
3167                        DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
3168
3169                if(priv->brfpath_rxenable[i])
3170                {
3171                        rf_num++;
3172                        cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
3173
3174                        if(rf_num == 1) // find first enabled rf path and the rssi values
3175                        {       //initialize, set all rssi index to the same one
3176                                max_rssi_index = min_rssi_index = sec_rssi_index = i;
3177                                tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
3178                        }
3179                        else if(rf_num == 2)
3180                        {       // we pick up the max index first, and let sec and min to be the same one
3181                                if(cur_rf_rssi >= tmp_max_rssi)
3182                                {
3183                                        tmp_max_rssi = cur_rf_rssi;
3184                                        max_rssi_index = i;
3185                                }
3186                                else
3187                                {
3188                                        tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
3189                                        sec_rssi_index = min_rssi_index = i;
3190                                }
3191                        }
3192                        else
3193                        {
3194                                if(cur_rf_rssi > tmp_max_rssi)
3195                                {
3196                                        tmp_sec_rssi = tmp_max_rssi;
3197                                        sec_rssi_index = max_rssi_index;
3198                                        tmp_max_rssi = cur_rf_rssi;
3199                                        max_rssi_index = i;
3200                                }
3201                                else if(cur_rf_rssi == tmp_max_rssi)
3202                                {       // let sec and min point to the different index
3203                                        tmp_sec_rssi = cur_rf_rssi;
3204                                        sec_rssi_index = i;
3205                                }
3206                                else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
3207                                {
3208                                        tmp_sec_rssi = cur_rf_rssi;
3209                                        sec_rssi_index = i;
3210                                }
3211                                else if(cur_rf_rssi == tmp_sec_rssi)
3212                                {
3213                                        if(tmp_sec_rssi == tmp_min_rssi)
3214                                        {       // let sec and min point to the different index
3215                                                tmp_sec_rssi = cur_rf_rssi;
3216                                                sec_rssi_index = i;
3217                                        }
3218                                        else
3219                                        {
3220                                                // This case we don't need to set any index
3221                                        }
3222                                }
3223                                else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
3224                                {
3225                                        // This case we don't need to set any index
3226                                }
3227                                else if(cur_rf_rssi == tmp_min_rssi)
3228                                {
3229                                        if(tmp_sec_rssi == tmp_min_rssi)
3230                                        {       // let sec and min point to the different index
3231                                                tmp_min_rssi = cur_rf_rssi;
3232                                                min_rssi_index = i;
3233                                        }
3234                                        else
3235                                        {
3236                                                // This case we don't need to set any index
3237                                        }
3238                                }
3239                                else if(cur_rf_rssi < tmp_min_rssi)
3240                                {
3241                                        tmp_min_rssi = cur_rf_rssi;
3242                                        min_rssi_index = i;
3243                                }
3244                        }
3245                }
3246        }
3247
3248        rf_num = 0;
3249        // decide max/sec/min cck pwdb index
3250        if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
3251        {
3252                for (i=0; i<RF90_PATH_MAX; i++)
3253                {
3254                        if(priv->brfpath_rxenable[i])
3255                        {
3256                                rf_num++;
3257                                cur_cck_pwdb =  DM_RxPathSelTable.cck_pwdb_sta[i];
3258
3259                                if(rf_num == 1) // find first enabled rf path and the rssi values
3260                                {       //initialize, set all rssi index to the same one
3261                                        cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
3262                                        tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
3263                                }
3264                                else if(rf_num == 2)
3265                                {       // we pick up the max index first, and let sec and min to be the same one
3266                                        if(cur_cck_pwdb >= tmp_cck_max_pwdb)
3267                                        {
3268                                                tmp_cck_max_pwdb = cur_cck_pwdb;
3269                                                cck_rx_ver2_max_index = i;
3270                                        }
3271                                        else
3272                                        {
3273                                                tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
3274                                                cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
3275                                        }
3276                                }
3277                                else
3278                                {
3279                                        if(cur_cck_pwdb > tmp_cck_max_pwdb)
3280                                        {
3281                                                tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
3282                                                cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
3283                                                tmp_cck_max_pwdb = cur_cck_pwdb;
3284                                                cck_rx_ver2_max_index = i;
3285                                        }
3286                                        else if(cur_cck_pwdb == tmp_cck_max_pwdb)
3287                                        {       // let sec and min point to the different index
3288                                                tmp_cck_sec_pwdb = cur_cck_pwdb;
3289                                                cck_rx_ver2_sec_index = i;
3290                                        }
3291                                        else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
3292                                        {
3293                                                tmp_cck_sec_pwdb = cur_cck_pwdb;
3294                                                cck_rx_ver2_sec_index = i;
3295                                        }
3296                                        else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
3297                                        {
3298                                                if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
3299                                                {       // let sec and min point to the different index
3300                                                        tmp_cck_sec_pwdb = cur_cck_pwdb;
3301                                                        cck_rx_ver2_sec_index = i;
3302                                                }
3303                                                else
3304                                                {
3305                                                        // This case we don't need to set any index
3306                                                }
3307                                        }
3308                                        else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
3309                                        {
3310                                                // This case we don't need to set any index
3311                                        }
3312                                        else if(cur_cck_pwdb == tmp_cck_min_pwdb)
3313                                        {
3314                                                if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
3315                                                {       // let sec and min point to the different index
3316                                                        tmp_cck_min_pwdb = cur_cck_pwdb;
3317                                                        cck_rx_ver2_min_index = i;
3318                                                }
3319                                                else
3320                                                {
3321                                                        // This case we don't need to set any index
3322                                                }
3323                                        }
3324                                        else if(cur_cck_pwdb < tmp_cck_min_pwdb)
3325                                        {
3326                                                tmp_cck_min_pwdb = cur_cck_pwdb;
3327                                                cck_rx_ver2_min_index = i;
3328                                        }
3329                                }
3330
3331                        }
3332                }
3333        }
3334
3335
3336        // Set CCK Rx path
3337        // reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
3338        update_cck_rx_path = 0;
3339        if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
3340        {
3341                cck_default_Rx = cck_rx_ver2_max_index;
3342                cck_optional_Rx = cck_rx_ver2_sec_index;
3343                if(tmp_cck_max_pwdb != -64)
3344                        update_cck_rx_path = 1;
3345        }
3346
3347        if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
3348        {
3349                if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
3350                {
3351                        //record the enabled rssi threshold
3352                        DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
3353                        //disable the BB Rx path, OFDM
3354                        rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0);  // 0xc04[3:0]
3355                        rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0);  // 0xd04[3:0]
3356                        disabled_rf_cnt++;
3357                }
3358                if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
3359                {
3360                        cck_default_Rx = max_rssi_index;
3361                        cck_optional_Rx = sec_rssi_index;
3362                        if(tmp_max_rssi)
3363                                update_cck_rx_path = 1;
3364                }
3365        }
3366
3367        if(update_cck_rx_path)
3368        {
3369                DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
3370                rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
3371        }
3372
3373        if(DM_RxPathSelTable.disabledRF)
3374        {
3375                for(i=0; i<4; i++)
3376                {
3377                        if((DM_RxPathSelTable.disabledRF>>i) & 0x1)     //disabled rf
3378                        {
3379                                if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
3380                                {
3381                                        //enable the BB Rx path
3382                                        //DbgPrint("RF-%d is enabled. \n", 0x1<<i);
3383                                        rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);       // 0xc04[3:0]
3384                                        rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);       // 0xd04[3:0]
3385                                        DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
3386                                        disabled_rf_cnt--;
3387                                }
3388                        }
3389                }
3390        }
3391}
3392
3393/*-----------------------------------------------------------------------------
3394 * Function:    dm_check_rx_path_selection()
3395 *
3396 * Overview:    Call a workitem to check current RXRF path and Rx Path selection by RSSI.
3397 *
3398 * Input:               NONE
3399 *
3400 * Output:              NONE
3401 *
3402 * Return:              NONE
3403 *
3404 * Revised History:
3405 *      When            Who             Remark
3406 *      05/28/2008      amy             Create Version 0 porting from windows code.
3407 *
3408 *---------------------------------------------------------------------------*/
3409static  void    dm_check_rx_path_selection(struct net_device *dev)
3410{
3411        struct r8192_priv *priv = ieee80211_priv(dev);
3412
3413        queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
3414}       /* dm_CheckRxRFPath */
3415
3416
3417static void dm_init_fsync (struct net_device *dev)
3418{
3419        struct r8192_priv *priv = ieee80211_priv(dev);
3420
3421        priv->ieee80211->fsync_time_interval = 500;
3422        priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
3423        priv->ieee80211->fsync_rssi_threshold = 30;
3424#ifdef RTL8190P
3425        priv->ieee80211->bfsync_enable = true;
3426#else
3427        priv->ieee80211->bfsync_enable = false;
3428#endif
3429        priv->ieee80211->fsync_multiple_timeinterval = 3;
3430        priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
3431        priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
3432        priv->ieee80211->fsync_state = Default_Fsync;
3433        priv->framesyncMonitor = 1;     // current default 0xc38 monitor on
3434
3435        init_timer(&priv->fsync_timer);
3436        priv->fsync_timer.data = (unsigned long)dev;
3437        priv->fsync_timer.function = dm_fsync_timer_callback;
3438}
3439
3440
3441static void dm_deInit_fsync(struct net_device *dev)
3442{
3443        struct r8192_priv *priv = ieee80211_priv(dev);
3444        del_timer_sync(&priv->fsync_timer);
3445}
3446
3447extern void dm_fsync_timer_callback(unsigned long data)
3448{
3449        struct net_device *dev = (struct net_device *)data;
3450        struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
3451        u32 rate_index, rate_count = 0, rate_count_diff=0;
3452        bool            bSwitchFromCountDiff = false;
3453        bool            bDoubleTimeInterval = false;
3454
3455        if(     priv->ieee80211->state == IEEE80211_LINKED &&
3456                priv->ieee80211->bfsync_enable &&
3457                (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
3458        {
3459                 // Count rate 54, MCS [7], [12, 13, 14, 15]
3460                u32 rate_bitmap;
3461                for(rate_index = 0; rate_index <= 27; rate_index++)
3462                {
3463                        rate_bitmap  = 1 << rate_index;
3464                        if(priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
3465                                rate_count+= priv->stats.received_rate_histogram[1][rate_index];
3466                }
3467
3468                if(rate_count < priv->rate_record)
3469                        rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
3470                else
3471                        rate_count_diff = rate_count - priv->rate_record;
3472                if(rate_count_diff < priv->rateCountDiffRecord)
3473                {
3474
3475                        u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
3476                        // Contiune count
3477                        if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
3478                                priv->ContiuneDiffCount++;
3479                        else
3480                                priv->ContiuneDiffCount = 0;
3481
3482                        // Contiune count over
3483                        if(priv->ContiuneDiffCount >=2)
3484                        {
3485                                bSwitchFromCountDiff = true;
3486                                priv->ContiuneDiffCount = 0;
3487                        }
3488                }
3489                else
3490                {
3491                        // Stop contiune count
3492                        priv->ContiuneDiffCount = 0;
3493                }
3494
3495                //If Count diff <= FsyncRateCountThreshold
3496                if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
3497                {
3498                        bSwitchFromCountDiff = true;
3499                        priv->ContiuneDiffCount = 0;
3500                }
3501                priv->rate_record = rate_count;
3502                priv->rateCountDiffRecord = rate_count_diff;
3503                RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
3504                // if we never receive those mcs rate and rssi > 30 % then switch fsyn
3505                if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
3506                {
3507                        bDoubleTimeInterval = true;
3508                        priv->bswitch_fsync = !priv->bswitch_fsync;
3509                        if(priv->bswitch_fsync)
3510                        {
3511                        #ifdef RTL8190P
3512                                write_nic_byte(dev, 0xC36, 0x00);
3513                        #else
3514                                write_nic_byte(dev,0xC36, 0x1c);
3515                        #endif
3516                                write_nic_byte(dev, 0xC3e, 0x90);
3517                        }
3518                        else
3519                        {
3520                        #ifdef RTL8190P
3521                                write_nic_byte(dev, 0xC36, 0x40);
3522                        #else
3523                                write_nic_byte(dev, 0xC36, 0x5c);
3524                        #endif
3525                                write_nic_byte(dev, 0xC3e, 0x96);
3526                        }
3527                }
3528                else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
3529                {
3530                        if(priv->bswitch_fsync)
3531                        {
3532                                priv->bswitch_fsync  = false;
3533                        #ifdef RTL8190P
3534                                write_nic_byte(dev, 0xC36, 0x40);
3535                        #else
3536                                write_nic_byte(dev, 0xC36, 0x5c);
3537                        #endif
3538                                write_nic_byte(dev, 0xC3e, 0x96);
3539                        }
3540                }
3541                if(bDoubleTimeInterval){
3542                        if(timer_pending(&priv->fsync_timer))
3543                                del_timer_sync(&priv->fsync_timer);
3544                        priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
3545                        add_timer(&priv->fsync_timer);
3546                }
3547                else{
3548                        if(timer_pending(&priv->fsync_timer))
3549                                del_timer_sync(&priv->fsync_timer);
3550                        priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
3551                        add_timer(&priv->fsync_timer);
3552                }
3553        }
3554        else
3555        {
3556                // Let Register return to default value;
3557                if(priv->bswitch_fsync)
3558                {
3559                        priv->bswitch_fsync  = false;
3560                #ifdef RTL8190P
3561                        write_nic_byte(dev, 0xC36, 0x40);
3562                #else
3563                        write_nic_byte(dev, 0xC36, 0x5c);
3564                #endif
3565                        write_nic_byte(dev, 0xC3e, 0x96);
3566                }
3567                priv->ContiuneDiffCount = 0;
3568        rtl8192_setBBreg(dev, rOFDM0_RxDetector2, bMaskDWord, 0x164052cd);
3569        }
3570        RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
3571        RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
3572}
3573
3574static void dm_StartHWFsync(struct net_device *dev)
3575{
3576        RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
3577        write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
3578        write_nic_byte(dev, 0xc3b, 0x41);
3579}
3580
3581static void dm_EndSWFsync(struct net_device *dev)
3582{
3583        struct r8192_priv *priv = ieee80211_priv(dev);
3584
3585        RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
3586        del_timer_sync(&(priv->fsync_timer));
3587
3588        // Let Register return to default value;
3589        if(priv->bswitch_fsync)
3590        {
3591                priv->bswitch_fsync  = false;
3592
3593                #ifdef RTL8190P
3594                        write_nic_byte(dev, 0xC36, 0x40);
3595                #else
3596                        write_nic_byte(dev, 0xC36, 0x5c);
3597                #endif
3598
3599                write_nic_byte(dev, 0xC3e, 0x96);
3600        }
3601
3602        priv->ContiuneDiffCount = 0;
3603#ifndef RTL8190P
3604        write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
3605#endif
3606
3607}
3608
3609static void dm_StartSWFsync(struct net_device *dev)
3610{
3611        struct r8192_priv *priv = ieee80211_priv(dev);
3612        u32                     rateIndex;
3613        u32                     rateBitmap;
3614
3615        RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
3616        // Initial rate record to zero, start to record.
3617        priv->rate_record = 0;
3618        // Initial contiune diff count to zero, start to record.
3619        priv->ContiuneDiffCount = 0;
3620        priv->rateCountDiffRecord = 0;
3621        priv->bswitch_fsync  = false;
3622
3623        if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
3624        {
3625                priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
3626                priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
3627        }
3628        else
3629        {
3630                priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
3631                priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
3632        }
3633        for(rateIndex = 0; rateIndex <= 27; rateIndex++)
3634        {
3635                rateBitmap  = 1 << rateIndex;
3636                if(priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
3637                        priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
3638        }
3639        if(timer_pending(&priv->fsync_timer))
3640                del_timer_sync(&priv->fsync_timer);
3641        priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
3642        add_timer(&priv->fsync_timer);
3643
3644#ifndef RTL8190P
3645        write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
3646#endif
3647
3648}
3649
3650static void dm_EndHWFsync(struct net_device *dev)
3651{
3652        RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
3653        write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
3654        write_nic_byte(dev, 0xc3b, 0x49);
3655
3656}
3657
3658void dm_check_fsync(struct net_device *dev)
3659{
3660#define RegC38_Default                          0
3661#define RegC38_NonFsync_Other_AP        1
3662#define RegC38_Fsync_AP_BCM             2
3663        struct r8192_priv *priv = ieee80211_priv(dev);
3664        //u32                   framesyncC34;
3665        static u8               reg_c38_State=RegC38_Default;
3666        static u32      reset_cnt=0;
3667
3668        RT_TRACE(COMP_HALDM, "RSSI %d TimeInterval %d MultipleTimeInterval %d\n", priv->ieee80211->fsync_rssi_threshold, priv->ieee80211->fsync_time_interval, priv->ieee80211->fsync_multiple_timeinterval);
3669        RT_TRACE(COMP_HALDM, "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n", priv->ieee80211->fsync_rate_bitmap, priv->ieee80211->fsync_firstdiff_ratethreshold, priv->ieee80211->fsync_seconddiff_ratethreshold);
3670
3671        if(     priv->ieee80211->state == IEEE80211_LINKED &&
3672                (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
3673        {
3674                if(priv->ieee80211->bfsync_enable == 0)
3675                {
3676                        switch(priv->ieee80211->fsync_state)
3677                        {
3678                                case Default_Fsync:
3679                                        dm_StartHWFsync(dev);
3680                                        priv->ieee80211->fsync_state = HW_Fsync;
3681                                        break;
3682                                case SW_Fsync:
3683                                        dm_EndSWFsync(dev);
3684                                        dm_StartHWFsync(dev);
3685                                        priv->ieee80211->fsync_state = HW_Fsync;
3686                                        break;
3687                                case HW_Fsync:
3688                                default:
3689                                        break;
3690                        }
3691                }
3692                else
3693                {
3694                        switch(priv->ieee80211->fsync_state)
3695                        {
3696                                case Default_Fsync:
3697                                        dm_StartSWFsync(dev);
3698                                        priv->ieee80211->fsync_state = SW_Fsync;
3699                                        break;
3700                                case HW_Fsync:
3701                                        dm_EndHWFsync(dev);
3702                                        dm_StartSWFsync(dev);
3703                                        priv->ieee80211->fsync_state = SW_Fsync;
3704                                        break;
3705                                case SW_Fsync:
3706                                default:
3707                                        break;
3708
3709                        }
3710                }
3711                if(priv->framesyncMonitor)
3712                {
3713                        if(reg_c38_State != RegC38_Fsync_AP_BCM)
3714                        {       //For broadcom AP we write different default value
3715                                #ifdef RTL8190P
3716                                        write_nic_byte(dev, rOFDM0_RxDetector3, 0x15);
3717                                #else
3718                                        write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
3719                                #endif
3720
3721                                reg_c38_State = RegC38_Fsync_AP_BCM;
3722                        }
3723                }
3724        }
3725        else
3726        {
3727                switch(priv->ieee80211->fsync_state)
3728                {
3729                        case HW_Fsync:
3730                                dm_EndHWFsync(dev);
3731                                priv->ieee80211->fsync_state = Default_Fsync;
3732                                break;
3733                        case SW_Fsync:
3734                                dm_EndSWFsync(dev);
3735                                priv->ieee80211->fsync_state = Default_Fsync;
3736                                break;
3737                        case Default_Fsync:
3738                        default:
3739                                break;
3740                }
3741
3742                if(priv->framesyncMonitor)
3743                {
3744                        if(priv->ieee80211->state == IEEE80211_LINKED)
3745                        {
3746                                if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
3747                                {
3748                                        if(reg_c38_State != RegC38_NonFsync_Other_AP)
3749                                        {
3750                                                #ifdef RTL8190P
3751                                                        write_nic_byte(dev, rOFDM0_RxDetector3, 0x10);
3752                                                #else
3753                                                        write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
3754                                                #endif
3755
3756                                                reg_c38_State = RegC38_NonFsync_Other_AP;
3757                                        }
3758                                }
3759                                else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
3760                                {
3761                                        if(reg_c38_State)
3762                                        {
3763                                                write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3764                                                reg_c38_State = RegC38_Default;
3765                                                //DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync);
3766                                        }
3767                                }
3768                        }
3769                        else
3770                        {
3771                                if(reg_c38_State)
3772                                {
3773                                        write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3774                                        reg_c38_State = RegC38_Default;
3775                                        //DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync);
3776                                }
3777                        }
3778                }
3779        }
3780        if(priv->framesyncMonitor)
3781        {
3782                if(priv->reset_count != reset_cnt)
3783                {       //After silent reset, the reg_c38_State will be returned to default value
3784                        write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3785                        reg_c38_State = RegC38_Default;
3786                        reset_cnt = priv->reset_count;
3787                        //DbgPrint("reg_c38_State = 0 for silent reset. \n");
3788                }
3789        }
3790        else
3791        {
3792                if(reg_c38_State)
3793                {
3794                        write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3795                        reg_c38_State = RegC38_Default;
3796                        //DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync);
3797                }
3798        }
3799}
3800
3801/*-----------------------------------------------------------------------------
3802 * Function:    dm_shadow_init()
3803 *
3804 * Overview:    Store all NIC MAC/BB register content.
3805 *
3806 * Input:               NONE
3807 *
3808 * Output:              NONE
3809 *
3810 * Return:              NONE
3811 *
3812 * Revised History:
3813 *      When            Who             Remark
3814 *      05/29/2008      amy             Create Version 0 porting from windows code.
3815 *
3816 *---------------------------------------------------------------------------*/
3817extern void dm_shadow_init(struct net_device *dev)
3818{
3819        u8      page;
3820        u16     offset;
3821
3822        for (page = 0; page < 5; page++)
3823                for (offset = 0; offset < 256; offset++)
3824                {
3825                        dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
3826                        //DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);
3827                }
3828
3829        for (page = 8; page < 11; page++)
3830                for (offset = 0; offset < 256; offset++)
3831                        dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
3832
3833        for (page = 12; page < 15; page++)
3834                for (offset = 0; offset < 256; offset++)
3835                        dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
3836
3837}   /* dm_shadow_init */
3838
3839/*---------------------------Define function prototype------------------------*/
3840/*-----------------------------------------------------------------------------
3841 * Function:    DM_DynamicTxPower()
3842 *
3843 * Overview:    Detect Signal strength to control TX Registry
3844                        Tx Power Control For Near/Far Range
3845 *
3846 * Input:               NONE
3847 *
3848 * Output:              NONE
3849 *
3850 * Return:              NONE
3851 *
3852 * Revised History:
3853 *      When            Who             Remark
3854 *      03/06/2008      Jacken  Create Version 0.
3855 *
3856 *---------------------------------------------------------------------------*/
3857static void dm_init_dynamic_txpower(struct net_device *dev)
3858{
3859        struct r8192_priv *priv = ieee80211_priv(dev);
3860
3861        //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
3862        priv->ieee80211->bdynamic_txpower_enable = true;    //Default to enable Tx Power Control
3863        priv->bLastDTPFlag_High = false;
3864        priv->bLastDTPFlag_Low = false;
3865        priv->bDynamicTxHighPower = false;
3866        priv->bDynamicTxLowPower = false;
3867}
3868
3869static void dm_dynamic_txpower(struct net_device *dev)
3870{
3871        struct r8192_priv *priv = ieee80211_priv(dev);
3872        unsigned int txhipower_threshhold=0;
3873        unsigned int txlowpower_threshold=0;
3874        if(priv->ieee80211->bdynamic_txpower_enable != true)
3875        {
3876                priv->bDynamicTxHighPower = false;
3877                priv->bDynamicTxLowPower = false;
3878                return;
3879        }
3880        //printk("priv->ieee80211->current_network.unknown_cap_exist is %d ,priv->ieee80211->current_network.broadcom_cap_exist is %d\n",priv->ieee80211->current_network.unknown_cap_exist,priv->ieee80211->current_network.broadcom_cap_exist);
3881        if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){
3882                txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
3883                txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
3884        }
3885        else
3886        {
3887                txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
3888                txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
3889        }
3890
3891//      printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__FUNCTION__,txhipower_threshhold,txlowpower_threshold);
3892        RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb);
3893
3894        if(priv->ieee80211->state == IEEE80211_LINKED)
3895        {
3896                if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
3897                {
3898                        priv->bDynamicTxHighPower = true;
3899                        priv->bDynamicTxLowPower = false;
3900                }
3901                else
3902                {
3903                        // high power state check
3904                        if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
3905                        {
3906                                priv->bDynamicTxHighPower = false;
3907                        }
3908                        // low power state check
3909                        if(priv->undecorated_smoothed_pwdb < 35)
3910                        {
3911                                priv->bDynamicTxLowPower = true;
3912                        }
3913                        else if(priv->undecorated_smoothed_pwdb >= 40)
3914                        {
3915                                priv->bDynamicTxLowPower = false;
3916                        }
3917                }
3918        }
3919        else
3920        {
3921                //pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
3922                priv->bDynamicTxHighPower = false;
3923                priv->bDynamicTxLowPower = false;
3924        }
3925
3926        if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) ||
3927                (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
3928        {
3929                RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190()  channel = %d \n" , priv->ieee80211->current_network.channel);
3930        }
3931        priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
3932        priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
3933
3934}       /* dm_dynamic_txpower */
3935
3936//added by vivi, for read tx rate and retrycount
3937static void dm_check_txrateandretrycount(struct net_device * dev)
3938{
3939        struct r8192_priv *priv = ieee80211_priv(dev);
3940        struct ieee80211_device* ieee = priv->ieee80211;
3941        //for 11n tx rate
3942//      priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
3943        ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, TX_RATE_REG);
3944        //printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);
3945        //for initial tx rate
3946//      priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);
3947        ieee->softmac_stats.last_packet_rate = read_nic_byte(dev ,Initial_Tx_Rate_Reg);
3948        //for tx tx retry count
3949//      priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
3950        ieee->softmac_stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
3951}
3952
3953static void dm_send_rssi_tofw(struct net_device *dev)
3954{
3955}
3956
3957#ifdef TO_DO_LIST
3958static  void
3959dm_CheckProtection(struct net_device *dev)
3960{
3961        struct r8192_priv *priv = ieee80211_priv(dev);
3962        //PMGNT_INFO            pMgntInfo = &(Adapter->MgntInfo);
3963        u8                      CurRate;
3964
3965        if(priv->ieee80211->pHTInfo->IOTAction & (HT_IOT_ACT_FORCED_RTS|HT_IOT_ACT_FORCED_CTS2SELF))
3966        {
3967                CurRate = read_nic_byte(dev, INIMCS_SEL);
3968                if(CurRate <= DESC92S_RATE11M)
3969                        priv->bDmDisableProtect = true;
3970                else
3971                        priv->bDmDisableProtect = fasle;
3972        }
3973}
3974#endif
3975
3976/*---------------------------Define function prototype------------------------*/
3977
3978