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