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