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