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