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