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