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