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