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