Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0
0002 /*++
0003 Copyright-c Realtek Semiconductor Corp. All rights reserved.
0004 
0005 Module Name:
0006     r8192U_dm.c
0007 
0008 Abstract:
0009     HW dynamic mechanism.
0010 
0011 Major Change History:
0012     When        Who             What
0013     ----------  --------------- -------------------------------
0014     2008-05-14  amy                     create version 0 porting from windows code.
0015 
0016 --*/
0017 #include "r8192U.h"
0018 #include "r8192U_dm.h"
0019 #include "r8192U_hw.h"
0020 #include "r819xU_phy.h"
0021 #include "r819xU_phyreg.h"
0022 #include "r8190_rtl8256.h"
0023 #include "r819xU_cmdpkt.h"
0024 /*---------------------------Define Local Constant---------------------------*/
0025 /* Indicate different AP vendor for IOT issue. */
0026 static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
0027     0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0x00a44f, 0x5ea44f
0028 };
0029 
0030 static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
0031     0x5e4322, 0x00a44f, 0x5e4322, 0x604322, 0x5ea44f, 0x5ea44f
0032 };
0033 
0034 #define RTK_UL_EDCA 0xa44f
0035 #define RTK_DL_EDCA 0x5e4322
0036 /*---------------------------Define Local Constant---------------------------*/
0037 
0038 
0039 /*------------------------Define global variable-----------------------------*/
0040 /* Debug variable ? */
0041 struct dig dm_digtable;
0042 /* Store current software write register content for MAC PHY. */
0043 u8      dm_shadow[16][256] = { {0} };
0044 /* For Dynamic Rx Path Selection by Signal Strength */
0045 static struct dynamic_rx_path_sel DM_RxPathSelTable;
0046 
0047 extern  void dm_check_fsync(struct net_device *dev);
0048 
0049 /* DM --> Rate Adaptive */
0050 static  void    dm_check_rate_adaptive(struct net_device *dev);
0051 
0052 /* DM --> Bandwidth switch */
0053 static  void    dm_init_bandwidth_autoswitch(struct net_device *dev);
0054 static  void    dm_bandwidth_autoswitch(struct net_device *dev);
0055 
0056 /* DM --> TX power control */
0057 /*static    void    dm_initialize_txpower_tracking(struct net_device *dev);*/
0058 
0059 static  void    dm_check_txpower_tracking(struct net_device *dev);
0060 
0061 /*static    void    dm_txpower_reset_recovery(struct net_device *dev);*/
0062 
0063 /* DM --> Dynamic Init Gain by RSSI */
0064 static  void    dm_dig_init(struct net_device *dev);
0065 static  void    dm_ctrl_initgain_byrssi(struct net_device *dev);
0066 static  void    dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
0067 static  void    dm_ctrl_initgain_byrssi_by_driverrssi(struct net_device *dev);
0068 static  void    dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
0069 static  void    dm_initial_gain(struct net_device *dev);
0070 static  void    dm_pd_th(struct net_device *dev);
0071 static  void    dm_cs_ratio(struct net_device *dev);
0072 
0073 static  void dm_init_ctstoself(struct net_device *dev);
0074 /* DM --> EDCA turbo mode control */
0075 static  void    dm_check_edca_turbo(struct net_device *dev);
0076 
0077 /*static    void    dm_gpio_change_rf(struct net_device *dev);*/
0078 /* DM --> Check PBC */
0079 static  void dm_check_pbc_gpio(struct net_device *dev);
0080 
0081 /* DM --> Check current RX RF path state */
0082 static  void    dm_check_rx_path_selection(struct net_device *dev);
0083 static  void dm_init_rxpath_selection(struct net_device *dev);
0084 static  void dm_rxpath_sel_byrssi(struct net_device *dev);
0085 
0086 /* DM --> Fsync for broadcom ap */
0087 static void dm_init_fsync(struct net_device *dev);
0088 static void dm_deInit_fsync(struct net_device *dev);
0089 
0090 /* Added by vivi, 20080522 */
0091 static  void    dm_check_txrateandretrycount(struct net_device *dev);
0092 
0093 /*---------------------Define local function prototype-----------------------*/
0094 
0095 /*---------------------Define of Tx Power Control For Near/Far Range --------*/   /*Add by Jacken 2008/02/18 */
0096 static  void    dm_init_dynamic_txpower(struct net_device *dev);
0097 static  void    dm_dynamic_txpower(struct net_device *dev);
0098 
0099 /* DM --> For rate adaptive and DIG, we must send RSSI to firmware */
0100 static  void dm_send_rssi_tofw(struct net_device *dev);
0101 static  void    dm_ctstoself(struct net_device *dev);
0102 /*---------------------------Define function prototype------------------------*/
0103 /* ================================================================================
0104  *  HW Dynamic mechanism interface.
0105  * ================================================================================
0106  *
0107  *
0108  *  Description:
0109  *      Prepare SW resource for HW dynamic mechanism.
0110  *
0111  *  Assumption:
0112  *      This function is only invoked at driver initialization once.
0113  */
0114 void init_hal_dm(struct net_device *dev)
0115 {
0116     struct r8192_priv *priv = ieee80211_priv(dev);
0117 
0118     /* Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism. */
0119     priv->undecorated_smoothed_pwdb = -1;
0120 
0121     /* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
0122     dm_init_dynamic_txpower(dev);
0123     init_rate_adaptive(dev);
0124     /*dm_initialize_txpower_tracking(dev);*/
0125     dm_dig_init(dev);
0126     dm_init_edca_turbo(dev);
0127     dm_init_bandwidth_autoswitch(dev);
0128     dm_init_fsync(dev);
0129     dm_init_rxpath_selection(dev);
0130     dm_init_ctstoself(dev);
0131 
0132 }   /* InitHalDm */
0133 
0134 void deinit_hal_dm(struct net_device *dev)
0135 {
0136     dm_deInit_fsync(dev);
0137 }
0138 
0139 #ifdef USB_RX_AGGREGATION_SUPPORT
0140 void dm_CheckRxAggregation(struct net_device *dev)
0141 {
0142     struct r8192_priv *priv = ieee80211_priv(dev);
0143     PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
0144     static unsigned long    lastTxOkCnt;
0145     static unsigned long    lastRxOkCnt;
0146     unsigned long       curTxOkCnt = 0;
0147     unsigned long       curRxOkCnt = 0;
0148 
0149 /*
0150     if (pHalData->bForcedUsbRxAggr) {
0151         if (pHalData->ForcedUsbRxAggrInfo == 0) {
0152             if (pHalData->bCurrentRxAggrEnable) {
0153                 Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, FALSE);
0154             }
0155         } else {
0156             if (!pHalData->bCurrentRxAggrEnable || (pHalData->ForcedUsbRxAggrInfo != pHalData->LastUsbRxAggrInfoSetting)) {
0157                 Adapter->HalFunc.HalUsbRxAggrHandler(Adapter, TRUE);
0158             }
0159         }
0160         return;
0161     }
0162 
0163 */
0164     curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
0165     curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
0166 
0167     if ((curTxOkCnt + curRxOkCnt) < 15000000)
0168         return;
0169 
0170     if (curTxOkCnt > 4*curRxOkCnt) {
0171         if (priv->bCurrentRxAggrEnable) {
0172             write_nic_dword(dev, 0x1a8, 0);
0173             priv->bCurrentRxAggrEnable = false;
0174         }
0175     } else {
0176         if (!priv->bCurrentRxAggrEnable && !pHTInfo->bCurrentRT2RTAggregation) {
0177             u32 ulValue;
0178 
0179             ulValue = (pHTInfo->UsbRxFwAggrEn<<24) | (pHTInfo->UsbRxFwAggrPageNum<<16) |
0180                 (pHTInfo->UsbRxFwAggrPacketNum<<8) | (pHTInfo->UsbRxFwAggrTimeout);
0181             /* If usb rx firmware aggregation is enabled,
0182              * when anyone of three threshold conditions above is reached,
0183              * firmware will send aggregated packet to driver.
0184              */
0185             write_nic_dword(dev, 0x1a8, ulValue);
0186             priv->bCurrentRxAggrEnable = true;
0187         }
0188     }
0189 
0190     lastTxOkCnt = priv->stats.txbytesunicast;
0191     lastRxOkCnt = priv->stats.rxbytesunicast;
0192 }   /* dm_CheckEdcaTurbo */
0193 #endif
0194 
0195 void hal_dm_watchdog(struct net_device *dev)
0196 {
0197     /*struct r8192_priv *priv = ieee80211_priv(dev);*/
0198 
0199     /*static u8 previous_bssid[6] ={0};*/
0200 
0201     /*Add by amy 2008/05/15 ,porting from windows code.*/
0202     dm_check_rate_adaptive(dev);
0203     dm_dynamic_txpower(dev);
0204     dm_check_txrateandretrycount(dev);
0205     dm_check_txpower_tracking(dev);
0206     dm_ctrl_initgain_byrssi(dev);
0207     dm_check_edca_turbo(dev);
0208     dm_bandwidth_autoswitch(dev);
0209     dm_check_rx_path_selection(dev);
0210     dm_check_fsync(dev);
0211 
0212     /* Add by amy 2008-05-15 porting from windows code. */
0213     dm_check_pbc_gpio(dev);
0214     dm_send_rssi_tofw(dev);
0215     dm_ctstoself(dev);
0216 #ifdef USB_RX_AGGREGATION_SUPPORT
0217     dm_CheckRxAggregation(dev);
0218 #endif
0219 }   /* HalDmWatchDog */
0220 
0221 /* Decide Rate Adaptive Set according to distance (signal strength)
0222  *  01/11/2008  MHC     Modify input arguments and RATR table level.
0223  *  01/16/2008  MHC     RF_Type is assigned in ReadAdapterInfo(). We must call
0224  *                      the function after making sure RF_Type.
0225  */
0226 void init_rate_adaptive(struct net_device *dev)
0227 {
0228     struct r8192_priv *priv = ieee80211_priv(dev);
0229     prate_adaptive  pra = (prate_adaptive)&priv->rate_adaptive;
0230 
0231     pra->ratr_state = DM_RATR_STA_MAX;
0232     pra->high2low_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH;
0233     pra->low2high_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M + 5;
0234     pra->low2high_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M + 5;
0235 
0236     pra->high_rssi_thresh_for_ra = RATE_ADAPTIVE_TH_HIGH + 5;
0237     pra->low_rssi_thresh_for_ra20M = RATE_ADAPTIVE_TH_LOW_20M;
0238     pra->low_rssi_thresh_for_ra40M = RATE_ADAPTIVE_TH_LOW_40M;
0239 
0240     if (priv->CustomerID == RT_CID_819x_Netcore)
0241         pra->ping_rssi_enable = 1;
0242     else
0243         pra->ping_rssi_enable = 0;
0244     pra->ping_rssi_thresh_for_ra = 15;
0245 
0246     if (priv->rf_type == RF_2T4R) {
0247         /* 07/10/08 MH Modify for RA smooth scheme.
0248          * 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.
0249          */
0250         pra->upper_rssi_threshold_ratr      =   0x8f0f0000;
0251         pra->middle_rssi_threshold_ratr     =   0x8f0ff000;
0252         pra->low_rssi_threshold_ratr        =   0x8f0ff001;
0253         pra->low_rssi_threshold_ratr_40M    =   0x8f0ff005;
0254         pra->low_rssi_threshold_ratr_20M    =   0x8f0ff001;
0255         pra->ping_rssi_ratr =   0x0000000d;/* cosa add for test */
0256     } else if (priv->rf_type == RF_1T2R) {
0257         pra->upper_rssi_threshold_ratr      =   0x000f0000;
0258         pra->middle_rssi_threshold_ratr     =   0x000ff000;
0259         pra->low_rssi_threshold_ratr        =   0x000ff001;
0260         pra->low_rssi_threshold_ratr_40M    =   0x000ff005;
0261         pra->low_rssi_threshold_ratr_20M    =   0x000ff001;
0262         pra->ping_rssi_ratr =   0x0000000d;/* cosa add for test */
0263     }
0264 
0265 }   /* InitRateAdaptive */
0266 
0267 /*-----------------------------------------------------------------------------
0268  * Function:    dm_check_rate_adaptive()
0269  *
0270  * Overview:
0271  *
0272  * Input:       NONE
0273  *
0274  * Output:      NONE
0275  *
0276  * Return:      NONE
0277  *
0278  * Revised History:
0279  *  When        Who     Remark
0280  *  05/26/08    amy Create version 0 porting from windows code.
0281  *
0282  *---------------------------------------------------------------------------*/
0283 static void dm_check_rate_adaptive(struct net_device *dev)
0284 {
0285     struct r8192_priv *priv = ieee80211_priv(dev);
0286     PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
0287     prate_adaptive          pra = (prate_adaptive)&priv->rate_adaptive;
0288     u32                     currentRATR, targetRATR = 0;
0289     u32                     LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
0290     bool                        bshort_gi_enabled = false;
0291     static u8                   ping_rssi_state;
0292 
0293     if (!priv->up) {
0294         RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
0295         return;
0296     }
0297 
0298     if (pra->rate_adaptive_disabled) /* this variable is set by ioctl. */
0299         return;
0300 
0301     /* TODO: Only 11n mode is implemented currently, */
0302     if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
0303           priv->ieee80211->mode == WIRELESS_MODE_N_5G))
0304         return;
0305 
0306     if (priv->ieee80211->state == IEEE80211_LINKED) {
0307         /*RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");*/
0308 
0309         /* Check whether Short GI is enabled */
0310         bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
0311             (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
0312 
0313         pra->upper_rssi_threshold_ratr =
0314                 (pra->upper_rssi_threshold_ratr & (~BIT(31))) |
0315                 ((bshort_gi_enabled) ? BIT(31) : 0);
0316 
0317         pra->middle_rssi_threshold_ratr =
0318                 (pra->middle_rssi_threshold_ratr & (~BIT(31))) |
0319                 ((bshort_gi_enabled) ? BIT(31) : 0);
0320 
0321         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
0322             pra->low_rssi_threshold_ratr =
0323                   (pra->low_rssi_threshold_ratr_40M & (~BIT(31))) |
0324                   ((bshort_gi_enabled) ? BIT(31) : 0);
0325         } else {
0326             pra->low_rssi_threshold_ratr =
0327             (pra->low_rssi_threshold_ratr_20M & (~BIT(31))) |
0328             ((bshort_gi_enabled) ? BIT(31) : 0);
0329         }
0330         /* cosa add for test */
0331         pra->ping_rssi_ratr =
0332                 (pra->ping_rssi_ratr & (~BIT(31))) |
0333                 ((bshort_gi_enabled) ? BIT(31) : 0);
0334 
0335         /* 2007/10/08 MH We support RA smooth scheme now. When it is the first
0336          * time to link with AP. We will not change upper/lower threshold. If
0337          * STA stay in high or low level, we must change two different threshold
0338          * to prevent jumping frequently.
0339          */
0340         if (pra->ratr_state == DM_RATR_STA_HIGH) {
0341             HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra;
0342             LowRSSIThreshForRA  = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
0343                     (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
0344         } else if (pra->ratr_state == DM_RATR_STA_LOW) {
0345             HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
0346             LowRSSIThreshForRA  = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
0347                     (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
0348         } else {
0349             HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
0350             LowRSSIThreshForRA  = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
0351                     (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
0352         }
0353 
0354         /*DbgPrint("[DM] THresh H/L=%d/%d\n\r", RATR.HighRSSIThreshForRA, RATR.LowRSSIThreshForRA);*/
0355         if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) {
0356             /*DbgPrint("[DM] RSSI=%d STA=HIGH\n\r", pHalData->UndecoratedSmoothedPWDB);*/
0357             pra->ratr_state = DM_RATR_STA_HIGH;
0358             targetRATR = pra->upper_rssi_threshold_ratr;
0359         } else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) {
0360             /*DbgPrint("[DM] RSSI=%d STA=Middle\n\r", pHalData->UndecoratedSmoothedPWDB);*/
0361             pra->ratr_state = DM_RATR_STA_MIDDLE;
0362             targetRATR = pra->middle_rssi_threshold_ratr;
0363         } else {
0364             /*DbgPrint("[DM] RSSI=%d STA=LOW\n\r", pHalData->UndecoratedSmoothedPWDB);*/
0365             pra->ratr_state = DM_RATR_STA_LOW;
0366             targetRATR = pra->low_rssi_threshold_ratr;
0367         }
0368 
0369         /* cosa add for test */
0370         if (pra->ping_rssi_enable) {
0371             /*pHalData->UndecoratedSmoothedPWDB = 19;*/
0372             if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) {
0373                 if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
0374                     ping_rssi_state) {
0375                     /*DbgPrint("TestRSSI = %d, set RATR to 0x%x\n", pHalData->UndecoratedSmoothedPWDB, pRA->TestRSSIRATR);*/
0376                     pra->ratr_state = DM_RATR_STA_LOW;
0377                     targetRATR = pra->ping_rssi_ratr;
0378                     ping_rssi_state = 1;
0379                 }
0380                 /*else
0381                     DbgPrint("TestRSSI is between the range.\n");*/
0382             } else {
0383                 /*DbgPrint("TestRSSI Recover to 0x%x\n", targetRATR);*/
0384                 ping_rssi_state = 0;
0385             }
0386         }
0387 
0388         /* 2008.04.01
0389          * For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
0390          */
0391         if (priv->ieee80211->GetHalfNmodeSupportByAPsHandler(dev))
0392             targetRATR &= 0xf00fffff;
0393 
0394         /* Check whether updating of RATR0 is required */
0395         read_nic_dword(dev, RATR0, &currentRATR);
0396         if (targetRATR !=  currentRATR) {
0397             u32 ratr_value;
0398 
0399             ratr_value = targetRATR;
0400             RT_TRACE(COMP_RATE, "currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
0401             if (priv->rf_type == RF_1T2R)
0402                 ratr_value &= ~(RATE_ALL_OFDM_2SS);
0403             write_nic_dword(dev, RATR0, ratr_value);
0404             write_nic_byte(dev, UFWP, 1);
0405 
0406             pra->last_ratr = targetRATR;
0407         }
0408 
0409     } else {
0410         pra->ratr_state = DM_RATR_STA_MAX;
0411     }
0412 
0413 }   /* dm_CheckRateAdaptive */
0414 
0415 static void dm_init_bandwidth_autoswitch(struct net_device *dev)
0416 {
0417     struct r8192_priv *priv = ieee80211_priv(dev);
0418 
0419     priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
0420     priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
0421     priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
0422     priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
0423 
0424 }   /* dm_init_bandwidth_autoswitch */
0425 
0426 static void dm_bandwidth_autoswitch(struct net_device *dev)
0427 {
0428     struct r8192_priv *priv = ieee80211_priv(dev);
0429 
0430     if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 || !priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable)
0431         return;
0432     if (!priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz) { /* If send packets in 40 Mhz in 20/40 */
0433         if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
0434             priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
0435     } else { /* in force send packets in 20 Mhz in 20/40 */
0436         if (priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
0437             priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
0438     }
0439 }   /* dm_BandwidthAutoSwitch */
0440 
0441 /* OFDM default at 0db, index=6. */
0442 static u32 OFDMSwingTable[OFDM_Table_Length] = {
0443     0x7f8001fe, /* 0, +6db */
0444     0x71c001c7, /* 1, +5db */
0445     0x65400195, /* 2, +4db */
0446     0x5a400169, /* 3, +3db */
0447     0x50800142, /* 4, +2db */
0448     0x47c0011f, /* 5, +1db */
0449     0x40000100, /* 6, +0db ===> default, upper for higher temperature, lower for low temperature */
0450     0x390000e4, /* 7, -1db */
0451     0x32c000cb, /* 8, -2db */
0452     0x2d4000b5, /* 9, -3db */
0453     0x288000a2, /* 10, -4db */
0454     0x24000090, /* 11, -5db */
0455     0x20000080, /* 12, -6db */
0456     0x1c800072, /* 13, -7db */
0457     0x19800066, /* 14, -8db */
0458     0x26c0005b, /* 15, -9db */
0459     0x24400051, /* 16, -10db */
0460     0x12000048, /* 17, -11db */
0461     0x10000040  /* 18, -12db */
0462 };
0463 
0464 static u8   CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
0465     {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},   /* 0, +0db ===> CCK40M default */
0466     {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},   /* 1, -1db */
0467     {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},   /* 2, -2db */
0468     {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},   /* 3, -3db */
0469     {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},   /* 4, -4db */
0470     {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},   /* 5, -5db */
0471     {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},   /* 6, -6db ===> CCK20M default */
0472     {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},   /* 7, -7db */
0473     {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},   /* 8, -8db */
0474     {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},   /* 9, -9db */
0475     {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},   /* 10, -10db */
0476     {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}    /* 11, -11db */
0477 };
0478 
0479 static u8   CCKSwingTable_Ch14[CCK_Table_length][8] = {
0480     {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},   /* 0, +0db  ===> CCK40M default */
0481     {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},   /* 1, -1db */
0482     {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},   /* 2, -2db */
0483     {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},   /* 3, -3db */
0484     {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},   /* 4, -4db */
0485     {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},   /* 5, -5db */
0486     {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},   /* 6, -6db  ===> CCK20M default */
0487     {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},   /* 7, -7db */
0488     {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},   /* 8, -8db */
0489     {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},   /* 9, -9db */
0490     {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},   /* 10, -10db */
0491     {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}    /* 11, -11db */
0492 };
0493 
0494 static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
0495 {
0496     struct r8192_priv *priv = ieee80211_priv(dev);
0497     bool                        viviflag = false;
0498     struct tx_config_cmd                    tx_cmd;
0499     u8                      powerlevelOFDM24G;
0500     int                     i = 0, j = 0, k = 0;
0501     u8                      RF_Type, tmp_report[5] = {0, 0, 0, 0, 0};
0502     u32                     Value;
0503     u8                      Pwr_Flag;
0504     u16                     Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0;
0505     /*RT_STATUS             rtStatus = RT_STATUS_SUCCESS;*/
0506     bool rtStatus = true;
0507     u32                     delta = 0;
0508 
0509     write_nic_byte(dev, 0x1ba, 0);
0510 
0511     priv->ieee80211->bdynamic_txpower_enable = false;
0512 
0513     powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
0514     RF_Type = priv->rf_type;
0515     Value = (RF_Type<<8) | powerlevelOFDM24G;
0516 
0517     RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
0518 
0519     for (j = 0; j <= 30; j++) { /* fill tx_cmd */
0520         tx_cmd.cmd_op = TXCMD_SET_TX_PWR_TRACKING;
0521         tx_cmd.cmd_length = sizeof(tx_cmd.cmd_op);
0522         tx_cmd.cmd_value = Value;
0523         rtStatus = SendTxCommandPacket(dev, &tx_cmd, sizeof(struct tx_config_cmd));
0524         if (rtStatus == RT_STATUS_FAILURE)
0525             RT_TRACE(COMP_POWER_TRACKING, "Set configuration with tx cmd queue fail!\n");
0526         usleep_range(1000, 2000);
0527         /*DbgPrint("hi, vivi, strange\n");*/
0528         for (i = 0; i <= 30; i++) {
0529             read_nic_byte(dev, 0x1ba, &Pwr_Flag);
0530 
0531             if (Pwr_Flag == 0) {
0532                 usleep_range(1000, 2000);
0533                 continue;
0534             }
0535             read_nic_word(dev, 0x13c, &Avg_TSSI_Meas);
0536             if (Avg_TSSI_Meas == 0) {
0537                 write_nic_byte(dev, 0x1ba, 0);
0538                 break;
0539             }
0540 
0541             for (k = 0; k < 5; k++) {
0542                 if (k != 4)
0543                     read_nic_byte(dev, 0x134+k, &tmp_report[k]);
0544                 else
0545                     read_nic_byte(dev, 0x13e, &tmp_report[k]);
0546                 RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
0547             }
0548 
0549             /* check if the report value is right */
0550             for (k = 0; k < 5; k++) {
0551                 if (tmp_report[k] <= 20) {
0552                     viviflag = true;
0553                     break;
0554                 }
0555             }
0556             if (viviflag) {
0557                 write_nic_byte(dev, 0x1ba, 0);
0558                 viviflag = false;
0559                 RT_TRACE(COMP_POWER_TRACKING, "we filtered the data\n");
0560                 for (k = 0; k < 5; k++)
0561                     tmp_report[k] = 0;
0562                 break;
0563             }
0564 
0565             for (k = 0; k < 5; k++)
0566                 Avg_TSSI_Meas_from_driver += tmp_report[k];
0567 
0568             Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
0569             RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
0570             TSSI_13dBm = priv->TSSI_13dBm;
0571             RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
0572 
0573             /*if (abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)*/
0574             /* For MacOS-compatible */
0575             if (Avg_TSSI_Meas_from_driver > TSSI_13dBm)
0576                 delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
0577             else
0578                 delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
0579 
0580             if (delta <= E_FOR_TX_POWER_TRACK) {
0581                 priv->ieee80211->bdynamic_txpower_enable = true;
0582                 write_nic_byte(dev, 0x1ba, 0);
0583                 RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
0584                 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
0585                 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
0586                 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation_difference = %d\n", priv->cck_present_attenuation_difference);
0587                 RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation = %d\n", priv->cck_present_attenuation);
0588                 return;
0589             }
0590             if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) {
0591                 if (priv->rfa_txpowertrackingindex > 0) {
0592                     priv->rfa_txpowertrackingindex--;
0593                     if (priv->rfa_txpowertrackingindex_real > 4) {
0594                         priv->rfa_txpowertrackingindex_real--;
0595                         rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
0596                     }
0597                 }
0598             } else {
0599                 if (priv->rfa_txpowertrackingindex < 36) {
0600                     priv->rfa_txpowertrackingindex++;
0601                     priv->rfa_txpowertrackingindex_real++;
0602                     rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
0603                 }
0604             }
0605             priv->cck_present_attenuation_difference
0606                 = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
0607 
0608             if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
0609                 priv->cck_present_attenuation
0610                     = priv->cck_present_attenuation_20Mdefault + priv->cck_present_attenuation_difference;
0611             else
0612                 priv->cck_present_attenuation
0613                     = priv->cck_present_attenuation_40Mdefault + priv->cck_present_attenuation_difference;
0614 
0615             if (priv->cck_present_attenuation > -1 && priv->cck_present_attenuation < 23) {
0616                 if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
0617                     priv->bcck_in_ch14 = true;
0618                     dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
0619                 } else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
0620                     priv->bcck_in_ch14 = false;
0621                     dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
0622                 } else
0623                     dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
0624             }
0625             RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
0626             RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
0627             RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation_difference = %d\n", priv->cck_present_attenuation_difference);
0628             RT_TRACE(COMP_POWER_TRACKING, "priv->cck_present_attenuation = %d\n", priv->cck_present_attenuation);
0629 
0630             if (priv->cck_present_attenuation_difference <= -12 || priv->cck_present_attenuation_difference >= 24) {
0631                 priv->ieee80211->bdynamic_txpower_enable = true;
0632                 write_nic_byte(dev, 0x1ba, 0);
0633                 RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
0634                 return;
0635             }
0636 
0637             write_nic_byte(dev, 0x1ba, 0);
0638             Avg_TSSI_Meas_from_driver = 0;
0639             for (k = 0; k < 5; k++)
0640                 tmp_report[k] = 0;
0641             break;
0642         }
0643     }
0644     priv->ieee80211->bdynamic_txpower_enable = true;
0645     write_nic_byte(dev, 0x1ba, 0);
0646 }
0647 
0648 static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
0649 {
0650 #define ThermalMeterVal 9
0651     struct r8192_priv *priv = ieee80211_priv(dev);
0652     u32 tmpRegA, TempCCk;
0653     u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
0654     int i = 0, CCKSwingNeedUpdate = 0;
0655 
0656     if (!priv->btxpower_trackingInit) {
0657         /* Query OFDM default setting */
0658         tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
0659         for (i = 0; i < OFDM_Table_Length; i++) { /* find the index */
0660             if (tmpRegA == OFDMSwingTable[i]) {
0661                 priv->OFDM_index = (u8)i;
0662                 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
0663                     rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
0664             }
0665         }
0666 
0667         /* Query CCK default setting From 0xa22 */
0668         TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
0669         for (i = 0; i < CCK_Table_length; i++) {
0670             if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
0671                 priv->CCK_index = (u8) i;
0672                 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
0673                     rCCK0_TxFilter1, TempCCk, priv->CCK_index);
0674                 break;
0675             }
0676         }
0677         priv->btxpower_trackingInit = true;
0678         /*pHalData->TXPowercount = 0;*/
0679         return;
0680     }
0681 
0682     /* ==========================
0683      * this is only for test, should be masked
0684      * ==========================
0685      */
0686 
0687     /* read and filter out unreasonable value */
0688     tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);    /* 0x12: RF Reg[10:7] */
0689     RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
0690     if (tmpRegA < 3 || tmpRegA > 13)
0691         return;
0692     if (tmpRegA >= 12)  /* if over 12, TP will be bad when high temperature */
0693         tmpRegA = 12;
0694     RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
0695     priv->ThermalMeter[0] = ThermalMeterVal;    /* We use fixed value by Bryant's suggestion */
0696     priv->ThermalMeter[1] = ThermalMeterVal;    /* We use fixed value by Bryant's suggestion */
0697 
0698     /* Get current RF-A temperature index */
0699     if (priv->ThermalMeter[0] >= (u8)tmpRegA) { /* lower temperature */
0700         tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
0701         tmpCCK40Mindex = tmpCCK20Mindex - 6;
0702         if (tmpOFDMindex >= OFDM_Table_Length)
0703             tmpOFDMindex = OFDM_Table_Length-1;
0704         if (tmpCCK20Mindex >= CCK_Table_length)
0705             tmpCCK20Mindex = CCK_Table_length-1;
0706         if (tmpCCK40Mindex >= CCK_Table_length)
0707             tmpCCK40Mindex = CCK_Table_length-1;
0708     } else {
0709         tmpval = (u8)tmpRegA - priv->ThermalMeter[0];
0710 
0711         if (tmpval >= 6) {
0712             /* higher temperature */
0713             tmpOFDMindex = 0;
0714             tmpCCK20Mindex = 0;
0715         } else {
0716             /* max to +6dB */
0717             tmpOFDMindex = 6 - tmpval;
0718             tmpCCK20Mindex = 6 - tmpval;
0719         }
0720         tmpCCK40Mindex = 0;
0721     }
0722     /*DbgPrint("%ddb, tmpOFDMindex = %d, tmpCCK20Mindex = %d, tmpCCK40Mindex = %d",
0723         ((u1Byte)tmpRegA - pHalData->ThermalMeter[0]),
0724         tmpOFDMindex, tmpCCK20Mindex, tmpCCK40Mindex);*/
0725     if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)  /* 40M */
0726         tmpCCKindex = tmpCCK40Mindex;
0727     else
0728         tmpCCKindex = tmpCCK20Mindex;
0729 
0730     if (priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14) {
0731         priv->bcck_in_ch14 = true;
0732         CCKSwingNeedUpdate = 1;
0733     } else if (priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14) {
0734         priv->bcck_in_ch14 = false;
0735         CCKSwingNeedUpdate = 1;
0736     }
0737 
0738     if (priv->CCK_index != tmpCCKindex) {
0739         priv->CCK_index = tmpCCKindex;
0740         CCKSwingNeedUpdate = 1;
0741     }
0742 
0743     if (CCKSwingNeedUpdate) {
0744         /*DbgPrint("Update CCK Swing, CCK_index = %d\n", pHalData->CCK_index);*/
0745         dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
0746     }
0747     if (priv->OFDM_index != tmpOFDMindex) {
0748         priv->OFDM_index = tmpOFDMindex;
0749         rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
0750         RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
0751             priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
0752     }
0753     priv->txpower_count = 0;
0754 }
0755 
0756 void dm_txpower_trackingcallback(struct work_struct *work)
0757 {
0758     struct delayed_work *dwork = to_delayed_work(work);
0759     struct r8192_priv *priv = container_of(dwork, struct r8192_priv, txpower_tracking_wq);
0760     struct net_device *dev = priv->ieee80211->dev;
0761 
0762     if (priv->bDcut)
0763         dm_TXPowerTrackingCallback_TSSI(dev);
0764     else
0765         dm_TXPowerTrackingCallback_ThermalMeter(dev);
0766 }
0767 
0768 static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
0769 {
0770     struct r8192_priv *priv = ieee80211_priv(dev);
0771 
0772     /* Initial the Tx BB index and mapping value */
0773     priv->txbbgain_table[0].txbb_iq_amplifygain =           12;
0774     priv->txbbgain_table[0].txbbgain_value = 0x7f8001fe;
0775     priv->txbbgain_table[1].txbb_iq_amplifygain =           11;
0776     priv->txbbgain_table[1].txbbgain_value = 0x788001e2;
0777     priv->txbbgain_table[2].txbb_iq_amplifygain =           10;
0778     priv->txbbgain_table[2].txbbgain_value = 0x71c001c7;
0779     priv->txbbgain_table[3].txbb_iq_amplifygain =           9;
0780     priv->txbbgain_table[3].txbbgain_value = 0x6b8001ae;
0781     priv->txbbgain_table[4].txbb_iq_amplifygain =              8;
0782     priv->txbbgain_table[4].txbbgain_value = 0x65400195;
0783     priv->txbbgain_table[5].txbb_iq_amplifygain =              7;
0784     priv->txbbgain_table[5].txbbgain_value = 0x5fc0017f;
0785     priv->txbbgain_table[6].txbb_iq_amplifygain =              6;
0786     priv->txbbgain_table[6].txbbgain_value = 0x5a400169;
0787     priv->txbbgain_table[7].txbb_iq_amplifygain =              5;
0788     priv->txbbgain_table[7].txbbgain_value = 0x55400155;
0789     priv->txbbgain_table[8].txbb_iq_amplifygain =              4;
0790     priv->txbbgain_table[8].txbbgain_value = 0x50800142;
0791     priv->txbbgain_table[9].txbb_iq_amplifygain =              3;
0792     priv->txbbgain_table[9].txbbgain_value = 0x4c000130;
0793     priv->txbbgain_table[10].txbb_iq_amplifygain =             2;
0794     priv->txbbgain_table[10].txbbgain_value = 0x47c0011f;
0795     priv->txbbgain_table[11].txbb_iq_amplifygain =             1;
0796     priv->txbbgain_table[11].txbbgain_value = 0x43c0010f;
0797     priv->txbbgain_table[12].txbb_iq_amplifygain =             0;
0798     priv->txbbgain_table[12].txbbgain_value = 0x40000100;
0799     priv->txbbgain_table[13].txbb_iq_amplifygain =             -1;
0800     priv->txbbgain_table[13].txbbgain_value = 0x3c8000f2;
0801     priv->txbbgain_table[14].txbb_iq_amplifygain =           -2;
0802     priv->txbbgain_table[14].txbbgain_value = 0x390000e4;
0803     priv->txbbgain_table[15].txbb_iq_amplifygain =           -3;
0804     priv->txbbgain_table[15].txbbgain_value = 0x35c000d7;
0805     priv->txbbgain_table[16].txbb_iq_amplifygain =           -4;
0806     priv->txbbgain_table[16].txbbgain_value = 0x32c000cb;
0807     priv->txbbgain_table[17].txbb_iq_amplifygain =           -5;
0808     priv->txbbgain_table[17].txbbgain_value = 0x300000c0;
0809     priv->txbbgain_table[18].txbb_iq_amplifygain =              -6;
0810     priv->txbbgain_table[18].txbbgain_value = 0x2d4000b5;
0811     priv->txbbgain_table[19].txbb_iq_amplifygain =           -7;
0812     priv->txbbgain_table[19].txbbgain_value = 0x2ac000ab;
0813     priv->txbbgain_table[20].txbb_iq_amplifygain =           -8;
0814     priv->txbbgain_table[20].txbbgain_value = 0x288000a2;
0815     priv->txbbgain_table[21].txbb_iq_amplifygain =           -9;
0816     priv->txbbgain_table[21].txbbgain_value = 0x26000098;
0817     priv->txbbgain_table[22].txbb_iq_amplifygain =           -10;
0818     priv->txbbgain_table[22].txbbgain_value = 0x24000090;
0819     priv->txbbgain_table[23].txbb_iq_amplifygain =           -11;
0820     priv->txbbgain_table[23].txbbgain_value = 0x22000088;
0821     priv->txbbgain_table[24].txbb_iq_amplifygain =           -12;
0822     priv->txbbgain_table[24].txbbgain_value = 0x20000080;
0823     priv->txbbgain_table[25].txbb_iq_amplifygain =           -13;
0824     priv->txbbgain_table[25].txbbgain_value = 0x1a00006c;
0825     priv->txbbgain_table[26].txbb_iq_amplifygain =           -14;
0826     priv->txbbgain_table[26].txbbgain_value = 0x1c800072;
0827     priv->txbbgain_table[27].txbb_iq_amplifygain =           -15;
0828     priv->txbbgain_table[27].txbbgain_value = 0x18000060;
0829     priv->txbbgain_table[28].txbb_iq_amplifygain =           -16;
0830     priv->txbbgain_table[28].txbbgain_value = 0x19800066;
0831     priv->txbbgain_table[29].txbb_iq_amplifygain =           -17;
0832     priv->txbbgain_table[29].txbbgain_value = 0x15800056;
0833     priv->txbbgain_table[30].txbb_iq_amplifygain =           -18;
0834     priv->txbbgain_table[30].txbbgain_value = 0x26c0005b;
0835     priv->txbbgain_table[31].txbb_iq_amplifygain =           -19;
0836     priv->txbbgain_table[31].txbbgain_value = 0x14400051;
0837     priv->txbbgain_table[32].txbb_iq_amplifygain =           -20;
0838     priv->txbbgain_table[32].txbbgain_value = 0x24400051;
0839     priv->txbbgain_table[33].txbb_iq_amplifygain =           -21;
0840     priv->txbbgain_table[33].txbbgain_value = 0x1300004c;
0841     priv->txbbgain_table[34].txbb_iq_amplifygain =           -22;
0842     priv->txbbgain_table[34].txbbgain_value = 0x12000048;
0843     priv->txbbgain_table[35].txbb_iq_amplifygain =           -23;
0844     priv->txbbgain_table[35].txbbgain_value = 0x11000044;
0845     priv->txbbgain_table[36].txbb_iq_amplifygain =           -24;
0846     priv->txbbgain_table[36].txbbgain_value = 0x10000040;
0847 
0848     /* ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
0849      * This Table is for CH1~CH13
0850      */
0851     priv->cck_txbbgain_table[0].ccktxbb_valuearray[0] = 0x36;
0852     priv->cck_txbbgain_table[0].ccktxbb_valuearray[1] = 0x35;
0853     priv->cck_txbbgain_table[0].ccktxbb_valuearray[2] = 0x2e;
0854     priv->cck_txbbgain_table[0].ccktxbb_valuearray[3] = 0x25;
0855     priv->cck_txbbgain_table[0].ccktxbb_valuearray[4] = 0x1c;
0856     priv->cck_txbbgain_table[0].ccktxbb_valuearray[5] = 0x12;
0857     priv->cck_txbbgain_table[0].ccktxbb_valuearray[6] = 0x09;
0858     priv->cck_txbbgain_table[0].ccktxbb_valuearray[7] = 0x04;
0859 
0860     priv->cck_txbbgain_table[1].ccktxbb_valuearray[0] = 0x33;
0861     priv->cck_txbbgain_table[1].ccktxbb_valuearray[1] = 0x32;
0862     priv->cck_txbbgain_table[1].ccktxbb_valuearray[2] = 0x2b;
0863     priv->cck_txbbgain_table[1].ccktxbb_valuearray[3] = 0x23;
0864     priv->cck_txbbgain_table[1].ccktxbb_valuearray[4] = 0x1a;
0865     priv->cck_txbbgain_table[1].ccktxbb_valuearray[5] = 0x11;
0866     priv->cck_txbbgain_table[1].ccktxbb_valuearray[6] = 0x08;
0867     priv->cck_txbbgain_table[1].ccktxbb_valuearray[7] = 0x04;
0868 
0869     priv->cck_txbbgain_table[2].ccktxbb_valuearray[0] = 0x30;
0870     priv->cck_txbbgain_table[2].ccktxbb_valuearray[1] = 0x2f;
0871     priv->cck_txbbgain_table[2].ccktxbb_valuearray[2] = 0x29;
0872     priv->cck_txbbgain_table[2].ccktxbb_valuearray[3] = 0x21;
0873     priv->cck_txbbgain_table[2].ccktxbb_valuearray[4] = 0x19;
0874     priv->cck_txbbgain_table[2].ccktxbb_valuearray[5] = 0x10;
0875     priv->cck_txbbgain_table[2].ccktxbb_valuearray[6] = 0x08;
0876     priv->cck_txbbgain_table[2].ccktxbb_valuearray[7] = 0x03;
0877 
0878     priv->cck_txbbgain_table[3].ccktxbb_valuearray[0] = 0x2d;
0879     priv->cck_txbbgain_table[3].ccktxbb_valuearray[1] = 0x2d;
0880     priv->cck_txbbgain_table[3].ccktxbb_valuearray[2] = 0x27;
0881     priv->cck_txbbgain_table[3].ccktxbb_valuearray[3] = 0x1f;
0882     priv->cck_txbbgain_table[3].ccktxbb_valuearray[4] = 0x18;
0883     priv->cck_txbbgain_table[3].ccktxbb_valuearray[5] = 0x0f;
0884     priv->cck_txbbgain_table[3].ccktxbb_valuearray[6] = 0x08;
0885     priv->cck_txbbgain_table[3].ccktxbb_valuearray[7] = 0x03;
0886 
0887     priv->cck_txbbgain_table[4].ccktxbb_valuearray[0] = 0x2b;
0888     priv->cck_txbbgain_table[4].ccktxbb_valuearray[1] = 0x2a;
0889     priv->cck_txbbgain_table[4].ccktxbb_valuearray[2] = 0x25;
0890     priv->cck_txbbgain_table[4].ccktxbb_valuearray[3] = 0x1e;
0891     priv->cck_txbbgain_table[4].ccktxbb_valuearray[4] = 0x16;
0892     priv->cck_txbbgain_table[4].ccktxbb_valuearray[5] = 0x0e;
0893     priv->cck_txbbgain_table[4].ccktxbb_valuearray[6] = 0x07;
0894     priv->cck_txbbgain_table[4].ccktxbb_valuearray[7] = 0x03;
0895 
0896     priv->cck_txbbgain_table[5].ccktxbb_valuearray[0] = 0x28;
0897     priv->cck_txbbgain_table[5].ccktxbb_valuearray[1] = 0x28;
0898     priv->cck_txbbgain_table[5].ccktxbb_valuearray[2] = 0x22;
0899     priv->cck_txbbgain_table[5].ccktxbb_valuearray[3] = 0x1c;
0900     priv->cck_txbbgain_table[5].ccktxbb_valuearray[4] = 0x15;
0901     priv->cck_txbbgain_table[5].ccktxbb_valuearray[5] = 0x0d;
0902     priv->cck_txbbgain_table[5].ccktxbb_valuearray[6] = 0x07;
0903     priv->cck_txbbgain_table[5].ccktxbb_valuearray[7] = 0x03;
0904 
0905     priv->cck_txbbgain_table[6].ccktxbb_valuearray[0] = 0x26;
0906     priv->cck_txbbgain_table[6].ccktxbb_valuearray[1] = 0x25;
0907     priv->cck_txbbgain_table[6].ccktxbb_valuearray[2] = 0x21;
0908     priv->cck_txbbgain_table[6].ccktxbb_valuearray[3] = 0x1b;
0909     priv->cck_txbbgain_table[6].ccktxbb_valuearray[4] = 0x14;
0910     priv->cck_txbbgain_table[6].ccktxbb_valuearray[5] = 0x0d;
0911     priv->cck_txbbgain_table[6].ccktxbb_valuearray[6] = 0x06;
0912     priv->cck_txbbgain_table[6].ccktxbb_valuearray[7] = 0x03;
0913 
0914     priv->cck_txbbgain_table[7].ccktxbb_valuearray[0] = 0x24;
0915     priv->cck_txbbgain_table[7].ccktxbb_valuearray[1] = 0x23;
0916     priv->cck_txbbgain_table[7].ccktxbb_valuearray[2] = 0x1f;
0917     priv->cck_txbbgain_table[7].ccktxbb_valuearray[3] = 0x19;
0918     priv->cck_txbbgain_table[7].ccktxbb_valuearray[4] = 0x13;
0919     priv->cck_txbbgain_table[7].ccktxbb_valuearray[5] = 0x0c;
0920     priv->cck_txbbgain_table[7].ccktxbb_valuearray[6] = 0x06;
0921     priv->cck_txbbgain_table[7].ccktxbb_valuearray[7] = 0x03;
0922 
0923     priv->cck_txbbgain_table[8].ccktxbb_valuearray[0] = 0x22;
0924     priv->cck_txbbgain_table[8].ccktxbb_valuearray[1] = 0x21;
0925     priv->cck_txbbgain_table[8].ccktxbb_valuearray[2] = 0x1d;
0926     priv->cck_txbbgain_table[8].ccktxbb_valuearray[3] = 0x18;
0927     priv->cck_txbbgain_table[8].ccktxbb_valuearray[4] = 0x11;
0928     priv->cck_txbbgain_table[8].ccktxbb_valuearray[5] = 0x0b;
0929     priv->cck_txbbgain_table[8].ccktxbb_valuearray[6] = 0x06;
0930     priv->cck_txbbgain_table[8].ccktxbb_valuearray[7] = 0x02;
0931 
0932     priv->cck_txbbgain_table[9].ccktxbb_valuearray[0] = 0x20;
0933     priv->cck_txbbgain_table[9].ccktxbb_valuearray[1] = 0x20;
0934     priv->cck_txbbgain_table[9].ccktxbb_valuearray[2] = 0x1b;
0935     priv->cck_txbbgain_table[9].ccktxbb_valuearray[3] = 0x16;
0936     priv->cck_txbbgain_table[9].ccktxbb_valuearray[4] = 0x11;
0937     priv->cck_txbbgain_table[9].ccktxbb_valuearray[5] = 0x08;
0938     priv->cck_txbbgain_table[9].ccktxbb_valuearray[6] = 0x05;
0939     priv->cck_txbbgain_table[9].ccktxbb_valuearray[7] = 0x02;
0940 
0941     priv->cck_txbbgain_table[10].ccktxbb_valuearray[0] = 0x1f;
0942     priv->cck_txbbgain_table[10].ccktxbb_valuearray[1] = 0x1e;
0943     priv->cck_txbbgain_table[10].ccktxbb_valuearray[2] = 0x1a;
0944     priv->cck_txbbgain_table[10].ccktxbb_valuearray[3] = 0x15;
0945     priv->cck_txbbgain_table[10].ccktxbb_valuearray[4] = 0x10;
0946     priv->cck_txbbgain_table[10].ccktxbb_valuearray[5] = 0x0a;
0947     priv->cck_txbbgain_table[10].ccktxbb_valuearray[6] = 0x05;
0948     priv->cck_txbbgain_table[10].ccktxbb_valuearray[7] = 0x02;
0949 
0950     priv->cck_txbbgain_table[11].ccktxbb_valuearray[0] = 0x1d;
0951     priv->cck_txbbgain_table[11].ccktxbb_valuearray[1] = 0x1c;
0952     priv->cck_txbbgain_table[11].ccktxbb_valuearray[2] = 0x18;
0953     priv->cck_txbbgain_table[11].ccktxbb_valuearray[3] = 0x14;
0954     priv->cck_txbbgain_table[11].ccktxbb_valuearray[4] = 0x0f;
0955     priv->cck_txbbgain_table[11].ccktxbb_valuearray[5] = 0x0a;
0956     priv->cck_txbbgain_table[11].ccktxbb_valuearray[6] = 0x05;
0957     priv->cck_txbbgain_table[11].ccktxbb_valuearray[7] = 0x02;
0958 
0959     priv->cck_txbbgain_table[12].ccktxbb_valuearray[0] = 0x1b;
0960     priv->cck_txbbgain_table[12].ccktxbb_valuearray[1] = 0x1a;
0961     priv->cck_txbbgain_table[12].ccktxbb_valuearray[2] = 0x17;
0962     priv->cck_txbbgain_table[12].ccktxbb_valuearray[3] = 0x13;
0963     priv->cck_txbbgain_table[12].ccktxbb_valuearray[4] = 0x0e;
0964     priv->cck_txbbgain_table[12].ccktxbb_valuearray[5] = 0x09;
0965     priv->cck_txbbgain_table[12].ccktxbb_valuearray[6] = 0x04;
0966     priv->cck_txbbgain_table[12].ccktxbb_valuearray[7] = 0x02;
0967 
0968     priv->cck_txbbgain_table[13].ccktxbb_valuearray[0] = 0x1a;
0969     priv->cck_txbbgain_table[13].ccktxbb_valuearray[1] = 0x19;
0970     priv->cck_txbbgain_table[13].ccktxbb_valuearray[2] = 0x16;
0971     priv->cck_txbbgain_table[13].ccktxbb_valuearray[3] = 0x12;
0972     priv->cck_txbbgain_table[13].ccktxbb_valuearray[4] = 0x0d;
0973     priv->cck_txbbgain_table[13].ccktxbb_valuearray[5] = 0x09;
0974     priv->cck_txbbgain_table[13].ccktxbb_valuearray[6] = 0x04;
0975     priv->cck_txbbgain_table[13].ccktxbb_valuearray[7] = 0x02;
0976 
0977     priv->cck_txbbgain_table[14].ccktxbb_valuearray[0] = 0x18;
0978     priv->cck_txbbgain_table[14].ccktxbb_valuearray[1] = 0x17;
0979     priv->cck_txbbgain_table[14].ccktxbb_valuearray[2] = 0x15;
0980     priv->cck_txbbgain_table[14].ccktxbb_valuearray[3] = 0x11;
0981     priv->cck_txbbgain_table[14].ccktxbb_valuearray[4] = 0x0c;
0982     priv->cck_txbbgain_table[14].ccktxbb_valuearray[5] = 0x08;
0983     priv->cck_txbbgain_table[14].ccktxbb_valuearray[6] = 0x04;
0984     priv->cck_txbbgain_table[14].ccktxbb_valuearray[7] = 0x02;
0985 
0986     priv->cck_txbbgain_table[15].ccktxbb_valuearray[0] = 0x17;
0987     priv->cck_txbbgain_table[15].ccktxbb_valuearray[1] = 0x16;
0988     priv->cck_txbbgain_table[15].ccktxbb_valuearray[2] = 0x13;
0989     priv->cck_txbbgain_table[15].ccktxbb_valuearray[3] = 0x10;
0990     priv->cck_txbbgain_table[15].ccktxbb_valuearray[4] = 0x0c;
0991     priv->cck_txbbgain_table[15].ccktxbb_valuearray[5] = 0x08;
0992     priv->cck_txbbgain_table[15].ccktxbb_valuearray[6] = 0x04;
0993     priv->cck_txbbgain_table[15].ccktxbb_valuearray[7] = 0x02;
0994 
0995     priv->cck_txbbgain_table[16].ccktxbb_valuearray[0] = 0x16;
0996     priv->cck_txbbgain_table[16].ccktxbb_valuearray[1] = 0x15;
0997     priv->cck_txbbgain_table[16].ccktxbb_valuearray[2] = 0x12;
0998     priv->cck_txbbgain_table[16].ccktxbb_valuearray[3] = 0x0f;
0999     priv->cck_txbbgain_table[16].ccktxbb_valuearray[4] = 0x0b;
1000     priv->cck_txbbgain_table[16].ccktxbb_valuearray[5] = 0x07;
1001     priv->cck_txbbgain_table[16].ccktxbb_valuearray[6] = 0x04;
1002     priv->cck_txbbgain_table[16].ccktxbb_valuearray[7] = 0x01;
1003 
1004     priv->cck_txbbgain_table[17].ccktxbb_valuearray[0] = 0x14;
1005     priv->cck_txbbgain_table[17].ccktxbb_valuearray[1] = 0x14;
1006     priv->cck_txbbgain_table[17].ccktxbb_valuearray[2] = 0x11;
1007     priv->cck_txbbgain_table[17].ccktxbb_valuearray[3] = 0x0e;
1008     priv->cck_txbbgain_table[17].ccktxbb_valuearray[4] = 0x0b;
1009     priv->cck_txbbgain_table[17].ccktxbb_valuearray[5] = 0x07;
1010     priv->cck_txbbgain_table[17].ccktxbb_valuearray[6] = 0x03;
1011     priv->cck_txbbgain_table[17].ccktxbb_valuearray[7] = 0x02;
1012 
1013     priv->cck_txbbgain_table[18].ccktxbb_valuearray[0] = 0x13;
1014     priv->cck_txbbgain_table[18].ccktxbb_valuearray[1] = 0x13;
1015     priv->cck_txbbgain_table[18].ccktxbb_valuearray[2] = 0x10;
1016     priv->cck_txbbgain_table[18].ccktxbb_valuearray[3] = 0x0d;
1017     priv->cck_txbbgain_table[18].ccktxbb_valuearray[4] = 0x0a;
1018     priv->cck_txbbgain_table[18].ccktxbb_valuearray[5] = 0x06;
1019     priv->cck_txbbgain_table[18].ccktxbb_valuearray[6] = 0x03;
1020     priv->cck_txbbgain_table[18].ccktxbb_valuearray[7] = 0x01;
1021 
1022     priv->cck_txbbgain_table[19].ccktxbb_valuearray[0] = 0x12;
1023     priv->cck_txbbgain_table[19].ccktxbb_valuearray[1] = 0x12;
1024     priv->cck_txbbgain_table[19].ccktxbb_valuearray[2] = 0x0f;
1025     priv->cck_txbbgain_table[19].ccktxbb_valuearray[3] = 0x0c;
1026     priv->cck_txbbgain_table[19].ccktxbb_valuearray[4] = 0x09;
1027     priv->cck_txbbgain_table[19].ccktxbb_valuearray[5] = 0x06;
1028     priv->cck_txbbgain_table[19].ccktxbb_valuearray[6] = 0x03;
1029     priv->cck_txbbgain_table[19].ccktxbb_valuearray[7] = 0x01;
1030 
1031     priv->cck_txbbgain_table[20].ccktxbb_valuearray[0] = 0x11;
1032     priv->cck_txbbgain_table[20].ccktxbb_valuearray[1] = 0x11;
1033     priv->cck_txbbgain_table[20].ccktxbb_valuearray[2] = 0x0f;
1034     priv->cck_txbbgain_table[20].ccktxbb_valuearray[3] = 0x0c;
1035     priv->cck_txbbgain_table[20].ccktxbb_valuearray[4] = 0x09;
1036     priv->cck_txbbgain_table[20].ccktxbb_valuearray[5] = 0x06;
1037     priv->cck_txbbgain_table[20].ccktxbb_valuearray[6] = 0x03;
1038     priv->cck_txbbgain_table[20].ccktxbb_valuearray[7] = 0x01;
1039 
1040     priv->cck_txbbgain_table[21].ccktxbb_valuearray[0] = 0x10;
1041     priv->cck_txbbgain_table[21].ccktxbb_valuearray[1] = 0x10;
1042     priv->cck_txbbgain_table[21].ccktxbb_valuearray[2] = 0x0e;
1043     priv->cck_txbbgain_table[21].ccktxbb_valuearray[3] = 0x0b;
1044     priv->cck_txbbgain_table[21].ccktxbb_valuearray[4] = 0x08;
1045     priv->cck_txbbgain_table[21].ccktxbb_valuearray[5] = 0x05;
1046     priv->cck_txbbgain_table[21].ccktxbb_valuearray[6] = 0x03;
1047     priv->cck_txbbgain_table[21].ccktxbb_valuearray[7] = 0x01;
1048 
1049     priv->cck_txbbgain_table[22].ccktxbb_valuearray[0] = 0x0f;
1050     priv->cck_txbbgain_table[22].ccktxbb_valuearray[1] = 0x0f;
1051     priv->cck_txbbgain_table[22].ccktxbb_valuearray[2] = 0x0d;
1052     priv->cck_txbbgain_table[22].ccktxbb_valuearray[3] = 0x0b;
1053     priv->cck_txbbgain_table[22].ccktxbb_valuearray[4] = 0x08;
1054     priv->cck_txbbgain_table[22].ccktxbb_valuearray[5] = 0x05;
1055     priv->cck_txbbgain_table[22].ccktxbb_valuearray[6] = 0x03;
1056     priv->cck_txbbgain_table[22].ccktxbb_valuearray[7] = 0x01;
1057 
1058     /* ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
1059      * This Table is for CH14
1060      */
1061     priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[0] = 0x36;
1062     priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[1] = 0x35;
1063     priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[2] = 0x2e;
1064     priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[3] = 0x1b;
1065     priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[4] = 0x00;
1066     priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[5] = 0x00;
1067     priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[6] = 0x00;
1068     priv->cck_txbbgain_ch14_table[0].ccktxbb_valuearray[7] = 0x00;
1069 
1070     priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[0] = 0x33;
1071     priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[1] = 0x32;
1072     priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[2] = 0x2b;
1073     priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[3] = 0x19;
1074     priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[4] = 0x00;
1075     priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[5] = 0x00;
1076     priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[6] = 0x00;
1077     priv->cck_txbbgain_ch14_table[1].ccktxbb_valuearray[7] = 0x00;
1078 
1079     priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[0] = 0x30;
1080     priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[1] = 0x2f;
1081     priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[2] = 0x29;
1082     priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[3] = 0x18;
1083     priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[4] = 0x00;
1084     priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[5] = 0x00;
1085     priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[6] = 0x00;
1086     priv->cck_txbbgain_ch14_table[2].ccktxbb_valuearray[7] = 0x00;
1087 
1088     priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[0] = 0x2d;
1089     priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[1] = 0x2d;
1090     priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[2] = 0x27;
1091     priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[3] = 0x17;
1092     priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[4] = 0x00;
1093     priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[5] = 0x00;
1094     priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[6] = 0x00;
1095     priv->cck_txbbgain_ch14_table[3].ccktxbb_valuearray[7] = 0x00;
1096 
1097     priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[0] = 0x2b;
1098     priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[1] = 0x2a;
1099     priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[2] = 0x25;
1100     priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[3] = 0x15;
1101     priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[4] = 0x00;
1102     priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[5] = 0x00;
1103     priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[6] = 0x00;
1104     priv->cck_txbbgain_ch14_table[4].ccktxbb_valuearray[7] = 0x00;
1105 
1106     priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[0] = 0x28;
1107     priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[1] = 0x28;
1108     priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[2] = 0x22;
1109     priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[3] = 0x14;
1110     priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[4] = 0x00;
1111     priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[5] = 0x00;
1112     priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[6] = 0x00;
1113     priv->cck_txbbgain_ch14_table[5].ccktxbb_valuearray[7] = 0x00;
1114 
1115     priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[0] = 0x26;
1116     priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[1] = 0x25;
1117     priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[2] = 0x21;
1118     priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[3] = 0x13;
1119     priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[4] = 0x00;
1120     priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[5] = 0x00;
1121     priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[6] = 0x00;
1122     priv->cck_txbbgain_ch14_table[6].ccktxbb_valuearray[7] = 0x00;
1123 
1124     priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[0] = 0x24;
1125     priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[1] = 0x23;
1126     priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[2] = 0x1f;
1127     priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[3] = 0x12;
1128     priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[4] = 0x00;
1129     priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[5] = 0x00;
1130     priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[6] = 0x00;
1131     priv->cck_txbbgain_ch14_table[7].ccktxbb_valuearray[7] = 0x00;
1132 
1133     priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[0] = 0x22;
1134     priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[1] = 0x21;
1135     priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[2] = 0x1d;
1136     priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[3] = 0x11;
1137     priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[4] = 0x00;
1138     priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[5] = 0x00;
1139     priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[6] = 0x00;
1140     priv->cck_txbbgain_ch14_table[8].ccktxbb_valuearray[7] = 0x00;
1141 
1142     priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[0] = 0x20;
1143     priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[1] = 0x20;
1144     priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[2] = 0x1b;
1145     priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[3] = 0x10;
1146     priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[4] = 0x00;
1147     priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[5] = 0x00;
1148     priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[6] = 0x00;
1149     priv->cck_txbbgain_ch14_table[9].ccktxbb_valuearray[7] = 0x00;
1150 
1151     priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[0] = 0x1f;
1152     priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[1] = 0x1e;
1153     priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[2] = 0x1a;
1154     priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[3] = 0x0f;
1155     priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[4] = 0x00;
1156     priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[5] = 0x00;
1157     priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[6] = 0x00;
1158     priv->cck_txbbgain_ch14_table[10].ccktxbb_valuearray[7] = 0x00;
1159 
1160     priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[0] = 0x1d;
1161     priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[1] = 0x1c;
1162     priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[2] = 0x18;
1163     priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[3] = 0x0e;
1164     priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[4] = 0x00;
1165     priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[5] = 0x00;
1166     priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[6] = 0x00;
1167     priv->cck_txbbgain_ch14_table[11].ccktxbb_valuearray[7] = 0x00;
1168 
1169     priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[0] = 0x1b;
1170     priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[1] = 0x1a;
1171     priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[2] = 0x17;
1172     priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[3] = 0x0e;
1173     priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[4] = 0x00;
1174     priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[5] = 0x00;
1175     priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[6] = 0x00;
1176     priv->cck_txbbgain_ch14_table[12].ccktxbb_valuearray[7] = 0x00;
1177 
1178     priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[0] = 0x1a;
1179     priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[1] = 0x19;
1180     priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[2] = 0x16;
1181     priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[3] = 0x0d;
1182     priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[4] = 0x00;
1183     priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[5] = 0x00;
1184     priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[6] = 0x00;
1185     priv->cck_txbbgain_ch14_table[13].ccktxbb_valuearray[7] = 0x00;
1186 
1187     priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[0] = 0x18;
1188     priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[1] = 0x17;
1189     priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[2] = 0x15;
1190     priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[3] = 0x0c;
1191     priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[4] = 0x00;
1192     priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[5] = 0x00;
1193     priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[6] = 0x00;
1194     priv->cck_txbbgain_ch14_table[14].ccktxbb_valuearray[7] = 0x00;
1195 
1196     priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[0] = 0x17;
1197     priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[1] = 0x16;
1198     priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[2] = 0x13;
1199     priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[3] = 0x0b;
1200     priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[4] = 0x00;
1201     priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[5] = 0x00;
1202     priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[6] = 0x00;
1203     priv->cck_txbbgain_ch14_table[15].ccktxbb_valuearray[7] = 0x00;
1204 
1205     priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[0] = 0x16;
1206     priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[1] = 0x15;
1207     priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[2] = 0x12;
1208     priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[3] = 0x0b;
1209     priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[4] = 0x00;
1210     priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[5] = 0x00;
1211     priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[6] = 0x00;
1212     priv->cck_txbbgain_ch14_table[16].ccktxbb_valuearray[7] = 0x00;
1213 
1214     priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[0] = 0x14;
1215     priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[1] = 0x14;
1216     priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[2] = 0x11;
1217     priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[3] = 0x0a;
1218     priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[4] = 0x00;
1219     priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[5] = 0x00;
1220     priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[6] = 0x00;
1221     priv->cck_txbbgain_ch14_table[17].ccktxbb_valuearray[7] = 0x00;
1222 
1223     priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[0] = 0x13;
1224     priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[1] = 0x13;
1225     priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[2] = 0x10;
1226     priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[3] = 0x0a;
1227     priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[4] = 0x00;
1228     priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[5] = 0x00;
1229     priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[6] = 0x00;
1230     priv->cck_txbbgain_ch14_table[18].ccktxbb_valuearray[7] = 0x00;
1231 
1232     priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[0] = 0x12;
1233     priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[1] = 0x12;
1234     priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[2] = 0x0f;
1235     priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[3] = 0x09;
1236     priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[4] = 0x00;
1237     priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[5] = 0x00;
1238     priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[6] = 0x00;
1239     priv->cck_txbbgain_ch14_table[19].ccktxbb_valuearray[7] = 0x00;
1240 
1241     priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[0] = 0x11;
1242     priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[1] = 0x11;
1243     priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[2] = 0x0f;
1244     priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[3] = 0x09;
1245     priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[4] = 0x00;
1246     priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[5] = 0x00;
1247     priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[6] = 0x00;
1248     priv->cck_txbbgain_ch14_table[20].ccktxbb_valuearray[7] = 0x00;
1249 
1250     priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[0] = 0x10;
1251     priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[1] = 0x10;
1252     priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[2] = 0x0e;
1253     priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[3] = 0x08;
1254     priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[4] = 0x00;
1255     priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[5] = 0x00;
1256     priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[6] = 0x00;
1257     priv->cck_txbbgain_ch14_table[21].ccktxbb_valuearray[7] = 0x00;
1258 
1259     priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[0] = 0x0f;
1260     priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[1] = 0x0f;
1261     priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[2] = 0x0d;
1262     priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[3] = 0x08;
1263     priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[4] = 0x00;
1264     priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[5] = 0x00;
1265     priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[6] = 0x00;
1266     priv->cck_txbbgain_ch14_table[22].ccktxbb_valuearray[7] = 0x00;
1267 
1268     priv->btxpower_tracking = true;
1269     priv->txpower_count       = 0;
1270     priv->btxpower_trackingInit = false;
1271 }
1272 
1273 static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
1274 {
1275     struct r8192_priv *priv = ieee80211_priv(dev);
1276 
1277     /* Tx Power tracking by Thermal Meter requires Firmware R/W 3-wire. This mechanism
1278      * can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
1279      * 3-wire by driver causes RF to go into a wrong state.
1280      */
1281     if (priv->ieee80211->FwRWRF)
1282         priv->btxpower_tracking = true;
1283     else
1284         priv->btxpower_tracking = false;
1285     priv->txpower_count       = 0;
1286     priv->btxpower_trackingInit = false;
1287 }
1288 
1289 void dm_initialize_txpower_tracking(struct net_device *dev)
1290 {
1291     struct r8192_priv *priv = ieee80211_priv(dev);
1292 
1293     if (priv->bDcut)
1294         dm_InitializeTXPowerTracking_TSSI(dev);
1295     else
1296         dm_InitializeTXPowerTracking_ThermalMeter(dev);
1297 } /* dm_InitializeTXPowerTracking */
1298 
1299 static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
1300 {
1301     struct r8192_priv *priv = ieee80211_priv(dev);
1302     static u32 tx_power_track_counter;
1303 
1304     if (!priv->btxpower_tracking)
1305         return;
1306     if ((tx_power_track_counter % 30 == 0) && (tx_power_track_counter != 0))
1307         queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1308     tx_power_track_counter++;
1309 }
1310 
1311 static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
1312 {
1313     struct r8192_priv *priv = ieee80211_priv(dev);
1314     static u8   TM_Trigger;
1315     /*DbgPrint("dm_CheckTXPowerTracking()\n");*/
1316     if (!priv->btxpower_tracking)
1317         return;
1318     if (priv->txpower_count  <= 2) {
1319         priv->txpower_count++;
1320         return;
1321     }
1322 
1323     if (!TM_Trigger) {
1324         /* Attention!! You have to write all 12bits of data to RF, or it may cause RF to crash
1325          * actually write reg0x02 bit1=0, then bit1=1.
1326          * DbgPrint("Trigger ThermalMeter, write RF reg0x2 = 0x4d to 0x4f\n");
1327          */
1328         rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1329         rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1330         rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1331         rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1332         TM_Trigger = 1;
1333         return;
1334     }
1335     /*DbgPrint("Schedule TxPowerTrackingWorkItem\n");*/
1336     queue_delayed_work(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1337     TM_Trigger = 0;
1338 }
1339 
1340 static void dm_check_txpower_tracking(struct net_device *dev)
1341 {
1342     struct r8192_priv *priv = ieee80211_priv(dev);
1343     /*static u32 tx_power_track_counter = 0;*/
1344 
1345 #ifdef RTL8190P
1346     dm_CheckTXPowerTracking_TSSI(dev);
1347 #else
1348     if (priv->bDcut)
1349         dm_CheckTXPowerTracking_TSSI(dev);
1350     else
1351         dm_CheckTXPowerTracking_ThermalMeter(dev);
1352 #endif
1353 
1354 }   /* dm_CheckTXPowerTracking */
1355 
1356 static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool  bInCH14)
1357 {
1358     u32 TempVal;
1359     struct r8192_priv *priv = ieee80211_priv(dev);
1360 
1361     /* Write 0xa22 0xa23 */
1362     TempVal = 0;
1363     if (!bInCH14) {
1364         /* Write 0xa22 0xa23 */
1365         TempVal =   priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[0] +
1366                     (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[1]<<8);
1367 
1368         rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1369         /* Write 0xa24 ~ 0xa27 */
1370         TempVal =   priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[2] +
1371                     (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[3]<<8) +
1372                     (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[4]<<16)+
1373                     (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[5]<<24);
1374         rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1375         /* Write 0xa28  0xa29 */
1376         TempVal =   priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[6] +
1377                     (priv->cck_txbbgain_table[priv->cck_present_attenuation].ccktxbb_valuearray[7]<<8);
1378 
1379         rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1380     } else {
1381         TempVal =   priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[0] +
1382                     (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[1]<<8);
1383 
1384         rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1385         /* Write 0xa24 ~ 0xa27 */
1386         TempVal =   priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[2] +
1387                     (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[3]<<8) +
1388                     (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[4]<<16)+
1389                     (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[5]<<24);
1390         rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1391         /* Write 0xa28  0xa29 */
1392         TempVal =   priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[6] +
1393                     (priv->cck_txbbgain_ch14_table[priv->cck_present_attenuation].ccktxbb_valuearray[7]<<8);
1394 
1395         rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1396     }
1397 }
1398 
1399 static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool  bInCH14)
1400 {
1401     u32 TempVal;
1402     struct r8192_priv *priv = ieee80211_priv(dev);
1403 
1404     TempVal = 0;
1405     if (!bInCH14) {
1406         /* Write 0xa22 0xa23 */
1407         TempVal =   CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1408                     (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8);
1409         rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1410         RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1411             rCCK0_TxFilter1, TempVal);
1412         /* Write 0xa24 ~ 0xa27 */
1413         TempVal =   CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1414                     (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1415                     (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+
1416                     (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1417         rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1418         RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1419             rCCK0_TxFilter2, TempVal);
1420         /* Write 0xa28  0xa29 */
1421         TempVal =   CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1422                     (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8);
1423 
1424         rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1425         RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1426             rCCK0_DebugPort, TempVal);
1427     } else {
1428         /*priv->CCKTxPowerAdjustCntNotCh14++;   cosa add for debug.*/
1429         /* Write 0xa22 0xa23 */
1430         TempVal =   CCKSwingTable_Ch14[priv->CCK_index][0] +
1431                     (CCKSwingTable_Ch14[priv->CCK_index][1]<<8);
1432 
1433         rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1434         RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1435              rCCK0_TxFilter1, TempVal);
1436         /* Write 0xa24 ~ 0xa27 */
1437         TempVal =   CCKSwingTable_Ch14[priv->CCK_index][2] +
1438                     (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1439                     (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+
1440                     (CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1441         rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1442         RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1443              rCCK0_TxFilter2, TempVal);
1444         /* Write 0xa28  0xa29 */
1445         TempVal =   CCKSwingTable_Ch14[priv->CCK_index][6] +
1446                     (CCKSwingTable_Ch14[priv->CCK_index][7]<<8);
1447 
1448         rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1449         RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1450              rCCK0_DebugPort, TempVal);
1451     }
1452 }
1453 
1454 void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
1455 {   /*  dm_CCKTxPowerAdjust */
1456     struct r8192_priv *priv = ieee80211_priv(dev);
1457 
1458     if (priv->bDcut)
1459         dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1460     else
1461         dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
1462 }
1463 
1464 #ifndef RTL8192U
1465 static void dm_txpower_reset_recovery(
1466     struct net_device *dev
1467 )
1468 {
1469     struct r8192_priv *priv = ieee80211_priv(dev);
1470 
1471     RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1472     rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1473     RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n", priv->txbbgain_table[priv->rfa_txpowertrackingindex].txbbgain_value);
1474     RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n", priv->rfa_txpowertrackingindex);
1475     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);
1476     RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: CCK Attenuation is %d dB\n", priv->cck_present_attenuation);
1477     dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1478 
1479     rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1480     RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n", priv->txbbgain_table[priv->rfc_txpowertrackingindex].txbbgain_value);
1481     RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n", priv->rfc_txpowertrackingindex);
1482     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);
1483 
1484 }   /* dm_TXPowerResetRecovery */
1485 
1486 void dm_restore_dynamic_mechanism_state(struct net_device *dev)
1487 {
1488     struct r8192_priv *priv = ieee80211_priv(dev);
1489     u32 reg_ratr = priv->rate_adaptive.last_ratr;
1490 
1491     if (!priv->up) {
1492         RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
1493         return;
1494     }
1495 
1496     /* Restore previous state for rate adaptive */
1497     if (priv->rate_adaptive.rate_adaptive_disabled)
1498         return;
1499     /* TODO: Only 11n mode is implemented currently, */
1500     if (!(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
1501           priv->ieee80211->mode == WIRELESS_MODE_N_5G))
1502         return;
1503 
1504     {
1505             /* 2007/11/15 MH Copy from 8190PCI. */
1506             u32 ratr_value;
1507 
1508             ratr_value = reg_ratr;
1509             if (priv->rf_type == RF_1T2R) { /* 1T2R, Spatial Stream 2 should be disabled */
1510                 ratr_value &= ~(RATE_ALL_OFDM_2SS);
1511                 /*DbgPrint("HW_VAR_TATR_0 from 0x%x ==> 0x%x\n", ((pu4Byte)(val))[0], ratr_value);*/
1512             }
1513             /*DbgPrint("set HW_VAR_TATR_0 = 0x%x\n", ratr_value);*/
1514             /*cosa PlatformEFIOWrite4Byte(Adapter, RATR0, ((pu4Byte)(val))[0]);*/
1515             write_nic_dword(dev, RATR0, ratr_value);
1516             write_nic_byte(dev, UFWP, 1);
1517     }
1518     /* Restore TX Power Tracking Index */
1519     if (priv->btxpower_trackingInit && priv->btxpower_tracking)
1520         dm_txpower_reset_recovery(dev);
1521 
1522     /* Restore BB Initial Gain */
1523     dm_bb_initialgain_restore(dev);
1524 
1525 }   /* DM_RestoreDynamicMechanismState */
1526 
1527 static void dm_bb_initialgain_restore(struct net_device *dev)
1528 {
1529     struct r8192_priv *priv = ieee80211_priv(dev);
1530     u32 bit_mask = 0x7f; /* Bit0~ Bit6 */
1531 
1532     if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1533         return;
1534 
1535     /* Disable Initial Gain */
1536     /*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
1537     rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   /* Only clear byte 1 and rewrite. */
1538     rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
1539     rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
1540     rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
1541     rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
1542     bit_mask  = bMaskByte2;
1543     rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
1544 
1545     RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1546     RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1547     RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1548     RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1549     RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca);
1550     /* Enable Initial Gain */
1551     /*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x100);*/
1552     rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);   /* Only clear byte 1 and rewrite. */
1553 
1554 }   /* dm_BBInitialGainRestore */
1555 
1556 static void dm_bb_initialgain_backup(struct net_device *dev)
1557 {
1558     struct r8192_priv *priv = ieee80211_priv(dev);
1559     u32 bit_mask = bMaskByte0; /* Bit0~ Bit6 */
1560 
1561     if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1562         return;
1563 
1564     /*PHY_SetBBReg(Adapter, UFWP, bMaskLWord, 0x800);*/
1565     rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   /* Only clear byte 1 and rewrite. */
1566     priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
1567     priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
1568     priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
1569     priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
1570     bit_mask  = bMaskByte2;
1571     priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
1572 
1573     RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1574     RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1575     RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1576     RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1577     RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca);
1578 
1579 }   /* dm_BBInitialGainBakcup */
1580 
1581 #endif
1582 /*-----------------------------------------------------------------------------
1583  * Function:    dm_dig_init()
1584  *
1585  * Overview:    Set DIG scheme init value.
1586  *
1587  * Input:       NONE
1588  *
1589  * Output:      NONE
1590  *
1591  * Return:      NONE
1592  *
1593  * Revised History:
1594  *  When        Who     Remark
1595  *  05/15/2008  amy     Create Version 0 porting from windows code.
1596  *
1597  *---------------------------------------------------------------------------*/
1598 static void dm_dig_init(struct net_device *dev)
1599 {
1600     struct r8192_priv *priv = ieee80211_priv(dev);
1601     /* 2007/10/05 MH Disable DIG scheme now. Not tested. */
1602     dm_digtable.dig_enable_flag = true;
1603     dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1604     dm_digtable.dig_algorithm_switch = 0;
1605 
1606     /* 2007/10/04 MH Define init gain threshold. */
1607     dm_digtable.dig_state       = DM_STA_DIG_MAX;
1608     dm_digtable.dig_highpwr_state   = DM_STA_DIG_MAX;
1609 
1610     dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW;
1611     dm_digtable.rssi_high_thresh    = DM_DIG_THRESH_HIGH;
1612 
1613     dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1614     dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1615 
1616     dm_digtable.rssi_val = 50;  /* for new dig debug rssi value */
1617     dm_digtable.backoff_val = DM_DIG_BACKOFF;
1618     if (priv->CustomerID == RT_CID_819x_Netcore)
1619         dm_digtable.rx_gain_range_min = DM_DIG_MIN_NETCORE;
1620     else
1621         dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1622 
1623 }   /* dm_dig_init */
1624 
1625 /*-----------------------------------------------------------------------------
1626  * Function:    dm_ctrl_initgain_byrssi()
1627  *
1628  * Overview:    Driver must monitor RSSI and notify firmware to change initial
1629  *              gain according to different threshold. BB team provide the
1630  *              suggested solution.
1631  *
1632  * Input:           struct net_device *dev
1633  *
1634  * Output:      NONE
1635  *
1636  * Return:      NONE
1637  *
1638  * Revised History:
1639  *  When        Who     Remark
1640  *  05/27/2008  amy     Create Version 0 porting from windows code.
1641  *---------------------------------------------------------------------------*/
1642 static void dm_ctrl_initgain_byrssi(struct net_device *dev)
1643 {
1644     if (!dm_digtable.dig_enable_flag)
1645         return;
1646 
1647     if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1648         dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
1649     else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1650         dm_ctrl_initgain_byrssi_by_driverrssi(dev);
1651     /* ; */
1652     else
1653         return;
1654 }
1655 
1656 static void dm_ctrl_initgain_byrssi_by_driverrssi(
1657     struct net_device *dev)
1658 {
1659     struct r8192_priv *priv = ieee80211_priv(dev);
1660     u8 i;
1661     static u8   fw_dig;
1662 
1663     if (!dm_digtable.dig_enable_flag)
1664         return;
1665 
1666     /*DbgPrint("Dig by Sw Rssi\n");*/
1667     if (dm_digtable.dig_algorithm_switch)   /* if switched algorithm, we have to disable FW Dig. */
1668         fw_dig = 0;
1669 
1670     if (fw_dig <= 3) { /* execute several times to make sure the FW Dig is disabled */
1671         /* FW DIG Off */
1672         for (i = 0; i < 3; i++)
1673             rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   /* Only clear byte 1 and rewrite. */
1674         fw_dig++;
1675         dm_digtable.dig_state = DM_STA_DIG_OFF; /* fw dig off. */
1676     }
1677 
1678     if (priv->ieee80211->state == IEEE80211_LINKED)
1679         dm_digtable.cur_connect_state = DIG_CONNECT;
1680     else
1681         dm_digtable.cur_connect_state = DIG_DISCONNECT;
1682 
1683     /*DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d\n",
1684         DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);*/
1685 
1686     dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1687     /*DbgPrint("DM_DigTable.Rssi_val = %d\n", DM_DigTable.Rssi_val);*/
1688     dm_initial_gain(dev);
1689     dm_pd_th(dev);
1690     dm_cs_ratio(dev);
1691     if (dm_digtable.dig_algorithm_switch)
1692         dm_digtable.dig_algorithm_switch = 0;
1693     dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
1694 
1695 }   /* dm_CtrlInitGainByRssi */
1696 
1697 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
1698     struct net_device *dev)
1699 {
1700     struct r8192_priv *priv = ieee80211_priv(dev);
1701     static u32 reset_cnt;
1702     u8 i;
1703 
1704     if (!dm_digtable.dig_enable_flag)
1705         return;
1706 
1707     if (dm_digtable.dig_algorithm_switch) {
1708         dm_digtable.dig_state = DM_STA_DIG_MAX;
1709         /* Fw DIG On. */
1710         for (i = 0; i < 3; i++)
1711             rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);   /* Only clear byte 1 and rewrite.*/
1712         dm_digtable.dig_algorithm_switch = 0;
1713     }
1714 
1715     if (priv->ieee80211->state != IEEE80211_LINKED)
1716         return;
1717 
1718     /* For smooth, we can not change DIG state. */
1719     if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1720         (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1721         return;
1722 
1723     /*DbgPrint("Dig by Fw False Alarm\n");*/
1724     /*if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)*/
1725     /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
1726     pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
1727     DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
1728     /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
1729      * and then execute the step below.
1730      */
1731     if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
1732         /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
1733          * will be reset to init value. We must prevent the condition.
1734          */
1735         if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1736             (priv->reset_count == reset_cnt)) {
1737             return;
1738         }
1739         reset_cnt = priv->reset_count;
1740 
1741         /* If DIG is off, DIG high power state must reset. */
1742         dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1743         dm_digtable.dig_state = DM_STA_DIG_OFF;
1744 
1745         /*  1.1 DIG Off. */
1746         rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   /*  Only clear byte 1 and rewrite. */
1747 
1748         /*  1.2 Set initial gain. */
1749         write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
1750         write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
1751         write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
1752         write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
1753 
1754         /*  1.3 Lower PD_TH for OFDM. */
1755         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
1756             /* 2008/01/11 MH 40MHZ 90/92 register are not the same.
1757              * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1758              */
1759             write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
1760             /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1761                 write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
1762             else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
1763             else
1764                 PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
1765             */
1766         } else
1767             write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1768 
1769         /* 1.4 Lower CS ratio for CCK. */
1770         write_nic_byte(dev, 0xa0a, 0x08);
1771 
1772         /* 1.5 Higher EDCCA. */
1773         /*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);*/
1774         return;
1775     }
1776 
1777     /* 2. When RSSI increase, We have to judge if it is larger than a threshold
1778      * and then execute the step below.
1779      */
1780     if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1781         u8 reset_flag = 0;
1782 
1783         if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1784             (priv->reset_count == reset_cnt)) {
1785             dm_ctrl_initgain_byrssi_highpwr(dev);
1786             return;
1787         }
1788         if (priv->reset_count != reset_cnt)
1789             reset_flag = 1;
1790 
1791         reset_cnt = priv->reset_count;
1792 
1793         dm_digtable.dig_state = DM_STA_DIG_ON;
1794         /*DbgPrint("DIG ON\n\r");*/
1795 
1796         /* 2.1 Set initial gain.
1797          * 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
1798          */
1799         if (reset_flag == 1) {
1800             write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
1801             write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
1802             write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
1803             write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
1804         } else {
1805             write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
1806             write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
1807             write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
1808             write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
1809         }
1810 
1811         /* 2.2 Higher PD_TH for OFDM. */
1812         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
1813             /* 2008/01/11 MH 40MHZ 90/92 register are not the same.
1814              * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1815              */
1816             write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1817             /*
1818             else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1819                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1820             else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
1821             else
1822                 PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
1823             */
1824         } else
1825             write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1826 
1827         /* 2.3 Higher CS ratio for CCK. */
1828         write_nic_byte(dev, 0xa0a, 0xcd);
1829 
1830         /* 2.4 Lower EDCCA.
1831          * 2008/01/11 MH 90/92 series are the same.
1832          */
1833         /*PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);*/
1834 
1835         /* 2.5 DIG On. */
1836         rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);   /*  Only clear byte 1 and rewrite. */
1837     }
1838 
1839     dm_ctrl_initgain_byrssi_highpwr(dev);
1840 
1841 }   /* dm_CtrlInitGainByRssi */
1842 
1843 /*-----------------------------------------------------------------------------
1844  * Function:    dm_ctrl_initgain_byrssi_highpwr()
1845  *
1846  * Overview:
1847  *
1848  * Input:       NONE
1849  *
1850  * Output:      NONE
1851  *
1852  * Return:      NONE
1853  *
1854  * Revised History:
1855  *  When        Who     Remark
1856  *  05/28/2008  amy     Create Version 0 porting from windows code.
1857  *
1858  *---------------------------------------------------------------------------*/
1859 static void dm_ctrl_initgain_byrssi_highpwr(
1860     struct net_device *dev)
1861 {
1862     struct r8192_priv *priv = ieee80211_priv(dev);
1863     static u32 reset_cnt_highpwr;
1864 
1865     /*  For smooth, we can not change high power DIG state in the range. */
1866     if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
1867         (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
1868         return;
1869 
1870     /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
1871      *    it is larger than a threshold and then execute the step below.
1872      *
1873      * 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
1874      */
1875     if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) {
1876         if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1877             (priv->reset_count == reset_cnt_highpwr))
1878             return;
1879         dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1880 
1881         /* 3.1 Higher PD_TH for OFDM for high power state. */
1882         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
1883             write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
1884 
1885             /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1886                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
1887             */
1888 
1889         } else
1890             write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
1891     } else {
1892         if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
1893             (priv->reset_count == reset_cnt_highpwr))
1894             return;
1895         dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1896 
1897         if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
1898              priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1899             /*  3.2 Recover PD_TH for OFDM for normal power region. */
1900             if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
1901                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1902                 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
1903                     write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1904                 */
1905 
1906             } else
1907                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1908         }
1909     }
1910 
1911     reset_cnt_highpwr = priv->reset_count;
1912 
1913 }   /* dm_CtrlInitGainByRssiHighPwr */
1914 
1915 static void dm_initial_gain(
1916     struct net_device *dev)
1917 {
1918     struct r8192_priv *priv = ieee80211_priv(dev);
1919     u8                  initial_gain = 0;
1920     static u8               initialized, force_write;
1921     static u32          reset_cnt;
1922     u8              tmp;
1923 
1924     if (dm_digtable.dig_algorithm_switch) {
1925         initialized = 0;
1926         reset_cnt = 0;
1927     }
1928 
1929     if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
1930         if (dm_digtable.cur_connect_state == DIG_CONNECT) {
1931             if ((dm_digtable.rssi_val + 10 - dm_digtable.backoff_val) > DM_DIG_MAX)
1932                 dm_digtable.cur_ig_value = DM_DIG_MAX;
1933             else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
1934                 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
1935             else
1936                 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
1937         } else {    /* current state is disconnected */
1938             if (dm_digtable.cur_ig_value == 0)
1939                 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1940             else
1941                 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1942         }
1943     } else { /*  disconnected -> connected or connected -> disconnected */
1944         dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1945         dm_digtable.pre_ig_value = 0;
1946     }
1947     /*DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);*/
1948 
1949     /* if silent reset happened, we should rewrite the values back */
1950     if (priv->reset_count != reset_cnt) {
1951         force_write = 1;
1952         reset_cnt = priv->reset_count;
1953     }
1954 
1955     read_nic_byte(dev, rOFDM0_XAAGCCore1, &tmp);
1956     if (dm_digtable.pre_ig_value != tmp)
1957         force_write = 1;
1958 
1959     {
1960         if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1961             || !initialized || force_write) {
1962             initial_gain = (u8)dm_digtable.cur_ig_value;
1963             /*DbgPrint("Write initial gain = 0x%x\n", initial_gain);*/
1964             /*  Set initial gain. */
1965             write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
1966             write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
1967             write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
1968             write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
1969             dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1970             initialized = 1;
1971             force_write = 0;
1972         }
1973     }
1974 }
1975 
1976 static void dm_pd_th(
1977     struct net_device *dev)
1978 {
1979     struct r8192_priv *priv = ieee80211_priv(dev);
1980     static u8               initialized, force_write;
1981     static u32          reset_cnt;
1982 
1983     if (dm_digtable.dig_algorithm_switch) {
1984         initialized = 0;
1985         reset_cnt = 0;
1986     }
1987 
1988     if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
1989         if (dm_digtable.cur_connect_state == DIG_CONNECT) {
1990             if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
1991                 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
1992             else if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
1993                 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1994             else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
1995                     (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
1996                 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
1997             else
1998                 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
1999         } else {
2000             dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2001         }
2002     } else { /* disconnected -> connected or connected -> disconnected */
2003         dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2004     }
2005 
2006     /*  if silent reset happened, we should rewrite the values back */
2007     if (priv->reset_count != reset_cnt) {
2008         force_write = 1;
2009         reset_cnt = priv->reset_count;
2010     }
2011 
2012     {
2013         if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
2014             (initialized <= 3) || force_write) {
2015             /*DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);*/
2016             if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
2017                 /*  Lower PD_TH for OFDM. */
2018                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2019                     /* 2008/01/11 MH 40MHZ 90/92 register are not the same.
2020                      * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2021                      */
2022                     write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
2023                     /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2024                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2025                     */
2026                 } else
2027                     write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2028             } else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) {
2029                 /* Higher PD_TH for OFDM. */
2030                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2031                     /* 2008/01/11 MH 40MHZ 90/92 register are not the same.
2032                      * 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2033                      */
2034                     write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2035                     /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2036                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2037                     */
2038                 } else
2039                     write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2040             } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
2041                 /* Higher PD_TH for OFDM for high power state. */
2042                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
2043                     write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2044                     /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2045                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2046                     */
2047                 } else
2048                     write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2049             }
2050             dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
2051             if (initialized <= 3)
2052                 initialized++;
2053             force_write = 0;
2054         }
2055     }
2056 }
2057 
2058 static  void dm_cs_ratio(
2059     struct net_device *dev)
2060 {
2061     struct r8192_priv *priv = ieee80211_priv(dev);
2062     static u8               initialized, force_write;
2063     static u32          reset_cnt;
2064 
2065     if (dm_digtable.dig_algorithm_switch) {
2066         initialized = 0;
2067         reset_cnt = 0;
2068     }
2069 
2070     if (dm_digtable.pre_connect_state == dm_digtable.cur_connect_state) {
2071         if (dm_digtable.cur_connect_state == DIG_CONNECT) {
2072             if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
2073                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2074             else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
2075                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
2076             else
2077                 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
2078         } else {
2079             dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2080         }
2081     } else  /* disconnected -> connected or connected -> disconnected */
2082         dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2083 
2084     /* if silent reset happened, we should rewrite the values back */
2085     if (priv->reset_count != reset_cnt) {
2086         force_write = 1;
2087         reset_cnt = priv->reset_count;
2088     }
2089 
2090     {
2091         if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
2092             !initialized || force_write) {
2093             /*DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);*/
2094             if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER) {
2095                 /*  Lower CS ratio for CCK. */
2096                 write_nic_byte(dev, 0xa0a, 0x08);
2097             } else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER) {
2098                 /*  Higher CS ratio for CCK. */
2099                 write_nic_byte(dev, 0xa0a, 0xcd);
2100             }
2101             dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
2102             initialized = 1;
2103             force_write = 0;
2104         }
2105     }
2106 }
2107 
2108 void dm_init_edca_turbo(struct net_device *dev)
2109 {
2110     struct r8192_priv *priv = ieee80211_priv(dev);
2111 
2112     priv->bcurrent_turbo_EDCA = false;
2113     priv->ieee80211->bis_any_nonbepkts = false;
2114     priv->bis_cur_rdlstate = false;
2115 }   /* dm_init_edca_turbo */
2116 
2117 static void dm_check_edca_turbo(
2118     struct net_device *dev)
2119 {
2120     struct r8192_priv *priv = ieee80211_priv(dev);
2121     PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
2122     /*PSTA_QOS          pStaQos = pMgntInfo->pStaQos;*/
2123 
2124     /* Keep past Tx/Rx packet count for RT-to-RT EDCA turbo. */
2125     static unsigned long            lastTxOkCnt;
2126     static unsigned long            lastRxOkCnt;
2127     unsigned long               curTxOkCnt = 0;
2128     unsigned long               curRxOkCnt = 0;
2129 
2130     /* Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
2131      * should follow the settings from QAP. By Bruce, 2007-12-07.
2132      */
2133     if (priv->ieee80211->state != IEEE80211_LINKED)
2134         goto dm_CheckEdcaTurbo_EXIT;
2135     /* We do not turn on EDCA turbo mode for some AP that has IOT issue */
2136     if (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
2137         goto dm_CheckEdcaTurbo_EXIT;
2138 
2139     /*printk("========>%s():bis_any_nonbepkts is %d\n", __func__, priv->bis_any_nonbepkts);*/
2140     /* Check the status for current condition. */
2141     if (!priv->ieee80211->bis_any_nonbepkts) {
2142         curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2143         curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2144         /* For RT-AP, we needs to turn it on when Rx>Tx */
2145         if (curRxOkCnt > 4*curTxOkCnt) {
2146             /*printk("%s():curRxOkCnt > 4*curTxOkCnt\n");*/
2147             if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
2148                 write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
2149                 priv->bis_cur_rdlstate = true;
2150             }
2151         } else {
2152             /*printk("%s():curRxOkCnt < 4*curTxOkCnt\n");*/
2153             if (priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
2154                 write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
2155                 priv->bis_cur_rdlstate = false;
2156             }
2157         }
2158 
2159         priv->bcurrent_turbo_EDCA = true;
2160     } else {
2161         /* Turn Off EDCA turbo here.
2162          * Restore original EDCA according to the declaration of AP.
2163          */
2164         if (priv->bcurrent_turbo_EDCA) {
2165             u8  u1bAIFS;
2166             u32 u4bAcParam, op_limit, cw_max, cw_min;
2167 
2168             struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2169             u8 mode = priv->ieee80211->mode;
2170 
2171             /*  For Each time updating EDCA parameter, reset EDCA turbo mode status. */
2172             dm_init_edca_turbo(dev);
2173 
2174             u1bAIFS = qos_parameters->aifs[0] * ((mode & (IEEE_G | IEEE_N_24G)) ? 9 : 20) + aSifsTime;
2175 
2176             op_limit = (u32)le16_to_cpu(qos_parameters->tx_op_limit[0]);
2177             cw_max   = (u32)le16_to_cpu(qos_parameters->cw_max[0]);
2178             cw_min   = (u32)le16_to_cpu(qos_parameters->cw_min[0]);
2179 
2180             op_limit <<= AC_PARAM_TXOP_LIMIT_OFFSET;
2181             cw_max   <<= AC_PARAM_ECW_MAX_OFFSET;
2182             cw_min   <<= AC_PARAM_ECW_MIN_OFFSET;
2183             u1bAIFS  <<= AC_PARAM_AIFS_OFFSET;
2184 
2185             u4bAcParam = op_limit | cw_max | cw_min | u1bAIFS;
2186             cpu_to_le32s(&u4bAcParam);
2187 
2188             write_nic_dword(dev, EDCAPARA_BE, u4bAcParam);
2189 
2190             /* Check ACM bit.
2191              * If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
2192              */
2193             {
2194                 /*  TODO:  Modified this part and try to set acm control in only 1 IO processing!! */
2195 
2196                 struct aci_aifsn *pAciAifsn = (struct aci_aifsn *)&(qos_parameters->aifs[0]);
2197                 u8      AcmCtrl;
2198 
2199                 read_nic_byte(dev, AcmHwCtrl, &AcmCtrl);
2200 
2201                 if (pAciAifsn->acm) { /*  acm bit is 1. */
2202                     AcmCtrl |= AcmHw_BeqEn;
2203                 } else {    /* ACM bit is 0. */
2204                     AcmCtrl &= (~AcmHw_BeqEn);
2205                 }
2206 
2207                 RT_TRACE(COMP_QOS, "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl);
2208                 write_nic_byte(dev, AcmHwCtrl, AcmCtrl);
2209             }
2210             priv->bcurrent_turbo_EDCA = false;
2211         }
2212     }
2213 
2214 dm_CheckEdcaTurbo_EXIT:
2215     /* Set variables for next time. */
2216     priv->ieee80211->bis_any_nonbepkts = false;
2217     lastTxOkCnt = priv->stats.txbytesunicast;
2218     lastRxOkCnt = priv->stats.rxbytesunicast;
2219 }   /* dm_CheckEdcaTurbo */
2220 
2221 static void dm_init_ctstoself(struct net_device *dev)
2222 {
2223     struct r8192_priv *priv = ieee80211_priv(dev);
2224 
2225     priv->ieee80211->bCTSToSelfEnable = true;
2226     priv->ieee80211->CTSToSelfTH = CTS_TO_SELF_TH_VAL;
2227 }
2228 
2229 static void dm_ctstoself(struct net_device *dev)
2230 {
2231     struct r8192_priv *priv = ieee80211_priv(dev);
2232     PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
2233     static unsigned long                lastTxOkCnt;
2234     static unsigned long                lastRxOkCnt;
2235     unsigned long                       curTxOkCnt = 0;
2236     unsigned long                       curRxOkCnt = 0;
2237 
2238     if (!priv->ieee80211->bCTSToSelfEnable) {
2239         pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2240         return;
2241     }
2242     /* 1. Uplink
2243      * 2. Linksys350/Linksys300N
2244      * 3. <50 disable, >55 enable
2245      */
2246 
2247     if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2248         curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2249         curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2250         if (curRxOkCnt > 4*curTxOkCnt) { /* downlink, disable CTS to self */
2251             pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2252             /*DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");*/
2253         } else { /* uplink */
2254             pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2255         }
2256 
2257         lastTxOkCnt = priv->stats.txbytesunicast;
2258         lastRxOkCnt = priv->stats.rxbytesunicast;
2259     }
2260 }
2261 
2262 /*-----------------------------------------------------------------------------
2263  * Function:    dm_check_pbc_gpio()
2264  *
2265  * Overview:    Check if PBC button is pressed.
2266  *
2267  * Input:       NONE
2268  *
2269  * Output:      NONE
2270  *
2271  * Return:      NONE
2272  *
2273  * Revised History:
2274  *  When        Who     Remark
2275  *  05/28/2008  amy Create Version 0 porting from windows code.
2276  *
2277  *---------------------------------------------------------------------------*/
2278 static  void    dm_check_pbc_gpio(struct net_device *dev)
2279 {
2280     struct r8192_priv *priv = ieee80211_priv(dev);
2281     u8 tmp1byte;
2282 
2283     read_nic_byte(dev, GPI, &tmp1byte);
2284     if (tmp1byte == 0xff)
2285         return;
2286 
2287     if (tmp1byte & BIT(6) || tmp1byte & BIT(0)) {
2288         /* Here we only set bPbcPressed to TRUE
2289          * After trigger PBC, the variable will be set to FALSE
2290          */
2291         RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
2292         priv->bpbc_pressed = true;
2293     }
2294 }
2295 
2296 /*-----------------------------------------------------------------------------
2297  * Function:    DM_RFPathCheckWorkItemCallBack()
2298  *
2299  * Overview:    Check if Current RF RX path is enabled
2300  *
2301  * Input:       NONE
2302  *
2303  * Output:      NONE
2304  *
2305  * Return:      NONE
2306  *
2307  * Revised History:
2308  *  When        Who     Remark
2309  *  01/30/2008  MHC     Create Version 0.
2310  *
2311  *---------------------------------------------------------------------------*/
2312 void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
2313 {
2314     struct delayed_work *dwork = to_delayed_work(work);
2315     struct r8192_priv *priv = container_of(dwork, struct r8192_priv, rfpath_check_wq);
2316     struct net_device *dev = priv->ieee80211->dev;
2317     /*bool bactually_set = false;*/
2318     u8 rfpath = 0, i;
2319 
2320     /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
2321      * always be the same. We only read 0xc04 now.
2322      */
2323     read_nic_byte(dev, 0xc04, &rfpath);
2324 
2325     /* Check Bit 0-3, it means if RF A-D is enabled. */
2326     for (i = 0; i < RF90_PATH_MAX; i++) {
2327         if (rfpath & (0x01<<i))
2328             priv->brfpath_rxenable[i] = true;
2329         else
2330             priv->brfpath_rxenable[i] = false;
2331     }
2332 
2333     dm_rxpath_sel_byrssi(dev);
2334 }   /* DM_RFPathCheckWorkItemCallBack */
2335 
2336 static void dm_init_rxpath_selection(struct net_device *dev)
2337 {
2338     u8 i;
2339     struct r8192_priv *priv = ieee80211_priv(dev);
2340 
2341     if (priv->CustomerID == RT_CID_819x_Netcore)
2342         DM_RxPathSelTable.cck_method = CCK_RX_VERSION_2;
2343     else
2344         DM_RxPathSelTable.cck_method = CCK_RX_VERSION_1;
2345     DM_RxPathSelTable.disabled_rf = 0;
2346     for (i = 0; i < 4; i++) {
2347         DM_RxPathSelTable.rf_rssi[i] = 50;
2348         DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
2349         DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2350     }
2351 }
2352 
2353 static void dm_rxpath_sel_byrssi(struct net_device *dev)
2354 {
2355     struct r8192_priv *priv = ieee80211_priv(dev);
2356     u8              i, max_rssi_index = 0, min_rssi_index = 0, sec_rssi_index = 0, rf_num = 0;
2357     u8              tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
2358     u8              cck_default_Rx = 0x2;  /* RF-C */
2359     u8              cck_optional_Rx = 0x3; /* RF-D */
2360     long                tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
2361     u8              cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0, cck_rx_ver2_sec_index = 0;
2362     u8              cur_rf_rssi;
2363     long                cur_cck_pwdb;
2364     static u8           disabled_rf_cnt, cck_Rx_Path_initialized;
2365     u8              update_cck_rx_path;
2366 
2367     if (priv->rf_type != RF_2T4R)
2368         return;
2369 
2370     if (!cck_Rx_Path_initialized) {
2371         read_nic_byte(dev, 0xa07, &DM_RxPathSelTable.cck_rx_path);
2372         DM_RxPathSelTable.cck_rx_path &= 0xf;
2373         cck_Rx_Path_initialized = 1;
2374     }
2375 
2376     read_nic_byte(dev, 0xc04, &DM_RxPathSelTable.disabled_rf);
2377     DM_RxPathSelTable.disabled_rf = ~DM_RxPathSelTable.disabled_rf & 0xf;
2378 
2379     if (priv->ieee80211->mode == WIRELESS_MODE_B) {
2380         DM_RxPathSelTable.cck_method = CCK_RX_VERSION_2;    /* pure B mode, fixed cck version2 */
2381         /*DbgPrint("Pure B mode, use cck rx version2\n");*/
2382     }
2383 
2384     /* decide max/sec/min rssi index */
2385     for (i = 0; i < RF90_PATH_MAX; i++) {
2386         DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
2387 
2388         if (priv->brfpath_rxenable[i]) {
2389             rf_num++;
2390             cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
2391 
2392             if (rf_num == 1) { /* find first enabled rf path and the rssi values */
2393                 /* initialize, set all rssi index to the same one */
2394                 max_rssi_index = min_rssi_index = sec_rssi_index = i;
2395                 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
2396             } else if (rf_num == 2) { /* we pick up the max index first, and let sec and min to be the same one */
2397                 if (cur_rf_rssi >= tmp_max_rssi) {
2398                     tmp_max_rssi = cur_rf_rssi;
2399                     max_rssi_index = i;
2400                 } else {
2401                     tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
2402                     sec_rssi_index = min_rssi_index = i;
2403                 }
2404             } else {
2405                 if (cur_rf_rssi > tmp_max_rssi) {
2406                     tmp_sec_rssi = tmp_max_rssi;
2407                     sec_rssi_index = max_rssi_index;
2408                     tmp_max_rssi = cur_rf_rssi;
2409                     max_rssi_index = i;
2410                 } else if (cur_rf_rssi == tmp_max_rssi) {   /* let sec and min point to the different index */
2411                     tmp_sec_rssi = cur_rf_rssi;
2412                     sec_rssi_index = i;
2413                 } else if ((cur_rf_rssi < tmp_max_rssi) && (cur_rf_rssi > tmp_sec_rssi)) {
2414                     tmp_sec_rssi = cur_rf_rssi;
2415                     sec_rssi_index = i;
2416                 } else if (cur_rf_rssi == tmp_sec_rssi) {
2417                     if (tmp_sec_rssi == tmp_min_rssi) {
2418                         /* let sec and min point to the different index */
2419                         tmp_sec_rssi = cur_rf_rssi;
2420                         sec_rssi_index = i;
2421                     } else {
2422                         /* This case we don't need to set any index */
2423                     }
2424                 } else if ((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi)) {
2425                     /* This case we don't need to set any index */
2426                 } else if (cur_rf_rssi == tmp_min_rssi) {
2427                     if (tmp_sec_rssi == tmp_min_rssi) {
2428                         /* let sec and min point to the different index */
2429                         tmp_min_rssi = cur_rf_rssi;
2430                         min_rssi_index = i;
2431                     } else {
2432                         /* This case we don't need to set any index */
2433                     }
2434                 } else if (cur_rf_rssi < tmp_min_rssi) {
2435                     tmp_min_rssi = cur_rf_rssi;
2436                     min_rssi_index = i;
2437                 }
2438             }
2439         }
2440     }
2441 
2442     rf_num = 0;
2443     /* decide max/sec/min cck pwdb index */
2444     if (DM_RxPathSelTable.cck_method == CCK_RX_VERSION_2) {
2445         for (i = 0; i < RF90_PATH_MAX; i++) {
2446             if (priv->brfpath_rxenable[i]) {
2447                 rf_num++;
2448                 cur_cck_pwdb =  DM_RxPathSelTable.cck_pwdb_sta[i];
2449 
2450                 if (rf_num == 1) {  /* find first enabled rf path and the rssi values */
2451                     /* initialize, set all rssi index to the same one */
2452                     cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
2453                     tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
2454                 } else if (rf_num == 2) {   /* we pick up the max index first, and let sec and min to be the same one */
2455                     if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
2456                         tmp_cck_max_pwdb = cur_cck_pwdb;
2457                         cck_rx_ver2_max_index = i;
2458                     } else {
2459                         tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
2460                         cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
2461                     }
2462                 } else {
2463                     if (cur_cck_pwdb > tmp_cck_max_pwdb) {
2464                         tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
2465                         cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
2466                         tmp_cck_max_pwdb = cur_cck_pwdb;
2467                         cck_rx_ver2_max_index = i;
2468                     } else if (cur_cck_pwdb == tmp_cck_max_pwdb) {
2469                         /* let sec and min point to the different index */
2470                         tmp_cck_sec_pwdb = cur_cck_pwdb;
2471                         cck_rx_ver2_sec_index = i;
2472                     } else if ((cur_cck_pwdb < tmp_cck_max_pwdb) && (cur_cck_pwdb > tmp_cck_sec_pwdb)) {
2473                         tmp_cck_sec_pwdb = cur_cck_pwdb;
2474                         cck_rx_ver2_sec_index = i;
2475                     } else if (cur_cck_pwdb == tmp_cck_sec_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2476                         /* let sec and min point to the different index */
2477                         tmp_cck_sec_pwdb = cur_cck_pwdb;
2478                         cck_rx_ver2_sec_index = i;
2479                         /* otherwise we don't need to set any index */
2480                     } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb)) {
2481                         /*  This case we don't need to set any index */
2482                     } else if (cur_cck_pwdb == tmp_cck_min_pwdb && tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2483                         /*  let sec and min point to the different index */
2484                         tmp_cck_min_pwdb = cur_cck_pwdb;
2485                         cck_rx_ver2_min_index = i;
2486                         /* otherwise we don't need to set any index */
2487                     } else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
2488                         tmp_cck_min_pwdb = cur_cck_pwdb;
2489                         cck_rx_ver2_min_index = i;
2490                     }
2491                 }
2492             }
2493         }
2494     }
2495 
2496     /* Set CCK Rx path
2497      * reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
2498      */
2499     update_cck_rx_path = 0;
2500     if (DM_RxPathSelTable.cck_method == CCK_RX_VERSION_2) {
2501         cck_default_Rx = cck_rx_ver2_max_index;
2502         cck_optional_Rx = cck_rx_ver2_sec_index;
2503         if (tmp_cck_max_pwdb != -64)
2504             update_cck_rx_path = 1;
2505     }
2506 
2507     if (tmp_min_rssi < RX_PATH_SELECTION_SS_TH_LOW && disabled_rf_cnt < 2) {
2508         if ((tmp_max_rssi - tmp_min_rssi) >= RX_PATH_SELECTION_DIFF_TH) {
2509             /* record the enabled rssi threshold */
2510             DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
2511             /* disable the BB Rx path, OFDM */
2512             rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0);  /* 0xc04[3:0] */
2513             rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0);  /* 0xd04[3:0] */
2514             disabled_rf_cnt++;
2515         }
2516         if (DM_RxPathSelTable.cck_method == CCK_RX_VERSION_1) {
2517             cck_default_Rx = max_rssi_index;
2518             cck_optional_Rx = sec_rssi_index;
2519             if (tmp_max_rssi)
2520                 update_cck_rx_path = 1;
2521         }
2522     }
2523 
2524     if (update_cck_rx_path) {
2525         DM_RxPathSelTable.cck_rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
2526         rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_rx_path);
2527     }
2528 
2529     if (DM_RxPathSelTable.disabled_rf) {
2530         for (i = 0; i < 4; i++) {
2531             if ((DM_RxPathSelTable.disabled_rf >> i) & 0x1) {   /* disabled rf */
2532                 if (tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i]) {
2533                     /* enable the BB Rx path */
2534                     /*DbgPrint("RF-%d is enabled.\n", 0x1<<i);*/
2535                     rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);   /* 0xc04[3:0] */
2536                     rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);   /* 0xd04[3:0] */
2537                     DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2538                     disabled_rf_cnt--;
2539                 }
2540             }
2541         }
2542     }
2543 }
2544 
2545 /*-----------------------------------------------------------------------------
2546  * Function:    dm_check_rx_path_selection()
2547  *
2548  * Overview:    Call a workitem to check current RXRF path and Rx Path selection by RSSI.
2549  *
2550  * Input:       NONE
2551  *
2552  * Output:      NONE
2553  *
2554  * Return:      NONE
2555  *
2556  * Revised History:
2557  *  When        Who     Remark
2558  *  05/28/2008  amy     Create Version 0 porting from windows code.
2559  *
2560  *---------------------------------------------------------------------------*/
2561 static void dm_check_rx_path_selection(struct net_device *dev)
2562 {
2563     struct r8192_priv *priv = ieee80211_priv(dev);
2564 
2565     queue_delayed_work(priv->priv_wq, &priv->rfpath_check_wq, 0);
2566 }   /* dm_CheckRxRFPath */
2567 
2568 static void dm_init_fsync(struct net_device *dev)
2569 {
2570     struct r8192_priv *priv = ieee80211_priv(dev);
2571 
2572     priv->ieee80211->fsync_time_interval = 500;
2573     priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
2574     priv->ieee80211->fsync_rssi_threshold = 30;
2575     priv->ieee80211->bfsync_enable = false;
2576     priv->ieee80211->fsync_multiple_timeinterval = 3;
2577     priv->ieee80211->fsync_firstdiff_ratethreshold = 100;
2578     priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
2579     priv->ieee80211->fsync_state = Default_Fsync;
2580     priv->framesyncMonitor = 1; /* current default 0xc38 monitor on */
2581     INIT_DELAYED_WORK(&priv->fsync_work, dm_fsync_work_callback);
2582 }
2583 
2584 static void dm_deInit_fsync(struct net_device *dev)
2585 {
2586     struct r8192_priv *priv = ieee80211_priv(dev);
2587 
2588     cancel_delayed_work_sync(&priv->fsync_work);
2589 }
2590 
2591 void dm_fsync_work_callback(struct work_struct *work)
2592 {
2593     struct r8192_priv *priv =
2594         container_of(work, struct r8192_priv, fsync_work.work);
2595     struct net_device *dev = priv->ieee80211->dev;
2596     u32 rate_index, rate_count = 0, rate_count_diff = 0;
2597     bool        bSwitchFromCountDiff = false;
2598     bool        bDoubleTimeInterval = false;
2599 
2600     if (priv->ieee80211->state == IEEE80211_LINKED &&
2601         priv->ieee80211->bfsync_enable &&
2602         (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2603         /* Count rate 54, MCS [7], [12, 13, 14, 15] */
2604         u32 rate_bitmap;
2605 
2606         for (rate_index = 0; rate_index <= 27; rate_index++) {
2607             rate_bitmap  = 1 << rate_index;
2608             if (priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
2609                 rate_count += priv->stats.received_rate_histogram[1][rate_index];
2610         }
2611 
2612         if (rate_count < priv->rate_record)
2613             rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
2614         else
2615             rate_count_diff = rate_count - priv->rate_record;
2616         if (rate_count_diff < priv->rateCountDiffRecord) {
2617             u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
2618             /* Continue count */
2619             if (DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
2620                 priv->ContinueDiffCount++;
2621             else
2622                 priv->ContinueDiffCount = 0;
2623 
2624             /* Continue count over */
2625             if (priv->ContinueDiffCount >= 2) {
2626                 bSwitchFromCountDiff = true;
2627                 priv->ContinueDiffCount = 0;
2628             }
2629         } else {
2630             /* Stop the continued count */
2631             priv->ContinueDiffCount = 0;
2632         }
2633 
2634         /* If Count diff <= FsyncRateCountThreshold */
2635         if (rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold) {
2636             bSwitchFromCountDiff = true;
2637             priv->ContinueDiffCount = 0;
2638         }
2639         priv->rate_record = rate_count;
2640         priv->rateCountDiffRecord = rate_count_diff;
2641         RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
2642         /* if we never receive those mcs rate and rssi > 30 % then switch fsyn */
2643         if (priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff) {
2644             bDoubleTimeInterval = true;
2645             priv->bswitch_fsync = !priv->bswitch_fsync;
2646             if (priv->bswitch_fsync) {
2647                 write_nic_byte(dev, 0xC36, 0x1c);
2648                 write_nic_byte(dev, 0xC3e, 0x90);
2649             } else {
2650                 write_nic_byte(dev, 0xC36, 0x5c);
2651                 write_nic_byte(dev, 0xC3e, 0x96);
2652             }
2653         } else if (priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold) {
2654             if (priv->bswitch_fsync) {
2655                 priv->bswitch_fsync  = false;
2656                 write_nic_byte(dev, 0xC36, 0x5c);
2657                 write_nic_byte(dev, 0xC3e, 0x96);
2658             }
2659         }
2660         if (bDoubleTimeInterval) {
2661             cancel_delayed_work_sync(&priv->fsync_work);
2662             schedule_delayed_work(&priv->fsync_work,
2663                           msecs_to_jiffies(priv
2664                           ->ieee80211->fsync_time_interval *
2665                           priv->ieee80211->fsync_multiple_timeinterval));
2666         } else {
2667             cancel_delayed_work_sync(&priv->fsync_work);
2668             schedule_delayed_work(&priv->fsync_work,
2669                           msecs_to_jiffies(priv
2670                           ->ieee80211->fsync_time_interval));
2671         }
2672     } else {
2673         /* Let Register return to default value; */
2674         if (priv->bswitch_fsync) {
2675             priv->bswitch_fsync  = false;
2676             write_nic_byte(dev, 0xC36, 0x5c);
2677             write_nic_byte(dev, 0xC3e, 0x96);
2678         }
2679         priv->ContinueDiffCount = 0;
2680         write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2681     }
2682     RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
2683     RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff, priv->bswitch_fsync);
2684 }
2685 
2686 static void dm_StartHWFsync(struct net_device *dev)
2687 {
2688     RT_TRACE(COMP_HALDM, "%s\n", __func__);
2689     write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
2690     write_nic_byte(dev, 0xc3b, 0x41);
2691 }
2692 
2693 static void dm_EndSWFsync(struct net_device *dev)
2694 {
2695     struct r8192_priv *priv = ieee80211_priv(dev);
2696 
2697     RT_TRACE(COMP_HALDM, "%s\n", __func__);
2698     cancel_delayed_work_sync(&priv->fsync_work);
2699 
2700     /* Let Register return to default value; */
2701     if (priv->bswitch_fsync) {
2702         priv->bswitch_fsync  = false;
2703 
2704         write_nic_byte(dev, 0xC36, 0x5c);
2705 
2706         write_nic_byte(dev, 0xC3e, 0x96);
2707     }
2708 
2709     priv->ContinueDiffCount = 0;
2710     write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2711 }
2712 
2713 static void dm_StartSWFsync(struct net_device *dev)
2714 {
2715     struct r8192_priv *priv = ieee80211_priv(dev);
2716     u32         rateIndex;
2717     u32         rateBitmap;
2718 
2719     RT_TRACE(COMP_HALDM, "%s\n", __func__);
2720     /* Initial rate record to zero, start to record. */
2721     priv->rate_record = 0;
2722     /* Initialize continue diff count to zero, start to record. */
2723     priv->ContinueDiffCount = 0;
2724     priv->rateCountDiffRecord = 0;
2725     priv->bswitch_fsync  = false;
2726 
2727     if (priv->ieee80211->mode == WIRELESS_MODE_N_24G) {
2728         priv->ieee80211->fsync_firstdiff_ratethreshold = 600;
2729         priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
2730     } else {
2731         priv->ieee80211->fsync_firstdiff_ratethreshold = 200;
2732         priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
2733     }
2734     for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
2735         rateBitmap = 1 << rateIndex;
2736         if (priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
2737             priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
2738     }
2739     cancel_delayed_work_sync(&priv->fsync_work);
2740     schedule_delayed_work(&priv->fsync_work,
2741                   msecs_to_jiffies(priv->ieee80211->fsync_time_interval));
2742 
2743     write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
2744 }
2745 
2746 static void dm_EndHWFsync(struct net_device *dev)
2747 {
2748     RT_TRACE(COMP_HALDM, "%s\n", __func__);
2749     write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2750     write_nic_byte(dev, 0xc3b, 0x49);
2751 }
2752 
2753 void dm_check_fsync(struct net_device *dev)
2754 {
2755 #define RegC38_Default              0
2756 #define RegC38_NonFsync_Other_AP        1
2757 #define RegC38_Fsync_AP_BCM         2
2758     struct r8192_priv *priv = ieee80211_priv(dev);
2759     /*u32           framesyncC34;*/
2760     static u8       reg_c38_State = RegC38_Default;
2761     static u32  reset_cnt;
2762 
2763     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);
2764     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);
2765 
2766     if (priv->ieee80211->state == IEEE80211_LINKED &&
2767         (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2768         if (priv->ieee80211->bfsync_enable == 0) {
2769             switch (priv->ieee80211->fsync_state) {
2770             case Default_Fsync:
2771                 dm_StartHWFsync(dev);
2772                 priv->ieee80211->fsync_state = HW_Fsync;
2773                 break;
2774             case SW_Fsync:
2775                 dm_EndSWFsync(dev);
2776                 dm_StartHWFsync(dev);
2777                 priv->ieee80211->fsync_state = HW_Fsync;
2778                 break;
2779             case HW_Fsync:
2780             default:
2781                 break;
2782             }
2783         } else {
2784             switch (priv->ieee80211->fsync_state) {
2785             case Default_Fsync:
2786                 dm_StartSWFsync(dev);
2787                 priv->ieee80211->fsync_state = SW_Fsync;
2788                 break;
2789             case HW_Fsync:
2790                 dm_EndHWFsync(dev);
2791                 dm_StartSWFsync(dev);
2792                 priv->ieee80211->fsync_state = SW_Fsync;
2793                 break;
2794             case SW_Fsync:
2795             default:
2796                 break;
2797             }
2798         }
2799         if (priv->framesyncMonitor) {
2800             if (reg_c38_State != RegC38_Fsync_AP_BCM) {
2801                 /* For broadcom AP we write different default value */
2802                 write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
2803 
2804                 reg_c38_State = RegC38_Fsync_AP_BCM;
2805             }
2806         }
2807     } else {
2808         switch (priv->ieee80211->fsync_state) {
2809         case HW_Fsync:
2810             dm_EndHWFsync(dev);
2811             priv->ieee80211->fsync_state = Default_Fsync;
2812             break;
2813         case SW_Fsync:
2814             dm_EndSWFsync(dev);
2815             priv->ieee80211->fsync_state = Default_Fsync;
2816             break;
2817         case Default_Fsync:
2818         default:
2819             break;
2820         }
2821 
2822         if (priv->framesyncMonitor) {
2823             if (priv->ieee80211->state == IEEE80211_LINKED) {
2824                 if (priv->undecorated_smoothed_pwdb <= REG_C38_TH) {
2825                     if (reg_c38_State != RegC38_NonFsync_Other_AP) {
2826                         write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
2827 
2828                         reg_c38_State = RegC38_NonFsync_Other_AP;
2829                     }
2830                 } else if (priv->undecorated_smoothed_pwdb >= (REG_C38_TH + 5)) {
2831                     if (reg_c38_State) {
2832                         write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2833                         reg_c38_State = RegC38_Default;
2834                         /*DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x\n", pHalData->framesync);*/
2835                     }
2836                 }
2837             } else {
2838                 if (reg_c38_State) {
2839                     write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2840                     reg_c38_State = RegC38_Default;
2841                     /*DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x\n", pHalData->framesync);*/
2842                 }
2843             }
2844         }
2845     }
2846     if (priv->framesyncMonitor) {
2847         if (priv->reset_count != reset_cnt) { /* After silent reset, the reg_c38_State will be returned to default value */
2848             write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2849             reg_c38_State = RegC38_Default;
2850             reset_cnt = priv->reset_count;
2851             /*DbgPrint("reg_c38_State = 0 for silent reset.\n");*/
2852         }
2853     } else {
2854         if (reg_c38_State) {
2855             write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
2856             reg_c38_State = RegC38_Default;
2857             /*DbgPrint("framesync no monitor, write 0xc38 = 0x%x\n", pHalData->framesync);*/
2858         }
2859     }
2860 }
2861 
2862 /*-----------------------------------------------------------------------------
2863  * Function:    dm_shadow_init()
2864  *
2865  * Overview:    Store all NIC MAC/BB register content.
2866  *
2867  * Input:       NONE
2868  *
2869  * Output:      NONE
2870  *
2871  * Return:      NONE
2872  *
2873  * Revised History:
2874  *  When        Who     Remark
2875  *  05/29/2008  amy     Create Version 0 porting from windows code.
2876  *
2877  *---------------------------------------------------------------------------
2878  */
2879 void dm_shadow_init(struct net_device *dev)
2880 {
2881     u8  page;
2882     u16 offset;
2883 
2884     for (page = 0; page < 5; page++)
2885         for (offset = 0; offset < 256; offset++) {
2886             read_nic_byte(dev, offset + page * 256, &dm_shadow[page][offset]);
2887             /*DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);*/
2888         }
2889 
2890     for (page = 8; page < 11; page++)
2891         for (offset = 0; offset < 256; offset++)
2892             read_nic_byte(dev, offset + page * 256, &dm_shadow[page][offset]);
2893 
2894     for (page = 12; page < 15; page++)
2895         for (offset = 0; offset < 256; offset++)
2896             read_nic_byte(dev, offset + page * 256, &dm_shadow[page][offset]);
2897 
2898 }   /* dm_shadow_init */
2899 
2900 /*---------------------------Define function prototype------------------------*/
2901 /*-----------------------------------------------------------------------------
2902  * Function:    DM_DynamicTxPower()
2903  *
2904  * Overview:    Detect Signal strength to control TX Registry
2905             Tx Power Control For Near/Far Range
2906  *
2907  * Input:       NONE
2908  *
2909  * Output:      NONE
2910  *
2911  * Return:      NONE
2912  *
2913  * Revised History:
2914  *  When        Who     Remark
2915  *  03/06/2008  Jacken  Create Version 0.
2916  *
2917  *---------------------------------------------------------------------------
2918  */
2919 static void dm_init_dynamic_txpower(struct net_device *dev)
2920 {
2921     struct r8192_priv *priv = ieee80211_priv(dev);
2922 
2923     /* Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code. */
2924     priv->ieee80211->bdynamic_txpower_enable = true;    /* Default to enable Tx Power Control */
2925     priv->bLastDTPFlag_High = false;
2926     priv->bLastDTPFlag_Low = false;
2927     priv->bDynamicTxHighPower = false;
2928     priv->bDynamicTxLowPower = false;
2929 }
2930 
2931 static void dm_dynamic_txpower(struct net_device *dev)
2932 {
2933     struct r8192_priv *priv = ieee80211_priv(dev);
2934     unsigned int txhipower_threshold = 0;
2935     unsigned int txlowpower_threshold = 0;
2936 
2937     if (!priv->ieee80211->bdynamic_txpower_enable) {
2938         priv->bDynamicTxHighPower = false;
2939         priv->bDynamicTxLowPower = false;
2940         return;
2941     }
2942     /*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);*/
2943     if ((priv->ieee80211->current_network.atheros_cap_exist) && (priv->ieee80211->mode == IEEE_G)) {
2944         txhipower_threshold = TX_POWER_ATHEROAP_THRESH_HIGH;
2945         txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2946     } else {
2947         txhipower_threshold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2948         txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2949     }
2950 
2951     /*printk("=======>%s(): txhipower_threshold is %d, txlowpower_threshold is %d\n", __func__, txhipower_threshold, txlowpower_threshold);*/
2952     RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n", priv->undecorated_smoothed_pwdb);
2953 
2954     if (priv->ieee80211->state == IEEE80211_LINKED) {
2955         if (priv->undecorated_smoothed_pwdb >= txhipower_threshold) {
2956             priv->bDynamicTxHighPower = true;
2957             priv->bDynamicTxLowPower = false;
2958         } else {
2959             /* high power state check */
2960             if (priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower)
2961                 priv->bDynamicTxHighPower = false;
2962 
2963             /* low power state check */
2964             if (priv->undecorated_smoothed_pwdb < 35)
2965                 priv->bDynamicTxLowPower = true;
2966             else if (priv->undecorated_smoothed_pwdb >= 40)
2967                 priv->bDynamicTxLowPower = false;
2968         }
2969     } else {
2970         /*pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;*/
2971         priv->bDynamicTxHighPower = false;
2972         priv->bDynamicTxLowPower = false;
2973     }
2974 
2975     if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
2976         (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
2977         RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190()  channel = %d\n", priv->ieee80211->current_network.channel);
2978 
2979 #if  defined(RTL8190P) || defined(RTL8192E)
2980         SetTxPowerLevel8190(Adapter, pHalData->CurrentChannel);
2981 #endif
2982 
2983         rtl8192_phy_setTxPower(dev, priv->ieee80211->current_network.channel);
2984         /*pHalData->bStartTxCtrlByTPCNFR = FALSE;    Clear th flag of Set TX Power from Sitesurvey*/
2985     }
2986     priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2987     priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2988 
2989 }   /* dm_dynamic_txpower */
2990 
2991 /* added by vivi, for read tx rate and retrycount */
2992 static void dm_check_txrateandretrycount(struct net_device *dev)
2993 {
2994     struct r8192_priv *priv = ieee80211_priv(dev);
2995     struct ieee80211_device *ieee = priv->ieee80211;
2996     /* for 11n tx rate */
2997     /*priv->stats.CurrentShowTxate = read_nic_byte(dev, CURRENT_TX_RATE_REG);*/
2998     read_nic_byte(dev, CURRENT_TX_RATE_REG, &ieee->softmac_stats.CurrentShowTxate);
2999     /*printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);*/
3000     /* for initial tx rate */
3001     /*priv->stats.last_packet_rate = read_nic_byte(dev, INITIAL_TX_RATE_REG);*/
3002     read_nic_byte(dev, INITIAL_TX_RATE_REG, &ieee->softmac_stats.last_packet_rate);
3003     /* for tx retry count */
3004     /*priv->stats.txretrycount = read_nic_dword(dev, TX_RETRY_COUNT_REG);*/
3005     read_nic_dword(dev, TX_RETRY_COUNT_REG, &ieee->softmac_stats.txretrycount);
3006 }
3007 
3008 static void dm_send_rssi_tofw(struct net_device *dev)
3009 {
3010     struct r8192_priv *priv = ieee80211_priv(dev);
3011 
3012     /* If we test chariot, we should stop the TX command ?
3013      * Because 92E will always silent reset when we send tx command. We use register
3014      * 0x1e0(byte) to notify driver.
3015      */
3016     write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
3017 }
3018 
3019 /*---------------------------Define function prototype------------------------*/