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