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