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