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