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