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