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