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