]> Pileus Git - ~andy/linux/blob - drivers/staging/rtl8192e/r8192E_dm.c
staging: rtl8192e: Pass rtl8192_priv to dm functions
[~andy/linux] / drivers / staging / rtl8192e / r8192E_dm.c
1 /*++
2 Copyright-c Realtek Semiconductor Corp. All rights reserved.
3
4 Module Name:
5         r8192U_dm.c
6
7 Abstract:
8         HW dynamic mechanism.
9
10 Major Change History:
11         When            Who                             What
12         ----------      --------------- -------------------------------
13         2008-05-14      amy                     create version 0 porting from windows code.
14
15 --*/
16 #include "r8192E.h"
17 #include "r8192E_dm.h"
18 #include "r8192E_hw.h"
19 #include "r819xE_phy.h"
20 #include "r819xE_phyreg.h"
21 #include "r8190_rtl8256.h"
22
23 #define DRV_NAME "rtl819xE"
24
25 //
26 // Indicate different AP vendor for IOT issue.
27 //
28 static const u32 edca_setting_DL[HT_IOT_PEER_MAX] =
29 { 0x5e4322,     0x5e4322,       0x5e4322,       0x604322,       0xa44f,         0x5e4322,       0x5e4322};
30 static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
31 { 0x5e4322,     0xa44f,         0x5e4322,       0x604322,       0x5e4322,       0x5e4322,       0x5e4322};
32
33 #define RTK_UL_EDCA 0xa44f
34 #define RTK_DL_EDCA 0x5e4322
35
36
37 dig_t   dm_digtable;
38 // For Dynamic Rx Path Selection by Signal Strength
39 DRxPathSel      DM_RxPathSelTable;
40
41 void dm_gpio_change_rf_callback(struct work_struct *work);
42
43 // DM --> Rate Adaptive
44 static void dm_check_rate_adaptive(struct r8192_priv *priv);
45
46 // DM --> Bandwidth switch
47 static void dm_init_bandwidth_autoswitch(struct r8192_priv *priv);
48 static void dm_bandwidth_autoswitch(struct r8192_priv *priv);
49
50 // DM --> TX power control
51 static void dm_check_txpower_tracking(struct r8192_priv *priv);
52
53 // DM --> Dynamic Init Gain by RSSI
54 static void dm_dig_init(struct r8192_priv *priv);
55 static void dm_ctrl_initgain_byrssi(struct r8192_priv *priv);
56 static void dm_ctrl_initgain_byrssi_highpwr(struct r8192_priv *priv);
57 static void dm_ctrl_initgain_byrssi_by_driverrssi(struct r8192_priv *priv);
58 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct r8192_priv *priv);
59 static void dm_initial_gain(struct r8192_priv *priv);
60 static void dm_pd_th(struct r8192_priv *priv);
61 static void dm_cs_ratio(struct r8192_priv *priv);
62
63 static void dm_init_ctstoself(struct r8192_priv *priv);
64 // DM --> EDCA turboe mode control
65 static void dm_check_edca_turbo(struct r8192_priv *priv);
66 static void dm_init_edca_turbo(struct r8192_priv *priv);
67
68 // DM --> HW RF control
69 static void dm_check_rfctrl_gpio(struct r8192_priv *priv);
70
71 // DM --> Check current RX RF path state
72 static void dm_check_rx_path_selection(struct r8192_priv *priv);
73 static void dm_init_rxpath_selection(struct r8192_priv *priv);
74 static void dm_rxpath_sel_byrssi(struct r8192_priv *priv);
75
76 // DM --> Fsync for broadcom ap
77 static void dm_init_fsync(struct r8192_priv *priv);
78 static void dm_deInit_fsync(struct r8192_priv *priv);
79
80 static void dm_check_txrateandretrycount(struct r8192_priv *priv);
81 static void dm_check_fsync(struct r8192_priv *priv);
82
83
84 /*---------------------Define of Tx Power Control For Near/Far Range --------*/   //Add by Jacken 2008/02/18
85 static void dm_init_dynamic_txpower(struct r8192_priv *priv);
86 static void dm_dynamic_txpower(struct r8192_priv *priv);
87
88 // DM --> For rate adaptive and DIG, we must send RSSI to firmware
89 static void dm_send_rssi_tofw(struct r8192_priv *priv);
90 static void dm_ctstoself(struct r8192_priv *priv);
91
92 static void dm_fsync_timer_callback(unsigned long data);
93
94 /*
95  * Prepare SW resource for HW dynamic mechanism.
96  * This function is only invoked at driver intialization once.
97  */
98 void init_hal_dm(struct r8192_priv *priv)
99 {
100         // Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism.
101         priv->undecorated_smoothed_pwdb = -1;
102
103         //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
104         dm_init_dynamic_txpower(priv);
105         init_rate_adaptive(priv);
106         //dm_initialize_txpower_tracking(dev);
107         dm_dig_init(priv);
108         dm_init_edca_turbo(priv);
109         dm_init_bandwidth_autoswitch(priv);
110         dm_init_fsync(priv);
111         dm_init_rxpath_selection(priv);
112         dm_init_ctstoself(priv);
113         INIT_DELAYED_WORK(&priv->gpio_change_rf_wq,  dm_gpio_change_rf_callback);
114
115 }
116
117 void deinit_hal_dm(struct r8192_priv *priv)
118 {
119         dm_deInit_fsync(priv);
120 }
121
122 void hal_dm_watchdog(struct r8192_priv *priv)
123 {
124
125         /*Add by amy 2008/05/15 ,porting from windows code.*/
126         dm_check_rate_adaptive(priv);
127         dm_dynamic_txpower(priv);
128         dm_check_txrateandretrycount(priv);
129
130         dm_check_txpower_tracking(priv);
131
132         dm_ctrl_initgain_byrssi(priv);
133         dm_check_edca_turbo(priv);
134         dm_bandwidth_autoswitch(priv);
135
136         dm_check_rfctrl_gpio(priv);
137         dm_check_rx_path_selection(priv);
138         dm_check_fsync(priv);
139
140         // Add by amy 2008-05-15 porting from windows code.
141         dm_send_rssi_tofw(priv);
142         dm_ctstoself(priv);
143 }
144
145
146 /*
147   * Decide Rate Adaptive Set according to distance (signal strength)
148   *     01/11/2008      MHC             Modify input arguments and RATR table level.
149   *     01/16/2008      MHC             RF_Type is assigned in ReadAdapterInfo(). We must call
150   *                                             the function after making sure RF_Type.
151   */
152 void init_rate_adaptive(struct r8192_priv *priv)
153 {
154         prate_adaptive pra = &priv->rate_adaptive;
155
156         pra->ratr_state = DM_RATR_STA_MAX;
157         pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
158         pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
159         pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
160
161         pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
162         pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
163         pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
164
165         if(priv->CustomerID == RT_CID_819x_Netcore)
166                 pra->ping_rssi_enable = 1;
167         else
168                 pra->ping_rssi_enable = 0;
169         pra->ping_rssi_thresh_for_ra = 15;
170
171
172         if (priv->rf_type == RF_2T4R)
173         {
174                 // 07/10/08 MH Modify for RA smooth scheme.
175                 /* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/
176                 pra->upper_rssi_threshold_ratr          =       0x8f0f0000;
177                 pra->middle_rssi_threshold_ratr         =       0x8f0ff000;
178                 pra->low_rssi_threshold_ratr            =       0x8f0ff001;
179                 pra->low_rssi_threshold_ratr_40M        =       0x8f0ff005;
180                 pra->low_rssi_threshold_ratr_20M        =       0x8f0ff001;
181                 pra->ping_rssi_ratr     =       0x0000000d;//cosa add for test
182         }
183         else if (priv->rf_type == RF_1T2R)
184         {
185                 pra->upper_rssi_threshold_ratr          =       0x000f0000;
186                 pra->middle_rssi_threshold_ratr         =       0x000ff000;
187                 pra->low_rssi_threshold_ratr            =       0x000ff001;
188                 pra->low_rssi_threshold_ratr_40M        =       0x000ff005;
189                 pra->low_rssi_threshold_ratr_20M        =       0x000ff001;
190                 pra->ping_rssi_ratr     =       0x0000000d;//cosa add for test
191         }
192
193 }
194
195
196 static void dm_check_rate_adaptive(struct r8192_priv *priv)
197 {
198         PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
199         prate_adaptive                  pra = (prate_adaptive)&priv->rate_adaptive;
200         u32                                             currentRATR, targetRATR = 0;
201         u32                                             LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
202         bool                                            bshort_gi_enabled = false;
203         static u8                                       ping_rssi_state=0;
204
205
206         if(!priv->up)
207         {
208                 RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
209                 return;
210         }
211
212         if(pra->rate_adaptive_disabled)//this variable is set by ioctl.
213                 return;
214
215         // TODO: Only 11n mode is implemented currently,
216         if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
217                  priv->ieee80211->mode == WIRELESS_MODE_N_5G))
218                  return;
219
220         if( priv->ieee80211->state == IEEE80211_LINKED )
221         {
222         //      RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
223
224                 //
225                 // Check whether Short GI is enabled
226                 //
227                 bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
228                         (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
229
230
231                 pra->upper_rssi_threshold_ratr =
232                                 (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
233
234                 pra->middle_rssi_threshold_ratr =
235                                 (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
236
237                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
238                 {
239                         pra->low_rssi_threshold_ratr =
240                                 (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
241                 }
242                 else
243                 {
244                         pra->low_rssi_threshold_ratr =
245                         (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
246                 }
247                 //cosa add for test
248                 pra->ping_rssi_ratr =
249                                 (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
250
251                 /* 2007/10/08 MH We support RA smooth scheme now. When it is the first
252                    time to link with AP. We will not change upper/lower threshold. If
253                    STA stay in high or low level, we must change two different threshold
254                    to prevent jumping frequently. */
255                 if (pra->ratr_state == DM_RATR_STA_HIGH)
256                 {
257                         HighRSSIThreshForRA     = pra->high2low_rssi_thresh_for_ra;
258                         LowRSSIThreshForRA      = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
259                                         (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
260                 }
261                 else if (pra->ratr_state == DM_RATR_STA_LOW)
262                 {
263                         HighRSSIThreshForRA     = pra->high_rssi_thresh_for_ra;
264                         LowRSSIThreshForRA      = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
265                                         (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
266                 }
267                 else
268                 {
269                         HighRSSIThreshForRA     = pra->high_rssi_thresh_for_ra;
270                         LowRSSIThreshForRA      = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
271                                         (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
272                 }
273
274                 if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
275                 {
276                         pra->ratr_state = DM_RATR_STA_HIGH;
277                         targetRATR = pra->upper_rssi_threshold_ratr;
278                 }else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA)
279                 {
280                         pra->ratr_state = DM_RATR_STA_MIDDLE;
281                         targetRATR = pra->middle_rssi_threshold_ratr;
282                 }else
283                 {
284                         pra->ratr_state = DM_RATR_STA_LOW;
285                         targetRATR = pra->low_rssi_threshold_ratr;
286                 }
287
288                         //cosa add for test
289                 if(pra->ping_rssi_enable)
290                 {
291                         //pHalData->UndecoratedSmoothedPWDB = 19;
292                         if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5))
293                         {
294                                 if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
295                                         ping_rssi_state )
296                                 {
297                                         pra->ratr_state = DM_RATR_STA_LOW;
298                                         targetRATR = pra->ping_rssi_ratr;
299                                         ping_rssi_state = 1;
300                                 }
301                         }
302                         else
303                         {
304                                 ping_rssi_state = 0;
305                         }
306                 }
307
308                 // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
309                 if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(priv->ieee80211))
310                         targetRATR &=  0xf00fffff;
311
312                 //
313                 // Check whether updating of RATR0 is required
314                 //
315                 currentRATR = read_nic_dword(priv, RATR0);
316                 if( targetRATR !=  currentRATR )
317                 {
318                         u32 ratr_value;
319                         ratr_value = targetRATR;
320                         RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
321                         if(priv->rf_type == RF_1T2R)
322                         {
323                                 ratr_value &= ~(RATE_ALL_OFDM_2SS);
324                         }
325                         write_nic_dword(priv, RATR0, ratr_value);
326                         write_nic_byte(priv, UFWP, 1);
327
328                         pra->last_ratr = targetRATR;
329                 }
330
331         }
332         else
333         {
334                 pra->ratr_state = DM_RATR_STA_MAX;
335         }
336
337 }
338
339
340 static void dm_init_bandwidth_autoswitch(struct r8192_priv *priv)
341 {
342         priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
343         priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
344         priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
345         priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
346
347 }
348
349
350 static void dm_bandwidth_autoswitch(struct r8192_priv *priv)
351 {
352         if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){
353                 return;
354         }else{
355                 if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40
356                         if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
357                                 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
358                 }else{//in force send packets in 20 Mhz in 20/40
359                         if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
360                                 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
361
362                 }
363         }
364 }
365
366 //OFDM default at 0db, index=6.
367 static const u32 OFDMSwingTable[OFDM_Table_Length] = {
368         0x7f8001fe,     // 0, +6db
369         0x71c001c7,     // 1, +5db
370         0x65400195,     // 2, +4db
371         0x5a400169,     // 3, +3db
372         0x50800142,     // 4, +2db
373         0x47c0011f,     // 5, +1db
374         0x40000100,     // 6, +0db ===> default, upper for higher temperature, lower for low temperature
375         0x390000e4,     // 7, -1db
376         0x32c000cb,     // 8, -2db
377         0x2d4000b5,     // 9, -3db
378         0x288000a2,     // 10, -4db
379         0x24000090,     // 11, -5db
380         0x20000080,     // 12, -6db
381         0x1c800072,     // 13, -7db
382         0x19800066,     // 14, -8db
383         0x26c0005b,     // 15, -9db
384         0x24400051,     // 16, -10db
385         0x12000048,     // 17, -11db
386         0x10000040      // 18, -12db
387 };
388 static const u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
389         {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},       // 0, +0db ===> CCK40M default
390         {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},       // 1, -1db
391         {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},       // 2, -2db
392         {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},       // 3, -3db
393         {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},       // 4, -4db
394         {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},       // 5, -5db
395         {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},       // 6, -6db ===> CCK20M default
396         {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},       // 7, -7db
397         {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},       // 8, -8db
398         {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},       // 9, -9db
399         {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},       // 10, -10db
400         {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}        // 11, -11db
401 };
402
403 static const u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
404         {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},       // 0, +0db  ===> CCK40M default
405         {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},       // 1, -1db
406         {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},       // 2, -2db
407         {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},       // 3, -3db
408         {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},       // 4, -4db
409         {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},       // 5, -5db
410         {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},       // 6, -6db  ===> CCK20M default
411         {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},       // 7, -7db
412         {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},       // 8, -8db
413         {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},       // 9, -9db
414         {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},       // 10, -10db
415         {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}        // 11, -11db
416 };
417
418 #define         Pw_Track_Flag                           0x11d
419 #define         Tssi_Mea_Value                          0x13c
420 #define         Tssi_Report_Value1                      0x134
421 #define         Tssi_Report_Value2                      0x13e
422 #define         FW_Busy_Flag                            0x13f
423 static void dm_TXPowerTrackingCallback_TSSI(struct r8192_priv *priv)
424 {
425         struct net_device *dev = priv->ieee80211->dev;
426         bool                                            bHighpowerstate, viviflag = FALSE;
427         DCMD_TXCMD_T                    tx_cmd;
428         u8                                      powerlevelOFDM24G;
429         int                                     i =0, j = 0, k = 0;
430         u8                                              RF_Type, tmp_report[5]={0, 0, 0, 0, 0};
431         u32                                             Value;
432         u8                                              Pwr_Flag;
433         u16                                     Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0;
434 //      bool rtStatus = true;
435         u32                                             delta=0;
436         RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
437 //      write_nic_byte(priv, 0x1ba, 0);
438         write_nic_byte(priv, Pw_Track_Flag, 0);
439         write_nic_byte(priv, FW_Busy_Flag, 0);
440         priv->ieee80211->bdynamic_txpower_enable = false;
441         bHighpowerstate = priv->bDynamicTxHighPower;
442
443         powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
444         RF_Type = priv->rf_type;
445         Value = (RF_Type<<8) | powerlevelOFDM24G;
446
447         RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
448
449         for(j = 0; j<=30; j++)
450 {       //fill tx_cmd
451
452         tx_cmd.Op               = TXCMD_SET_TX_PWR_TRACKING;
453         tx_cmd.Length   = 4;
454         tx_cmd.Value            = Value;
455         cmpk_message_handle_tx(dev, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
456         mdelay(1);
457
458         for(i = 0;i <= 30; i++)
459         {
460                 Pwr_Flag = read_nic_byte(priv, Pw_Track_Flag);
461
462                 if (Pwr_Flag == 0)
463                 {
464                         mdelay(1);
465                         continue;
466                 }
467
468                 Avg_TSSI_Meas = read_nic_word(priv, Tssi_Mea_Value);
469
470                 if(Avg_TSSI_Meas == 0)
471                 {
472                         write_nic_byte(priv, Pw_Track_Flag, 0);
473                         write_nic_byte(priv, FW_Busy_Flag, 0);
474                         return;
475                 }
476
477                 for(k = 0;k < 5; k++)
478                 {
479                         if(k !=4)
480                                 tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value1+k);
481                         else
482                                 tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value2);
483
484                         RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
485                 }
486
487                 //check if the report value is right
488                 for(k = 0;k < 5; k++)
489                 {
490                         if(tmp_report[k] <= 20)
491                         {
492                                 viviflag =TRUE;
493                                 break;
494                         }
495                 }
496                 if(viviflag ==TRUE)
497                 {
498                         write_nic_byte(priv, Pw_Track_Flag, 0);
499                         viviflag = FALSE;
500                         RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
501                         for(k = 0;k < 5; k++)
502                                 tmp_report[k] = 0;
503                         break;
504                 }
505
506                 for(k = 0;k < 5; k++)
507                 {
508                         Avg_TSSI_Meas_from_driver += tmp_report[k];
509                 }
510
511                 Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
512                 RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
513                 TSSI_13dBm = priv->TSSI_13dBm;
514                 RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
515
516                 //if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)
517                 // For MacOS-compatible
518                 if(Avg_TSSI_Meas_from_driver > TSSI_13dBm)
519                         delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
520                 else
521                         delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
522
523                 if(delta <= E_FOR_TX_POWER_TRACK)
524                 {
525                         priv->ieee80211->bdynamic_txpower_enable = TRUE;
526                         write_nic_byte(priv, Pw_Track_Flag, 0);
527                         write_nic_byte(priv, FW_Busy_Flag, 0);
528                         RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
529                         RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
530                         RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
531                         RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
532                         RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
533                         return;
534                 }
535                 else
536                 {
537                         if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
538                         {
539                                 if (RF_Type == RF_2T4R)
540                                 {
541
542                                                 if((priv->rfa_txpowertrackingindex > 0) &&(priv->rfc_txpowertrackingindex > 0))
543                                 {
544                                         priv->rfa_txpowertrackingindex--;
545                                         if(priv->rfa_txpowertrackingindex_real > 4)
546                                         {
547                                                 priv->rfa_txpowertrackingindex_real--;
548                                                 rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
549                                         }
550
551                                         priv->rfc_txpowertrackingindex--;
552                                         if(priv->rfc_txpowertrackingindex_real > 4)
553                                         {
554                                                 priv->rfc_txpowertrackingindex_real--;
555                                                 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
556                                         }
557                                                 }
558                                                 else
559                                                 {
560                                                                 rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
561                                                                 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
562                                 }
563                         }
564                         else
565                         {
566                                                 if(priv->rfc_txpowertrackingindex > 0)
567                                                 {
568                                                         priv->rfc_txpowertrackingindex--;
569                                                         if(priv->rfc_txpowertrackingindex_real > 4)
570                                                         {
571                                                                 priv->rfc_txpowertrackingindex_real--;
572                                                                 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
573                                                         }
574                                                 }
575                                                 else
576                                                         rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
577                                 }
578                         }
579                         else
580                         {
581                                 if (RF_Type == RF_2T4R)
582                                 {
583                                         if((priv->rfa_txpowertrackingindex < TxBBGainTableLength - 1) &&(priv->rfc_txpowertrackingindex < TxBBGainTableLength - 1))
584                                 {
585                                         priv->rfa_txpowertrackingindex++;
586                                         priv->rfa_txpowertrackingindex_real++;
587                                         rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
588                                         priv->rfc_txpowertrackingindex++;
589                                         priv->rfc_txpowertrackingindex_real++;
590                                         rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
591                                 }
592                                         else
593                                         {
594                                                 rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
595                                                 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
596                         }
597                                 }
598                                 else
599                                 {
600                                         if(priv->rfc_txpowertrackingindex < (TxBBGainTableLength - 1))
601                                         {
602                                                         priv->rfc_txpowertrackingindex++;
603                                                         priv->rfc_txpowertrackingindex_real++;
604                                                         rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
605                                         }
606                                         else
607                                                         rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
608                                 }
609                         }
610                         if (RF_Type == RF_2T4R)
611                         priv->CCKPresentAttentuation_difference
612                                 = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
613                         else
614                                 priv->CCKPresentAttentuation_difference
615                                         = priv->rfc_txpowertrackingindex - priv->rfc_txpowertracking_default;
616
617                         if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
618                                 priv->CCKPresentAttentuation
619                                 = priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference;
620                         else
621                                 priv->CCKPresentAttentuation
622                                 = priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference;
623
624                         if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
625                                         priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
626                         if(priv->CCKPresentAttentuation < 0)
627                                         priv->CCKPresentAttentuation = 0;
628
629                         if(1)
630                         {
631                                 if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
632                                 {
633                                         priv->bcck_in_ch14 = TRUE;
634                                         dm_cck_txpower_adjust(priv, priv->bcck_in_ch14);
635                                 }
636                                 else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
637                                 {
638                                         priv->bcck_in_ch14 = FALSE;
639                                         dm_cck_txpower_adjust(priv, priv->bcck_in_ch14);
640                                 }
641                                 else
642                                         dm_cck_txpower_adjust(priv, priv->bcck_in_ch14);
643                         }
644                 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
645                 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
646                 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
647                 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
648
649                 if (priv->CCKPresentAttentuation_difference <= -12||priv->CCKPresentAttentuation_difference >= 24)
650                 {
651                         priv->ieee80211->bdynamic_txpower_enable = TRUE;
652                         write_nic_byte(priv, Pw_Track_Flag, 0);
653                         write_nic_byte(priv, FW_Busy_Flag, 0);
654                         RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
655                         return;
656                 }
657
658
659         }
660                 write_nic_byte(priv, Pw_Track_Flag, 0);
661                 Avg_TSSI_Meas_from_driver = 0;
662                 for(k = 0;k < 5; k++)
663                         tmp_report[k] = 0;
664                 break;
665         }
666         write_nic_byte(priv, FW_Busy_Flag, 0);
667 }
668                 priv->ieee80211->bdynamic_txpower_enable = TRUE;
669                 write_nic_byte(priv, Pw_Track_Flag, 0);
670 }
671
672 static void dm_TXPowerTrackingCallback_ThermalMeter(struct r8192_priv *priv)
673 {
674 #define ThermalMeterVal 9
675         u32 tmpRegA, TempCCk;
676         u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
677         int i =0, CCKSwingNeedUpdate=0;
678
679         if(!priv->btxpower_trackingInit)
680         {
681                 //Query OFDM default setting
682                 tmpRegA = rtl8192_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord);
683                 for(i=0; i<OFDM_Table_Length; i++)      //find the index
684                 {
685                         if(tmpRegA == OFDMSwingTable[i])
686                         {
687                                 priv->OFDM_index= (u8)i;
688                                 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
689                                         rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
690                         }
691                 }
692
693                 //Query CCK default setting From 0xa22
694                 TempCCk = rtl8192_QueryBBReg(priv, rCCK0_TxFilter1, bMaskByte2);
695                 for(i=0 ; i<CCK_Table_length ; i++)
696                 {
697                         if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0])
698                         {
699                                 priv->CCK_index =(u8) i;
700                                 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
701                                         rCCK0_TxFilter1, TempCCk, priv->CCK_index);
702                                 break;
703                         }
704                 }
705                 priv->btxpower_trackingInit = TRUE;
706                 //pHalData->TXPowercount = 0;
707                 return;
708         }
709
710         // read and filter out unreasonable value
711         tmpRegA = rtl8192_phy_QueryRFReg(priv, RF90_PATH_A, 0x12, 0x078);       // 0x12: RF Reg[10:7]
712         RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
713         if(tmpRegA < 3 || tmpRegA > 13)
714                 return;
715         if(tmpRegA >= 12)       // if over 12, TP will be bad when high temperature
716                 tmpRegA = 12;
717         RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
718         priv->ThermalMeter[0] = ThermalMeterVal;        //We use fixed value by Bryant's suggestion
719         priv->ThermalMeter[1] = ThermalMeterVal;        //We use fixed value by Bryant's suggestion
720
721         //Get current RF-A temperature index
722         if(priv->ThermalMeter[0] >= (u8)tmpRegA)        //lower temperature
723         {
724                 tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
725                 tmpCCK40Mindex = tmpCCK20Mindex - 6;
726                 if(tmpOFDMindex >= OFDM_Table_Length)
727                         tmpOFDMindex = OFDM_Table_Length-1;
728                 if(tmpCCK20Mindex >= CCK_Table_length)
729                         tmpCCK20Mindex = CCK_Table_length-1;
730                 if(tmpCCK40Mindex >= CCK_Table_length)
731                         tmpCCK40Mindex = CCK_Table_length-1;
732         }
733         else
734         {
735                 tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
736                 if(tmpval >= 6)                                                         // higher temperature
737                         tmpOFDMindex = tmpCCK20Mindex = 0;              // max to +6dB
738                 else
739                         tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
740                 tmpCCK40Mindex = 0;
741         }
742
743         if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)       //40M
744                 tmpCCKindex = tmpCCK40Mindex;
745         else
746                 tmpCCKindex = tmpCCK20Mindex;
747
748         //record for bandwidth swith
749         priv->Record_CCK_20Mindex = tmpCCK20Mindex;
750         priv->Record_CCK_40Mindex = tmpCCK40Mindex;
751         RT_TRACE(COMP_POWER_TRACKING, "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n",
752                 priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
753
754         if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
755         {
756                 priv->bcck_in_ch14 = TRUE;
757                 CCKSwingNeedUpdate = 1;
758         }
759         else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
760         {
761                 priv->bcck_in_ch14 = FALSE;
762                 CCKSwingNeedUpdate = 1;
763         }
764
765         if(priv->CCK_index != tmpCCKindex)
766 {
767                 priv->CCK_index = tmpCCKindex;
768                 CCKSwingNeedUpdate = 1;
769         }
770
771         if(CCKSwingNeedUpdate)
772         {
773                 dm_cck_txpower_adjust(priv, priv->bcck_in_ch14);
774         }
775         if(priv->OFDM_index != tmpOFDMindex)
776         {
777                 priv->OFDM_index = tmpOFDMindex;
778                 rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
779                 RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
780                         priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
781         }
782         priv->txpower_count = 0;
783 }
784
785 void dm_txpower_trackingcallback(struct work_struct *work)
786 {
787         struct delayed_work *dwork = container_of(work,struct delayed_work,work);
788         struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
789
790         if(priv->IC_Cut >= IC_VersionCut_D)
791                 dm_TXPowerTrackingCallback_TSSI(priv);
792         else
793                 dm_TXPowerTrackingCallback_ThermalMeter(priv);
794 }
795
796
797 static const txbbgain_struct rtl8192_txbbgain_table[] = {
798         { 12,   0x7f8001fe },
799         { 11,   0x788001e2 },
800         { 10,   0x71c001c7 },
801         { 9,    0x6b8001ae },
802         { 8,    0x65400195 },
803         { 7,    0x5fc0017f },
804         { 6,    0x5a400169 },
805         { 5,    0x55400155 },
806         { 4,    0x50800142 },
807         { 3,    0x4c000130 },
808         { 2,    0x47c0011f },
809         { 1,    0x43c0010f },
810         { 0,    0x40000100 },
811         { -1,   0x3c8000f2 },
812         { -2,   0x390000e4 },
813         { -3,   0x35c000d7 },
814         { -4,   0x32c000cb },
815         { -5,   0x300000c0 },
816         { -6,   0x2d4000b5 },
817         { -7,   0x2ac000ab },
818         { -8,   0x288000a2 },
819         { -9,   0x26000098 },
820         { -10,  0x24000090 },
821         { -11,  0x22000088 },
822         { -12,  0x20000080 },
823         { -13,  0x1a00006c },
824         { -14,  0x1c800072 },
825         { -15,  0x18000060 },
826         { -16,  0x19800066 },
827         { -17,  0x15800056 },
828         { -18,  0x26c0005b },
829         { -19,  0x14400051 },
830         { -20,  0x24400051 },
831         { -21,  0x1300004c },
832         { -22,  0x12000048 },
833         { -23,  0x11000044 },
834         { -24,  0x10000040 },
835 };
836
837 /*
838  * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
839  * This Table is for CH1~CH13
840  */
841 static const ccktxbbgain_struct rtl8192_cck_txbbgain_table[] = {
842         {{ 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 }},
843         {{ 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 }},
844         {{ 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03 }},
845         {{ 0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03 }},
846         {{ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 }},
847         {{ 0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03 }},
848         {{ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 }},
849         {{ 0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03 }},
850         {{ 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02 }},
851         {{ 0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02 }},
852         {{ 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02 }},
853         {{ 0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02 }},
854         {{ 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02 }},
855         {{ 0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02 }},
856         {{ 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02 }},
857         {{ 0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02 }},
858         {{ 0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01 }},
859         {{ 0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02 }},
860         {{ 0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01 }},
861         {{ 0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }},
862         {{ 0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }},
863         {{ 0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01 }},
864         {{ 0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01 }},
865 };
866
867 /*
868  * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
869  * This Table is for CH14
870  */
871 static const ccktxbbgain_struct rtl8192_cck_txbbgain_ch14_table[] = {
872         {{ 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 }},
873         {{ 0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00 }},
874         {{ 0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00 }},
875         {{ 0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00 }},
876         {{ 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 }},
877         {{ 0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00 }},
878         {{ 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00 }},
879         {{ 0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00 }},
880         {{ 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00 }},
881         {{ 0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00 }},
882         {{ 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00 }},
883         {{ 0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00 }},
884         {{ 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00 }},
885         {{ 0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00 }},
886         {{ 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00 }},
887         {{ 0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00 }},
888         {{ 0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00 }},
889         {{ 0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00 }},
890         {{ 0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00 }},
891         {{ 0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }},
892         {{ 0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }},
893         {{ 0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00 }},
894         {{ 0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00 }},
895 };
896
897 static void dm_InitializeTXPowerTracking_TSSI(struct r8192_priv *priv)
898 {
899         priv->txbbgain_table = rtl8192_txbbgain_table;
900         priv->cck_txbbgain_table = rtl8192_cck_txbbgain_table;
901         priv->cck_txbbgain_ch14_table = rtl8192_cck_txbbgain_ch14_table;
902
903         priv->btxpower_tracking = TRUE;
904         priv->txpower_count       = 0;
905         priv->btxpower_trackingInit = FALSE;
906
907 }
908
909 static void dm_InitializeTXPowerTracking_ThermalMeter(struct r8192_priv *priv)
910 {
911         // Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism
912         // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
913         // 3-wire by driver cause RF goes into wrong state.
914         if(priv->ieee80211->FwRWRF)
915                 priv->btxpower_tracking = TRUE;
916         else
917                 priv->btxpower_tracking = FALSE;
918         priv->txpower_count       = 0;
919         priv->btxpower_trackingInit = FALSE;
920 }
921
922 void dm_initialize_txpower_tracking(struct r8192_priv *priv)
923 {
924         if(priv->IC_Cut >= IC_VersionCut_D)
925                 dm_InitializeTXPowerTracking_TSSI(priv);
926         else
927                 dm_InitializeTXPowerTracking_ThermalMeter(priv);
928 }
929
930
931 static void dm_CheckTXPowerTracking_TSSI(struct r8192_priv *priv)
932 {
933         static u32 tx_power_track_counter = 0;
934         RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
935         if(read_nic_byte(priv, 0x11e) ==1)
936                 return;
937         if(!priv->btxpower_tracking)
938                 return;
939         tx_power_track_counter++;
940
941         if (tx_power_track_counter > 90) {
942                 queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
943                 tx_power_track_counter =0;
944         }
945 }
946
947 static void dm_CheckTXPowerTracking_ThermalMeter(struct r8192_priv *priv)
948 {
949         static u8       TM_Trigger=0;
950
951         if(!priv->btxpower_tracking)
952                 return;
953         else
954         {
955                 if(priv->txpower_count  <= 2)
956                 {
957                         priv->txpower_count++;
958                         return;
959                 }
960         }
961
962         if(!TM_Trigger)
963         {
964                 //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash
965                 //actually write reg0x02 bit1=0, then bit1=1.
966                 rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
967                 rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
968                 rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
969                 rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
970                 TM_Trigger = 1;
971                 return;
972         }
973         else {
974                 queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
975                 TM_Trigger = 0;
976         }
977 }
978
979 static void dm_check_txpower_tracking(struct r8192_priv *priv)
980 {
981         if(priv->IC_Cut >= IC_VersionCut_D)
982                 dm_CheckTXPowerTracking_TSSI(priv);
983         else
984                 dm_CheckTXPowerTracking_ThermalMeter(priv);
985 }
986
987
988 static void dm_CCKTxPowerAdjust_TSSI(struct r8192_priv *priv, bool bInCH14)
989 {
990         u32 TempVal;
991         //Write 0xa22 0xa23
992         TempVal = 0;
993         if(!bInCH14){
994                 //Write 0xa22 0xa23
995                 TempVal =       (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
996                                         (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
997
998                 rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal);
999                 //Write 0xa24 ~ 0xa27
1000                 TempVal = 0;
1001                 TempVal =       (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1002                                         (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1003                                         (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
1004                                         (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1005                 rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal);
1006                 //Write 0xa28  0xa29
1007                 TempVal = 0;
1008                 TempVal =       (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1009                                         (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1010
1011                 rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal);
1012         }
1013         else
1014         {
1015                 TempVal =       (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
1016                                         (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
1017
1018                 rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal);
1019                 //Write 0xa24 ~ 0xa27
1020                 TempVal = 0;
1021                 TempVal =       (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1022                                         (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1023                                         (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
1024                                         (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1025                 rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal);
1026                 //Write 0xa28  0xa29
1027                 TempVal = 0;
1028                 TempVal =       (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1029                                         (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1030
1031                 rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal);
1032         }
1033
1034
1035 }
1036
1037 static void dm_CCKTxPowerAdjust_ThermalMeter(struct r8192_priv *priv,
1038                                              bool bInCH14)
1039 {
1040         u32 TempVal;
1041
1042         TempVal = 0;
1043         if(!bInCH14)
1044         {
1045                 //Write 0xa22 0xa23
1046                 TempVal =       CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1047                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
1048                 rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal);
1049                 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1050                         rCCK0_TxFilter1, TempVal);
1051                 //Write 0xa24 ~ 0xa27
1052                 TempVal = 0;
1053                 TempVal =       CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1054                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1055                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+
1056                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1057                 rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal);
1058                 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1059                         rCCK0_TxFilter2, TempVal);
1060                 //Write 0xa28  0xa29
1061                 TempVal = 0;
1062                 TempVal =       CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1063                                         (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
1064
1065                 rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal);
1066                 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1067                         rCCK0_DebugPort, TempVal);
1068         }
1069         else
1070         {
1071 //              priv->CCKTxPowerAdjustCntNotCh14++;     //cosa add for debug.
1072                 //Write 0xa22 0xa23
1073                 TempVal =       CCKSwingTable_Ch14[priv->CCK_index][0] +
1074                                         (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
1075
1076                 rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal);
1077                 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1078                         rCCK0_TxFilter1, TempVal);
1079                 //Write 0xa24 ~ 0xa27
1080                 TempVal = 0;
1081                 TempVal =       CCKSwingTable_Ch14[priv->CCK_index][2] +
1082                                         (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1083                                         (CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+
1084                                         (CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1085                 rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal);
1086                 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1087                         rCCK0_TxFilter2, TempVal);
1088                 //Write 0xa28  0xa29
1089                 TempVal = 0;
1090                 TempVal =       CCKSwingTable_Ch14[priv->CCK_index][6] +
1091                                         (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
1092
1093                 rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal);
1094                 RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n",
1095                         rCCK0_DebugPort, TempVal);
1096         }
1097 }
1098
1099 void dm_cck_txpower_adjust(struct r8192_priv *priv, bool binch14)
1100 {
1101         if(priv->IC_Cut >= IC_VersionCut_D)
1102                 dm_CCKTxPowerAdjust_TSSI(priv, binch14);
1103         else
1104                 dm_CCKTxPowerAdjust_ThermalMeter(priv, binch14);
1105 }
1106
1107 /* Set DIG scheme init value. */
1108 static void dm_dig_init(struct r8192_priv *priv)
1109 {
1110         /* 2007/10/05 MH Disable DIG scheme now. Not tested. */
1111         dm_digtable.dig_enable_flag     = true;
1112         dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1113         dm_digtable.dbg_mode = DM_DBG_OFF;      //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
1114         dm_digtable.dig_algorithm_switch = 0;
1115
1116         /* 2007/10/04 MH Define init gain threshold. */
1117         dm_digtable.dig_state           = DM_STA_DIG_MAX;
1118         dm_digtable.dig_highpwr_state   = DM_STA_DIG_MAX;
1119         dm_digtable.initialgain_lowerbound_state = false;
1120
1121         dm_digtable.rssi_low_thresh     = DM_DIG_THRESH_LOW;
1122         dm_digtable.rssi_high_thresh    = DM_DIG_THRESH_HIGH;
1123
1124         dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1125         dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1126
1127         dm_digtable.rssi_val = 50;      //for new dig debug rssi value
1128         dm_digtable.backoff_val = DM_DIG_BACKOFF;
1129         dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1130         if(priv->CustomerID == RT_CID_819x_Netcore)
1131                 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1132         else
1133                 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1134
1135 }
1136
1137
1138 /*
1139  * Driver must monitor RSSI and notify firmware to change initial
1140  * gain according to different threshold. BB team provide the
1141  * suggested solution.
1142  */
1143 static void dm_ctrl_initgain_byrssi(struct r8192_priv *priv)
1144 {
1145         if (dm_digtable.dig_enable_flag == false)
1146                 return;
1147
1148         if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1149                 dm_ctrl_initgain_byrssi_by_fwfalse_alarm(priv);
1150         else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1151                 dm_ctrl_initgain_byrssi_by_driverrssi(priv);
1152 }
1153
1154
1155 static void dm_ctrl_initgain_byrssi_by_driverrssi(struct r8192_priv *priv)
1156 {
1157         u8 i;
1158         static u8       fw_dig=0;
1159
1160         if (dm_digtable.dig_enable_flag == false)
1161                 return;
1162
1163         if(dm_digtable.dig_algorithm_switch)    // if swithed algorithm, we have to disable FW Dig.
1164                 fw_dig = 0;
1165         if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled
1166         {// FW DIG Off
1167                 for(i=0; i<3; i++)
1168                         rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8);  // Only clear byte 1 and rewrite.
1169                 fw_dig++;
1170                 dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off.
1171         }
1172
1173         if(priv->ieee80211->state == IEEE80211_LINKED)
1174                 dm_digtable.cur_connect_state = DIG_CONNECT;
1175         else
1176                 dm_digtable.cur_connect_state = DIG_DISCONNECT;
1177
1178         if(dm_digtable.dbg_mode == DM_DBG_OFF)
1179                 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1180
1181         dm_initial_gain(priv);
1182         dm_pd_th(priv);
1183         dm_cs_ratio(priv);
1184         if(dm_digtable.dig_algorithm_switch)
1185                 dm_digtable.dig_algorithm_switch = 0;
1186         dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
1187
1188 }
1189
1190 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct r8192_priv *priv)
1191 {
1192         static u32 reset_cnt = 0;
1193         u8 i;
1194
1195         if (dm_digtable.dig_enable_flag == false)
1196                 return;
1197
1198         if(dm_digtable.dig_algorithm_switch)
1199         {
1200                 dm_digtable.dig_state = DM_STA_DIG_MAX;
1201                 // Fw DIG On.
1202                 for(i=0; i<3; i++)
1203                         rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1);  // Only clear byte 1 and rewrite.
1204                 dm_digtable.dig_algorithm_switch = 0;
1205         }
1206
1207         if (priv->ieee80211->state != IEEE80211_LINKED)
1208                 return;
1209
1210         // For smooth, we can not change DIG state.
1211         if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1212                 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1213         {
1214                 return;
1215         }
1216
1217         /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
1218                   and then execute below step. */
1219         if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
1220         {
1221                 /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
1222                    will be reset to init value. We must prevent the condition. */
1223                 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1224                         (priv->reset_count == reset_cnt))
1225                 {
1226                         return;
1227                 }
1228                 else
1229                 {
1230                         reset_cnt = priv->reset_count;
1231                 }
1232
1233                 // If DIG is off, DIG high power state must reset.
1234                 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1235                 dm_digtable.dig_state = DM_STA_DIG_OFF;
1236
1237                 // 1.1 DIG Off.
1238                 rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8);  // Only clear byte 1 and rewrite.
1239
1240                 // 1.2 Set initial gain.
1241                 write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x17);
1242                 write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x17);
1243                 write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x17);
1244                 write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x17);
1245
1246                 // 1.3 Lower PD_TH for OFDM.
1247                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1248                 {
1249                         /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1250                         // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1251                         write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00);
1252                 }
1253                 else
1254                         write_nic_byte(priv, rOFDM0_RxDetector1, 0x42);
1255
1256                 // 1.4 Lower CS ratio for CCK.
1257                 write_nic_byte(priv, 0xa0a, 0x08);
1258
1259                 // 1.5 Higher EDCCA.
1260                 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
1261                 return;
1262
1263         }
1264
1265         /* 2. When RSSI increase, We have to judge if it is larger than a threshold
1266                   and then execute below step.  */
1267         if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
1268         {
1269                 u8 reset_flag = 0;
1270
1271                 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1272                         (priv->reset_count == reset_cnt))
1273                 {
1274                         dm_ctrl_initgain_byrssi_highpwr(priv);
1275                         return;
1276                 }
1277                 else
1278                 {
1279                         if (priv->reset_count != reset_cnt)
1280                                 reset_flag = 1;
1281
1282                         reset_cnt = priv->reset_count;
1283                 }
1284
1285                 dm_digtable.dig_state = DM_STA_DIG_ON;
1286
1287                 // 2.1 Set initial gain.
1288                 // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
1289                 if (reset_flag == 1)
1290                 {
1291                         write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x2c);
1292                         write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x2c);
1293                         write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x2c);
1294                         write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x2c);
1295                 }
1296                 else
1297                 {
1298                         write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x20);
1299                         write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x20);
1300                         write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x20);
1301                         write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x20);
1302                 }
1303
1304                 // 2.2 Higher PD_TH for OFDM.
1305                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1306                 {
1307                         /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1308                         // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1309                         write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20);
1310                 }
1311                 else
1312                         write_nic_byte(priv, rOFDM0_RxDetector1, 0x44);
1313
1314                 // 2.3 Higher CS ratio for CCK.
1315                 write_nic_byte(priv, 0xa0a, 0xcd);
1316
1317                 // 2.4 Lower EDCCA.
1318                 /* 2008/01/11 MH 90/92 series are the same. */
1319                 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
1320
1321                 // 2.5 DIG On.
1322                 rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1);  // Only clear byte 1 and rewrite.
1323
1324         }
1325
1326         dm_ctrl_initgain_byrssi_highpwr(priv);
1327
1328 }
1329
1330 static void dm_ctrl_initgain_byrssi_highpwr(struct r8192_priv *priv)
1331 {
1332         static u32 reset_cnt_highpwr = 0;
1333
1334         // For smooth, we can not change high power DIG state in the range.
1335         if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
1336                 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
1337         {
1338                 return;
1339         }
1340
1341         /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
1342                   it is larger than a threshold and then execute below step.  */
1343         // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
1344         if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
1345         {
1346                 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1347                         (priv->reset_count == reset_cnt_highpwr))
1348                         return;
1349                 else
1350                         dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1351
1352                 // 3.1 Higher PD_TH for OFDM for high power state.
1353                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1354                 {
1355                         write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10);
1356                 }
1357                 else
1358                         write_nic_byte(priv, rOFDM0_RxDetector1, 0x43);
1359         }
1360         else
1361         {
1362                 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
1363                         (priv->reset_count == reset_cnt_highpwr))
1364                         return;
1365                 else
1366                         dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1367
1368                 if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
1369                          priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
1370                 {
1371                         // 3.2 Recover PD_TH for OFDM for normal power region.
1372                         if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1373                         {
1374                                 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20);
1375                         }
1376                         else
1377                                 write_nic_byte(priv, rOFDM0_RxDetector1, 0x44);
1378                 }
1379         }
1380
1381         reset_cnt_highpwr = priv->reset_count;
1382
1383 }
1384
1385
1386 static void dm_initial_gain(struct r8192_priv *priv)
1387 {
1388         u8                                      initial_gain=0;
1389         static u8                               initialized=0, force_write=0;
1390         static u32                      reset_cnt=0;
1391
1392         if(dm_digtable.dig_algorithm_switch)
1393         {
1394                 initialized = 0;
1395                 reset_cnt = 0;
1396         }
1397
1398         if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
1399         {
1400                 if(dm_digtable.cur_connect_state == DIG_CONNECT)
1401                 {
1402                         if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
1403                                 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
1404                         else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
1405                                 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
1406                         else
1407                                 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
1408                 }
1409                 else            //current state is disconnected
1410                 {
1411                         if(dm_digtable.cur_ig_value == 0)
1412                                 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1413                         else
1414                                 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1415                 }
1416         }
1417         else    // disconnected -> connected or connected -> disconnected
1418         {
1419                 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1420                 dm_digtable.pre_ig_value = 0;
1421         }
1422
1423         // if silent reset happened, we should rewrite the values back
1424         if(priv->reset_count != reset_cnt)
1425         {
1426                 force_write = 1;
1427                 reset_cnt = priv->reset_count;
1428         }
1429
1430         if(dm_digtable.pre_ig_value != read_nic_byte(priv, rOFDM0_XAAGCCore1))
1431                 force_write = 1;
1432
1433         {
1434                 if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1435                         || !initialized || force_write)
1436                 {
1437                         initial_gain = (u8)dm_digtable.cur_ig_value;
1438                         // Set initial gain.
1439                         write_nic_byte(priv, rOFDM0_XAAGCCore1, initial_gain);
1440                         write_nic_byte(priv, rOFDM0_XBAGCCore1, initial_gain);
1441                         write_nic_byte(priv, rOFDM0_XCAGCCore1, initial_gain);
1442                         write_nic_byte(priv, rOFDM0_XDAGCCore1, initial_gain);
1443                         dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1444                         initialized = 1;
1445                         force_write = 0;
1446                 }
1447         }
1448 }
1449
1450 static void dm_pd_th(struct r8192_priv *priv)
1451 {
1452         static u8                               initialized=0, force_write=0;
1453         static u32                      reset_cnt = 0;
1454
1455         if(dm_digtable.dig_algorithm_switch)
1456         {
1457                 initialized = 0;
1458                 reset_cnt = 0;
1459         }
1460
1461         if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
1462         {
1463                 if(dm_digtable.cur_connect_state == DIG_CONNECT)
1464                 {
1465                         if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
1466                                 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
1467                         else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
1468                                 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1469                         else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
1470                                         (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
1471                                 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
1472                         else
1473                                 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
1474                 }
1475                 else
1476                 {
1477                         dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1478                 }
1479         }
1480         else    // disconnected -> connected or connected -> disconnected
1481         {
1482                 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1483         }
1484
1485         // if silent reset happened, we should rewrite the values back
1486         if(priv->reset_count != reset_cnt)
1487         {
1488                 force_write = 1;
1489                 reset_cnt = priv->reset_count;
1490         }
1491
1492         {
1493                 if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
1494                         (initialized<=3) || force_write)
1495                 {
1496                         if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
1497                         {
1498                                 // Lower PD_TH for OFDM.
1499                                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1500                                 {
1501                                         /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1502                                         // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1503                                         write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00);
1504                                 }
1505                                 else
1506                                         write_nic_byte(priv, rOFDM0_RxDetector1, 0x42);
1507                         }
1508                         else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
1509                         {
1510                                 // Higher PD_TH for OFDM.
1511                                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1512                                 {
1513                                         /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1514                                         // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1515                                         write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20);
1516                                 }
1517                                 else
1518                                         write_nic_byte(priv, rOFDM0_RxDetector1, 0x44);
1519                         }
1520                         else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
1521                         {
1522                                 // Higher PD_TH for OFDM for high power state.
1523                                 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1524                                 {
1525                                         write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10);
1526                                 }
1527                                 else
1528                                         write_nic_byte(priv, rOFDM0_RxDetector1, 0x43);
1529                         }
1530                         dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
1531                         if(initialized <= 3)
1532                                 initialized++;
1533                         force_write = 0;
1534                 }
1535         }
1536 }
1537
1538 static void dm_cs_ratio(struct r8192_priv *priv)
1539 {
1540         static u8                               initialized=0,force_write=0;
1541         static u32                      reset_cnt = 0;
1542
1543         if(dm_digtable.dig_algorithm_switch)
1544         {
1545                 initialized = 0;
1546                 reset_cnt = 0;
1547         }
1548
1549         if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
1550         {
1551                 if(dm_digtable.cur_connect_state == DIG_CONNECT)
1552                 {
1553                         if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
1554                                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1555                         else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) )
1556                                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
1557                         else
1558                                 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
1559                 }
1560                 else
1561                 {
1562                         dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1563                 }
1564         }
1565         else    // disconnected -> connected or connected -> disconnected
1566         {
1567                 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1568         }
1569
1570         // if silent reset happened, we should rewrite the values back
1571         if(priv->reset_count != reset_cnt)
1572         {
1573                 force_write = 1;
1574                 reset_cnt = priv->reset_count;
1575         }
1576
1577
1578         if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
1579                 !initialized || force_write)
1580         {
1581                 if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
1582                 {
1583                         // Lower CS ratio for CCK.
1584                         write_nic_byte(priv, 0xa0a, 0x08);
1585                 }
1586                 else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
1587                 {
1588                         // Higher CS ratio for CCK.
1589                         write_nic_byte(priv, 0xa0a, 0xcd);
1590                 }
1591                 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
1592                 initialized = 1;
1593                 force_write = 0;
1594         }
1595 }
1596
1597 void dm_init_edca_turbo(struct r8192_priv *priv)
1598 {
1599
1600         priv->bcurrent_turbo_EDCA = false;
1601         priv->ieee80211->bis_any_nonbepkts = false;
1602         priv->bis_cur_rdlstate = false;
1603 }
1604
1605 static void dm_check_edca_turbo(struct r8192_priv *priv)
1606 {
1607         PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
1608         //PSTA_QOS                      pStaQos = pMgntInfo->pStaQos;
1609
1610         // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
1611         static unsigned long                    lastTxOkCnt = 0;
1612         static unsigned long                    lastRxOkCnt = 0;
1613         unsigned long                           curTxOkCnt = 0;
1614         unsigned long                           curRxOkCnt = 0;
1615
1616         //
1617         // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
1618         // should follow the settings from QAP. By Bruce, 2007-12-07.
1619         //
1620         if(priv->ieee80211->state != IEEE80211_LINKED)
1621                 goto dm_CheckEdcaTurbo_EXIT;
1622         // We do not turn on EDCA turbo mode for some AP that has IOT issue
1623         if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
1624                 goto dm_CheckEdcaTurbo_EXIT;
1625
1626         // Check the status for current condition.
1627         if(!priv->ieee80211->bis_any_nonbepkts)
1628         {
1629                 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1630                 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1631                 // For RT-AP, we needs to turn it on when Rx>Tx
1632                 if(curRxOkCnt > 4*curTxOkCnt)
1633                 {
1634                         if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
1635                         {
1636                                 write_nic_dword(priv, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
1637                                 priv->bis_cur_rdlstate = true;
1638                         }
1639                 }
1640                 else
1641                 {
1642                         if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
1643                         {
1644                                 write_nic_dword(priv, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
1645                                 priv->bis_cur_rdlstate = false;
1646                         }
1647
1648                 }
1649
1650                 priv->bcurrent_turbo_EDCA = true;
1651         }
1652         else
1653         {
1654                 //
1655                 // Turn Off EDCA turbo here.
1656                 // Restore original EDCA according to the declaration of AP.
1657                 //
1658                  if(priv->bcurrent_turbo_EDCA)
1659                 {
1660
1661                         {
1662                                 u8              u1bAIFS;
1663                                 u32             u4bAcParam;
1664                                 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1665                                 u8 mode = priv->ieee80211->mode;
1666
1667                         // For Each time updating EDCA parameter, reset EDCA turbo mode status.
1668                                 dm_init_edca_turbo(priv);
1669                                 u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
1670                                 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
1671                                         (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
1672                                         (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
1673                                         ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
1674                                 printk("===>u4bAcParam:%x, ", u4bAcParam);
1675                         //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
1676                                 write_nic_dword(priv, EDCAPARA_BE,  u4bAcParam);
1677
1678                         // Check ACM bit.
1679                         // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
1680                                 {
1681                         // TODO:  Modified this part and try to set acm control in only 1 IO processing!!
1682
1683                                         PACI_AIFSN      pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
1684                                         u8              AcmCtrl = read_nic_byte(priv, AcmHwCtrl );
1685                                         if( pAciAifsn->f.ACM )
1686                                         { // ACM bit is 1.
1687                                                 AcmCtrl |= AcmHw_BeqEn;
1688                                         }
1689                                         else
1690                                         { // ACM bit is 0.
1691                                                 AcmCtrl &= (~AcmHw_BeqEn);
1692                                         }
1693
1694                                         RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ;
1695                                         write_nic_byte(priv, AcmHwCtrl, AcmCtrl );
1696                                 }
1697                         }
1698                         priv->bcurrent_turbo_EDCA = false;
1699                 }
1700         }
1701
1702
1703 dm_CheckEdcaTurbo_EXIT:
1704         // Set variables for next time.
1705         priv->ieee80211->bis_any_nonbepkts = false;
1706         lastTxOkCnt = priv->stats.txbytesunicast;
1707         lastRxOkCnt = priv->stats.rxbytesunicast;
1708 }
1709
1710 static void dm_init_ctstoself(struct r8192_priv *priv)
1711 {
1712         priv->ieee80211->bCTSToSelfEnable = TRUE;
1713         priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
1714 }
1715
1716 static void dm_ctstoself(struct r8192_priv *priv)
1717 {
1718         PRT_HIGH_THROUGHPUT     pHTInfo = priv->ieee80211->pHTInfo;
1719         static unsigned long                            lastTxOkCnt = 0;
1720         static unsigned long                            lastRxOkCnt = 0;
1721         unsigned long                                           curTxOkCnt = 0;
1722         unsigned long                                           curRxOkCnt = 0;
1723
1724         if(priv->ieee80211->bCTSToSelfEnable != TRUE)
1725         {
1726                 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1727                 return;
1728         }
1729         /*
1730         1. Uplink
1731         2. Linksys350/Linksys300N
1732         3. <50 disable, >55 enable
1733         */
1734
1735         if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
1736         {
1737                 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1738                 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1739                 if(curRxOkCnt > 4*curTxOkCnt)   //downlink, disable CTS to self
1740                 {
1741                         pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1742                 }
1743                 else    //uplink
1744                 {
1745                         pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
1746                 }
1747
1748                 lastTxOkCnt = priv->stats.txbytesunicast;
1749                 lastRxOkCnt = priv->stats.rxbytesunicast;
1750         }
1751 }
1752
1753
1754
1755 /* Copy 8187B template for 9xseries */
1756 static void dm_check_rfctrl_gpio(struct r8192_priv *priv)
1757 {
1758
1759         // Walk around for DTM test, we will not enable HW - radio on/off because r/w
1760         // page 1 register before Lextra bus is enabled cause system fails when resuming
1761         // from S4. 20080218, Emily
1762
1763         // Stop to execute workitem to prevent S3/S4 bug.
1764         queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
1765 }
1766
1767 /* PCI will not support workitem call back HW radio on-off control. */
1768 void dm_gpio_change_rf_callback(struct work_struct *work)
1769 {
1770         struct delayed_work *dwork = container_of(work,struct delayed_work,work);
1771         struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
1772         u8 tmp1byte;
1773         RT_RF_POWER_STATE       eRfPowerStateToSet;
1774         bool bActuallySet = false;
1775
1776         if (!priv->up) {
1777                 RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
1778         } else {
1779                 // 0x108 GPIO input register is read only
1780                 //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
1781                 tmp1byte = read_nic_byte(priv, GPI);
1782
1783                 eRfPowerStateToSet = (tmp1byte&BIT1) ?  eRfOn : eRfOff;
1784
1785                 if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
1786                         RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio ON\n");
1787
1788                         priv->bHwRadioOff = false;
1789                         bActuallySet = true;
1790                 } else if ((!priv->bHwRadioOff) && (eRfPowerStateToSet == eRfOff)) {
1791                         RT_TRACE(COMP_RF, "gpiochangeRF  - HW Radio OFF\n");
1792                         priv->bHwRadioOff = true;
1793                         bActuallySet = true;
1794                 }
1795
1796                 if (bActuallySet) {
1797                         priv->bHwRfOffAction = 1;
1798                         MgntActSet_RF_State(priv, eRfPowerStateToSet, RF_CHANGE_BY_HW);
1799                         //DrvIFIndicateCurrentPhyStatus(pAdapter);
1800                 } else {
1801                         msleep(2000);
1802                 }
1803         }
1804 }
1805
1806 /* Check if Current RF RX path is enabled */
1807 void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
1808 {
1809         struct delayed_work *dwork = container_of(work,struct delayed_work,work);
1810         struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
1811         u8 rfpath = 0, i;
1812
1813
1814         /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
1815            always be the same. We only read 0xc04 now. */
1816         rfpath = read_nic_byte(priv, 0xc04);
1817
1818         // Check Bit 0-3, it means if RF A-D is enabled.
1819         for (i = 0; i < RF90_PATH_MAX; i++)
1820         {
1821                 if (rfpath & (0x01<<i))
1822                         priv->brfpath_rxenable[i] = 1;
1823                 else
1824                         priv->brfpath_rxenable[i] = 0;
1825         }
1826         if(!DM_RxPathSelTable.Enable)
1827                 return;
1828
1829         dm_rxpath_sel_byrssi(priv);
1830 }
1831
1832 static void dm_init_rxpath_selection(struct r8192_priv *priv)
1833 {
1834         u8 i;
1835
1836         DM_RxPathSelTable.Enable = 1;   //default enabled
1837         DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
1838         DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
1839         if(priv->CustomerID == RT_CID_819x_Netcore)
1840                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1841         else
1842                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
1843         DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
1844         DM_RxPathSelTable.disabledRF = 0;
1845         for(i=0; i<4; i++)
1846         {
1847                 DM_RxPathSelTable.rf_rssi[i] = 50;
1848                 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
1849                 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
1850         }
1851 }
1852
1853 static void dm_rxpath_sel_byrssi(struct r8192_priv *priv)
1854 {
1855         u8                              i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
1856         u8                              tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
1857         u8                              cck_default_Rx=0x2;     //RF-C
1858         u8                              cck_optional_Rx=0x3;//RF-D
1859         long                            tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
1860         u8                              cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
1861         u8                              cur_rf_rssi;
1862         long                            cur_cck_pwdb;
1863         static u8                       disabled_rf_cnt=0, cck_Rx_Path_initialized=0;
1864         u8                              update_cck_rx_path;
1865
1866         if(priv->rf_type != RF_2T4R)
1867                 return;
1868
1869         if(!cck_Rx_Path_initialized)
1870         {
1871                 DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(priv, 0xa07)&0xf);
1872                 cck_Rx_Path_initialized = 1;
1873         }
1874
1875         DM_RxPathSelTable.disabledRF = 0xf;
1876         DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(priv, 0xc04));
1877
1878         if(priv->ieee80211->mode == WIRELESS_MODE_B)
1879         {
1880                 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;        //pure B mode, fixed cck version2
1881         }
1882
1883         //decide max/sec/min rssi index
1884         for (i=0; i<RF90_PATH_MAX; i++)
1885         {
1886                 if(!DM_RxPathSelTable.DbgMode)
1887                         DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
1888
1889                 if(priv->brfpath_rxenable[i])
1890                 {
1891                         rf_num++;
1892                         cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
1893
1894                         if(rf_num == 1) // find first enabled rf path and the rssi values
1895                         {       //initialize, set all rssi index to the same one
1896                                 max_rssi_index = min_rssi_index = sec_rssi_index = i;
1897                                 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
1898                         }
1899                         else if(rf_num == 2)
1900                         {       // we pick up the max index first, and let sec and min to be the same one
1901                                 if(cur_rf_rssi >= tmp_max_rssi)
1902                                 {
1903                                         tmp_max_rssi = cur_rf_rssi;
1904                                         max_rssi_index = i;
1905                                 }
1906                                 else
1907                                 {
1908                                         tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
1909                                         sec_rssi_index = min_rssi_index = i;
1910                                 }
1911                         }
1912                         else
1913                         {
1914                                 if(cur_rf_rssi > tmp_max_rssi)
1915                                 {
1916                                         tmp_sec_rssi = tmp_max_rssi;
1917                                         sec_rssi_index = max_rssi_index;
1918                                         tmp_max_rssi = cur_rf_rssi;
1919                                         max_rssi_index = i;
1920                                 }
1921                                 else if(cur_rf_rssi == tmp_max_rssi)
1922                                 {       // let sec and min point to the different index
1923                                         tmp_sec_rssi = cur_rf_rssi;
1924                                         sec_rssi_index = i;
1925                                 }
1926                                 else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
1927                                 {
1928                                         tmp_sec_rssi = cur_rf_rssi;
1929                                         sec_rssi_index = i;
1930                                 }
1931                                 else if(cur_rf_rssi == tmp_sec_rssi)
1932                                 {
1933                                         if(tmp_sec_rssi == tmp_min_rssi)
1934                                         {       // let sec and min point to the different index
1935                                                 tmp_sec_rssi = cur_rf_rssi;
1936                                                 sec_rssi_index = i;
1937                                         }
1938                                         else
1939                                         {
1940                                                 // This case we don't need to set any index
1941                                         }
1942                                 }
1943                                 else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
1944                                 {
1945                                         // This case we don't need to set any index
1946                                 }
1947                                 else if(cur_rf_rssi == tmp_min_rssi)
1948                                 {
1949                                         if(tmp_sec_rssi == tmp_min_rssi)
1950                                         {       // let sec and min point to the different index
1951                                                 tmp_min_rssi = cur_rf_rssi;
1952                                                 min_rssi_index = i;
1953                                         }
1954                                         else
1955                                         {
1956                                                 // This case we don't need to set any index
1957                                         }
1958                                 }
1959                                 else if(cur_rf_rssi < tmp_min_rssi)
1960                                 {
1961                                         tmp_min_rssi = cur_rf_rssi;
1962                                         min_rssi_index = i;
1963                                 }
1964                         }
1965                 }
1966         }
1967
1968         rf_num = 0;
1969         // decide max/sec/min cck pwdb index
1970         if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
1971         {
1972                 for (i=0; i<RF90_PATH_MAX; i++)
1973                 {
1974                         if(priv->brfpath_rxenable[i])
1975                         {
1976                                 rf_num++;
1977                                 cur_cck_pwdb =  DM_RxPathSelTable.cck_pwdb_sta[i];
1978
1979                                 if(rf_num == 1) // find first enabled rf path and the rssi values
1980                                 {       //initialize, set all rssi index to the same one
1981                                         cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
1982                                         tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
1983                                 }
1984                                 else if(rf_num == 2)
1985                                 {       // we pick up the max index first, and let sec and min to be the same one
1986                                         if(cur_cck_pwdb >= tmp_cck_max_pwdb)
1987                                         {
1988                                                 tmp_cck_max_pwdb = cur_cck_pwdb;
1989                                                 cck_rx_ver2_max_index = i;
1990                                         }
1991                                         else
1992                                         {
1993                                                 tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
1994                                                 cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
1995                                         }
1996                                 }
1997                                 else
1998                                 {
1999                                         if(cur_cck_pwdb > tmp_cck_max_pwdb)
2000                                         {
2001                                                 tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
2002                                                 cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
2003                                                 tmp_cck_max_pwdb = cur_cck_pwdb;
2004                                                 cck_rx_ver2_max_index = i;
2005                                         }
2006                                         else if(cur_cck_pwdb == tmp_cck_max_pwdb)
2007                                         {       // let sec and min point to the different index
2008                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
2009                                                 cck_rx_ver2_sec_index = i;
2010                                         }
2011                                         else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
2012                                         {
2013                                                 tmp_cck_sec_pwdb = cur_cck_pwdb;
2014                                                 cck_rx_ver2_sec_index = i;
2015                                         }
2016                                         else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
2017                                         {
2018                                                 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
2019                                                 {       // let sec and min point to the different index
2020                                                         tmp_cck_sec_pwdb = cur_cck_pwdb;
2021                                                         cck_rx_ver2_sec_index = i;
2022                                                 }
2023                                                 else
2024                                                 {
2025                                                         // This case we don't need to set any index
2026                                                 }
2027                                         }
2028                                         else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
2029                                         {
2030                                                 // This case we don't need to set any index
2031                                         }
2032                                         else if(cur_cck_pwdb == tmp_cck_min_pwdb)
2033                                         {
2034                                                 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
2035                                                 {       // let sec and min point to the different index
2036                                                         tmp_cck_min_pwdb = cur_cck_pwdb;
2037                                                         cck_rx_ver2_min_index = i;
2038                                                 }
2039                                                 else
2040                                                 {
2041                                                         // This case we don't need to set any index
2042                                                 }
2043                                         }
2044                                         else if(cur_cck_pwdb < tmp_cck_min_pwdb)
2045                                         {
2046                                                 tmp_cck_min_pwdb = cur_cck_pwdb;
2047                                                 cck_rx_ver2_min_index = i;
2048                                         }
2049                                 }
2050
2051                         }
2052                 }
2053         }
2054
2055
2056         // Set CCK Rx path
2057         // reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
2058         update_cck_rx_path = 0;
2059         if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
2060         {
2061                 cck_default_Rx = cck_rx_ver2_max_index;
2062                 cck_optional_Rx = cck_rx_ver2_sec_index;
2063                 if(tmp_cck_max_pwdb != -64)
2064                         update_cck_rx_path = 1;
2065         }
2066
2067         if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
2068         {
2069                 if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
2070                 {
2071                         //record the enabled rssi threshold
2072                         DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
2073                         //disable the BB Rx path, OFDM
2074                         rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xc04[3:0]
2075                         rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xd04[3:0]
2076                         disabled_rf_cnt++;
2077                 }
2078                 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
2079                 {
2080                         cck_default_Rx = max_rssi_index;
2081                         cck_optional_Rx = sec_rssi_index;
2082                         if(tmp_max_rssi)
2083                                 update_cck_rx_path = 1;
2084                 }
2085         }
2086
2087         if(update_cck_rx_path)
2088         {
2089                 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
2090                 rtl8192_setBBreg(priv, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
2091         }
2092
2093         if(DM_RxPathSelTable.disabledRF)
2094         {
2095                 for(i=0; i<4; i++)
2096                 {
2097                         if((DM_RxPathSelTable.disabledRF>>i) & 0x1)     //disabled rf
2098                         {
2099                                 if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
2100                                 {
2101                                         //enable the BB Rx path
2102                                         rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0x1<<i, 0x1);      // 0xc04[3:0]
2103                                         rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0x1<<i, 0x1);      // 0xd04[3:0]
2104                                         DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2105                                         disabled_rf_cnt--;
2106                                 }
2107                         }
2108                 }
2109         }
2110 }
2111
2112 /*
2113  * Call a workitem to check current RXRF path and Rx Path selection by RSSI.
2114  */
2115 static void dm_check_rx_path_selection(struct r8192_priv *priv)
2116 {
2117         queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
2118 }
2119
2120 static void dm_init_fsync(struct r8192_priv *priv)
2121 {
2122         priv->ieee80211->fsync_time_interval = 500;
2123         priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
2124         priv->ieee80211->fsync_rssi_threshold = 30;
2125         priv->ieee80211->bfsync_enable = false;
2126         priv->ieee80211->fsync_multiple_timeinterval = 3;
2127         priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
2128         priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
2129         priv->ieee80211->fsync_state = Default_Fsync;
2130         priv->framesyncMonitor = 1;     // current default 0xc38 monitor on
2131
2132         init_timer(&priv->fsync_timer);
2133         priv->fsync_timer.data = (unsigned long)priv;
2134         priv->fsync_timer.function = dm_fsync_timer_callback;
2135 }
2136
2137
2138 static void dm_deInit_fsync(struct r8192_priv *priv)
2139 {
2140         del_timer_sync(&priv->fsync_timer);
2141 }
2142
2143 static void dm_fsync_timer_callback(unsigned long data)
2144 {
2145         struct r8192_priv *priv = (struct r8192_priv *)data;
2146         u32 rate_index, rate_count = 0, rate_count_diff=0;
2147         bool            bSwitchFromCountDiff = false;
2148         bool            bDoubleTimeInterval = false;
2149
2150         if(     priv->ieee80211->state == IEEE80211_LINKED &&
2151                 priv->ieee80211->bfsync_enable &&
2152                 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
2153         {
2154                  // Count rate 54, MCS [7], [12, 13, 14, 15]
2155                 u32 rate_bitmap;
2156                 for(rate_index = 0; rate_index <= 27; rate_index++)
2157                 {
2158                         rate_bitmap  = 1 << rate_index;
2159                         if(priv->ieee80211->fsync_rate_bitmap &  rate_bitmap)
2160                                 rate_count+= priv->stats.received_rate_histogram[1][rate_index];
2161                 }
2162
2163                 if(rate_count < priv->rate_record)
2164                         rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
2165                 else
2166                         rate_count_diff = rate_count - priv->rate_record;
2167                 if(rate_count_diff < priv->rateCountDiffRecord)
2168                 {
2169
2170                         u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
2171                         // Contiune count
2172                         if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
2173                                 priv->ContiuneDiffCount++;
2174                         else
2175                                 priv->ContiuneDiffCount = 0;
2176
2177                         // Contiune count over
2178                         if(priv->ContiuneDiffCount >=2)
2179                         {
2180                                 bSwitchFromCountDiff = true;
2181                                 priv->ContiuneDiffCount = 0;
2182                         }
2183                 }
2184                 else
2185                 {
2186                         // Stop contiune count
2187                         priv->ContiuneDiffCount = 0;
2188                 }
2189
2190                 //If Count diff <= FsyncRateCountThreshold
2191                 if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
2192                 {
2193                         bSwitchFromCountDiff = true;
2194                         priv->ContiuneDiffCount = 0;
2195                 }
2196                 priv->rate_record = rate_count;
2197                 priv->rateCountDiffRecord = rate_count_diff;
2198                 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
2199                 // if we never receive those mcs rate and rssi > 30 % then switch fsyn
2200                 if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
2201                 {
2202                         bDoubleTimeInterval = true;
2203                         priv->bswitch_fsync = !priv->bswitch_fsync;
2204                         if(priv->bswitch_fsync)
2205                         {
2206                                 write_nic_byte(priv,0xC36, 0x1c);
2207                                 write_nic_byte(priv, 0xC3e, 0x90);
2208                         }
2209                         else
2210                         {
2211                                 write_nic_byte(priv, 0xC36, 0x5c);
2212                                 write_nic_byte(priv, 0xC3e, 0x96);
2213                         }
2214                 }
2215                 else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
2216                 {
2217                         if(priv->bswitch_fsync)
2218                         {
2219                                 priv->bswitch_fsync  = false;
2220                                 write_nic_byte(priv, 0xC36, 0x5c);
2221                                 write_nic_byte(priv, 0xC3e, 0x96);
2222                         }
2223                 }
2224                 if(bDoubleTimeInterval){
2225                         if(timer_pending(&priv->fsync_timer))
2226                                 del_timer_sync(&priv->fsync_timer);
2227                         priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
2228                         add_timer(&priv->fsync_timer);
2229                 }
2230                 else{
2231                         if(timer_pending(&priv->fsync_timer))
2232                                 del_timer_sync(&priv->fsync_timer);
2233                         priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
2234                         add_timer(&priv->fsync_timer);
2235                 }
2236         }
2237         else
2238         {
2239                 // Let Register return to default value;
2240                 if(priv->bswitch_fsync)
2241                 {
2242                         priv->bswitch_fsync  = false;
2243                         write_nic_byte(priv, 0xC36, 0x5c);
2244                         write_nic_byte(priv, 0xC3e, 0x96);
2245                 }
2246                 priv->ContiuneDiffCount = 0;
2247                 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd);
2248         }
2249         RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
2250         RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
2251 }
2252
2253 static void dm_StartHWFsync(struct r8192_priv *priv)
2254 {
2255         RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
2256         write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cf);
2257         write_nic_byte(priv, 0xc3b, 0x41);
2258 }
2259
2260 static void dm_EndSWFsync(struct r8192_priv *priv)
2261 {
2262         RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
2263         del_timer_sync(&(priv->fsync_timer));
2264
2265         // Let Register return to default value;
2266         if(priv->bswitch_fsync)
2267         {
2268                 priv->bswitch_fsync  = false;
2269
2270                 write_nic_byte(priv, 0xC36, 0x40);
2271
2272                 write_nic_byte(priv, 0xC3e, 0x96);
2273         }
2274
2275         priv->ContiuneDiffCount = 0;
2276
2277         write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd);
2278 }
2279
2280 static void dm_StartSWFsync(struct r8192_priv *priv)
2281 {
2282         u32                     rateIndex;
2283         u32                     rateBitmap;
2284
2285         RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
2286         // Initial rate record to zero, start to record.
2287         priv->rate_record = 0;
2288         // Initial contiune diff count to zero, start to record.
2289         priv->ContiuneDiffCount = 0;
2290         priv->rateCountDiffRecord = 0;
2291         priv->bswitch_fsync  = false;
2292
2293         if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
2294         {
2295                 priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
2296                 priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
2297         }
2298         else
2299         {
2300                 priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
2301                 priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
2302         }
2303         for(rateIndex = 0; rateIndex <= 27; rateIndex++)
2304         {
2305                 rateBitmap  = 1 << rateIndex;
2306                 if(priv->ieee80211->fsync_rate_bitmap &  rateBitmap)
2307                         priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
2308         }
2309         if(timer_pending(&priv->fsync_timer))
2310                 del_timer_sync(&priv->fsync_timer);
2311         priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
2312         add_timer(&priv->fsync_timer);
2313
2314         write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cd);
2315 }
2316
2317 static void dm_EndHWFsync(struct r8192_priv *priv)
2318 {
2319         RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
2320         write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd);
2321         write_nic_byte(priv, 0xc3b, 0x49);
2322 }
2323
2324 static void dm_check_fsync(struct r8192_priv *priv)
2325 {
2326 #define RegC38_Default                          0
2327 #define RegC38_NonFsync_Other_AP        1
2328 #define RegC38_Fsync_AP_BCM             2
2329         //u32                   framesyncC34;
2330         static u8               reg_c38_State=RegC38_Default;
2331         static u32      reset_cnt=0;
2332
2333         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);
2334         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);
2335
2336         if(     priv->ieee80211->state == IEEE80211_LINKED &&
2337                 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
2338         {
2339                 if(priv->ieee80211->bfsync_enable == 0)
2340                 {
2341                         switch(priv->ieee80211->fsync_state)
2342                         {
2343                                 case Default_Fsync:
2344                                         dm_StartHWFsync(priv);
2345                                         priv->ieee80211->fsync_state = HW_Fsync;
2346                                         break;
2347                                 case SW_Fsync:
2348                                         dm_EndSWFsync(priv);
2349                                         dm_StartHWFsync(priv);
2350                                         priv->ieee80211->fsync_state = HW_Fsync;
2351                                         break;
2352                                 case HW_Fsync:
2353                                 default:
2354                                         break;
2355                         }
2356                 }
2357                 else
2358                 {
2359                         switch(priv->ieee80211->fsync_state)
2360                         {
2361                                 case Default_Fsync:
2362                                         dm_StartSWFsync(priv);
2363                                         priv->ieee80211->fsync_state = SW_Fsync;
2364                                         break;
2365                                 case HW_Fsync:
2366                                         dm_EndHWFsync(priv);
2367                                         dm_StartSWFsync(priv);
2368                                         priv->ieee80211->fsync_state = SW_Fsync;
2369                                         break;
2370                                 case SW_Fsync:
2371                                 default:
2372                                         break;
2373
2374                         }
2375                 }
2376                 if(priv->framesyncMonitor)
2377                 {
2378                         if(reg_c38_State != RegC38_Fsync_AP_BCM)
2379                         {       //For broadcom AP we write different default value
2380                                 write_nic_byte(priv, rOFDM0_RxDetector3, 0x95);
2381
2382                                 reg_c38_State = RegC38_Fsync_AP_BCM;
2383                         }
2384                 }
2385         }
2386         else
2387         {
2388                 switch(priv->ieee80211->fsync_state)
2389                 {
2390                         case HW_Fsync:
2391                                 dm_EndHWFsync(priv);
2392                                 priv->ieee80211->fsync_state = Default_Fsync;
2393                                 break;
2394                         case SW_Fsync:
2395                                 dm_EndSWFsync(priv);
2396                                 priv->ieee80211->fsync_state = Default_Fsync;
2397                                 break;
2398                         case Default_Fsync:
2399                         default:
2400                                 break;
2401                 }
2402
2403                 if(priv->framesyncMonitor)
2404                 {
2405                         if(priv->ieee80211->state == IEEE80211_LINKED)
2406                         {
2407                                 if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
2408                                 {
2409                                         if(reg_c38_State != RegC38_NonFsync_Other_AP)
2410                                         {
2411                                                 write_nic_byte(priv, rOFDM0_RxDetector3, 0x90);
2412
2413                                                 reg_c38_State = RegC38_NonFsync_Other_AP;
2414                                         }
2415                                 }
2416                                 else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
2417                                 {
2418                                         if(reg_c38_State)
2419                                         {
2420                                                 write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
2421                                                 reg_c38_State = RegC38_Default;
2422                                         }
2423                                 }
2424                         }
2425                         else
2426                         {
2427                                 if(reg_c38_State)
2428                                 {
2429                                         write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
2430                                         reg_c38_State = RegC38_Default;
2431                                 }
2432                         }
2433                 }
2434         }
2435         if(priv->framesyncMonitor)
2436         {
2437                 if(priv->reset_count != reset_cnt)
2438                 {       //After silent reset, the reg_c38_State will be returned to default value
2439                         write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
2440                         reg_c38_State = RegC38_Default;
2441                         reset_cnt = priv->reset_count;
2442                 }
2443         }
2444         else
2445         {
2446                 if(reg_c38_State)
2447                 {
2448                         write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
2449                         reg_c38_State = RegC38_Default;
2450                 }
2451         }
2452 }
2453
2454 /*
2455  * Detect Signal strength to control TX Registry
2456  * Tx Power Control For Near/Far Range
2457  */
2458 static void dm_init_dynamic_txpower(struct r8192_priv *priv)
2459 {
2460         //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
2461         priv->ieee80211->bdynamic_txpower_enable = true;    //Default to enable Tx Power Control
2462         priv->bLastDTPFlag_High = false;
2463         priv->bLastDTPFlag_Low = false;
2464         priv->bDynamicTxHighPower = false;
2465         priv->bDynamicTxLowPower = false;
2466 }
2467
2468 static void dm_dynamic_txpower(struct r8192_priv *priv)
2469 {
2470         unsigned int txhipower_threshhold=0;
2471         unsigned int txlowpower_threshold=0;
2472         if(priv->ieee80211->bdynamic_txpower_enable != true)
2473         {
2474                 priv->bDynamicTxHighPower = false;
2475                 priv->bDynamicTxLowPower = false;
2476                 return;
2477         }
2478         if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){
2479                 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
2480                 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2481         }
2482         else
2483         {
2484                 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2485                 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2486         }
2487
2488         RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n" , priv->undecorated_smoothed_pwdb);
2489
2490         if(priv->ieee80211->state == IEEE80211_LINKED)
2491         {
2492                 if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
2493                 {
2494                         priv->bDynamicTxHighPower = true;
2495                         priv->bDynamicTxLowPower = false;
2496                 }
2497                 else
2498                 {
2499                         // high power state check
2500                         if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
2501                         {
2502                                 priv->bDynamicTxHighPower = false;
2503                         }
2504                         // low power state check
2505                         if(priv->undecorated_smoothed_pwdb < 35)
2506                         {
2507                                 priv->bDynamicTxLowPower = true;
2508                         }
2509                         else if(priv->undecorated_smoothed_pwdb >= 40)
2510                         {
2511                                 priv->bDynamicTxLowPower = false;
2512                         }
2513                 }
2514         }
2515         else
2516         {
2517                 //pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
2518                 priv->bDynamicTxHighPower = false;
2519                 priv->bDynamicTxLowPower = false;
2520         }
2521
2522         if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) ||
2523                 (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
2524         {
2525                 RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n", priv->ieee80211->current_network.channel);
2526
2527
2528                 rtl8192_phy_setTxPower(priv, priv->ieee80211->current_network.channel);
2529
2530         }
2531         priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2532         priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2533
2534 }
2535
2536 //added by vivi, for read tx rate and retrycount
2537 static void dm_check_txrateandretrycount(struct r8192_priv *priv)
2538 {
2539         struct ieee80211_device* ieee = priv->ieee80211;
2540
2541         //for initial tx rate
2542         ieee->softmac_stats.last_packet_rate = read_nic_byte(priv ,Initial_Tx_Rate_Reg);
2543         //for tx tx retry count
2544         ieee->softmac_stats.txretrycount = read_nic_dword(priv, Tx_Retry_Count_Reg);
2545 }
2546
2547 static void dm_send_rssi_tofw(struct r8192_priv *priv)
2548 {
2549         // If we test chariot, we should stop the TX command ?
2550         // Because 92E will always silent reset when we send tx command. We use register
2551         // 0x1e0(byte) to botify driver.
2552         write_nic_byte(priv, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);
2553         return;
2554 }
2555