2 Copyright-c Realtek Semiconductor Corp. All rights reserved.
12 ---------- --------------- -------------------------------
13 2008-05-14 amy create version 0 porting from windows code.
17 #include "r8192E_dm.h"
18 #include "r8192E_hw.h"
19 #include "r819xE_phy.h"
20 #include "r819xE_phyreg.h"
21 #include "r8190_rtl8256.h"
23 #define DRV_NAME "rtl819xE"
26 // Indicate different AP vendor for IOT issue.
28 static const u32 edca_setting_DL[HT_IOT_PEER_MAX] =
29 { 0x5e4322, 0x5e4322, 0x5e4322, 0x604322, 0xa44f, 0x5e4322, 0x5e4322};
30 static const u32 edca_setting_UL[HT_IOT_PEER_MAX] =
31 { 0x5e4322, 0xa44f, 0x5e4322, 0x604322, 0x5e4322, 0x5e4322, 0x5e4322};
33 #define RTK_UL_EDCA 0xa44f
34 #define RTK_DL_EDCA 0x5e4322
38 // For Dynamic Rx Path Selection by Signal Strength
39 DRxPathSel DM_RxPathSelTable;
41 void dm_gpio_change_rf_callback(struct work_struct *work);
43 // DM --> Rate Adaptive
44 static void dm_check_rate_adaptive(struct r8192_priv *priv);
46 // DM --> Bandwidth switch
47 static void dm_init_bandwidth_autoswitch(struct r8192_priv *priv);
48 static void dm_bandwidth_autoswitch(struct r8192_priv *priv);
50 // DM --> TX power control
51 static void dm_check_txpower_tracking(struct r8192_priv *priv);
53 // DM --> Dynamic Init Gain by RSSI
54 static void dm_dig_init(struct r8192_priv *priv);
55 static void dm_ctrl_initgain_byrssi(struct r8192_priv *priv);
56 static void dm_ctrl_initgain_byrssi_highpwr(struct r8192_priv *priv);
57 static void dm_ctrl_initgain_byrssi_by_driverrssi(struct r8192_priv *priv);
58 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct r8192_priv *priv);
59 static void dm_initial_gain(struct r8192_priv *priv);
60 static void dm_pd_th(struct r8192_priv *priv);
61 static void dm_cs_ratio(struct r8192_priv *priv);
63 static void dm_init_ctstoself(struct r8192_priv *priv);
64 // DM --> EDCA turboe mode control
65 static void dm_check_edca_turbo(struct r8192_priv *priv);
66 static void dm_init_edca_turbo(struct r8192_priv *priv);
68 // DM --> HW RF control
69 static void dm_check_rfctrl_gpio(struct r8192_priv *priv);
71 // DM --> Check current RX RF path state
72 static void dm_check_rx_path_selection(struct r8192_priv *priv);
73 static void dm_init_rxpath_selection(struct r8192_priv *priv);
74 static void dm_rxpath_sel_byrssi(struct r8192_priv *priv);
76 // DM --> Fsync for broadcom ap
77 static void dm_init_fsync(struct r8192_priv *priv);
78 static void dm_deInit_fsync(struct r8192_priv *priv);
80 static void dm_check_txrateandretrycount(struct r8192_priv *priv);
81 static void dm_check_fsync(struct r8192_priv *priv);
84 /*---------------------Define of Tx Power Control For Near/Far Range --------*/ //Add by Jacken 2008/02/18
85 static void dm_init_dynamic_txpower(struct r8192_priv *priv);
86 static void dm_dynamic_txpower(struct r8192_priv *priv);
88 // DM --> For rate adaptive and DIG, we must send RSSI to firmware
89 static void dm_send_rssi_tofw(struct r8192_priv *priv);
90 static void dm_ctstoself(struct r8192_priv *priv);
92 static void dm_fsync_timer_callback(unsigned long data);
95 * Prepare SW resource for HW dynamic mechanism.
96 * This function is only invoked at driver intialization once.
98 void init_hal_dm(struct r8192_priv *priv)
100 // Undecorated Smoothed Signal Strength, it can utilized to dynamic mechanism.
101 priv->undecorated_smoothed_pwdb = -1;
103 //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
104 dm_init_dynamic_txpower(priv);
105 init_rate_adaptive(priv);
106 //dm_initialize_txpower_tracking(dev);
108 dm_init_edca_turbo(priv);
109 dm_init_bandwidth_autoswitch(priv);
111 dm_init_rxpath_selection(priv);
112 dm_init_ctstoself(priv);
113 INIT_DELAYED_WORK(&priv->gpio_change_rf_wq, dm_gpio_change_rf_callback);
117 void deinit_hal_dm(struct r8192_priv *priv)
119 dm_deInit_fsync(priv);
122 void hal_dm_watchdog(struct r8192_priv *priv)
125 /*Add by amy 2008/05/15 ,porting from windows code.*/
126 dm_check_rate_adaptive(priv);
127 dm_dynamic_txpower(priv);
128 dm_check_txrateandretrycount(priv);
130 dm_check_txpower_tracking(priv);
132 dm_ctrl_initgain_byrssi(priv);
133 dm_check_edca_turbo(priv);
134 dm_bandwidth_autoswitch(priv);
136 dm_check_rfctrl_gpio(priv);
137 dm_check_rx_path_selection(priv);
138 dm_check_fsync(priv);
140 // Add by amy 2008-05-15 porting from windows code.
141 dm_send_rssi_tofw(priv);
147 * Decide Rate Adaptive Set according to distance (signal strength)
148 * 01/11/2008 MHC Modify input arguments and RATR table level.
149 * 01/16/2008 MHC RF_Type is assigned in ReadAdapterInfo(). We must call
150 * the function after making sure RF_Type.
152 void init_rate_adaptive(struct r8192_priv *priv)
154 prate_adaptive pra = &priv->rate_adaptive;
156 pra->ratr_state = DM_RATR_STA_MAX;
157 pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
158 pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
159 pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
161 pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
162 pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
163 pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
165 if(priv->CustomerID == RT_CID_819x_Netcore)
166 pra->ping_rssi_enable = 1;
168 pra->ping_rssi_enable = 0;
169 pra->ping_rssi_thresh_for_ra = 15;
172 if (priv->rf_type == RF_2T4R)
174 // 07/10/08 MH Modify for RA smooth scheme.
175 /* 2008/01/11 MH Modify 2T RATR table for different RSSI. 080515 porting by amy from windows code.*/
176 pra->upper_rssi_threshold_ratr = 0x8f0f0000;
177 pra->middle_rssi_threshold_ratr = 0x8f0ff000;
178 pra->low_rssi_threshold_ratr = 0x8f0ff001;
179 pra->low_rssi_threshold_ratr_40M = 0x8f0ff005;
180 pra->low_rssi_threshold_ratr_20M = 0x8f0ff001;
181 pra->ping_rssi_ratr = 0x0000000d;//cosa add for test
183 else if (priv->rf_type == RF_1T2R)
185 pra->upper_rssi_threshold_ratr = 0x000f0000;
186 pra->middle_rssi_threshold_ratr = 0x000ff000;
187 pra->low_rssi_threshold_ratr = 0x000ff001;
188 pra->low_rssi_threshold_ratr_40M = 0x000ff005;
189 pra->low_rssi_threshold_ratr_20M = 0x000ff001;
190 pra->ping_rssi_ratr = 0x0000000d;//cosa add for test
196 static void dm_check_rate_adaptive(struct r8192_priv *priv)
198 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
199 prate_adaptive pra = (prate_adaptive)&priv->rate_adaptive;
200 u32 currentRATR, targetRATR = 0;
201 u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
202 bool bshort_gi_enabled = false;
203 static u8 ping_rssi_state=0;
208 RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
212 if(pra->rate_adaptive_disabled)//this variable is set by ioctl.
215 // TODO: Only 11n mode is implemented currently,
216 if( !(priv->ieee80211->mode == WIRELESS_MODE_N_24G ||
217 priv->ieee80211->mode == WIRELESS_MODE_N_5G))
220 if( priv->ieee80211->state == IEEE80211_LINKED )
222 // RT_TRACE(COMP_RATE, "dm_CheckRateAdaptive(): \t");
225 // Check whether Short GI is enabled
227 bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
228 (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
231 pra->upper_rssi_threshold_ratr =
232 (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
234 pra->middle_rssi_threshold_ratr =
235 (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
237 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
239 pra->low_rssi_threshold_ratr =
240 (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
244 pra->low_rssi_threshold_ratr =
245 (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
248 pra->ping_rssi_ratr =
249 (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled)? BIT31:0) ;
251 /* 2007/10/08 MH We support RA smooth scheme now. When it is the first
252 time to link with AP. We will not change upper/lower threshold. If
253 STA stay in high or low level, we must change two different threshold
254 to prevent jumping frequently. */
255 if (pra->ratr_state == DM_RATR_STA_HIGH)
257 HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra;
258 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
259 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
261 else if (pra->ratr_state == DM_RATR_STA_LOW)
263 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
264 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
265 (pra->low2high_rssi_thresh_for_ra40M):(pra->low2high_rssi_thresh_for_ra20M);
269 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
270 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)?
271 (pra->low_rssi_thresh_for_ra40M):(pra->low_rssi_thresh_for_ra20M);
274 if(priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA)
276 pra->ratr_state = DM_RATR_STA_HIGH;
277 targetRATR = pra->upper_rssi_threshold_ratr;
278 }else if(priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA)
280 pra->ratr_state = DM_RATR_STA_MIDDLE;
281 targetRATR = pra->middle_rssi_threshold_ratr;
284 pra->ratr_state = DM_RATR_STA_LOW;
285 targetRATR = pra->low_rssi_threshold_ratr;
289 if(pra->ping_rssi_enable)
291 //pHalData->UndecoratedSmoothedPWDB = 19;
292 if(priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5))
294 if( (priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
297 pra->ratr_state = DM_RATR_STA_LOW;
298 targetRATR = pra->ping_rssi_ratr;
308 // For RTL819X, if pairwisekey = wep/tkip, we support only MCS0~7.
309 if(priv->ieee80211->GetHalfNmodeSupportByAPsHandler(priv->ieee80211))
310 targetRATR &= 0xf00fffff;
313 // Check whether updating of RATR0 is required
315 currentRATR = read_nic_dword(priv, RATR0);
316 if( targetRATR != currentRATR )
319 ratr_value = targetRATR;
320 RT_TRACE(COMP_RATE,"currentRATR = %x, targetRATR = %x\n", currentRATR, targetRATR);
321 if(priv->rf_type == RF_1T2R)
323 ratr_value &= ~(RATE_ALL_OFDM_2SS);
325 write_nic_dword(priv, RATR0, ratr_value);
326 write_nic_byte(priv, UFWP, 1);
328 pra->last_ratr = targetRATR;
334 pra->ratr_state = DM_RATR_STA_MAX;
340 static void dm_init_bandwidth_autoswitch(struct r8192_priv *priv)
342 priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
343 priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
344 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
345 priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable = false;
350 static void dm_bandwidth_autoswitch(struct r8192_priv *priv)
352 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||!priv->ieee80211->bandwidth_auto_switch.bautoswitch_enable){
355 if(priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz == false){//If send packets in 40 Mhz in 20/40
356 if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
357 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = true;
358 }else{//in force send packets in 20 Mhz in 20/40
359 if(priv->undecorated_smoothed_pwdb >= priv->ieee80211->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
360 priv->ieee80211->bandwidth_auto_switch.bforced_tx20Mhz = false;
366 //OFDM default at 0db, index=6.
367 static const u32 OFDMSwingTable[OFDM_Table_Length] = {
368 0x7f8001fe, // 0, +6db
369 0x71c001c7, // 1, +5db
370 0x65400195, // 2, +4db
371 0x5a400169, // 3, +3db
372 0x50800142, // 4, +2db
373 0x47c0011f, // 5, +1db
374 0x40000100, // 6, +0db ===> default, upper for higher temperature, lower for low temperature
375 0x390000e4, // 7, -1db
376 0x32c000cb, // 8, -2db
377 0x2d4000b5, // 9, -3db
378 0x288000a2, // 10, -4db
379 0x24000090, // 11, -5db
380 0x20000080, // 12, -6db
381 0x1c800072, // 13, -7db
382 0x19800066, // 14, -8db
383 0x26c0005b, // 15, -9db
384 0x24400051, // 16, -10db
385 0x12000048, // 17, -11db
386 0x10000040 // 18, -12db
388 static const u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
389 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}, // 0, +0db ===> CCK40M default
390 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, // 1, -1db
391 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, // 2, -2db
392 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, // 3, -3db
393 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, // 4, -4db
394 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, // 5, -5db
395 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, // 6, -6db ===> CCK20M default
396 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, // 7, -7db
397 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, // 8, -8db
398 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, // 9, -9db
399 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, // 10, -10db
400 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01} // 11, -11db
403 static const u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
404 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}, // 0, +0db ===> CCK40M default
405 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, // 1, -1db
406 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, // 2, -2db
407 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, // 3, -3db
408 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, // 4, -4db
409 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, // 5, -5db
410 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, // 6, -6db ===> CCK20M default
411 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, // 7, -7db
412 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, // 8, -8db
413 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, // 9, -9db
414 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, // 10, -10db
415 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00} // 11, -11db
418 #define Pw_Track_Flag 0x11d
419 #define Tssi_Mea_Value 0x13c
420 #define Tssi_Report_Value1 0x134
421 #define Tssi_Report_Value2 0x13e
422 #define FW_Busy_Flag 0x13f
423 static void dm_TXPowerTrackingCallback_TSSI(struct r8192_priv *priv)
425 struct net_device *dev = priv->ieee80211->dev;
426 bool bHighpowerstate, viviflag = FALSE;
428 u8 powerlevelOFDM24G;
429 int i =0, j = 0, k = 0;
430 u8 RF_Type, tmp_report[5]={0, 0, 0, 0, 0};
433 u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver=0;
434 // bool rtStatus = true;
436 RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
437 // write_nic_byte(priv, 0x1ba, 0);
438 write_nic_byte(priv, Pw_Track_Flag, 0);
439 write_nic_byte(priv, FW_Busy_Flag, 0);
440 priv->ieee80211->bdynamic_txpower_enable = false;
441 bHighpowerstate = priv->bDynamicTxHighPower;
443 powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
444 RF_Type = priv->rf_type;
445 Value = (RF_Type<<8) | powerlevelOFDM24G;
447 RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n", powerlevelOFDM24G);
449 for(j = 0; j<=30; j++)
452 tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING;
454 tx_cmd.Value = Value;
455 cmpk_message_handle_tx(dev, (u8*)&tx_cmd, DESC_PACKET_TYPE_INIT, sizeof(DCMD_TXCMD_T));
458 for(i = 0;i <= 30; i++)
460 Pwr_Flag = read_nic_byte(priv, Pw_Track_Flag);
468 Avg_TSSI_Meas = read_nic_word(priv, Tssi_Mea_Value);
470 if(Avg_TSSI_Meas == 0)
472 write_nic_byte(priv, Pw_Track_Flag, 0);
473 write_nic_byte(priv, FW_Busy_Flag, 0);
477 for(k = 0;k < 5; k++)
480 tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value1+k);
482 tmp_report[k] = read_nic_byte(priv, Tssi_Report_Value2);
484 RT_TRACE(COMP_POWER_TRACKING, "TSSI_report_value = %d\n", tmp_report[k]);
487 //check if the report value is right
488 for(k = 0;k < 5; k++)
490 if(tmp_report[k] <= 20)
498 write_nic_byte(priv, Pw_Track_Flag, 0);
500 RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
501 for(k = 0;k < 5; k++)
506 for(k = 0;k < 5; k++)
508 Avg_TSSI_Meas_from_driver += tmp_report[k];
511 Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
512 RT_TRACE(COMP_POWER_TRACKING, "Avg_TSSI_Meas_from_driver = %d\n", Avg_TSSI_Meas_from_driver);
513 TSSI_13dBm = priv->TSSI_13dBm;
514 RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
516 //if(abs(Avg_TSSI_Meas_from_driver - TSSI_13dBm) <= E_FOR_TX_POWER_TRACK)
517 // For MacOS-compatible
518 if(Avg_TSSI_Meas_from_driver > TSSI_13dBm)
519 delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
521 delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
523 if(delta <= E_FOR_TX_POWER_TRACK)
525 priv->ieee80211->bdynamic_txpower_enable = TRUE;
526 write_nic_byte(priv, Pw_Track_Flag, 0);
527 write_nic_byte(priv, FW_Busy_Flag, 0);
528 RT_TRACE(COMP_POWER_TRACKING, "tx power track is done\n");
529 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
530 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
531 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
532 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
537 if(Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
539 if (RF_Type == RF_2T4R)
542 if((priv->rfa_txpowertrackingindex > 0) &&(priv->rfc_txpowertrackingindex > 0))
544 priv->rfa_txpowertrackingindex--;
545 if(priv->rfa_txpowertrackingindex_real > 4)
547 priv->rfa_txpowertrackingindex_real--;
548 rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
551 priv->rfc_txpowertrackingindex--;
552 if(priv->rfc_txpowertrackingindex_real > 4)
554 priv->rfc_txpowertrackingindex_real--;
555 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
560 rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
561 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
566 if(priv->rfc_txpowertrackingindex > 0)
568 priv->rfc_txpowertrackingindex--;
569 if(priv->rfc_txpowertrackingindex_real > 4)
571 priv->rfc_txpowertrackingindex_real--;
572 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
576 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[4].txbbgain_value);
581 if (RF_Type == RF_2T4R)
583 if((priv->rfa_txpowertrackingindex < TxBBGainTableLength - 1) &&(priv->rfc_txpowertrackingindex < TxBBGainTableLength - 1))
585 priv->rfa_txpowertrackingindex++;
586 priv->rfa_txpowertrackingindex_real++;
587 rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfa_txpowertrackingindex_real].txbbgain_value);
588 priv->rfc_txpowertrackingindex++;
589 priv->rfc_txpowertrackingindex_real++;
590 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
594 rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
595 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
600 if(priv->rfc_txpowertrackingindex < (TxBBGainTableLength - 1))
602 priv->rfc_txpowertrackingindex++;
603 priv->rfc_txpowertrackingindex_real++;
604 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[priv->rfc_txpowertrackingindex_real].txbbgain_value);
607 rtl8192_setBBreg(priv, rOFDM0_XCTxIQImbalance, bMaskDWord, priv->txbbgain_table[TxBBGainTableLength - 1].txbbgain_value);
610 if (RF_Type == RF_2T4R)
611 priv->CCKPresentAttentuation_difference
612 = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
614 priv->CCKPresentAttentuation_difference
615 = priv->rfc_txpowertrackingindex - priv->rfc_txpowertracking_default;
617 if(priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
618 priv->CCKPresentAttentuation
619 = priv->CCKPresentAttentuation_20Mdefault + priv->CCKPresentAttentuation_difference;
621 priv->CCKPresentAttentuation
622 = priv->CCKPresentAttentuation_40Mdefault + priv->CCKPresentAttentuation_difference;
624 if(priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
625 priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
626 if(priv->CCKPresentAttentuation < 0)
627 priv->CCKPresentAttentuation = 0;
631 if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
633 priv->bcck_in_ch14 = TRUE;
634 dm_cck_txpower_adjust(priv, priv->bcck_in_ch14);
636 else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
638 priv->bcck_in_ch14 = FALSE;
639 dm_cck_txpower_adjust(priv, priv->bcck_in_ch14);
642 dm_cck_txpower_adjust(priv, priv->bcck_in_ch14);
644 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex = %d\n", priv->rfa_txpowertrackingindex);
645 RT_TRACE(COMP_POWER_TRACKING, "priv->rfa_txpowertrackingindex_real = %d\n", priv->rfa_txpowertrackingindex_real);
646 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation_difference = %d\n", priv->CCKPresentAttentuation_difference);
647 RT_TRACE(COMP_POWER_TRACKING, "priv->CCKPresentAttentuation = %d\n", priv->CCKPresentAttentuation);
649 if (priv->CCKPresentAttentuation_difference <= -12||priv->CCKPresentAttentuation_difference >= 24)
651 priv->ieee80211->bdynamic_txpower_enable = TRUE;
652 write_nic_byte(priv, Pw_Track_Flag, 0);
653 write_nic_byte(priv, FW_Busy_Flag, 0);
654 RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
660 write_nic_byte(priv, Pw_Track_Flag, 0);
661 Avg_TSSI_Meas_from_driver = 0;
662 for(k = 0;k < 5; k++)
666 write_nic_byte(priv, FW_Busy_Flag, 0);
668 priv->ieee80211->bdynamic_txpower_enable = TRUE;
669 write_nic_byte(priv, Pw_Track_Flag, 0);
672 static void dm_TXPowerTrackingCallback_ThermalMeter(struct r8192_priv *priv)
674 #define ThermalMeterVal 9
675 u32 tmpRegA, TempCCk;
676 u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
677 int i =0, CCKSwingNeedUpdate=0;
679 if(!priv->btxpower_trackingInit)
681 //Query OFDM default setting
682 tmpRegA = rtl8192_QueryBBReg(priv, rOFDM0_XATxIQImbalance, bMaskDWord);
683 for(i=0; i<OFDM_Table_Length; i++) //find the index
685 if(tmpRegA == OFDMSwingTable[i])
687 priv->OFDM_index= (u8)i;
688 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index=0x%x\n",
689 rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index);
693 //Query CCK default setting From 0xa22
694 TempCCk = rtl8192_QueryBBReg(priv, rCCK0_TxFilter1, bMaskByte2);
695 for(i=0 ; i<CCK_Table_length ; i++)
697 if(TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0])
699 priv->CCK_index =(u8) i;
700 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, CCK_index=0x%x\n",
701 rCCK0_TxFilter1, TempCCk, priv->CCK_index);
705 priv->btxpower_trackingInit = TRUE;
706 //pHalData->TXPowercount = 0;
710 // read and filter out unreasonable value
711 tmpRegA = rtl8192_phy_QueryRFReg(priv, RF90_PATH_A, 0x12, 0x078); // 0x12: RF Reg[10:7]
712 RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
713 if(tmpRegA < 3 || tmpRegA > 13)
715 if(tmpRegA >= 12) // if over 12, TP will be bad when high temperature
717 RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
718 priv->ThermalMeter[0] = ThermalMeterVal; //We use fixed value by Bryant's suggestion
719 priv->ThermalMeter[1] = ThermalMeterVal; //We use fixed value by Bryant's suggestion
721 //Get current RF-A temperature index
722 if(priv->ThermalMeter[0] >= (u8)tmpRegA) //lower temperature
724 tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0]-(u8)tmpRegA);
725 tmpCCK40Mindex = tmpCCK20Mindex - 6;
726 if(tmpOFDMindex >= OFDM_Table_Length)
727 tmpOFDMindex = OFDM_Table_Length-1;
728 if(tmpCCK20Mindex >= CCK_Table_length)
729 tmpCCK20Mindex = CCK_Table_length-1;
730 if(tmpCCK40Mindex >= CCK_Table_length)
731 tmpCCK40Mindex = CCK_Table_length-1;
735 tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
736 if(tmpval >= 6) // higher temperature
737 tmpOFDMindex = tmpCCK20Mindex = 0; // max to +6dB
739 tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
743 if(priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) //40M
744 tmpCCKindex = tmpCCK40Mindex;
746 tmpCCKindex = tmpCCK20Mindex;
748 //record for bandwidth swith
749 priv->Record_CCK_20Mindex = tmpCCK20Mindex;
750 priv->Record_CCK_40Mindex = tmpCCK40Mindex;
751 RT_TRACE(COMP_POWER_TRACKING, "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n",
752 priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
754 if(priv->ieee80211->current_network.channel == 14 && !priv->bcck_in_ch14)
756 priv->bcck_in_ch14 = TRUE;
757 CCKSwingNeedUpdate = 1;
759 else if(priv->ieee80211->current_network.channel != 14 && priv->bcck_in_ch14)
761 priv->bcck_in_ch14 = FALSE;
762 CCKSwingNeedUpdate = 1;
765 if(priv->CCK_index != tmpCCKindex)
767 priv->CCK_index = tmpCCKindex;
768 CCKSwingNeedUpdate = 1;
771 if(CCKSwingNeedUpdate)
773 dm_cck_txpower_adjust(priv, priv->bcck_in_ch14);
775 if(priv->OFDM_index != tmpOFDMindex)
777 priv->OFDM_index = tmpOFDMindex;
778 rtl8192_setBBreg(priv, rOFDM0_XATxIQImbalance, bMaskDWord, OFDMSwingTable[priv->OFDM_index]);
779 RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
780 priv->OFDM_index, OFDMSwingTable[priv->OFDM_index]);
782 priv->txpower_count = 0;
785 void dm_txpower_trackingcallback(struct work_struct *work)
787 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
788 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,txpower_tracking_wq);
790 if(priv->IC_Cut >= IC_VersionCut_D)
791 dm_TXPowerTrackingCallback_TSSI(priv);
793 dm_TXPowerTrackingCallback_ThermalMeter(priv);
797 static const txbbgain_struct rtl8192_txbbgain_table[] = {
838 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
839 * This Table is for CH1~CH13
841 static const ccktxbbgain_struct rtl8192_cck_txbbgain_table[] = {
842 {{ 0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04 }},
843 {{ 0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04 }},
844 {{ 0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03 }},
845 {{ 0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03 }},
846 {{ 0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03 }},
847 {{ 0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03 }},
848 {{ 0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03 }},
849 {{ 0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03 }},
850 {{ 0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02 }},
851 {{ 0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02 }},
852 {{ 0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02 }},
853 {{ 0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02 }},
854 {{ 0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02 }},
855 {{ 0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02 }},
856 {{ 0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02 }},
857 {{ 0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02 }},
858 {{ 0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01 }},
859 {{ 0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02 }},
860 {{ 0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01 }},
861 {{ 0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }},
862 {{ 0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01 }},
863 {{ 0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01 }},
864 {{ 0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01 }},
868 * ccktxbb_valuearray[0] is 0xA22 [1] is 0xA24 ...[7] is 0xA29
869 * This Table is for CH14
871 static const ccktxbbgain_struct rtl8192_cck_txbbgain_ch14_table[] = {
872 {{ 0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00 }},
873 {{ 0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00 }},
874 {{ 0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00 }},
875 {{ 0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00 }},
876 {{ 0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00 }},
877 {{ 0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00 }},
878 {{ 0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00 }},
879 {{ 0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00 }},
880 {{ 0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00 }},
881 {{ 0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00 }},
882 {{ 0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00 }},
883 {{ 0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00 }},
884 {{ 0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00 }},
885 {{ 0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00 }},
886 {{ 0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00 }},
887 {{ 0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00 }},
888 {{ 0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00 }},
889 {{ 0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00 }},
890 {{ 0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00 }},
891 {{ 0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }},
892 {{ 0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00 }},
893 {{ 0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00 }},
894 {{ 0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00 }},
897 static void dm_InitializeTXPowerTracking_TSSI(struct r8192_priv *priv)
899 priv->txbbgain_table = rtl8192_txbbgain_table;
900 priv->cck_txbbgain_table = rtl8192_cck_txbbgain_table;
901 priv->cck_txbbgain_ch14_table = rtl8192_cck_txbbgain_ch14_table;
903 priv->btxpower_tracking = TRUE;
904 priv->txpower_count = 0;
905 priv->btxpower_trackingInit = FALSE;
909 static void dm_InitializeTXPowerTracking_ThermalMeter(struct r8192_priv *priv)
911 // Tx Power tracking by Theremal Meter require Firmware R/W 3-wire. This mechanism
912 // can be enabled only when Firmware R/W 3-wire is enabled. Otherwise, frequent r/w
913 // 3-wire by driver cause RF goes into wrong state.
914 if(priv->ieee80211->FwRWRF)
915 priv->btxpower_tracking = TRUE;
917 priv->btxpower_tracking = FALSE;
918 priv->txpower_count = 0;
919 priv->btxpower_trackingInit = FALSE;
922 void dm_initialize_txpower_tracking(struct r8192_priv *priv)
924 if(priv->IC_Cut >= IC_VersionCut_D)
925 dm_InitializeTXPowerTracking_TSSI(priv);
927 dm_InitializeTXPowerTracking_ThermalMeter(priv);
931 static void dm_CheckTXPowerTracking_TSSI(struct r8192_priv *priv)
933 static u32 tx_power_track_counter = 0;
934 RT_TRACE(COMP_POWER_TRACKING,"%s()\n",__FUNCTION__);
935 if(read_nic_byte(priv, 0x11e) ==1)
937 if(!priv->btxpower_tracking)
939 tx_power_track_counter++;
941 if (tx_power_track_counter > 90) {
942 queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
943 tx_power_track_counter =0;
947 static void dm_CheckTXPowerTracking_ThermalMeter(struct r8192_priv *priv)
949 static u8 TM_Trigger=0;
951 if(!priv->btxpower_tracking)
955 if(priv->txpower_count <= 2)
957 priv->txpower_count++;
964 //Attention!! You have to wirte all 12bits data to RF, or it may cause RF to crash
965 //actually write reg0x02 bit1=0, then bit1=1.
966 rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
967 rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
968 rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
969 rtl8192_phy_SetRFReg(priv, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
974 queue_delayed_work(priv->priv_wq,&priv->txpower_tracking_wq,0);
979 static void dm_check_txpower_tracking(struct r8192_priv *priv)
981 if(priv->IC_Cut >= IC_VersionCut_D)
982 dm_CheckTXPowerTracking_TSSI(priv);
984 dm_CheckTXPowerTracking_ThermalMeter(priv);
988 static void dm_CCKTxPowerAdjust_TSSI(struct r8192_priv *priv, bool bInCH14)
995 TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
996 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
998 rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal);
999 //Write 0xa24 ~ 0xa27
1001 TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1002 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1003 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
1004 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1005 rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal);
1008 TempVal = (u32)(priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1009 (priv->cck_txbbgain_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1011 rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal);
1015 TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[0] +
1016 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[1]<<8)) ;
1018 rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal);
1019 //Write 0xa24 ~ 0xa27
1021 TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[2] +
1022 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[3]<<8) +
1023 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[4]<<16 )+
1024 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[5]<<24));
1025 rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal);
1028 TempVal = (u32)(priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[6] +
1029 (priv->cck_txbbgain_ch14_table[(u8)(priv->CCKPresentAttentuation)].ccktxbb_valuearray[7]<<8)) ;
1031 rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal);
1037 static void dm_CCKTxPowerAdjust_ThermalMeter(struct r8192_priv *priv,
1046 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1047 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8) ;
1048 rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal);
1049 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1050 rCCK0_TxFilter1, TempVal);
1051 //Write 0xa24 ~ 0xa27
1053 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1054 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1055 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16 )+
1056 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1057 rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal);
1058 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1059 rCCK0_TxFilter2, TempVal);
1062 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1063 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8) ;
1065 rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal);
1066 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1067 rCCK0_DebugPort, TempVal);
1071 // priv->CCKTxPowerAdjustCntNotCh14++; //cosa add for debug.
1073 TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] +
1074 (CCKSwingTable_Ch14[priv->CCK_index][1]<<8) ;
1076 rtl8192_setBBreg(priv, rCCK0_TxFilter1, bMaskHWord, TempVal);
1077 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1078 rCCK0_TxFilter1, TempVal);
1079 //Write 0xa24 ~ 0xa27
1081 TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] +
1082 (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1083 (CCKSwingTable_Ch14[priv->CCK_index][4]<<16 )+
1084 (CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1085 rtl8192_setBBreg(priv, rCCK0_TxFilter2, bMaskDWord, TempVal);
1086 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1087 rCCK0_TxFilter2, TempVal);
1090 TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] +
1091 (CCKSwingTable_Ch14[priv->CCK_index][7]<<8) ;
1093 rtl8192_setBBreg(priv, rCCK0_DebugPort, bMaskLWord, TempVal);
1094 RT_TRACE(COMP_POWER_TRACKING,"CCK chnl 14, reg 0x%x = 0x%x\n",
1095 rCCK0_DebugPort, TempVal);
1099 void dm_cck_txpower_adjust(struct r8192_priv *priv, bool binch14)
1101 if(priv->IC_Cut >= IC_VersionCut_D)
1102 dm_CCKTxPowerAdjust_TSSI(priv, binch14);
1104 dm_CCKTxPowerAdjust_ThermalMeter(priv, binch14);
1107 /* Set DIG scheme init value. */
1108 static void dm_dig_init(struct r8192_priv *priv)
1110 /* 2007/10/05 MH Disable DIG scheme now. Not tested. */
1111 dm_digtable.dig_enable_flag = true;
1112 dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1113 dm_digtable.dbg_mode = DM_DBG_OFF; //off=by real rssi value, on=by DM_DigTable.Rssi_val for new dig
1114 dm_digtable.dig_algorithm_switch = 0;
1116 /* 2007/10/04 MH Define init gain threshold. */
1117 dm_digtable.dig_state = DM_STA_DIG_MAX;
1118 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1119 dm_digtable.initialgain_lowerbound_state = false;
1121 dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW;
1122 dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH;
1124 dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1125 dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1127 dm_digtable.rssi_val = 50; //for new dig debug rssi value
1128 dm_digtable.backoff_val = DM_DIG_BACKOFF;
1129 dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1130 if(priv->CustomerID == RT_CID_819x_Netcore)
1131 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1133 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1139 * Driver must monitor RSSI and notify firmware to change initial
1140 * gain according to different threshold. BB team provide the
1141 * suggested solution.
1143 static void dm_ctrl_initgain_byrssi(struct r8192_priv *priv)
1145 if (dm_digtable.dig_enable_flag == false)
1148 if(dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1149 dm_ctrl_initgain_byrssi_by_fwfalse_alarm(priv);
1150 else if(dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1151 dm_ctrl_initgain_byrssi_by_driverrssi(priv);
1155 static void dm_ctrl_initgain_byrssi_by_driverrssi(struct r8192_priv *priv)
1160 if (dm_digtable.dig_enable_flag == false)
1163 if(dm_digtable.dig_algorithm_switch) // if swithed algorithm, we have to disable FW Dig.
1165 if(fw_dig <= 3) // execute several times to make sure the FW Dig is disabled
1168 rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite.
1170 dm_digtable.dig_state = DM_STA_DIG_OFF; //fw dig off.
1173 if(priv->ieee80211->state == IEEE80211_LINKED)
1174 dm_digtable.cur_connect_state = DIG_CONNECT;
1176 dm_digtable.cur_connect_state = DIG_DISCONNECT;
1178 if(dm_digtable.dbg_mode == DM_DBG_OFF)
1179 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1181 dm_initial_gain(priv);
1184 if(dm_digtable.dig_algorithm_switch)
1185 dm_digtable.dig_algorithm_switch = 0;
1186 dm_digtable.pre_connect_state = dm_digtable.cur_connect_state;
1190 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct r8192_priv *priv)
1192 static u32 reset_cnt = 0;
1195 if (dm_digtable.dig_enable_flag == false)
1198 if(dm_digtable.dig_algorithm_switch)
1200 dm_digtable.dig_state = DM_STA_DIG_MAX;
1203 rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite.
1204 dm_digtable.dig_algorithm_switch = 0;
1207 if (priv->ieee80211->state != IEEE80211_LINKED)
1210 // For smooth, we can not change DIG state.
1211 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1212 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1217 /* 1. When RSSI decrease, We have to judge if it is smaller than a threshold
1218 and then execute below step. */
1219 if ((priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh))
1221 /* 2008/02/05 MH When we execute silent reset, the DIG PHY parameters
1222 will be reset to init value. We must prevent the condition. */
1223 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1224 (priv->reset_count == reset_cnt))
1230 reset_cnt = priv->reset_count;
1233 // If DIG is off, DIG high power state must reset.
1234 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1235 dm_digtable.dig_state = DM_STA_DIG_OFF;
1238 rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x8); // Only clear byte 1 and rewrite.
1240 // 1.2 Set initial gain.
1241 write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x17);
1242 write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x17);
1243 write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x17);
1244 write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x17);
1246 // 1.3 Lower PD_TH for OFDM.
1247 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1249 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1250 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1251 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00);
1254 write_nic_byte(priv, rOFDM0_RxDetector1, 0x42);
1256 // 1.4 Lower CS ratio for CCK.
1257 write_nic_byte(priv, 0xa0a, 0x08);
1259 // 1.5 Higher EDCCA.
1260 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x325);
1265 /* 2. When RSSI increase, We have to judge if it is larger than a threshold
1266 and then execute below step. */
1267 if ((priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) )
1271 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1272 (priv->reset_count == reset_cnt))
1274 dm_ctrl_initgain_byrssi_highpwr(priv);
1279 if (priv->reset_count != reset_cnt)
1282 reset_cnt = priv->reset_count;
1285 dm_digtable.dig_state = DM_STA_DIG_ON;
1287 // 2.1 Set initial gain.
1288 // 2008/02/26 MH SD3-Jerry suggest to prevent dirty environment.
1289 if (reset_flag == 1)
1291 write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x2c);
1292 write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x2c);
1293 write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x2c);
1294 write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x2c);
1298 write_nic_byte(priv, rOFDM0_XAAGCCore1, 0x20);
1299 write_nic_byte(priv, rOFDM0_XBAGCCore1, 0x20);
1300 write_nic_byte(priv, rOFDM0_XCAGCCore1, 0x20);
1301 write_nic_byte(priv, rOFDM0_XDAGCCore1, 0x20);
1304 // 2.2 Higher PD_TH for OFDM.
1305 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1307 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1308 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1309 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20);
1312 write_nic_byte(priv, rOFDM0_RxDetector1, 0x44);
1314 // 2.3 Higher CS ratio for CCK.
1315 write_nic_byte(priv, 0xa0a, 0xcd);
1318 /* 2008/01/11 MH 90/92 series are the same. */
1319 //PlatformEFIOWrite4Byte(pAdapter, rOFDM0_ECCAThreshold, 0x346);
1322 rtl8192_setBBreg(priv, UFWP, bMaskByte1, 0x1); // Only clear byte 1 and rewrite.
1326 dm_ctrl_initgain_byrssi_highpwr(priv);
1330 static void dm_ctrl_initgain_byrssi_highpwr(struct r8192_priv *priv)
1332 static u32 reset_cnt_highpwr = 0;
1334 // For smooth, we can not change high power DIG state in the range.
1335 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
1336 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
1341 /* 3. When RSSI >75% or <70%, it is a high power issue. We have to judge if
1342 it is larger than a threshold and then execute below step. */
1343 // 2008/02/05 MH SD3-Jerry Modify PD_TH for high power issue.
1344 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh)
1346 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1347 (priv->reset_count == reset_cnt_highpwr))
1350 dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1352 // 3.1 Higher PD_TH for OFDM for high power state.
1353 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1355 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10);
1358 write_nic_byte(priv, rOFDM0_RxDetector1, 0x43);
1362 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF&&
1363 (priv->reset_count == reset_cnt_highpwr))
1366 dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1368 if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
1369 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh)
1371 // 3.2 Recover PD_TH for OFDM for normal power region.
1372 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1374 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20);
1377 write_nic_byte(priv, rOFDM0_RxDetector1, 0x44);
1381 reset_cnt_highpwr = priv->reset_count;
1386 static void dm_initial_gain(struct r8192_priv *priv)
1389 static u8 initialized=0, force_write=0;
1390 static u32 reset_cnt=0;
1392 if(dm_digtable.dig_algorithm_switch)
1398 if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
1400 if(dm_digtable.cur_connect_state == DIG_CONNECT)
1402 if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
1403 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
1404 else if((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
1405 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
1407 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
1409 else //current state is disconnected
1411 if(dm_digtable.cur_ig_value == 0)
1412 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1414 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1417 else // disconnected -> connected or connected -> disconnected
1419 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1420 dm_digtable.pre_ig_value = 0;
1423 // if silent reset happened, we should rewrite the values back
1424 if(priv->reset_count != reset_cnt)
1427 reset_cnt = priv->reset_count;
1430 if(dm_digtable.pre_ig_value != read_nic_byte(priv, rOFDM0_XAAGCCore1))
1434 if((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1435 || !initialized || force_write)
1437 initial_gain = (u8)dm_digtable.cur_ig_value;
1438 // Set initial gain.
1439 write_nic_byte(priv, rOFDM0_XAAGCCore1, initial_gain);
1440 write_nic_byte(priv, rOFDM0_XBAGCCore1, initial_gain);
1441 write_nic_byte(priv, rOFDM0_XCAGCCore1, initial_gain);
1442 write_nic_byte(priv, rOFDM0_XDAGCCore1, initial_gain);
1443 dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1450 static void dm_pd_th(struct r8192_priv *priv)
1452 static u8 initialized=0, force_write=0;
1453 static u32 reset_cnt = 0;
1455 if(dm_digtable.dig_algorithm_switch)
1461 if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
1463 if(dm_digtable.cur_connect_state == DIG_CONNECT)
1465 if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
1466 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
1467 else if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
1468 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1469 else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
1470 (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
1471 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
1473 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
1477 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1480 else // disconnected -> connected or connected -> disconnected
1482 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1485 // if silent reset happened, we should rewrite the values back
1486 if(priv->reset_count != reset_cnt)
1489 reset_cnt = priv->reset_count;
1493 if((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
1494 (initialized<=3) || force_write)
1496 if(dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER)
1498 // Lower PD_TH for OFDM.
1499 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1501 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1502 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1503 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x00);
1506 write_nic_byte(priv, rOFDM0_RxDetector1, 0x42);
1508 else if(dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER)
1510 // Higher PD_TH for OFDM.
1511 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1513 /* 2008/01/11 MH 40MHZ 90/92 register are not the same. */
1514 // 2008/02/05 MH SD3-Jerry 92U/92E PD_TH are the same.
1515 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x20);
1518 write_nic_byte(priv, rOFDM0_RxDetector1, 0x44);
1520 else if(dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER)
1522 // Higher PD_TH for OFDM for high power state.
1523 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1525 write_nic_byte(priv, (rOFDM0_XATxAFE+3), 0x10);
1528 write_nic_byte(priv, rOFDM0_RxDetector1, 0x43);
1530 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
1531 if(initialized <= 3)
1538 static void dm_cs_ratio(struct r8192_priv *priv)
1540 static u8 initialized=0,force_write=0;
1541 static u32 reset_cnt = 0;
1543 if(dm_digtable.dig_algorithm_switch)
1549 if(dm_digtable.pre_connect_state == dm_digtable.cur_connect_state)
1551 if(dm_digtable.cur_connect_state == DIG_CONNECT)
1553 if ((dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh))
1554 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1555 else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) )
1556 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
1558 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
1562 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1565 else // disconnected -> connected or connected -> disconnected
1567 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1570 // if silent reset happened, we should rewrite the values back
1571 if(priv->reset_count != reset_cnt)
1574 reset_cnt = priv->reset_count;
1578 if((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
1579 !initialized || force_write)
1581 if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
1583 // Lower CS ratio for CCK.
1584 write_nic_byte(priv, 0xa0a, 0x08);
1586 else if(dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
1588 // Higher CS ratio for CCK.
1589 write_nic_byte(priv, 0xa0a, 0xcd);
1591 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
1597 void dm_init_edca_turbo(struct r8192_priv *priv)
1600 priv->bcurrent_turbo_EDCA = false;
1601 priv->ieee80211->bis_any_nonbepkts = false;
1602 priv->bis_cur_rdlstate = false;
1605 static void dm_check_edca_turbo(struct r8192_priv *priv)
1607 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
1608 //PSTA_QOS pStaQos = pMgntInfo->pStaQos;
1610 // Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.
1611 static unsigned long lastTxOkCnt = 0;
1612 static unsigned long lastRxOkCnt = 0;
1613 unsigned long curTxOkCnt = 0;
1614 unsigned long curRxOkCnt = 0;
1617 // Do not be Turbo if it's under WiFi config and Qos Enabled, because the EDCA parameters
1618 // should follow the settings from QAP. By Bruce, 2007-12-07.
1620 if(priv->ieee80211->state != IEEE80211_LINKED)
1621 goto dm_CheckEdcaTurbo_EXIT;
1622 // We do not turn on EDCA turbo mode for some AP that has IOT issue
1623 if(priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
1624 goto dm_CheckEdcaTurbo_EXIT;
1626 // Check the status for current condition.
1627 if(!priv->ieee80211->bis_any_nonbepkts)
1629 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1630 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1631 // For RT-AP, we needs to turn it on when Rx>Tx
1632 if(curRxOkCnt > 4*curTxOkCnt)
1634 if(!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
1636 write_nic_dword(priv, EDCAPARA_BE, edca_setting_DL[pHTInfo->IOTPeer]);
1637 priv->bis_cur_rdlstate = true;
1642 if(priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA)
1644 write_nic_dword(priv, EDCAPARA_BE, edca_setting_UL[pHTInfo->IOTPeer]);
1645 priv->bis_cur_rdlstate = false;
1650 priv->bcurrent_turbo_EDCA = true;
1655 // Turn Off EDCA turbo here.
1656 // Restore original EDCA according to the declaration of AP.
1658 if(priv->bcurrent_turbo_EDCA)
1664 struct ieee80211_qos_parameters *qos_parameters = &priv->ieee80211->current_network.qos_data.parameters;
1665 u8 mode = priv->ieee80211->mode;
1667 // For Each time updating EDCA parameter, reset EDCA turbo mode status.
1668 dm_init_edca_turbo(priv);
1669 u1bAIFS = qos_parameters->aifs[0] * ((mode&(IEEE_G|IEEE_N_24G)) ?9:20) + aSifsTime;
1670 u4bAcParam = ((((u32)(qos_parameters->tx_op_limit[0]))<< AC_PARAM_TXOP_LIMIT_OFFSET)|
1671 (((u32)(qos_parameters->cw_max[0]))<< AC_PARAM_ECW_MAX_OFFSET)|
1672 (((u32)(qos_parameters->cw_min[0]))<< AC_PARAM_ECW_MIN_OFFSET)|
1673 ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
1674 printk("===>u4bAcParam:%x, ", u4bAcParam);
1675 //write_nic_dword(dev, WDCAPARA_ADD[i], u4bAcParam);
1676 write_nic_dword(priv, EDCAPARA_BE, u4bAcParam);
1679 // If it is set, immediately set ACM control bit to downgrading AC for passing WMM testplan. Annie, 2005-12-13.
1681 // TODO: Modified this part and try to set acm control in only 1 IO processing!!
1683 PACI_AIFSN pAciAifsn = (PACI_AIFSN)&(qos_parameters->aifs[0]);
1684 u8 AcmCtrl = read_nic_byte(priv, AcmHwCtrl );
1685 if( pAciAifsn->f.ACM )
1687 AcmCtrl |= AcmHw_BeqEn;
1691 AcmCtrl &= (~AcmHw_BeqEn);
1694 RT_TRACE( COMP_QOS,"SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", AcmCtrl ) ;
1695 write_nic_byte(priv, AcmHwCtrl, AcmCtrl );
1698 priv->bcurrent_turbo_EDCA = false;
1703 dm_CheckEdcaTurbo_EXIT:
1704 // Set variables for next time.
1705 priv->ieee80211->bis_any_nonbepkts = false;
1706 lastTxOkCnt = priv->stats.txbytesunicast;
1707 lastRxOkCnt = priv->stats.rxbytesunicast;
1710 static void dm_init_ctstoself(struct r8192_priv *priv)
1712 priv->ieee80211->bCTSToSelfEnable = TRUE;
1713 priv->ieee80211->CTSToSelfTH = CTSToSelfTHVal;
1716 static void dm_ctstoself(struct r8192_priv *priv)
1718 PRT_HIGH_THROUGHPUT pHTInfo = priv->ieee80211->pHTInfo;
1719 static unsigned long lastTxOkCnt = 0;
1720 static unsigned long lastRxOkCnt = 0;
1721 unsigned long curTxOkCnt = 0;
1722 unsigned long curRxOkCnt = 0;
1724 if(priv->ieee80211->bCTSToSelfEnable != TRUE)
1726 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1731 2. Linksys350/Linksys300N
1732 3. <50 disable, >55 enable
1735 if(pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM)
1737 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1738 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1739 if(curRxOkCnt > 4*curTxOkCnt) //downlink, disable CTS to self
1741 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1745 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
1748 lastTxOkCnt = priv->stats.txbytesunicast;
1749 lastRxOkCnt = priv->stats.rxbytesunicast;
1755 /* Copy 8187B template for 9xseries */
1756 static void dm_check_rfctrl_gpio(struct r8192_priv *priv)
1759 // Walk around for DTM test, we will not enable HW - radio on/off because r/w
1760 // page 1 register before Lextra bus is enabled cause system fails when resuming
1761 // from S4. 20080218, Emily
1763 // Stop to execute workitem to prevent S3/S4 bug.
1764 queue_delayed_work(priv->priv_wq,&priv->gpio_change_rf_wq,0);
1767 /* PCI will not support workitem call back HW radio on-off control. */
1768 void dm_gpio_change_rf_callback(struct work_struct *work)
1770 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
1771 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,gpio_change_rf_wq);
1773 RT_RF_POWER_STATE eRfPowerStateToSet;
1774 bool bActuallySet = false;
1777 RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),"dm_gpio_change_rf_callback(): Callback function breaks out!!\n");
1779 // 0x108 GPIO input register is read only
1780 //set 0x108 B1= 1: RF-ON; 0: RF-OFF.
1781 tmp1byte = read_nic_byte(priv, GPI);
1783 eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff;
1785 if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
1786 RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n");
1788 priv->bHwRadioOff = false;
1789 bActuallySet = true;
1790 } else if ((!priv->bHwRadioOff) && (eRfPowerStateToSet == eRfOff)) {
1791 RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n");
1792 priv->bHwRadioOff = true;
1793 bActuallySet = true;
1797 priv->bHwRfOffAction = 1;
1798 MgntActSet_RF_State(priv, eRfPowerStateToSet, RF_CHANGE_BY_HW);
1799 //DrvIFIndicateCurrentPhyStatus(pAdapter);
1806 /* Check if Current RF RX path is enabled */
1807 void dm_rf_pathcheck_workitemcallback(struct work_struct *work)
1809 struct delayed_work *dwork = container_of(work,struct delayed_work,work);
1810 struct r8192_priv *priv = container_of(dwork,struct r8192_priv,rfpath_check_wq);
1814 /* 2008/01/30 MH After discussing with SD3 Jerry, 0xc04/0xd04 register will
1815 always be the same. We only read 0xc04 now. */
1816 rfpath = read_nic_byte(priv, 0xc04);
1818 // Check Bit 0-3, it means if RF A-D is enabled.
1819 for (i = 0; i < RF90_PATH_MAX; i++)
1821 if (rfpath & (0x01<<i))
1822 priv->brfpath_rxenable[i] = 1;
1824 priv->brfpath_rxenable[i] = 0;
1826 if(!DM_RxPathSelTable.Enable)
1829 dm_rxpath_sel_byrssi(priv);
1832 static void dm_init_rxpath_selection(struct r8192_priv *priv)
1836 DM_RxPathSelTable.Enable = 1; //default enabled
1837 DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
1838 DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
1839 if(priv->CustomerID == RT_CID_819x_Netcore)
1840 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1842 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
1843 DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
1844 DM_RxPathSelTable.disabledRF = 0;
1847 DM_RxPathSelTable.rf_rssi[i] = 50;
1848 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
1849 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
1853 static void dm_rxpath_sel_byrssi(struct r8192_priv *priv)
1855 u8 i, max_rssi_index=0, min_rssi_index=0, sec_rssi_index=0, rf_num=0;
1856 u8 tmp_max_rssi=0, tmp_min_rssi=0, tmp_sec_rssi=0;
1857 u8 cck_default_Rx=0x2; //RF-C
1858 u8 cck_optional_Rx=0x3;//RF-D
1859 long tmp_cck_max_pwdb=0, tmp_cck_min_pwdb=0, tmp_cck_sec_pwdb=0;
1860 u8 cck_rx_ver2_max_index=0, cck_rx_ver2_min_index=0, cck_rx_ver2_sec_index=0;
1863 static u8 disabled_rf_cnt=0, cck_Rx_Path_initialized=0;
1864 u8 update_cck_rx_path;
1866 if(priv->rf_type != RF_2T4R)
1869 if(!cck_Rx_Path_initialized)
1871 DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(priv, 0xa07)&0xf);
1872 cck_Rx_Path_initialized = 1;
1875 DM_RxPathSelTable.disabledRF = 0xf;
1876 DM_RxPathSelTable.disabledRF &=~ (read_nic_byte(priv, 0xc04));
1878 if(priv->ieee80211->mode == WIRELESS_MODE_B)
1880 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2; //pure B mode, fixed cck version2
1883 //decide max/sec/min rssi index
1884 for (i=0; i<RF90_PATH_MAX; i++)
1886 if(!DM_RxPathSelTable.DbgMode)
1887 DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
1889 if(priv->brfpath_rxenable[i])
1892 cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
1894 if(rf_num == 1) // find first enabled rf path and the rssi values
1895 { //initialize, set all rssi index to the same one
1896 max_rssi_index = min_rssi_index = sec_rssi_index = i;
1897 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
1899 else if(rf_num == 2)
1900 { // we pick up the max index first, and let sec and min to be the same one
1901 if(cur_rf_rssi >= tmp_max_rssi)
1903 tmp_max_rssi = cur_rf_rssi;
1908 tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
1909 sec_rssi_index = min_rssi_index = i;
1914 if(cur_rf_rssi > tmp_max_rssi)
1916 tmp_sec_rssi = tmp_max_rssi;
1917 sec_rssi_index = max_rssi_index;
1918 tmp_max_rssi = cur_rf_rssi;
1921 else if(cur_rf_rssi == tmp_max_rssi)
1922 { // let sec and min point to the different index
1923 tmp_sec_rssi = cur_rf_rssi;
1926 else if((cur_rf_rssi < tmp_max_rssi) &&(cur_rf_rssi > tmp_sec_rssi))
1928 tmp_sec_rssi = cur_rf_rssi;
1931 else if(cur_rf_rssi == tmp_sec_rssi)
1933 if(tmp_sec_rssi == tmp_min_rssi)
1934 { // let sec and min point to the different index
1935 tmp_sec_rssi = cur_rf_rssi;
1940 // This case we don't need to set any index
1943 else if((cur_rf_rssi < tmp_sec_rssi) && (cur_rf_rssi > tmp_min_rssi))
1945 // This case we don't need to set any index
1947 else if(cur_rf_rssi == tmp_min_rssi)
1949 if(tmp_sec_rssi == tmp_min_rssi)
1950 { // let sec and min point to the different index
1951 tmp_min_rssi = cur_rf_rssi;
1956 // This case we don't need to set any index
1959 else if(cur_rf_rssi < tmp_min_rssi)
1961 tmp_min_rssi = cur_rf_rssi;
1969 // decide max/sec/min cck pwdb index
1970 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
1972 for (i=0; i<RF90_PATH_MAX; i++)
1974 if(priv->brfpath_rxenable[i])
1977 cur_cck_pwdb = DM_RxPathSelTable.cck_pwdb_sta[i];
1979 if(rf_num == 1) // find first enabled rf path and the rssi values
1980 { //initialize, set all rssi index to the same one
1981 cck_rx_ver2_max_index = cck_rx_ver2_min_index = cck_rx_ver2_sec_index = i;
1982 tmp_cck_max_pwdb = tmp_cck_min_pwdb = tmp_cck_sec_pwdb = cur_cck_pwdb;
1984 else if(rf_num == 2)
1985 { // we pick up the max index first, and let sec and min to be the same one
1986 if(cur_cck_pwdb >= tmp_cck_max_pwdb)
1988 tmp_cck_max_pwdb = cur_cck_pwdb;
1989 cck_rx_ver2_max_index = i;
1993 tmp_cck_sec_pwdb = tmp_cck_min_pwdb = cur_cck_pwdb;
1994 cck_rx_ver2_sec_index = cck_rx_ver2_min_index = i;
1999 if(cur_cck_pwdb > tmp_cck_max_pwdb)
2001 tmp_cck_sec_pwdb = tmp_cck_max_pwdb;
2002 cck_rx_ver2_sec_index = cck_rx_ver2_max_index;
2003 tmp_cck_max_pwdb = cur_cck_pwdb;
2004 cck_rx_ver2_max_index = i;
2006 else if(cur_cck_pwdb == tmp_cck_max_pwdb)
2007 { // let sec and min point to the different index
2008 tmp_cck_sec_pwdb = cur_cck_pwdb;
2009 cck_rx_ver2_sec_index = i;
2011 else if((cur_cck_pwdb < tmp_cck_max_pwdb) &&(cur_cck_pwdb > tmp_cck_sec_pwdb))
2013 tmp_cck_sec_pwdb = cur_cck_pwdb;
2014 cck_rx_ver2_sec_index = i;
2016 else if(cur_cck_pwdb == tmp_cck_sec_pwdb)
2018 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
2019 { // let sec and min point to the different index
2020 tmp_cck_sec_pwdb = cur_cck_pwdb;
2021 cck_rx_ver2_sec_index = i;
2025 // This case we don't need to set any index
2028 else if((cur_cck_pwdb < tmp_cck_sec_pwdb) && (cur_cck_pwdb > tmp_cck_min_pwdb))
2030 // This case we don't need to set any index
2032 else if(cur_cck_pwdb == tmp_cck_min_pwdb)
2034 if(tmp_cck_sec_pwdb == tmp_cck_min_pwdb)
2035 { // let sec and min point to the different index
2036 tmp_cck_min_pwdb = cur_cck_pwdb;
2037 cck_rx_ver2_min_index = i;
2041 // This case we don't need to set any index
2044 else if(cur_cck_pwdb < tmp_cck_min_pwdb)
2046 tmp_cck_min_pwdb = cur_cck_pwdb;
2047 cck_rx_ver2_min_index = i;
2057 // reg0xA07[3:2]=cck default rx path, reg0xa07[1:0]=cck optional rx path.
2058 update_cck_rx_path = 0;
2059 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_2)
2061 cck_default_Rx = cck_rx_ver2_max_index;
2062 cck_optional_Rx = cck_rx_ver2_sec_index;
2063 if(tmp_cck_max_pwdb != -64)
2064 update_cck_rx_path = 1;
2067 if(tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2)
2069 if((tmp_max_rssi - tmp_min_rssi) >= DM_RxPathSelTable.diff_TH)
2071 //record the enabled rssi threshold
2072 DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] = tmp_max_rssi+5;
2073 //disable the BB Rx path, OFDM
2074 rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xc04[3:0]
2075 rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0x1<<min_rssi_index, 0x0); // 0xd04[3:0]
2078 if(DM_RxPathSelTable.cck_method == CCK_Rx_Version_1)
2080 cck_default_Rx = max_rssi_index;
2081 cck_optional_Rx = sec_rssi_index;
2083 update_cck_rx_path = 1;
2087 if(update_cck_rx_path)
2089 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2)|(cck_optional_Rx);
2090 rtl8192_setBBreg(priv, rCCK0_AFESetting, 0x0f000000, DM_RxPathSelTable.cck_Rx_path);
2093 if(DM_RxPathSelTable.disabledRF)
2097 if((DM_RxPathSelTable.disabledRF>>i) & 0x1) //disabled rf
2099 if(tmp_max_rssi >= DM_RxPathSelTable.rf_enable_rssi_th[i])
2101 //enable the BB Rx path
2102 rtl8192_setBBreg(priv, rOFDM0_TRxPathEnable, 0x1<<i, 0x1); // 0xc04[3:0]
2103 rtl8192_setBBreg(priv, rOFDM1_TRxPathEnable, 0x1<<i, 0x1); // 0xd04[3:0]
2104 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
2113 * Call a workitem to check current RXRF path and Rx Path selection by RSSI.
2115 static void dm_check_rx_path_selection(struct r8192_priv *priv)
2117 queue_delayed_work(priv->priv_wq,&priv->rfpath_check_wq,0);
2120 static void dm_init_fsync(struct r8192_priv *priv)
2122 priv->ieee80211->fsync_time_interval = 500;
2123 priv->ieee80211->fsync_rate_bitmap = 0x0f000800;
2124 priv->ieee80211->fsync_rssi_threshold = 30;
2125 priv->ieee80211->bfsync_enable = false;
2126 priv->ieee80211->fsync_multiple_timeinterval = 3;
2127 priv->ieee80211->fsync_firstdiff_ratethreshold= 100;
2128 priv->ieee80211->fsync_seconddiff_ratethreshold= 200;
2129 priv->ieee80211->fsync_state = Default_Fsync;
2130 priv->framesyncMonitor = 1; // current default 0xc38 monitor on
2132 init_timer(&priv->fsync_timer);
2133 priv->fsync_timer.data = (unsigned long)priv;
2134 priv->fsync_timer.function = dm_fsync_timer_callback;
2138 static void dm_deInit_fsync(struct r8192_priv *priv)
2140 del_timer_sync(&priv->fsync_timer);
2143 static void dm_fsync_timer_callback(unsigned long data)
2145 struct r8192_priv *priv = (struct r8192_priv *)data;
2146 u32 rate_index, rate_count = 0, rate_count_diff=0;
2147 bool bSwitchFromCountDiff = false;
2148 bool bDoubleTimeInterval = false;
2150 if( priv->ieee80211->state == IEEE80211_LINKED &&
2151 priv->ieee80211->bfsync_enable &&
2152 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
2154 // Count rate 54, MCS [7], [12, 13, 14, 15]
2156 for(rate_index = 0; rate_index <= 27; rate_index++)
2158 rate_bitmap = 1 << rate_index;
2159 if(priv->ieee80211->fsync_rate_bitmap & rate_bitmap)
2160 rate_count+= priv->stats.received_rate_histogram[1][rate_index];
2163 if(rate_count < priv->rate_record)
2164 rate_count_diff = 0xffffffff - rate_count + priv->rate_record;
2166 rate_count_diff = rate_count - priv->rate_record;
2167 if(rate_count_diff < priv->rateCountDiffRecord)
2170 u32 DiffNum = priv->rateCountDiffRecord - rate_count_diff;
2172 if(DiffNum >= priv->ieee80211->fsync_seconddiff_ratethreshold)
2173 priv->ContiuneDiffCount++;
2175 priv->ContiuneDiffCount = 0;
2177 // Contiune count over
2178 if(priv->ContiuneDiffCount >=2)
2180 bSwitchFromCountDiff = true;
2181 priv->ContiuneDiffCount = 0;
2186 // Stop contiune count
2187 priv->ContiuneDiffCount = 0;
2190 //If Count diff <= FsyncRateCountThreshold
2191 if(rate_count_diff <= priv->ieee80211->fsync_firstdiff_ratethreshold)
2193 bSwitchFromCountDiff = true;
2194 priv->ContiuneDiffCount = 0;
2196 priv->rate_record = rate_count;
2197 priv->rateCountDiffRecord = rate_count_diff;
2198 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
2199 // if we never receive those mcs rate and rssi > 30 % then switch fsyn
2200 if(priv->undecorated_smoothed_pwdb > priv->ieee80211->fsync_rssi_threshold && bSwitchFromCountDiff)
2202 bDoubleTimeInterval = true;
2203 priv->bswitch_fsync = !priv->bswitch_fsync;
2204 if(priv->bswitch_fsync)
2206 write_nic_byte(priv,0xC36, 0x1c);
2207 write_nic_byte(priv, 0xC3e, 0x90);
2211 write_nic_byte(priv, 0xC36, 0x5c);
2212 write_nic_byte(priv, 0xC3e, 0x96);
2215 else if(priv->undecorated_smoothed_pwdb <= priv->ieee80211->fsync_rssi_threshold)
2217 if(priv->bswitch_fsync)
2219 priv->bswitch_fsync = false;
2220 write_nic_byte(priv, 0xC36, 0x5c);
2221 write_nic_byte(priv, 0xC3e, 0x96);
2224 if(bDoubleTimeInterval){
2225 if(timer_pending(&priv->fsync_timer))
2226 del_timer_sync(&priv->fsync_timer);
2227 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval*priv->ieee80211->fsync_multiple_timeinterval);
2228 add_timer(&priv->fsync_timer);
2231 if(timer_pending(&priv->fsync_timer))
2232 del_timer_sync(&priv->fsync_timer);
2233 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
2234 add_timer(&priv->fsync_timer);
2239 // Let Register return to default value;
2240 if(priv->bswitch_fsync)
2242 priv->bswitch_fsync = false;
2243 write_nic_byte(priv, 0xC36, 0x5c);
2244 write_nic_byte(priv, 0xC3e, 0x96);
2246 priv->ContiuneDiffCount = 0;
2247 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd);
2249 RT_TRACE(COMP_HALDM, "ContiuneDiffCount %d\n", priv->ContiuneDiffCount);
2250 RT_TRACE(COMP_HALDM, "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n", priv->rate_record, rate_count, rate_count_diff , priv->bswitch_fsync);
2253 static void dm_StartHWFsync(struct r8192_priv *priv)
2255 RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
2256 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cf);
2257 write_nic_byte(priv, 0xc3b, 0x41);
2260 static void dm_EndSWFsync(struct r8192_priv *priv)
2262 RT_TRACE(COMP_HALDM, "%s\n", __FUNCTION__);
2263 del_timer_sync(&(priv->fsync_timer));
2265 // Let Register return to default value;
2266 if(priv->bswitch_fsync)
2268 priv->bswitch_fsync = false;
2270 write_nic_byte(priv, 0xC36, 0x40);
2272 write_nic_byte(priv, 0xC3e, 0x96);
2275 priv->ContiuneDiffCount = 0;
2277 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd);
2280 static void dm_StartSWFsync(struct r8192_priv *priv)
2285 RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
2286 // Initial rate record to zero, start to record.
2287 priv->rate_record = 0;
2288 // Initial contiune diff count to zero, start to record.
2289 priv->ContiuneDiffCount = 0;
2290 priv->rateCountDiffRecord = 0;
2291 priv->bswitch_fsync = false;
2293 if(priv->ieee80211->mode == WIRELESS_MODE_N_24G)
2295 priv->ieee80211->fsync_firstdiff_ratethreshold= 600;
2296 priv->ieee80211->fsync_seconddiff_ratethreshold = 0xffff;
2300 priv->ieee80211->fsync_firstdiff_ratethreshold= 200;
2301 priv->ieee80211->fsync_seconddiff_ratethreshold = 200;
2303 for(rateIndex = 0; rateIndex <= 27; rateIndex++)
2305 rateBitmap = 1 << rateIndex;
2306 if(priv->ieee80211->fsync_rate_bitmap & rateBitmap)
2307 priv->rate_record += priv->stats.received_rate_histogram[1][rateIndex];
2309 if(timer_pending(&priv->fsync_timer))
2310 del_timer_sync(&priv->fsync_timer);
2311 priv->fsync_timer.expires = jiffies + MSECS(priv->ieee80211->fsync_time_interval);
2312 add_timer(&priv->fsync_timer);
2314 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c12cd);
2317 static void dm_EndHWFsync(struct r8192_priv *priv)
2319 RT_TRACE(COMP_HALDM,"%s\n", __FUNCTION__);
2320 write_nic_dword(priv, rOFDM0_RxDetector2, 0x465c52cd);
2321 write_nic_byte(priv, 0xc3b, 0x49);
2324 static void dm_check_fsync(struct r8192_priv *priv)
2326 #define RegC38_Default 0
2327 #define RegC38_NonFsync_Other_AP 1
2328 #define RegC38_Fsync_AP_BCM 2
2330 static u8 reg_c38_State=RegC38_Default;
2331 static u32 reset_cnt=0;
2333 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);
2334 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);
2336 if( priv->ieee80211->state == IEEE80211_LINKED &&
2337 (priv->ieee80211->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC))
2339 if(priv->ieee80211->bfsync_enable == 0)
2341 switch(priv->ieee80211->fsync_state)
2344 dm_StartHWFsync(priv);
2345 priv->ieee80211->fsync_state = HW_Fsync;
2348 dm_EndSWFsync(priv);
2349 dm_StartHWFsync(priv);
2350 priv->ieee80211->fsync_state = HW_Fsync;
2359 switch(priv->ieee80211->fsync_state)
2362 dm_StartSWFsync(priv);
2363 priv->ieee80211->fsync_state = SW_Fsync;
2366 dm_EndHWFsync(priv);
2367 dm_StartSWFsync(priv);
2368 priv->ieee80211->fsync_state = SW_Fsync;
2376 if(priv->framesyncMonitor)
2378 if(reg_c38_State != RegC38_Fsync_AP_BCM)
2379 { //For broadcom AP we write different default value
2380 write_nic_byte(priv, rOFDM0_RxDetector3, 0x95);
2382 reg_c38_State = RegC38_Fsync_AP_BCM;
2388 switch(priv->ieee80211->fsync_state)
2391 dm_EndHWFsync(priv);
2392 priv->ieee80211->fsync_state = Default_Fsync;
2395 dm_EndSWFsync(priv);
2396 priv->ieee80211->fsync_state = Default_Fsync;
2403 if(priv->framesyncMonitor)
2405 if(priv->ieee80211->state == IEEE80211_LINKED)
2407 if(priv->undecorated_smoothed_pwdb <= RegC38_TH)
2409 if(reg_c38_State != RegC38_NonFsync_Other_AP)
2411 write_nic_byte(priv, rOFDM0_RxDetector3, 0x90);
2413 reg_c38_State = RegC38_NonFsync_Other_AP;
2416 else if(priv->undecorated_smoothed_pwdb >= (RegC38_TH+5))
2420 write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
2421 reg_c38_State = RegC38_Default;
2429 write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
2430 reg_c38_State = RegC38_Default;
2435 if(priv->framesyncMonitor)
2437 if(priv->reset_count != reset_cnt)
2438 { //After silent reset, the reg_c38_State will be returned to default value
2439 write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
2440 reg_c38_State = RegC38_Default;
2441 reset_cnt = priv->reset_count;
2448 write_nic_byte(priv, rOFDM0_RxDetector3, priv->framesync);
2449 reg_c38_State = RegC38_Default;
2455 * Detect Signal strength to control TX Registry
2456 * Tx Power Control For Near/Far Range
2458 static void dm_init_dynamic_txpower(struct r8192_priv *priv)
2460 //Initial TX Power Control for near/far range , add by amy 2008/05/15, porting from windows code.
2461 priv->ieee80211->bdynamic_txpower_enable = true; //Default to enable Tx Power Control
2462 priv->bLastDTPFlag_High = false;
2463 priv->bLastDTPFlag_Low = false;
2464 priv->bDynamicTxHighPower = false;
2465 priv->bDynamicTxLowPower = false;
2468 static void dm_dynamic_txpower(struct r8192_priv *priv)
2470 unsigned int txhipower_threshhold=0;
2471 unsigned int txlowpower_threshold=0;
2472 if(priv->ieee80211->bdynamic_txpower_enable != true)
2474 priv->bDynamicTxHighPower = false;
2475 priv->bDynamicTxLowPower = false;
2478 if((priv->ieee80211->current_network.atheros_cap_exist ) && (priv->ieee80211->mode == IEEE_G)){
2479 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
2480 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2484 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2485 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2488 RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n" , priv->undecorated_smoothed_pwdb);
2490 if(priv->ieee80211->state == IEEE80211_LINKED)
2492 if(priv->undecorated_smoothed_pwdb >= txhipower_threshhold)
2494 priv->bDynamicTxHighPower = true;
2495 priv->bDynamicTxLowPower = false;
2499 // high power state check
2500 if(priv->undecorated_smoothed_pwdb < txlowpower_threshold && priv->bDynamicTxHighPower == true)
2502 priv->bDynamicTxHighPower = false;
2504 // low power state check
2505 if(priv->undecorated_smoothed_pwdb < 35)
2507 priv->bDynamicTxLowPower = true;
2509 else if(priv->undecorated_smoothed_pwdb >= 40)
2511 priv->bDynamicTxLowPower = false;
2517 //pHalData->bTXPowerCtrlforNearFarRange = !pHalData->bTXPowerCtrlforNearFarRange;
2518 priv->bDynamicTxHighPower = false;
2519 priv->bDynamicTxLowPower = false;
2522 if( (priv->bDynamicTxHighPower != priv->bLastDTPFlag_High ) ||
2523 (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low ) )
2525 RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n", priv->ieee80211->current_network.channel);
2528 rtl8192_phy_setTxPower(priv, priv->ieee80211->current_network.channel);
2531 priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2532 priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2536 //added by vivi, for read tx rate and retrycount
2537 static void dm_check_txrateandretrycount(struct r8192_priv *priv)
2539 struct ieee80211_device* ieee = priv->ieee80211;
2541 //for initial tx rate
2542 ieee->softmac_stats.last_packet_rate = read_nic_byte(priv ,Initial_Tx_Rate_Reg);
2543 //for tx tx retry count
2544 ieee->softmac_stats.txretrycount = read_nic_dword(priv, Tx_Retry_Count_Reg);
2547 static void dm_send_rssi_tofw(struct r8192_priv *priv)
2549 // If we test chariot, we should stop the TX command ?
2550 // Because 92E will always silent reset when we send tx command. We use register
2551 // 0x1e0(byte) to botify driver.
2552 write_nic_byte(priv, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);