Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/vapier...
[pandora-kernel.git] / drivers / staging / rtl8192e / r8192E_dm.c
1 /*++
2 Copyright-c Realtek Semiconductor Corp. All rights reserved.
3
4 Module Name:
5         r8192U_dm.c
6
7 Abstract:
8         HW dynamic mechanism.
9
10 Major Change History:
11         When            Who                             What
12         ----------      --------------- -------------------------------
13         2008-05-14      amy                     create version 0 porting from windows code.
14
15 --*/
16 #include "r8192E.h"
17 #include "r8192E_dm.h"
18 #include "r8192E_hw.h"
19 #include "r819xE_phy.h"
20 #include "r819xE_phyreg.h"
21 #include "r8190_rtl8256.h"
22
23 #define DRV_NAME "rtl819xE"
24 /*---------------------------Define Local Constant---------------------------*/
25 //
26 // Indicate different AP vendor for IOT issue.
27 //
28 #ifdef  RTL8190P
29 static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
30 { 0x5e4322,     0x5e4322,       0x5e4322,       0x604322,       0xa44f,         0x5e4322,       0x5e4322};
31 static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
32 { 0x5e4322,     0xa44f,         0x5e4322,       0x604322,       0x5e4322,       0x5e4322,       0x5e4322};
33 #else
34 #ifdef RTL8192E
35 static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
36 { 0x5e4322,     0x5e4322,       0x5e4322,       0x604322,       0xa44f,         0x5e4322,       0x5e4322};
37 static u32 edca_setting_UL[HT_IOT_PEER_MAX] =
38 { 0x5e4322,     0xa44f,         0x5e4322,       0x604322,       0x5e4322,       0x5e4322,       0x5e4322};
39 #else
40 static u32 edca_setting_DL[HT_IOT_PEER_MAX] =
41 { 0x5e4322,     0x5e4322,       0x5e4322,       0x604322,       0xa44f,         0x5ea44f,       0x5e4322};
42 static 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 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 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 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         else
2098                 return;
2099 }
2100
2101
2102 static void dm_ctrl_initgain_byrssi_by_driverrssi(
2103         struct net_device *dev)
2104 {
2105         struct r8192_priv *priv = ieee80211_priv(dev);
2106         u8 i;
2107         static u8       fw_dig=0;
2108
2109         if (dm_digtable.dig_enable_flag == false)
2110                 return;
2111
2112         //DbgPrint("Dig by Sw Rssi \n");
2113         if(dm_digtable.dig_algorithm_switch)    // if swithed algorithm, we have to disable FW Dig.
2114                 fw_dig = 0;
2115         if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled
2116         {// FW DIG Off
2117                 for(i=0; i<3; i++)
2118                         rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   // Only clear byte 1 and rewrite.
2119                 fw_dig++;
2120                 dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off.
2121         }
2122
2123         if(priv->ieee80211->state == IEEE80211_LINKED)
2124                 dm_digtable.cur_connect_state = DIG_CONNECT;
2125         else
2126                 dm_digtable.cur_connect_state = DIG_DISCONNECT;
2127
2128         //DbgPrint("DM_DigTable.PreConnectState = %d, DM_DigTable.CurConnectState = %d \n",
2129                 //DM_DigTable.PreConnectState, DM_DigTable.CurConnectState);
2130
2131         if(dm_digtable.dbg_mode == DM_DBG_OFF)
2132                 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
2133         //DbgPrint("DM_DigTable.Rssi_val = %d \n", DM_DigTable.Rssi_val);
2134         dm_initial_gain(dev);
2135         dm_pd_th(dev);
2136         dm_cs_ratio(dev);
2137         if(dm_digtable.dig_algorithm_switch)
2138                 dm_digtable.dig_algorithm_switch = 0;
2139         dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
2140
2141 }       /* dm_CtrlInitGainByRssi */
2142
2143 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
2144         struct net_device *dev)
2145 {
2146         struct r8192_priv *priv = ieee80211_priv(dev);
2147         static u32 reset_cnt = 0;
2148         u8 i;
2149
2150         if (dm_digtable.dig_enable_flag == false)
2151                 return;
2152
2153         if(dm_digtable.dig_algorithm_switch)
2154         {
2155                 dm_digtable.dig_state = DM_STA_DIG_MAX;
2156                 // Fw DIG On.
2157                 for(i=0; i<3; i++)
2158                         rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);   // Only clear byte 1 and rewrite.
2159                 dm_digtable.dig_algorithm_switch = 0;
2160         }
2161
2162         if (priv->ieee80211->state != IEEE80211_LINKED)
2163                 return;
2164
2165         // For smooth, we can not change DIG state.
2166         if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
2167                 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
2168         {
2169                 return;
2170         }
2171         //DbgPrint("Dig by Fw False Alarm\n");
2172         //if (DM_DigTable.Dig_State == DM_STA_DIG_OFF)
2173         /*DbgPrint("DIG Check\n\r RSSI=%d LOW=%d HIGH=%d STATE=%d",
2174         pHalData->UndecoratedSmoothedPWDB, DM_DigTable.RssiLowThresh,
2175         DM_DigTable.RssiHighThresh, DM_DigTable.Dig_State);*/
2176         /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
2177                   and then execute below step. */
2178         if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
2179         {
2180                 /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
2181                    will be reset to init value. We must prevent the condition. */
2182                 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
2183                         (priv->reset_count == reset_cnt))
2184                 {
2185                         return;
2186                 }
2187                 else
2188                 {
2189                         reset_cnt = priv->reset_count;
2190                 }
2191
2192                 // If DIG is off, DIG high power state must reset.
2193                 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
2194                 dm_digtable.dig_state = DM_STA_DIG_OFF;
2195
2196                 // 1.1 DIG Off.
2197                 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);   // Only clear byte 1 and rewrite.
2198
2199                 // 1.2 Set initial gain.
2200                 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
2201                 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
2202                 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
2203                 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
2204
2205                 // 1.3 Lower PD_TH for OFDM.
2206                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2207                 {
2208                         /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2209                         // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2210                         #ifdef RTL8190P
2211                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2212                         #else
2213                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
2214                                 #endif
2215                         /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2216                                 write_nic_byte(pAdapter, rOFDM0_RxDetector1, 0x40);
2217                         */
2218                         //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
2219
2220
2221                         //else
2222                                 //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x40);
2223                 }
2224                 else
2225                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2226
2227                 // 1.4 Lower CS ratio for CCK.
2228                 write_nic_byte(dev, 0xa0a, 0x08);
2229
2230                 // 1.5 Higher EDCCA.
2231                 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
2232                 return;
2233
2234         }
2235
2236         /* 2. When RSSI increase, We have to judge if it is larger than a threshold
2237                   and then execute below step.  */
2238         if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
2239         {
2240                 u8 reset_flag = 0;
2241
2242                 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
2243                         (priv->reset_count == reset_cnt))
2244                 {
2245                         dm_ctrl_initgain_byrssi_highpwr(dev);
2246                         return;
2247                 }
2248                 else
2249                 {
2250                         if (priv->reset_count != reset_cnt)
2251                                 reset_flag = 1;
2252
2253                         reset_cnt = priv->reset_count;
2254                 }
2255
2256                 dm_digtable.dig_state = DM_STA_DIG_ON;
2257                 //DbgPrint("DIG ON\n\r");
2258
2259                 // 2.1 Set initial gain.
2260                 // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
2261                 if (reset_flag == 1)
2262                 {
2263                         write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
2264                         write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
2265                         write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
2266                         write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
2267                 }
2268                 else
2269                 {
2270                 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
2271                 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
2272                 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
2273                 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
2274                 }
2275
2276                 // 2.2 Higher PD_TH for OFDM.
2277                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2278                 {
2279                         /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2280                         // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2281                         #ifdef RTL8190P
2282                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2283                         #else
2284                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2285                                 #endif
2286                         /*
2287                         else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2288                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2289                         */
2290                         //else if (pAdapter->HardwareType == HARDWARE_TYPE_RTL8192E)
2291
2292                         //else
2293                                 //PlatformEFIOWrite1Byte(pAdapter, rOFDM0_RxDetector1, 0x42);
2294                 }
2295                 else
2296                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2297
2298                 // 2.3 Higher CS ratio for CCK.
2299                 write_nic_byte(dev, 0xa0a, 0xcd);
2300
2301                 // 2.4 Lower EDCCA.
2302                 /* 2008/01/11 MH 90/92 series are the same. */
2303                 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
2304
2305                 // 2.5 DIG On.
2306                 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);   // Only clear byte 1 and rewrite.
2307
2308         }
2309
2310         dm_ctrl_initgain_byrssi_highpwr(dev);
2311
2312 }       /* dm_CtrlInitGainByRssi */
2313
2314
2315 /*-----------------------------------------------------------------------------
2316  * Function:    dm_ctrl_initgain_byrssi_highpwr()
2317  *
2318  * Overview:
2319  *
2320  * Input:               NONE
2321  *
2322  * Output:              NONE
2323  *
2324  * Return:              NONE
2325  *
2326  * Revised History:
2327  *      When            Who             Remark
2328  *      05/28/2008      amy             Create Version 0 porting from windows code.
2329  *
2330  *---------------------------------------------------------------------------*/
2331 static void dm_ctrl_initgain_byrssi_highpwr(
2332         struct net_device * dev)
2333 {
2334         struct r8192_priv *priv = ieee80211_priv(dev);
2335         static u32 reset_cnt_highpwr = 0;
2336
2337         // For smooth, we can not change high power DIG state in the range.
2338         if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
2339                 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
2340         {
2341                 return;
2342         }
2343
2344         /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
2345                   it is larger than a threshold and then execute below step.  */
2346         // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
2347         if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
2348         {
2349                 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
2350                         (priv->reset_count == reset_cnt_highpwr))
2351                         return;
2352                 else
2353                         dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
2354
2355                 // 3.1 Higher PD_TH for OFDM for high power state.
2356                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2357                 {
2358                         #ifdef RTL8190P
2359                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2360                         #else
2361                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2362                                 #endif
2363
2364                         /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2365                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2366                         */
2367
2368                 }
2369                 else
2370                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2371         }
2372         else
2373         {
2374                 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
2375                         (priv->reset_count == reset_cnt_highpwr))
2376                         return;
2377                 else
2378                         dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
2379
2380                 if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
2381                          priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
2382                 {
2383                         // 3.2 Recover PD_TH for OFDM for normal power region.
2384                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2385                         {
2386                                 #ifdef RTL8190P
2387                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2388                                 #else
2389                                         write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2390                                         #endif
2391                                 /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2392                                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2393                                 */
2394
2395                         }
2396                         else
2397                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2398                 }
2399         }
2400
2401         reset_cnt_highpwr = priv->reset_count;
2402
2403 }       /* dm_CtrlInitGainByRssiHighPwr */
2404
2405
2406 static void dm_initial_gain(
2407         struct net_device * dev)
2408 {
2409         struct r8192_priv *priv = ieee80211_priv(dev);
2410         u8                                      initial_gain=0;
2411         static u8                               initialized=0, force_write=0;
2412         static u32                      reset_cnt=0;
2413
2414         if(dm_digtable.dig_algorithm_switch)
2415         {
2416                 initialized = 0;
2417                 reset_cnt = 0;
2418         }
2419
2420         if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
2421         {
2422                 if(dm_digtable.cur_connect_state == DIG_CONNECT)
2423                 {
2424                         if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
2425                                 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
2426                         else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
2427                                 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
2428                         else
2429                                 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
2430                 }
2431                 else            //current state is disconnected
2432                 {
2433                         if(dm_digtable.cur_ig_value == 0)
2434                                 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2435                         else
2436                                 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
2437                 }
2438         }
2439         else    // disconnected -> connected or connected -> disconnected
2440         {
2441                 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
2442                 dm_digtable.pre_ig_value = 0;
2443         }
2444         //DbgPrint("DM_DigTable.CurIGValue = 0x%x, DM_DigTable.PreIGValue = 0x%x\n", DM_DigTable.CurIGValue, DM_DigTable.PreIGValue);
2445
2446         // if silent reset happened, we should rewrite the values back
2447         if(priv->reset_count != reset_cnt)
2448         {
2449                 force_write = 1;
2450                 reset_cnt = priv->reset_count;
2451         }
2452
2453         if(dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1))
2454                 force_write = 1;
2455
2456         {
2457                 if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
2458                         || !initialized || force_write)
2459                 {
2460                         initial_gain = (u8)dm_digtable.cur_ig_value;
2461                         //DbgPrint("Write initial gain = 0x%x\n", initial_gain);
2462                         // Set initial gain.
2463                         write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
2464                         write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
2465                         write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
2466                         write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
2467                         dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
2468                         initialized = 1;
2469                         force_write = 0;
2470                 }
2471         }
2472 }
2473
2474 static void dm_pd_th(
2475         struct net_device * dev)
2476 {
2477         struct r8192_priv *priv = ieee80211_priv(dev);
2478         static u8                               initialized=0, force_write=0;
2479         static u32                      reset_cnt = 0;
2480
2481         if(dm_digtable.dig_algorithm_switch)
2482         {
2483                 initialized = 0;
2484                 reset_cnt = 0;
2485         }
2486
2487         if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
2488         {
2489                 if(dm_digtable.cur_connect_state == DIG_CONNECT)
2490                 {
2491                         if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
2492                                 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
2493                         else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2494                                 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2495                         else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
2496                                         (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
2497                                 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
2498                         else
2499                                 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
2500                 }
2501                 else
2502                 {
2503                         dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2504                 }
2505         }
2506         else    // disconnected -> connected or connected -> disconnected
2507         {
2508                 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
2509         }
2510
2511         // if silent reset happened, we should rewrite the values back
2512         if(priv->reset_count != reset_cnt)
2513         {
2514                 force_write = 1;
2515                 reset_cnt = priv->reset_count;
2516         }
2517
2518         {
2519                 if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
2520                         (initialized<=3) || force_write)
2521                 {
2522                         //DbgPrint("Write PD_TH state = %d\n", DM_DigTable.CurPD_THState);
2523                         if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
2524                         {
2525                                 // Lower PD_TH for OFDM.
2526                                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2527                                 {
2528                                         /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2529                                         // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2530                                         #ifdef RTL8190P
2531                                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2532                                         #else
2533                                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
2534                                                 #endif
2535                                         /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2536                                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x40);
2537                                         */
2538                                 }
2539                                 else
2540                                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2541                         }
2542                         else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
2543                         {
2544                                 // Higher PD_TH for OFDM.
2545                                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2546                                 {
2547                                         /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
2548                                         // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
2549                                         #ifdef RTL8190P
2550                                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2551                                         #else
2552                                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
2553                                                 #endif
2554                                         /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2555                                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
2556                                         */
2557                                 }
2558                                 else
2559                                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
2560                         }
2561                         else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
2562                         {
2563                                 // Higher PD_TH for OFDM for high power state.
2564                                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
2565                                 {
2566                                         #ifdef RTL8190P
2567                                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2568                                         #else
2569                                                 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
2570                                                 #endif
2571                                         /*else if (priv->card_8192 == HARDWARE_TYPE_RTL8190P)
2572                                                 write_nic_byte(dev, rOFDM0_RxDetector1, 0x41);
2573                                         */
2574                                 }
2575                                 else
2576                                         write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
2577                         }
2578                         dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
2579                         if(initialized <= 3)
2580                                 initialized++;
2581                         force_write = 0;
2582                 }
2583         }
2584 }
2585
2586 static  void dm_cs_ratio(
2587         struct net_device * dev)
2588 {
2589         struct r8192_priv *priv = ieee80211_priv(dev);
2590         static u8                               initialized=0,force_write=0;
2591         static u32                      reset_cnt = 0;
2592
2593         if(dm_digtable.dig_algorithm_switch)
2594         {
2595                 initialized = 0;
2596                 reset_cnt = 0;
2597         }
2598
2599         if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
2600         {
2601                 if(dm_digtable.cur_connect_state == DIG_CONNECT)
2602                 {
2603                         if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
2604                                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2605                         else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) )
2606                                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
2607                         else
2608                                 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
2609                 }
2610                 else
2611                 {
2612                         dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2613                 }
2614         }
2615         else    // disconnected -> connected or connected -> disconnected
2616         {
2617                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
2618         }
2619
2620         // if silent reset happened, we should rewrite the values back
2621         if(priv->reset_count != reset_cnt)
2622         {
2623                 force_write = 1;
2624                 reset_cnt = priv->reset_count;
2625         }
2626
2627
2628         {
2629                 if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
2630                         !initialized || force_write)
2631                 {
2632                         //DbgPrint("Write CS_ratio state = %d\n", DM_DigTable.CurCS_ratioState);
2633                         if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
2634                         {
2635                                 // Lower CS ratio for CCK.
2636                                 write_nic_byte(dev, 0xa0a, 0x08);
2637                         }
2638                         else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
2639                         {
2640                                 // Higher CS ratio for CCK.
2641                                 write_nic_byte(dev, 0xa0a, 0xcd);
2642                         }
2643                         dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
2644                         initialized = 1;
2645                         force_write = 0;
2646                 }
2647         }
2648 }
2649
2650 void dm_init_edca_turbo(struct net_device *dev)
2651 {
2652         struct r8192_priv *priv = ieee80211_priv(dev);
2653
2654         priv->bcurrent_turbo_EDCA = false;
2655         priv->ieee80211->bis_any_nonbepkts = false;
2656         priv->bis_cur_rdlstate = false;
2657 }       // dm_init_edca_turbo
2658
2659 #if 1
2660 static void dm_check_edca_turbo(
2661         struct net_device * dev)
2662 {
2663         struct r8192_priv *priv = ieee80211_priv(dev);
2664         PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
2665         //PSTA_QOS                      pStaQos = pMgntInfo->pStaQos;
2666
2667         // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
2668         static unsigned long                    lastTxOkCnt = 0;
2669         static unsigned long                    lastRxOkCnt = 0;
2670         unsigned long                           curTxOkCnt = 0;
2671         unsigned long                           curRxOkCnt = 0;
2672
2673         //
2674         // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
2675         // should follow the settings from QAP. By Bruce, 2007-12-07.
2676         //
2677         #if 1
2678         if(priv->ieee80211->state != IEEE80211_LINKED)
2679                 goto dm_CheckEdcaTurbo_EXIT;
2680         #endif
2681         // We do not turn on EDCA turbo mode for some AP that has IOT issue
2682         if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
2683                 goto dm_CheckEdcaTurbo_EXIT;
2684
2685 //      printk("========>%s():bis_any_nonbepkts is %d\n",__FUNCTION__,priv->bis_any_nonbepkts);
2686         // Check the status for current condition.
2687         if(!priv->ieee80211->bis_any_nonbepkts)
2688         {
2689                 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2690                 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2691                 // For RT-AP, we needs to turn it on when Rx>Tx
2692                 if(curRxOkCnt > 4*curTxOkCnt)
2693                 {
2694                         //printk("%s():curRxOkCnt > 4*curTxOkCnt\n");
2695                         if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2696                         {
2697                                 write_nic_dword(dev, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
2698                                 priv->bis_cur_rdlstate = true;
2699                         }
2700                 }
2701                 else
2702                 {
2703
2704                         //printk("%s():curRxOkCnt < 4*curTxOkCnt\n");
2705                         if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
2706                         {
2707                                 write_nic_dword(dev, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
2708                                 priv->bis_cur_rdlstate = false;
2709                         }
2710
2711                 }
2712
2713                 priv->bcurrent_turbo_EDCA = true;
2714         }
2715         else
2716         {
2717                 //
2718                 // Turn Off EDCA turbo here.
2719                 // Restore original EDCA according to the declaration of AP.
2720                 //
2721                  if(priv->bcurrent_turbo_EDCA)
2722                 {
2723
2724                         {
2725                                 u8              u1bAIFS;
2726                                 u32             u4bAcParam;
2727                                 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
2728                                 u8 mode = priv->ieee80211->mode;
2729
2730                         // For Each time updating EDCA parameter, reset EDCA turbo mode status.
2731                                 dm_init_edca_turbo(dev);
2732                                 u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
2733                                 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
2734                                         (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
2735                                         (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
2736                                         ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
2737                                 printk("===>u4bAcParam:%x, ", u4bAcParam);
2738                         //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
2739                                 write_nic_dword(dev, EDCAPARA_BE,  u4bAcParam);
2740
2741                         // Check ACM bit.
2742                         // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
2743                                 {
2744                         // TODO:  Modified this part and try to set acm control in only 1 IO processing!!
2745
2746                                         PACI_AIFSN      pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
2747                                         u8              AcmCtrl = read_nic_byte( dev, AcmHwCtrl );
2748                                         if( pAciAifsn->f.ACM )
2749                                         { // ACM bit is 1.
2750                                                 AcmCtrl |= AcmHw_BeqEn;
2751                                         }
2752                                         else
2753                                         { // ACM bit is 0.
2754                                                 AcmCtrl &= (~AcmHw_BeqEn);
2755                                         }
2756
2757                                         RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ;
2758                                         write_nic_byte(dev, AcmHwCtrl, AcmCtrl );
2759                                 }
2760                         }
2761                         priv->bcurrent_turbo_EDCA = false;
2762                 }
2763         }
2764
2765
2766 dm_CheckEdcaTurbo_EXIT:
2767         // Set variables for next time.
2768         priv->ieee80211->bis_any_nonbepkts = false;
2769         lastTxOkCnt = priv->stats.txbytesunicast;
2770         lastRxOkCnt = priv->stats.rxbytesunicast;
2771 }       // dm_CheckEdcaTurbo
2772 #endif
2773
2774 static void dm_init_ctstoself(struct net_device * dev)
2775 {
2776         struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
2777
2778         priv->ieee80211->bCTSToSelfEnable = TRUE;
2779         priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
2780 }
2781
2782 static void dm_ctstoself(struct net_device *dev)
2783 {
2784         struct r8192_priv *priv = ieee80211_priv((struct net_device *)dev);
2785         PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
2786         static unsigned long                            lastTxOkCnt = 0;
2787         static unsigned long                            lastRxOkCnt = 0;
2788         unsigned long                                           curTxOkCnt = 0;
2789         unsigned long                                           curRxOkCnt = 0;
2790
2791         if(priv->ieee80211->bCTSToSelfEnable != TRUE)
2792         {
2793                 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2794                 return;
2795         }
2796         /*
2797         1. Uplink
2798         2. Linksys350/Linksys300N
2799         3. <50 disable, >55 enable
2800         */
2801
2802         if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
2803         {
2804                 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
2805                 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
2806                 if(curRxOkCnt > 4*curTxOkCnt)   //downlink, disable CTS to self
2807                 {
2808                         pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2809                         //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled -- downlink\n");
2810                 }
2811                 else    //uplink
2812                 {
2813                 #if 1
2814                         pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2815                 #else
2816                         if(priv->undecorated_smoothed_pwdb < priv->ieee80211->CTSToSelfTH)      // disable CTS to self
2817                         {
2818                                 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
2819                                 //DbgPrint("dm_CTSToSelf() ==> CTS to self disabled\n");
2820                         }
2821                         else if(priv->undecorated_smoothed_pwdb >= (priv->ieee80211->CTSToSelfTH+5))    // enable CTS to self
2822                         {
2823                                 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
2824                                 //DbgPrint("dm_CTSToSelf() ==> CTS to self enabled\n");
2825                         }
2826                 #endif
2827                 }
2828
2829                 lastTxOkCnt = priv->stats.txbytesunicast;
2830                 lastRxOkCnt = priv->stats.rxbytesunicast;
2831         }
2832 }
2833
2834
2835
2836 /*-----------------------------------------------------------------------------
2837  * Function:    dm_check_rfctrl_gpio()
2838  *
2839  * Overview:    Copy 8187B template for 9xseries.
2840  *
2841  * Input:               NONE
2842  *
2843  * Output:              NONE
2844  *
2845  * Return:              NONE
2846  *
2847  * Revised History:
2848  *      When            Who             Remark
2849  *      05/28/2008      amy             Create Version 0 porting from windows code.
2850  *
2851  *---------------------------------------------------------------------------*/
2852 #if 1
2853 static void dm_check_rfctrl_gpio(struct net_device * dev)
2854 {
2855 #ifdef RTL8192E
2856         struct r8192_priv *priv = ieee80211_priv(dev);
2857 #endif
2858
2859         // Walk around for DTM test, we will not enable HW - radio on/off because r/w
2860         // page 1 register before Lextra bus is enabled cause system fails when resuming
2861         // from S4. 20080218, Emily
2862
2863         // Stop to execute workitem to prevent S3/S4 bug.
2864 #ifdef RTL8190P
2865         return;
2866 #endif
2867 #ifdef RTL8192U
2868         return;
2869 #endif
2870 #ifdef RTL8192E
2871                 queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
2872 #endif
2873
2874 }       /* dm_CheckRfCtrlGPIO */
2875
2876 #endif
2877 /*-----------------------------------------------------------------------------
2878  * Function:    dm_check_pbc_gpio()
2879  *
2880  * Overview:    Check if PBC button is pressed.
2881  *
2882  * Input:               NONE
2883  *
2884  * Output:              NONE
2885  *
2886  * Return:              NONE
2887  *
2888  * Revised History:
2889  *      When            Who             Remark
2890  *      05/28/2008      amy     Create Version 0 porting from windows code.
2891  *
2892  *---------------------------------------------------------------------------*/
2893 static  void    dm_check_pbc_gpio(struct net_device *dev)
2894 {
2895 #ifdef RTL8192U
2896         struct r8192_priv *priv = ieee80211_priv(dev);
2897         u8 tmp1byte;
2898
2899
2900         tmp1byte = read_nic_byte(dev,GPI);
2901         if(tmp1byte == 0xff)
2902         return;
2903
2904         if (tmp1byte&BIT6 || tmp1byte&BIT0)
2905         {
2906                 // Here we only set bPbcPressed to TRUE
2907                 // After trigger PBC, the variable will be set to FALSE
2908                 RT_TRACE(COMP_IO, "CheckPbcGPIO - PBC is pressed\n");
2909                 priv->bpbc_pressed = true;
2910         }
2911 #endif
2912
2913 }
2914
2915 #ifdef RTL8192E
2916
2917 /*-----------------------------------------------------------------------------
2918  * Function:    dm_GPIOChangeRF
2919  * Overview:    PCI will not support workitem call back HW radio on-off control.
2920  *
2921  * Input:               NONE
2922  *
2923  * Output:              NONE
2924  *
2925  * Return:              NONE
2926  *
2927  * Revised History:
2928  *      When            Who             Remark
2929  *      02/21/2008      MHC             Create Version 0.
2930  *
2931  *---------------------------------------------------------------------------*/
2932 void dm_gpio_change_rf_callback(struct work_struct *work)
2933 {
2934         struct delayed_work *dwork = container_of(work,struct delayed_work,work);
2935        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
2936        struct net_device *dev = priv->ieee80211->dev;
2937         u8 tmp1byte;
2938         RT_RF_POWER_STATE       eRfPowerStateToSet;
2939         bool bActuallySet = false;
2940
2941                 bActuallySet=false;
2942
2943                 if(!priv->up)
2944                 {
2945                 RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
2946                 }
2947                 else
2948                 {
2949                         // 0x108 GPIO input register is read only
2950                         //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
2951                         tmp1byte = read_nic_byte(dev,GPI);
2952
2953                         eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
2954
2955                         if( (priv->bHwRadioOff == true) && (eRfPowerStateToSet == eRfOn))
2956                         {
2957                         RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
2958
2959                                 priv->bHwRadioOff = false;
2960                                 bActuallySet = true;
2961                         }
2962                         else if ( (priv->bHwRadioOff == false) && (eRfPowerStateToSet == eRfOff))
2963                         {
2964                         RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
2965                                 priv->bHwRadioOff = true;
2966                                 bActuallySet = true;
2967                         }
2968
2969                         if(bActuallySet)
2970                         {
2971                         priv->bHwRfOffAction = 1;
2972                                 MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
2973                                 //DrvIFIndicateCurrentPhyStatus(pAdapter);
2974
2975                 }
2976                 else
2977                 {
2978                         msleep(2000);
2979                         }
2980
2981                 }
2982
2983 }       /* dm_GPIOChangeRF */
2984
2985 #endif
2986 /*-----------------------------------------------------------------------------
2987  * Function:    DM_RFPathCheckWorkItemCallBack()
2988  *
2989  * Overview:    Check if Current RF RX path is enabled
2990  *
2991  * Input:               NONE
2992  *
2993  * Output:              NONE
2994  *
2995  * Return:              NONE
2996  *
2997  * Revised History:
2998  *      When            Who             Remark
2999  *      01/30/2008      MHC             Create Version 0.
3000  *
3001  *---------------------------------------------------------------------------*/
3002 void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
3003 {
3004         struct delayed_work *dwork = container_of(work,struct delayed_work,work);
3005        struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
3006        struct net_device *dev =priv->ieee80211->dev;
3007         //bool bactually_set = false;
3008         u8 rfpath = 0, i;
3009
3010
3011         /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
3012            always be the same. We only read 0xc04 now. */
3013         rfpath = read_nic_byte(dev, 0xc04);
3014
3015         // Check Bit 0-3, it means if RF A-D is enabled.
3016         for (i = 0; i < RF90_PATH_MAX; i++)
3017         {
3018                 if (rfpath & (0x01<<i))
3019                         priv->brfpath_rxenable[i] = 1;
3020                 else
3021                         priv->brfpath_rxenable[i] = 0;
3022         }
3023         if(!DM_RxPathSelTable.Enable)
3024                 return;
3025
3026         dm_rxpath_sel_byrssi(dev);
3027 }       /* DM_RFPathCheckWorkItemCallBack */
3028
3029 static void dm_init_rxpath_selection(struct net_device * dev)
3030 {
3031         u8 i;
3032         struct r8192_priv *priv = ieee80211_priv(dev);
3033         DM_RxPathSelTable.Enable = 1;   //default enabled
3034         DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
3035         DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
3036         if(priv->CustomerID == RT_CID_819x_Netcore)
3037                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
3038         else
3039                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
3040         DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
3041         DM_RxPathSelTable.disabledRF = 0;
3042         for(i=0; i<4; i++)
3043         {
3044                 DM_RxPathSelTable.rf_rssi[i] = 50;
3045                 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
3046                 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
3047         }
3048 }
3049
3050 static void dm_rxpath_sel_byrssi(struct net_device * dev)
3051 {
3052         struct r8192_priv *priv = ieee80211_priv(dev);
3053         u8                              i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
3054         u8                              tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
3055         u8                              cck_default_Rx=0x2;     //RF-C
3056         u8                              cck_optional_Rx=0x3;//RF-D
3057         long                            tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
3058         u8                              cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
3059         u8                              cur_rf_rssi;
3060         long                            cur_cck_pwdb;
3061         static u8                       disabled_rf_cnt=0, cck_Rx_Path_initialized=0;
3062         u8                              update_cck_rx_path;
3063
3064         if(priv->rf_type != RF_2T4R)
3065                 return;
3066
3067         if(!cck_Rx_Path_initialized)
3068         {
3069                 DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf);
3070                 cck_Rx_Path_initialized = 1;
3071         }
3072
3073         DM_RxPathSelTable.disabledRF = 0xf;
3074         DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(dev, 0xc04));
3075
3076         if(priv->ieee80211->mode == WIRELESS_MODE_B)
3077         {
3078                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;        //pure B mode, fixed cck version2
3079                 //DbgPrint("Pure B mode, use cck rx version2 \n");
3080         }
3081
3082         //decide max/sec/min rssi index
3083         for (i=0; i<RF90_PATH_MAX; i++)
3084         {
3085                 if(!DM_RxPathSelTable.DbgMode)
3086                         DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
3087
3088                 if(priv->brfpath_rxenable[i])
3089                 {
3090                         rf_num++;
3091                         cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
3092
3093                         if(rf_num == 1) // find first enabled rf path and the rssi values
3094                         {       //initialize, set all rssi index to the same one
3095                                 max_rssi_index = min_rssi_index = sec_rssi_index = i;
3096                                 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
3097                         }
3098                         else if(rf_num == 2)
3099                         {       // we pick up the max index first, and let sec and min to be the same one
3100                                 if(cur_rf_rssi >= tmp_max_rssi)
3101                                 {
3102                                         tmp_max_rssi = cur_rf_rssi;
3103                                         max_rssi_index = i;
3104                                 }
3105                                 else
3106                                 {
3107                                         tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
3108                                         sec_rssi_index = min_rssi_index = i;
3109                                 }
3110                         }
3111                         else
3112                         {
3113                                 if(cur_rf_rssi > tmp_max_rssi)
3114                                 {
3115                                         tmp_sec_rssi = tmp_max_rssi;
3116                                         sec_rssi_index = max_rssi_index;
3117                                         tmp_max_rssi = cur_rf_rssi;
3118                                         max_rssi_index = i;
3119                                 }
3120                                 else if(cur_rf_rssi == tmp_max_rssi)
3121                                 {       // let sec and min point to the different index
3122                                         tmp_sec_rssi = cur_rf_rssi;
3123                                         sec_rssi_index = i;
3124                                 }
3125                                 else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
3126                                 {
3127                                         tmp_sec_rssi = cur_rf_rssi;
3128                                         sec_rssi_index = i;
3129                                 }
3130                                 else if(cur_rf_rssi == tmp_sec_rssi)
3131                                 {
3132                                         if(tmp_sec_rssi == tmp_min_rssi)
3133                                         {       // let sec and min point to the different index
3134                                                 tmp_sec_rssi = cur_rf_rssi;
3135                                                 sec_rssi_index = i;
3136                                         }
3137                                         else
3138                                         {
3139                                                 // This case we don't need to set any index
3140                                         }
3141                                 }
3142                                 else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
3143                                 {
3144                                         // This case we don't need to set any index
3145                                 }
3146                                 else if(cur_rf_rssi == tmp_min_rssi)
3147                                 {
3148                                         if(tmp_sec_rssi == tmp_min_rssi)
3149                                         {       // let sec and min point to the different index
3150                                                 tmp_min_rssi = cur_rf_rssi;
3151                                                 min_rssi_index = i;
3152                                         }
3153                                         else
3154                                         {
3155                                                 // This case we don't need to set any index
3156                                         }
3157                                 }
3158                                 else if(cur_rf_rssi < tmp_min_rssi)
3159                                 {
3160                                         tmp_min_rssi = cur_rf_rssi;
3161                                         min_rssi_index = i;
3162                                 }
3163                         }
3164                 }
3165         }
3166
3167         rf_num = 0;
3168         // decide max/sec/min cck pwdb index
3169         if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
3170         {
3171                 for (i=0; i<RF90_PATH_MAX; i++)
3172                 {
3173                         if(priv->brfpath_rxenable[i])
3174                         {
3175                                 rf_num++;
3176                                 cur_cck_pwdb =  DM_RxPathSelTable.cck_pwdb_sta[i];
3177
3178                                 if(rf_num == 1) // find first enabled rf path and the rssi values
3179                                 {       //initialize, set all rssi index to the same one
3180                                         cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
3181                                         tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
3182                                 }
3183                                 else if(rf_num == 2)
3184                                 {       // we pick up the max index first, and let sec and min to be the same one
3185                                         if(cur_cck_pwdb >= tmp_cck_max_pwdb)
3186                                         {
3187                                                 tmp_cck_max_pwdb = cur_cck_pwdb;
3188                                                 cck_rx_ver2_max_index = i;
3189                                         }
3190                                         else
3191                                         {
3192                                                 tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
3193                                                 cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
3194                                         }
3195                                 }
3196                                 else
3197                                 {
3198                                         if(cur_cck_pwdb > tmp_cck_max_pwdb)
3199                                         {
3200                                                 tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
3201                                                 cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
3202                                                 tmp_cck_max_pwdb = cur_cck_pwdb;
3203                                                 cck_rx_ver2_max_index = i;
3204                                         }
3205                                         else if(cur_cck_pwdb == tmp_cck_max_pwdb)
3206                                         {       // let sec and min point to the different index
3207                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
3208                                                 cck_rx_ver2_sec_index = i;
3209                                         }
3210                                         else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
3211                                         {
3212                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
3213                                                 cck_rx_ver2_sec_index = i;
3214                                         }
3215                                         else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
3216                                         {
3217                                                 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
3218                                                 {       // let sec and min point to the different index
3219                                                         tmp_cck_sec_pwdb = cur_cck_pwdb;
3220                                                         cck_rx_ver2_sec_index = i;
3221                                                 }
3222                                                 else
3223                                                 {
3224                                                         // This case we don't need to set any index
3225                                                 }
3226                                         }
3227                                         else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
3228                                         {
3229                                                 // This case we don't need to set any index
3230                                         }
3231                                         else if(cur_cck_pwdb == tmp_cck_min_pwdb)
3232                                         {
3233                                                 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
3234                                                 {       // let sec and min point to the different index
3235                                                         tmp_cck_min_pwdb = cur_cck_pwdb;
3236                                                         cck_rx_ver2_min_index = i;
3237                                                 }
3238                                                 else
3239                                                 {
3240                                                         // This case we don't need to set any index
3241                                                 }
3242                                         }
3243                                         else if(cur_cck_pwdb < tmp_cck_min_pwdb)
3244                                         {
3245                                                 tmp_cck_min_pwdb = cur_cck_pwdb;
3246                                                 cck_rx_ver2_min_index = i;
3247                                         }
3248                                 }
3249
3250                         }
3251                 }
3252         }
3253
3254
3255         // Set CCK Rx path
3256         // reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
3257         update_cck_rx_path = 0;
3258         if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
3259         {
3260                 cck_default_Rx = cck_rx_ver2_max_index;
3261                 cck_optional_Rx = cck_rx_ver2_sec_index;
3262                 if(tmp_cck_max_pwdb != -64)
3263                         update_cck_rx_path = 1;
3264         }
3265
3266         if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
3267         {
3268                 if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
3269                 {
3270                         //record the enabled rssi threshold
3271                         DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
3272                         //disable the BB Rx path, OFDM
3273                         rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0);  // 0xc04[3:0]
3274                         rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0);  // 0xd04[3:0]
3275                         disabled_rf_cnt++;
3276                 }
3277                 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
3278                 {
3279                         cck_default_Rx = max_rssi_index;
3280                         cck_optional_Rx = sec_rssi_index;
3281                         if(tmp_max_rssi)
3282                                 update_cck_rx_path = 1;
3283                 }
3284         }
3285
3286         if(update_cck_rx_path)
3287         {
3288                 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
3289                 rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
3290         }
3291
3292         if(DM_RxPathSelTable.disabledRF)
3293         {
3294                 for(i=0; i<4; i++)
3295                 {
3296                         if((DM_RxPathSelTable.disabledRF>>i) & 0x1)     //disabled rf
3297                         {
3298                                 if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
3299                                 {
3300                                         //enable the BB Rx path
3301                                         //DbgPrint("RF-%d is enabled. \n", 0x1<<i);
3302                                         rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);       // 0xc04[3:0]
3303                                         rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);       // 0xd04[3:0]
3304                                         DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
3305                                         disabled_rf_cnt--;
3306                                 }
3307                         }
3308                 }
3309         }
3310 }
3311
3312 /*-----------------------------------------------------------------------------
3313  * Function:    dm_check_rx_path_selection()
3314  *
3315  * Overview:    Call a workitem to check current RXRF path and Rx Path selection by RSSI.
3316  *
3317  * Input:               NONE
3318  *
3319  * Output:              NONE
3320  *
3321  * Return:              NONE
3322  *
3323  * Revised History:
3324  *      When            Who             Remark
3325  *      05/28/2008      amy             Create Version 0 porting from windows code.
3326  *
3327  *---------------------------------------------------------------------------*/
3328 static  void    dm_check_rx_path_selection(struct net_device *dev)
3329 {
3330         struct r8192_priv *priv = ieee80211_priv(dev);
3331         queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
3332 }       /* dm_CheckRxRFPath */
3333
3334
3335 static void dm_init_fsync (struct net_device *dev)
3336 {
3337         struct r8192_priv *priv = ieee80211_priv(dev);
3338
3339         priv->ieee80211->fsync_time_interval = 500;
3340         priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
3341         priv->ieee80211->fsync_rssi_threshold = 30;
3342 #ifdef RTL8190P
3343         priv->ieee80211->bfsync_enable = true;
3344 #else
3345         priv->ieee80211->bfsync_enable = false;
3346 #endif
3347         priv->ieee80211->fsync_multiple_timeinterval = 3;
3348         priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
3349         priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
3350         priv->ieee80211->fsync_state = Default_Fsync;
3351         priv->framesyncMonitor = 1;     // current default 0xc38 monitor on
3352
3353         init_timer(&priv->fsync_timer);
3354         priv->fsync_timer.data = (unsigned long)dev;
3355         priv->fsync_timer.function = dm_fsync_timer_callback;
3356 }
3357
3358
3359 static void dm_deInit_fsync(struct net_device *dev)
3360 {
3361         struct r8192_priv *priv = ieee80211_priv(dev);
3362         del_timer_sync(&priv->fsync_timer);
3363 }
3364
3365 void dm_fsync_timer_callback(unsigned long data)
3366 {
3367         struct net_device *dev = (struct net_device *)data;
3368         struct r8192_priv *priv = ieee80211_priv((struct net_device *)data);
3369         u32 rate_index, rate_count = 0, rate_count_diff=0;
3370         bool            bSwitchFromCountDiff = false;
3371         bool            bDoubleTimeInterval = false;
3372
3373         if(     priv->ieee80211->state == IEEE80211_LINKED &&
3374                 priv->ieee80211->bfsync_enable &&
3375                 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
3376         {
3377                  // Count rate 54, MCS [7], [12, 13, 14, 15]
3378                 u32 rate_bitmap;
3379                 for(rate_index = 0; rate_index <= 27; rate_index++)
3380                 {
3381                         rate_bitmap  = 1 << rate_index;
3382                         if(priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
3383                                 rate_count+= priv->stats.received_rate_histogram[1][rate_index];
3384                 }
3385
3386                 if(rate_count < priv->rate_record)
3387                         rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
3388                 else
3389                         rate_count_diff = rate_count - priv->rate_record;
3390                 if(rate_count_diff < priv->rateCountDiffRecord)
3391                 {
3392
3393                         u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
3394                         // Contiune count
3395                         if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
3396                                 priv->ContiuneDiffCount++;
3397                         else
3398                                 priv->ContiuneDiffCount = 0;
3399
3400                         // Contiune count over
3401                         if(priv->ContiuneDiffCount >=2)
3402                         {
3403                                 bSwitchFromCountDiff = true;
3404                                 priv->ContiuneDiffCount = 0;
3405                         }
3406                 }
3407                 else
3408                 {
3409                         // Stop contiune count
3410                         priv->ContiuneDiffCount = 0;
3411                 }
3412
3413                 //If Count diff <= FsyncRateCountThreshold
3414                 if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
3415                 {
3416                         bSwitchFromCountDiff = true;
3417                         priv->ContiuneDiffCount = 0;
3418                 }
3419                 priv->rate_record = rate_count;
3420                 priv->rateCountDiffRecord = rate_count_diff;
3421                 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
3422                 // if we never receive those mcs rate and rssi > 30 % then switch fsyn
3423                 if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
3424                 {
3425                         bDoubleTimeInterval = true;
3426                         priv->bswitch_fsync = !priv->bswitch_fsync;
3427                         if(priv->bswitch_fsync)
3428                         {
3429                         #ifdef RTL8190P
3430                                 write_nic_byte(dev,0xC36, 0x00);
3431                         #else
3432                                 write_nic_byte(dev,0xC36, 0x1c);
3433                         #endif
3434                                 write_nic_byte(dev, 0xC3e, 0x90);
3435                         }
3436                         else
3437                         {
3438                         #ifdef RTL8190P
3439                                 write_nic_byte(dev, 0xC36, 0x40);
3440                         #else
3441                                 write_nic_byte(dev, 0xC36, 0x5c);
3442                         #endif
3443                                 write_nic_byte(dev, 0xC3e, 0x96);
3444                         }
3445                 }
3446                 else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
3447                 {
3448                         if(priv->bswitch_fsync)
3449                         {
3450                                 priv->bswitch_fsync  = false;
3451                         #ifdef RTL8190P
3452                                 write_nic_byte(dev, 0xC36, 0x40);
3453                         #else
3454                                 write_nic_byte(dev, 0xC36, 0x5c);
3455                         #endif
3456                                 write_nic_byte(dev, 0xC3e, 0x96);
3457                         }
3458                 }
3459                 if(bDoubleTimeInterval){
3460                         if(timer_pending(&priv->fsync_timer))
3461                                 del_timer_sync(&priv->fsync_timer);
3462                         priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
3463                         add_timer(&priv->fsync_timer);
3464                 }
3465                 else{
3466                         if(timer_pending(&priv->fsync_timer))
3467                                 del_timer_sync(&priv->fsync_timer);
3468                         priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
3469                         add_timer(&priv->fsync_timer);
3470                 }
3471         }
3472         else
3473         {
3474                 // Let Register return to default value;
3475                 if(priv->bswitch_fsync)
3476                 {
3477                         priv->bswitch_fsync  = false;
3478                 #ifdef RTL8190P
3479                         write_nic_byte(dev, 0xC36, 0x40);
3480                 #else
3481                         write_nic_byte(dev, 0xC36, 0x5c);
3482                 #endif
3483                         write_nic_byte(dev, 0xC3e, 0x96);
3484                 }
3485                 priv->ContiuneDiffCount = 0;
3486         #ifdef RTL8190P
3487                 write_nic_dword(dev, rOFDM0_RxDetector2, 0x164052cd);
3488         #else
3489                 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
3490         #endif
3491         }
3492         RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
3493         RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
3494 }
3495
3496 static void dm_StartHWFsync(struct net_device *dev)
3497 {
3498         RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
3499         write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
3500         write_nic_byte(dev, 0xc3b, 0x41);
3501 }
3502
3503 static void dm_EndSWFsync(struct net_device *dev)
3504 {
3505         struct r8192_priv *priv = ieee80211_priv(dev);
3506
3507         RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
3508         del_timer_sync(&(priv->fsync_timer));
3509
3510         // Let Register return to default value;
3511         if(priv->bswitch_fsync)
3512         {
3513                 priv->bswitch_fsync  = false;
3514
3515                 #ifdef RTL8190P
3516                         write_nic_byte(dev, 0xC36, 0x40);
3517                 #else
3518                 write_nic_byte(dev, 0xC36, 0x5c);
3519 #endif
3520
3521                 write_nic_byte(dev, 0xC3e, 0x96);
3522         }
3523
3524         priv->ContiuneDiffCount = 0;
3525 #ifndef RTL8190P
3526         write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
3527 #endif
3528
3529 }
3530
3531 static void dm_StartSWFsync(struct net_device *dev)
3532 {
3533         struct r8192_priv *priv = ieee80211_priv(dev);
3534         u32                     rateIndex;
3535         u32                     rateBitmap;
3536
3537         RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
3538         // Initial rate record to zero, start to record.
3539         priv->rate_record = 0;
3540         // Initial contiune diff count to zero, start to record.
3541         priv->ContiuneDiffCount = 0;
3542         priv->rateCountDiffRecord = 0;
3543         priv->bswitch_fsync  = false;
3544
3545         if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
3546         {
3547                 priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
3548                 priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
3549         }
3550         else
3551         {
3552                 priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
3553                 priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
3554         }
3555         for(rateIndex = 0; rateIndex <= 27; rateIndex++)
3556         {
3557                 rateBitmap  = 1 << rateIndex;
3558                 if(priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
3559                         priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
3560         }
3561         if(timer_pending(&priv->fsync_timer))
3562                 del_timer_sync(&priv->fsync_timer);
3563         priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
3564         add_timer(&priv->fsync_timer);
3565
3566 #ifndef RTL8190P
3567         write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
3568 #endif
3569
3570 }
3571
3572 static void dm_EndHWFsync(struct net_device *dev)
3573 {
3574         RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
3575         write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
3576         write_nic_byte(dev, 0xc3b, 0x49);
3577
3578 }
3579
3580 void dm_check_fsync(struct net_device *dev)
3581 {
3582 #define RegC38_Default                          0
3583 #define RegC38_NonFsync_Other_AP        1
3584 #define RegC38_Fsync_AP_BCM             2
3585         struct r8192_priv *priv = ieee80211_priv(dev);
3586         //u32                   framesyncC34;
3587         static u8               reg_c38_State=RegC38_Default;
3588         static u32      reset_cnt=0;
3589
3590         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);
3591         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);
3592
3593         if(     priv->ieee80211->state == IEEE80211_LINKED &&
3594                 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
3595         {
3596                 if(priv->ieee80211->bfsync_enable == 0)
3597                 {
3598                         switch(priv->ieee80211->fsync_state)
3599                         {
3600                                 case Default_Fsync:
3601                                         dm_StartHWFsync(dev);
3602                                         priv->ieee80211->fsync_state = HW_Fsync;
3603                                         break;
3604                                 case SW_Fsync:
3605                                         dm_EndSWFsync(dev);
3606                                         dm_StartHWFsync(dev);
3607                                         priv->ieee80211->fsync_state = HW_Fsync;
3608                                         break;
3609                                 case HW_Fsync:
3610                                 default:
3611                                         break;
3612                         }
3613                 }
3614                 else
3615                 {
3616                         switch(priv->ieee80211->fsync_state)
3617                         {
3618                                 case Default_Fsync:
3619                                         dm_StartSWFsync(dev);
3620                                         priv->ieee80211->fsync_state = SW_Fsync;
3621                                         break;
3622                                 case HW_Fsync:
3623                                         dm_EndHWFsync(dev);
3624                                         dm_StartSWFsync(dev);
3625                                         priv->ieee80211->fsync_state = SW_Fsync;
3626                                         break;
3627                                 case SW_Fsync:
3628                                 default:
3629                                         break;
3630
3631                         }
3632                 }
3633                 if(priv->framesyncMonitor)
3634                 {
3635                         if(reg_c38_State != RegC38_Fsync_AP_BCM)
3636                         {       //For broadcom AP we write different default value
3637                                 #ifdef RTL8190P
3638                                         write_nic_byte(dev, rOFDM0_RxDetector3, 0x15);
3639                                 #else
3640                                         write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
3641                                 #endif
3642
3643                                 reg_c38_State = RegC38_Fsync_AP_BCM;
3644                         }
3645                 }
3646         }
3647         else
3648         {
3649                 switch(priv->ieee80211->fsync_state)
3650                 {
3651                         case HW_Fsync:
3652                                 dm_EndHWFsync(dev);
3653                                 priv->ieee80211->fsync_state = Default_Fsync;
3654                                 break;
3655                         case SW_Fsync:
3656                                 dm_EndSWFsync(dev);
3657                                 priv->ieee80211->fsync_state = Default_Fsync;
3658                                 break;
3659                         case Default_Fsync:
3660                         default:
3661                                 break;
3662                 }
3663
3664                 if(priv->framesyncMonitor)
3665                 {
3666                         if(priv->ieee80211->state == IEEE80211_LINKED)
3667                         {
3668                                 if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
3669                                 {
3670                                         if(reg_c38_State != RegC38_NonFsync_Other_AP)
3671                                         {
3672                                                 #ifdef RTL8190P
3673                                                         write_nic_byte(dev, rOFDM0_RxDetector3, 0x10);
3674                                                 #else
3675                                                         write_nic_byte(dev, rOFDM0_RxDetector3, 0x90);
3676                                                 #endif
3677
3678                                                 reg_c38_State = RegC38_NonFsync_Other_AP;
3679                                         #if 0//cosa
3680                                                 if (Adapter->HardwareType == HARDWARE_TYPE_RTL8190P)
3681                                                         DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x10);
3682                                                 else
3683                                                         DbgPrint("Fsync is idle, rssi<=35, write 0xc38 = 0x%x \n", 0x90);
3684                                         #endif
3685                                         }
3686                                 }
3687                                 else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
3688                                 {
3689                                         if(reg_c38_State)
3690                                         {
3691                                                 write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3692                                                 reg_c38_State = RegC38_Default;
3693                                                 //DbgPrint("Fsync is idle, rssi>=40, write 0xc38 = 0x%x \n", pHalData->framesync);
3694                                         }
3695                                 }
3696                         }
3697                         else
3698                         {
3699                                 if(reg_c38_State)
3700                                 {
3701                                         write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3702                                         reg_c38_State = RegC38_Default;
3703                                         //DbgPrint("Fsync is idle, not connected, write 0xc38 = 0x%x \n", pHalData->framesync);
3704                                 }
3705                         }
3706                 }
3707         }
3708         if(priv->framesyncMonitor)
3709         {
3710                 if(priv->reset_count != reset_cnt)
3711                 {       //After silent reset, the reg_c38_State will be returned to default value
3712                         write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3713                         reg_c38_State = RegC38_Default;
3714                         reset_cnt = priv->reset_count;
3715                         //DbgPrint("reg_c38_State = 0 for silent reset. \n");
3716                 }
3717         }
3718         else
3719         {
3720                 if(reg_c38_State)
3721                 {
3722                         write_nic_byte(dev, rOFDM0_RxDetector3, priv->framesync);
3723                         reg_c38_State = RegC38_Default;
3724                         //DbgPrint("framesync no monitor, write 0xc38 = 0x%x \n", pHalData->framesync);
3725                 }
3726         }
3727 }
3728
3729
3730 /*-----------------------------------------------------------------------------
3731  * Function:    dm_shadow_init()
3732  *
3733  * Overview:    Store all NIC MAC/BB register content.
3734  *
3735  * Input:               NONE
3736  *
3737  * Output:              NONE
3738  *
3739  * Return:              NONE
3740  *
3741  * Revised History:
3742  *      When            Who             Remark
3743  *      05/29/2008      amy             Create Version 0 porting from windows code.
3744  *
3745  *---------------------------------------------------------------------------*/
3746 void dm_shadow_init(struct net_device *dev)
3747 {
3748         u8      page;
3749         u16     offset;
3750
3751         for (page = 0; page < 5; page++)
3752                 for (offset = 0; offset < 256; offset++)
3753                 {
3754                         dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
3755                         //DbgPrint("P-%d/O-%02x=%02x\r\n", page, offset, DM_Shadow[page][offset]);
3756                 }
3757
3758         for (page = 8; page < 11; page++)
3759                 for (offset = 0; offset < 256; offset++)
3760                         dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
3761
3762         for (page = 12; page < 15; page++)
3763                 for (offset = 0; offset < 256; offset++)
3764                         dm_shadow[page][offset] = read_nic_byte(dev, offset+page*256);
3765
3766 }   /* dm_shadow_init */
3767
3768 /*---------------------------Define function prototype------------------------*/
3769 /*-----------------------------------------------------------------------------
3770  * Function:    DM_DynamicTxPower()
3771  *
3772  * Overview:    Detect Signal strength to control TX Registry
3773                         Tx Power Control For Near/Far Range
3774  *
3775  * Input:               NONE
3776  *
3777  * Output:              NONE
3778  *
3779  * Return:              NONE
3780  *
3781  * Revised History:
3782  *      When            Who             Remark
3783  *      03/06/2008      Jacken  Create Version 0.
3784  *
3785  *---------------------------------------------------------------------------*/
3786 static void dm_init_dynamic_txpower(struct net_device *dev)
3787 {
3788         struct r8192_priv *priv = ieee80211_priv(dev);
3789
3790         //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
3791         priv->ieee80211->bdynamic_txpower_enable = true;    //Default to enable Tx Power Control
3792         priv->bLastDTPFlag_High = false;
3793         priv->bLastDTPFlag_Low = false;
3794         priv->bDynamicTxHighPower = false;
3795         priv->bDynamicTxLowPower = false;
3796 }
3797
3798 static void dm_dynamic_txpower(struct net_device *dev)
3799 {
3800         struct r8192_priv *priv = ieee80211_priv(dev);
3801         unsigned int txhipower_threshhold=0;
3802         unsigned int txlowpower_threshold=0;
3803         if(priv->ieee80211->bdynamic_txpower_enable != true)
3804         {
3805                 priv->bDynamicTxHighPower = false;
3806                 priv->bDynamicTxLowPower = false;
3807                 return;
3808         }
3809         //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);
3810         if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){
3811                 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
3812                 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
3813         }
3814         else
3815         {
3816                 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
3817                 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
3818         }
3819
3820 //      printk("=======>%s(): txhipower_threshhold is %d,txlowpower_threshold is %d\n",__FUNCTION__,txhipower_threshhold,txlowpower_threshold);
3821
3822         RT_TRACE(COMP_TXAGC,"priv->undecorated_smoothed_pwdb = %ld \n" , priv->undecorated_smoothed_pwdb);
3823
3824         if(priv->ieee80211->state == IEEE80211_LINKED)
3825         {
3826                 if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
3827                 {
3828                         priv->bDynamicTxHighPower = true;
3829                         priv->bDynamicTxLowPower = false;
3830                 }
3831                 else
3832                 {
3833                         // high power state check
3834                         if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
3835                         {
3836                                 priv->bDynamicTxHighPower = false;
3837                         }
3838                         // low power state check
3839                         if(priv->undecorated_smoothed_pwdb < 35)
3840                         {
3841                                 priv->bDynamicTxLowPower = true;
3842                         }
3843                         else if(priv->undecorated_smoothed_pwdb >= 40)
3844                         {
3845                                 priv->bDynamicTxLowPower = false;
3846                         }
3847                 }
3848         }
3849         else
3850         {
3851                 //pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
3852                 priv->bDynamicTxHighPower = false;
3853                 priv->bDynamicTxLowPower = false;
3854         }
3855
3856         if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) ||
3857                 (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
3858         {
3859                 RT_TRACE(COMP_TXAGC,"SetTxPowerLevel8190()  channel = %d \n" , priv->ieee80211->current_network.channel);
3860
3861
3862                 rtl8192_phy_setTxPower(dev,priv->ieee80211->current_network.channel);
3863
3864         }
3865         priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
3866         priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
3867
3868 }       /* dm_dynamic_txpower */
3869
3870 //added by vivi, for read tx rate and retrycount
3871 static void dm_check_txrateandretrycount(struct net_device * dev)
3872 {
3873         struct r8192_priv *priv = ieee80211_priv(dev);
3874         struct ieee80211_device* ieee = priv->ieee80211;
3875         //for 11n tx rate
3876 //      priv->stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
3877         ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev, Current_Tx_Rate_Reg);
3878         //printk("=============>tx_rate_reg:%x\n", ieee->softmac_stats.CurrentShowTxate);
3879         //for initial tx rate
3880 //      priv->stats.last_packet_rate = read_nic_byte(dev, Initial_Tx_Rate_Reg);
3881         ieee->softmac_stats.last_packet_rate = read_nic_byte(dev ,Initial_Tx_Rate_Reg);
3882         //for tx tx retry count
3883 //      priv->stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
3884         ieee->softmac_stats.txretrycount = read_nic_dword(dev, Tx_Retry_Count_Reg);
3885 }
3886
3887 static void dm_send_rssi_tofw(struct net_device *dev)
3888 {
3889         DCMD_TXCMD_T                    tx_cmd;
3890         struct r8192_priv *priv = ieee80211_priv(dev);
3891
3892         // If we test chariot, we should stop the TX command ?
3893         // Because 92E will always silent reset when we send tx command. We use register
3894         // 0x1e0(byte) to botify driver.
3895         write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
3896         return;
3897 #if 1
3898         tx_cmd.Op               = TXCMD_SET_RX_RSSI;
3899         tx_cmd.Length   = 4;
3900         tx_cmd.Value            = priv->undecorated_smoothed_pwdb;
3901
3902         cmpk_message_handle_tx(dev, (u8*)&tx_cmd,
3903                                                                 DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
3904 #endif
3905 }
3906
3907 /*---------------------------Define function prototype------------------------*/
3908