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