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