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