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