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