1 /******************************************************************************
2 * Copyright(c) 2008 - 2010 Realtek Corporation. All rights reserved.
4 * This program is distributed in the hope that it will be useful, but WITHOUT
5 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
6 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
9 * You should have received a copy of the GNU General Public License along with
10 * this program; if not, write to the Free Software Foundation, Inc.,
11 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
13 * The full GNU General Public License is included in this distribution in the
14 * file called LICENSE.
16 * Contact Information:
17 * wlanfae <wlanfae@realtek.com>
18 ******************************************************************************/
21 #include "r8192E_hw.h"
22 #include "r8192E_phy.h"
23 #include "r8192E_phyreg.h"
24 #include "r8190P_rtl8256.h"
25 #include "r8192E_cmdpkt.h"
27 /*---------------------------Define Local Constant---------------------------*/
28 static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
39 static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = {
50 static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
61 #define RTK_UL_EDCA 0xa44f
62 #define RTK_DL_EDCA 0x5e4322
64 const u32 dm_tx_bb_gain[TxBBGainTableLength] = {
65 0x7f8001fe, /* 12 dB */
66 0x788001e2, /* 11 dB */
101 0x10000040, /* -24 dB */
104 const u8 dm_cck_tx_bb_gain[CCKTxBBGainTableLength][8] = {
105 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
106 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
107 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
108 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
109 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
110 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
111 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
112 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
113 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
114 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
115 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
116 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
117 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
118 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
119 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
120 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
121 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
122 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
123 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
124 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
125 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
126 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
127 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
130 const u8 dm_cck_tx_bb_gain_ch14[CCKTxBBGainTableLength][8] = {
131 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
132 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
133 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
134 {0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00},
135 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
136 {0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00},
137 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
138 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
139 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
140 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
141 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
142 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
143 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
144 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
145 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
146 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
147 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
148 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
149 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
150 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
151 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
152 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
153 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
156 /*---------------------------Define Local Constant---------------------------*/
159 /*------------------------Define global variable-----------------------------*/
160 struct dig_t dm_digtable;
161 u8 dm_shadow[16][256] = {
165 struct drx_path_sel DM_RxPathSelTable;
166 /*------------------------Define global variable-----------------------------*/
169 /*------------------------Define local variable------------------------------*/
170 /*------------------------Define local variable------------------------------*/
174 /*---------------------Define local function prototype-----------------------*/
175 static void dm_check_rate_adaptive(struct net_device *dev);
177 static void dm_init_bandwidth_autoswitch(struct net_device *dev);
178 static void dm_bandwidth_autoswitch(struct net_device *dev);
181 static void dm_check_txpower_tracking(struct net_device *dev);
187 static void dm_bb_initialgain_restore(struct net_device *dev);
190 static void dm_bb_initialgain_backup(struct net_device *dev);
192 static void dm_dig_init(struct net_device *dev);
193 static void dm_ctrl_initgain_byrssi(struct net_device *dev);
194 static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
195 static void dm_ctrl_initgain_byrssi_by_driverrssi(struct net_device *dev);
196 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(struct net_device *dev);
197 static void dm_initial_gain(struct net_device *dev);
198 static void dm_pd_th(struct net_device *dev);
199 static void dm_cs_ratio(struct net_device *dev);
201 static void dm_init_ctstoself(struct net_device *dev);
202 static void dm_Init_WA_Broadcom_IOT(struct net_device *dev);
204 static void dm_check_edca_turbo(struct net_device *dev);
206 static void dm_check_pbc_gpio(struct net_device *dev);
209 static void dm_check_rx_path_selection(struct net_device *dev);
210 static void dm_init_rxpath_selection(struct net_device *dev);
211 static void dm_rxpath_sel_byrssi(struct net_device *dev);
214 static void dm_init_fsync(struct net_device *dev);
215 static void dm_deInit_fsync(struct net_device *dev);
217 static void dm_check_txrateandretrycount(struct net_device *dev);
218 static void dm_check_ac_dc_power(struct net_device *dev);
220 /*---------------------Define local function prototype-----------------------*/
222 static void dm_init_dynamic_txpower(struct net_device *dev);
223 static void dm_dynamic_txpower(struct net_device *dev);
226 static void dm_send_rssi_tofw(struct net_device *dev);
227 static void dm_ctstoself(struct net_device *dev);
228 /*---------------------------Define function prototype------------------------*/
230 void init_hal_dm(struct net_device *dev)
232 struct r8192_priv *priv = rtllib_priv(dev);
234 priv->DM_Type = DM_Type_ByDriver;
236 priv->undecorated_smoothed_pwdb = -1;
238 dm_init_dynamic_txpower(dev);
240 init_rate_adaptive(dev);
243 dm_init_edca_turbo(dev);
244 dm_init_bandwidth_autoswitch(dev);
246 dm_init_rxpath_selection(dev);
247 dm_init_ctstoself(dev);
248 if (IS_HARDWARE_TYPE_8192SE(dev))
249 dm_Init_WA_Broadcom_IOT(dev);
251 INIT_DELAYED_WORK_RSL(&priv->gpio_change_rf_wq, (void *)dm_CheckRfCtrlGPIO, dev);
254 void deinit_hal_dm(struct net_device *dev)
257 dm_deInit_fsync(dev);
261 void hal_dm_watchdog(struct net_device *dev)
263 struct r8192_priv *priv = rtllib_priv(dev);
265 if (priv->being_init_adapter)
268 dm_check_ac_dc_power(dev);
270 dm_check_pbc_gpio(dev);
271 dm_check_txrateandretrycount(dev);
272 dm_check_edca_turbo(dev);
274 dm_check_rate_adaptive(dev);
275 dm_dynamic_txpower(dev);
276 dm_check_txpower_tracking(dev);
278 dm_ctrl_initgain_byrssi(dev);
279 dm_bandwidth_autoswitch(dev);
281 dm_check_rx_path_selection(dev);
284 dm_send_rssi_tofw(dev);
288 static void dm_check_ac_dc_power(struct net_device *dev)
290 struct r8192_priv *priv = rtllib_priv(dev);
291 static char *ac_dc_check_script_path = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
292 char *argv[] = {ac_dc_check_script_path, DRV_NAME, NULL};
293 static char *envp[] = {"HOME=/",
295 "PATH=/usr/bin:/bin",
298 if (priv->ResetProgress == RESET_TYPE_SILENT) {
299 RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),
300 "GPIOChangeRFWorkItemCallBack(): Silent Reset!!!!!!!\n");
304 if (priv->rtllib->state != RTLLIB_LINKED)
306 call_usermodehelper(ac_dc_check_script_path, argv, envp, UMH_WAIT_PROC);
312 void init_rate_adaptive(struct net_device *dev)
315 struct r8192_priv *priv = rtllib_priv(dev);
316 struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive;
318 pra->ratr_state = DM_RATR_STA_MAX;
319 pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
320 pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
321 pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
323 pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
324 pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
325 pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
327 if (priv->CustomerID == RT_CID_819x_Netcore)
328 pra->ping_rssi_enable = 1;
330 pra->ping_rssi_enable = 0;
331 pra->ping_rssi_thresh_for_ra = 15;
334 if (priv->rf_type == RF_2T4R) {
335 pra->upper_rssi_threshold_ratr = 0x8f0f0000;
336 pra->middle_rssi_threshold_ratr = 0x8f0ff000;
337 pra->low_rssi_threshold_ratr = 0x8f0ff001;
338 pra->low_rssi_threshold_ratr_40M = 0x8f0ff005;
339 pra->low_rssi_threshold_ratr_20M = 0x8f0ff001;
340 pra->ping_rssi_ratr = 0x0000000d;
341 } else if (priv->rf_type == RF_1T2R) {
342 pra->upper_rssi_threshold_ratr = 0x000fc000;
343 pra->middle_rssi_threshold_ratr = 0x000ff000;
344 pra->low_rssi_threshold_ratr = 0x000ff001;
345 pra->low_rssi_threshold_ratr_40M = 0x000ff005;
346 pra->low_rssi_threshold_ratr_20M = 0x000ff001;
347 pra->ping_rssi_ratr = 0x0000000d;
353 static void dm_check_rate_adaptive(struct net_device *dev)
355 struct r8192_priv *priv = rtllib_priv(dev);
356 struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
357 struct rate_adaptive *pra = (struct rate_adaptive *)&priv->rate_adaptive;
358 u32 currentRATR, targetRATR = 0;
359 u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
360 bool bshort_gi_enabled = false;
361 static u8 ping_rssi_state;
364 RT_TRACE(COMP_RATE, "<---- dm_check_rate_adaptive(): driver is going to unload\n");
368 if (pra->rate_adaptive_disabled)
371 if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
372 priv->rtllib->mode == WIRELESS_MODE_N_5G))
375 if (priv->rtllib->state == RTLLIB_LINKED) {
377 bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI40MHz) ||
378 (!pHTInfo->bCurTxBW40MHz && pHTInfo->bCurShortGI20MHz);
381 pra->upper_rssi_threshold_ratr =
382 (pra->upper_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
384 pra->middle_rssi_threshold_ratr =
385 (pra->middle_rssi_threshold_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
387 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
388 pra->low_rssi_threshold_ratr =
389 (pra->low_rssi_threshold_ratr_40M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
391 pra->low_rssi_threshold_ratr =
392 (pra->low_rssi_threshold_ratr_20M & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
394 pra->ping_rssi_ratr =
395 (pra->ping_rssi_ratr & (~BIT31)) | ((bshort_gi_enabled) ? BIT31 : 0);
397 if (pra->ratr_state == DM_RATR_STA_HIGH) {
398 HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra;
399 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
400 (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
401 } else if (pra->ratr_state == DM_RATR_STA_LOW) {
402 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
403 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
404 (pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M);
406 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
407 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
408 (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
411 if (priv->undecorated_smoothed_pwdb >= (long)HighRSSIThreshForRA) {
412 pra->ratr_state = DM_RATR_STA_HIGH;
413 targetRATR = pra->upper_rssi_threshold_ratr;
414 } else if (priv->undecorated_smoothed_pwdb >= (long)LowRSSIThreshForRA) {
415 pra->ratr_state = DM_RATR_STA_MIDDLE;
416 targetRATR = pra->middle_rssi_threshold_ratr;
418 pra->ratr_state = DM_RATR_STA_LOW;
419 targetRATR = pra->low_rssi_threshold_ratr;
422 if (pra->ping_rssi_enable) {
423 if (priv->undecorated_smoothed_pwdb < (long)(pra->ping_rssi_thresh_for_ra+5)) {
424 if ((priv->undecorated_smoothed_pwdb < (long)pra->ping_rssi_thresh_for_ra) ||
426 pra->ratr_state = DM_RATR_STA_LOW;
427 targetRATR = pra->ping_rssi_ratr;
435 if (priv->rtllib->GetHalfNmodeSupportByAPsHandler(dev))
436 targetRATR &= 0xf00fffff;
438 currentRATR = read_nic_dword(dev, RATR0);
439 if (targetRATR != currentRATR) {
442 ratr_value = targetRATR;
444 "currentRATR = %x, targetRATR = %x\n",
445 currentRATR, targetRATR);
446 if (priv->rf_type == RF_1T2R)
447 ratr_value &= ~(RATE_ALL_OFDM_2SS);
448 write_nic_dword(dev, RATR0, ratr_value);
449 write_nic_byte(dev, UFWP, 1);
451 pra->last_ratr = targetRATR;
455 pra->ratr_state = DM_RATR_STA_MAX;
459 static void dm_init_bandwidth_autoswitch(struct net_device *dev)
461 struct r8192_priv *priv = rtllib_priv(dev);
463 priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
464 priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
465 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
466 priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false;
469 static void dm_bandwidth_autoswitch(struct net_device *dev)
471 struct r8192_priv *priv = rtllib_priv(dev);
473 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||
474 !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable)
476 if (priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz == false) {
477 if (priv->undecorated_smoothed_pwdb <=
478 priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
479 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = true;
481 if (priv->undecorated_smoothed_pwdb >=
482 priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
483 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
487 static u32 OFDMSwingTable[OFDM_Table_Length] = {
509 static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
510 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
511 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
512 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
513 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
514 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
515 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
516 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
517 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
518 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
519 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
520 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
521 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
524 static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
525 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
526 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
527 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
528 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
529 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
530 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
531 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
532 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
533 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
534 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
535 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
536 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
539 #define Pw_Track_Flag 0x11d
540 #define Tssi_Mea_Value 0x13c
541 #define Tssi_Report_Value1 0x134
542 #define Tssi_Report_Value2 0x13e
543 #define FW_Busy_Flag 0x13f
545 static void dm_TXPowerTrackingCallback_TSSI(struct net_device *dev)
547 struct r8192_priv *priv = rtllib_priv(dev);
548 bool bHighpowerstate, viviflag = false;
549 struct dcmd_txcmd tx_cmd;
550 u8 powerlevelOFDM24G;
551 int i = 0, j = 0, k = 0;
552 u8 RF_Type, tmp_report[5] = {0, 0, 0, 0, 0};
555 u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0;
558 RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__);
559 write_nic_byte(dev, Pw_Track_Flag, 0);
560 write_nic_byte(dev, FW_Busy_Flag, 0);
561 priv->rtllib->bdynamic_txpower_enable = false;
562 bHighpowerstate = priv->bDynamicTxHighPower;
564 powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
565 RF_Type = priv->rf_type;
566 Value = (RF_Type<<8) | powerlevelOFDM24G;
568 RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n",
572 for (j = 0; j <= 30; j++) {
574 tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING;
576 tx_cmd.Value = Value;
577 cmpk_message_handle_tx(dev, (u8 *)&tx_cmd,
578 DESC_PACKET_TYPE_INIT,
579 sizeof(struct dcmd_txcmd));
581 for (i = 0; i <= 30; i++) {
582 Pwr_Flag = read_nic_byte(dev, Pw_Track_Flag);
587 if (priv->bResetInProgress) {
588 RT_TRACE(COMP_POWER_TRACKING,
589 "we are in silent reset progress, so return\n");
590 write_nic_byte(dev, Pw_Track_Flag, 0);
591 write_nic_byte(dev, FW_Busy_Flag, 0);
594 if (priv->rtllib->eRFPowerState != eRfOn) {
595 RT_TRACE(COMP_POWER_TRACKING,
596 "we are in power save, so return\n");
597 write_nic_byte(dev, Pw_Track_Flag, 0);
598 write_nic_byte(dev, FW_Busy_Flag, 0);
605 Avg_TSSI_Meas = read_nic_word(dev, Tssi_Mea_Value);
607 if (Avg_TSSI_Meas == 0) {
608 write_nic_byte(dev, Pw_Track_Flag, 0);
609 write_nic_byte(dev, FW_Busy_Flag, 0);
613 for (k = 0; k < 5; k++) {
615 tmp_report[k] = read_nic_byte(dev,
616 Tssi_Report_Value1+k);
618 tmp_report[k] = read_nic_byte(dev,
621 RT_TRACE(COMP_POWER_TRACKING,
622 "TSSI_report_value = %d\n",
625 if (tmp_report[k] <= 20) {
632 write_nic_byte(dev, Pw_Track_Flag, 0);
634 RT_TRACE(COMP_POWER_TRACKING, "we filted this data\n");
635 for (k = 0; k < 5; k++)
640 for (k = 0; k < 5; k++)
641 Avg_TSSI_Meas_from_driver += tmp_report[k];
643 Avg_TSSI_Meas_from_driver = Avg_TSSI_Meas_from_driver*100/5;
644 RT_TRACE(COMP_POWER_TRACKING,
645 "Avg_TSSI_Meas_from_driver = %d\n",
646 Avg_TSSI_Meas_from_driver);
647 TSSI_13dBm = priv->TSSI_13dBm;
648 RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n", TSSI_13dBm);
650 if (Avg_TSSI_Meas_from_driver > TSSI_13dBm)
651 delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
653 delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
655 if (delta <= E_FOR_TX_POWER_TRACK) {
656 priv->rtllib->bdynamic_txpower_enable = true;
657 write_nic_byte(dev, Pw_Track_Flag, 0);
658 write_nic_byte(dev, FW_Busy_Flag, 0);
659 RT_TRACE(COMP_POWER_TRACKING,
660 "tx power track is done\n");
661 RT_TRACE(COMP_POWER_TRACKING,
662 "priv->rfa_txpowertrackingindex = %d\n",
663 priv->rfa_txpowertrackingindex);
664 RT_TRACE(COMP_POWER_TRACKING,
665 "priv->rfa_txpowertrackingindex_real = %d\n",
666 priv->rfa_txpowertrackingindex_real);
667 RT_TRACE(COMP_POWER_TRACKING,
668 "priv->CCKPresentAttentuation_difference = %d\n",
669 priv->CCKPresentAttentuation_difference);
670 RT_TRACE(COMP_POWER_TRACKING,
671 "priv->CCKPresentAttentuation = %d\n",
672 priv->CCKPresentAttentuation);
675 if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK) {
676 if (RF_Type == RF_2T4R) {
678 if ((priv->rfa_txpowertrackingindex > 0) &&
679 (priv->rfc_txpowertrackingindex > 0)) {
680 priv->rfa_txpowertrackingindex--;
681 if (priv->rfa_txpowertrackingindex_real > 4) {
682 priv->rfa_txpowertrackingindex_real--;
683 rtl8192_setBBreg(dev,
684 rOFDM0_XATxIQImbalance,
686 dm_tx_bb_gain[priv->rfa_txpowertrackingindex_real]);
689 priv->rfc_txpowertrackingindex--;
690 if (priv->rfc_txpowertrackingindex_real > 4) {
691 priv->rfc_txpowertrackingindex_real--;
692 rtl8192_setBBreg(dev,
693 rOFDM0_XCTxIQImbalance,
695 dm_tx_bb_gain[priv->rfc_txpowertrackingindex_real]);
698 rtl8192_setBBreg(dev,
699 rOFDM0_XATxIQImbalance,
702 rtl8192_setBBreg(dev,
703 rOFDM0_XCTxIQImbalance,
704 bMaskDWord, dm_tx_bb_gain[4]);
707 if (priv->rfa_txpowertrackingindex > 0) {
708 priv->rfa_txpowertrackingindex--;
709 if (priv->rfa_txpowertrackingindex_real > 4) {
710 priv->rfa_txpowertrackingindex_real--;
711 rtl8192_setBBreg(dev,
712 rOFDM0_XATxIQImbalance,
714 dm_tx_bb_gain[priv->rfa_txpowertrackingindex_real]);
717 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance,
718 bMaskDWord, dm_tx_bb_gain[4]);
722 if (RF_Type == RF_2T4R) {
723 if ((priv->rfa_txpowertrackingindex <
724 TxBBGainTableLength - 1) &&
725 (priv->rfc_txpowertrackingindex <
726 TxBBGainTableLength - 1)) {
727 priv->rfa_txpowertrackingindex++;
728 priv->rfa_txpowertrackingindex_real++;
729 rtl8192_setBBreg(dev,
730 rOFDM0_XATxIQImbalance,
732 dm_tx_bb_gain[priv->rfa_txpowertrackingindex_real]);
733 priv->rfc_txpowertrackingindex++;
734 priv->rfc_txpowertrackingindex_real++;
735 rtl8192_setBBreg(dev,
736 rOFDM0_XCTxIQImbalance,
738 dm_tx_bb_gain[priv->rfc_txpowertrackingindex_real]);
740 rtl8192_setBBreg(dev,
741 rOFDM0_XATxIQImbalance,
743 dm_tx_bb_gain[TxBBGainTableLength - 1]);
744 rtl8192_setBBreg(dev,
745 rOFDM0_XCTxIQImbalance,
746 bMaskDWord, dm_tx_bb_gain[TxBBGainTableLength - 1]);
749 if (priv->rfa_txpowertrackingindex < (TxBBGainTableLength - 1)) {
750 priv->rfa_txpowertrackingindex++;
751 priv->rfa_txpowertrackingindex_real++;
752 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance,
754 dm_tx_bb_gain[priv->rfa_txpowertrackingindex_real]);
756 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance,
758 dm_tx_bb_gain[TxBBGainTableLength - 1]);
761 if (RF_Type == RF_2T4R) {
762 priv->CCKPresentAttentuation_difference
763 = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
765 priv->CCKPresentAttentuation_difference
766 = priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default;
769 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
770 priv->CCKPresentAttentuation =
771 priv->CCKPresentAttentuation_20Mdefault +
772 priv->CCKPresentAttentuation_difference;
774 priv->CCKPresentAttentuation =
775 priv->CCKPresentAttentuation_40Mdefault +
776 priv->CCKPresentAttentuation_difference;
778 if (priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
779 priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
780 if (priv->CCKPresentAttentuation < 0)
781 priv->CCKPresentAttentuation = 0;
783 if (priv->CCKPresentAttentuation > -1 &&
784 priv->CCKPresentAttentuation < CCKTxBBGainTableLength) {
785 if (priv->rtllib->current_network.channel == 14 &&
786 !priv->bcck_in_ch14) {
787 priv->bcck_in_ch14 = true;
788 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
789 } else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) {
790 priv->bcck_in_ch14 = false;
791 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
793 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
795 RT_TRACE(COMP_POWER_TRACKING,
796 "priv->rfa_txpowertrackingindex = %d\n",
797 priv->rfa_txpowertrackingindex);
798 RT_TRACE(COMP_POWER_TRACKING,
799 "priv->rfa_txpowertrackingindex_real = %d\n",
800 priv->rfa_txpowertrackingindex_real);
801 RT_TRACE(COMP_POWER_TRACKING,
802 "priv->CCKPresentAttentuation_difference = %d\n",
803 priv->CCKPresentAttentuation_difference);
804 RT_TRACE(COMP_POWER_TRACKING,
805 "priv->CCKPresentAttentuation = %d\n",
806 priv->CCKPresentAttentuation);
808 if (priv->CCKPresentAttentuation_difference <= -12 || priv->CCKPresentAttentuation_difference >= 24) {
809 priv->rtllib->bdynamic_txpower_enable = true;
810 write_nic_byte(dev, Pw_Track_Flag, 0);
811 write_nic_byte(dev, FW_Busy_Flag, 0);
812 RT_TRACE(COMP_POWER_TRACKING, "tx power track--->limited\n");
816 write_nic_byte(dev, Pw_Track_Flag, 0);
817 Avg_TSSI_Meas_from_driver = 0;
818 for (k = 0; k < 5; k++)
822 write_nic_byte(dev, FW_Busy_Flag, 0);
824 priv->rtllib->bdynamic_txpower_enable = true;
825 write_nic_byte(dev, Pw_Track_Flag, 0);
828 static void dm_TXPowerTrackingCallback_ThermalMeter(struct net_device *dev)
830 #define ThermalMeterVal 9
831 struct r8192_priv *priv = rtllib_priv(dev);
832 u32 tmpRegA, TempCCk;
833 u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
834 int i = 0, CCKSwingNeedUpdate = 0;
836 if (!priv->btxpower_trackingInit) {
837 tmpRegA = rtl8192_QueryBBReg(dev, rOFDM0_XATxIQImbalance, bMaskDWord);
838 for (i = 0; i < OFDM_Table_Length; i++) {
839 if (tmpRegA == OFDMSwingTable[i]) {
840 priv->OFDM_index[0] = (u8)i;
841 RT_TRACE(COMP_POWER_TRACKING, "Initial reg0x%x = 0x%x, OFDM_index = 0x%x\n",
842 rOFDM0_XATxIQImbalance, tmpRegA, priv->OFDM_index[0]);
846 TempCCk = rtl8192_QueryBBReg(dev, rCCK0_TxFilter1, bMaskByte2);
847 for (i = 0; i < CCK_Table_length; i++) {
848 if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
849 priv->CCK_index = (u8) i;
850 RT_TRACE(COMP_POWER_TRACKING,
851 "Initial reg0x%x = 0x%x, CCK_index = 0x%x\n",
852 rCCK0_TxFilter1, TempCCk,
857 priv->btxpower_trackingInit = true;
861 tmpRegA = rtl8192_phy_QueryRFReg(dev, RF90_PATH_A, 0x12, 0x078);
862 RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
863 if (tmpRegA < 3 || tmpRegA > 13)
867 RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
868 priv->ThermalMeter[0] = ThermalMeterVal;
869 priv->ThermalMeter[1] = ThermalMeterVal;
871 if (priv->ThermalMeter[0] >= (u8)tmpRegA) {
872 tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0] -
874 tmpCCK40Mindex = tmpCCK20Mindex - 6;
875 if (tmpOFDMindex >= OFDM_Table_Length)
876 tmpOFDMindex = OFDM_Table_Length-1;
877 if (tmpCCK20Mindex >= CCK_Table_length)
878 tmpCCK20Mindex = CCK_Table_length-1;
879 if (tmpCCK40Mindex >= CCK_Table_length)
880 tmpCCK40Mindex = CCK_Table_length-1;
882 tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
884 tmpOFDMindex = tmpCCK20Mindex = 0;
886 tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
889 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
890 tmpCCKindex = tmpCCK40Mindex;
892 tmpCCKindex = tmpCCK20Mindex;
894 priv->Record_CCK_20Mindex = tmpCCK20Mindex;
895 priv->Record_CCK_40Mindex = tmpCCK40Mindex;
896 RT_TRACE(COMP_POWER_TRACKING,
897 "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n",
898 priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
900 if (priv->rtllib->current_network.channel == 14 &&
901 !priv->bcck_in_ch14) {
902 priv->bcck_in_ch14 = true;
903 CCKSwingNeedUpdate = 1;
904 } else if (priv->rtllib->current_network.channel != 14 &&
905 priv->bcck_in_ch14) {
906 priv->bcck_in_ch14 = false;
907 CCKSwingNeedUpdate = 1;
910 if (priv->CCK_index != tmpCCKindex) {
911 priv->CCK_index = tmpCCKindex;
912 CCKSwingNeedUpdate = 1;
915 if (CCKSwingNeedUpdate)
916 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
917 if (priv->OFDM_index[0] != tmpOFDMindex) {
918 priv->OFDM_index[0] = tmpOFDMindex;
919 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
920 OFDMSwingTable[priv->OFDM_index[0]]);
921 RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
923 OFDMSwingTable[priv->OFDM_index[0]]);
925 priv->txpower_count = 0;
928 void dm_txpower_trackingcallback(void *data)
930 struct r8192_priv *priv = container_of_dwork_rsl(data,
931 struct r8192_priv, txpower_tracking_wq);
932 struct net_device *dev = priv->rtllib->dev;
934 if (priv->IC_Cut >= IC_VersionCut_D)
935 dm_TXPowerTrackingCallback_TSSI(dev);
937 dm_TXPowerTrackingCallback_ThermalMeter(dev);
940 static void dm_InitializeTXPowerTracking_TSSI(struct net_device *dev)
943 struct r8192_priv *priv = rtllib_priv(dev);
944 priv->btxpower_tracking = true;
945 priv->txpower_count = 0;
946 priv->btxpower_trackingInit = false;
950 static void dm_InitializeTXPowerTracking_ThermalMeter(struct net_device *dev)
952 struct r8192_priv *priv = rtllib_priv(dev);
955 if (priv->rtllib->FwRWRF)
956 priv->btxpower_tracking = true;
958 priv->btxpower_tracking = false;
959 priv->txpower_count = 0;
960 priv->btxpower_trackingInit = false;
961 RT_TRACE(COMP_POWER_TRACKING, "pMgntInfo->bTXPowerTracking = %d\n",
962 priv->btxpower_tracking);
965 void dm_initialize_txpower_tracking(struct net_device *dev)
967 struct r8192_priv *priv = rtllib_priv(dev);
969 if (priv->IC_Cut >= IC_VersionCut_D)
970 dm_InitializeTXPowerTracking_TSSI(dev);
972 dm_InitializeTXPowerTracking_ThermalMeter(dev);
975 static void dm_CheckTXPowerTracking_TSSI(struct net_device *dev)
977 struct r8192_priv *priv = rtllib_priv(dev);
978 static u32 tx_power_track_counter;
980 RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__);
981 if (read_nic_byte(dev, 0x11e) == 1)
983 if (!priv->btxpower_tracking)
985 tx_power_track_counter++;
988 if (tx_power_track_counter >= 180) {
989 queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0);
990 tx_power_track_counter = 0;
994 static void dm_CheckTXPowerTracking_ThermalMeter(struct net_device *dev)
996 struct r8192_priv *priv = rtllib_priv(dev);
997 static u8 TM_Trigger;
998 u8 TxPowerCheckCnt = 0;
1000 if (IS_HARDWARE_TYPE_8192SE(dev))
1001 TxPowerCheckCnt = 5;
1003 TxPowerCheckCnt = 2;
1004 if (!priv->btxpower_tracking)
1007 if (priv->txpower_count <= TxPowerCheckCnt) {
1008 priv->txpower_count++;
1014 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1015 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1016 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1017 rtl8192_phy_SetRFReg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1022 netdev_info(dev, "===============>Schedule TxPowerTrackingWorkItem\n");
1023 queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1028 static void dm_check_txpower_tracking(struct net_device *dev)
1030 struct r8192_priv *priv = rtllib_priv(dev);
1032 if (priv->IC_Cut >= IC_VersionCut_D)
1033 dm_CheckTXPowerTracking_TSSI(dev);
1035 dm_CheckTXPowerTracking_ThermalMeter(dev);
1038 static void dm_CCKTxPowerAdjust_TSSI(struct net_device *dev, bool bInCH14)
1041 struct r8192_priv *priv = rtllib_priv(dev);
1042 u8 attenuation = (u8)priv->CCKPresentAttentuation;
1046 TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][0] +
1047 (dm_cck_tx_bb_gain[attenuation][1] << 8));
1049 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1050 TempVal = (u32)((dm_cck_tx_bb_gain[attenuation][2]) +
1051 (dm_cck_tx_bb_gain[attenuation][3] << 8) +
1052 (dm_cck_tx_bb_gain[attenuation][4] << 16)+
1053 (dm_cck_tx_bb_gain[attenuation][5] << 24));
1054 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1055 TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][6] +
1056 (dm_cck_tx_bb_gain[attenuation][7] << 8));
1058 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1060 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][0]) +
1061 (dm_cck_tx_bb_gain_ch14[attenuation][1] << 8));
1063 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1064 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][2]) +
1065 (dm_cck_tx_bb_gain_ch14[attenuation][3] << 8) +
1066 (dm_cck_tx_bb_gain_ch14[attenuation][4] << 16)+
1067 (dm_cck_tx_bb_gain_ch14[attenuation][5] << 24));
1068 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1069 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][6]) +
1070 (dm_cck_tx_bb_gain_ch14[attenuation][7] << 8));
1072 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1076 static void dm_CCKTxPowerAdjust_ThermalMeter(struct net_device *dev, bool bInCH14)
1079 struct r8192_priv *priv = rtllib_priv(dev);
1083 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1084 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1]<<8);
1085 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1086 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1087 rCCK0_TxFilter1, TempVal);
1088 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1089 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3]<<8) +
1090 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4]<<16)+
1091 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5]<<24);
1092 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1093 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1094 rCCK0_TxFilter2, TempVal);
1095 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1096 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7]<<8);
1098 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1099 RT_TRACE(COMP_POWER_TRACKING, "CCK not chnl 14, reg 0x%x = 0x%x\n",
1100 rCCK0_DebugPort, TempVal);
1102 TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] +
1103 (CCKSwingTable_Ch14[priv->CCK_index][1]<<8);
1105 rtl8192_setBBreg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1106 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1107 rCCK0_TxFilter1, TempVal);
1108 TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] +
1109 (CCKSwingTable_Ch14[priv->CCK_index][3]<<8) +
1110 (CCKSwingTable_Ch14[priv->CCK_index][4]<<16)+
1111 (CCKSwingTable_Ch14[priv->CCK_index][5]<<24);
1112 rtl8192_setBBreg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1113 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1114 rCCK0_TxFilter2, TempVal);
1115 TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] +
1116 (CCKSwingTable_Ch14[priv->CCK_index][7]<<8);
1118 rtl8192_setBBreg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1119 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1120 rCCK0_DebugPort, TempVal);
1124 void dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
1126 struct r8192_priv *priv = rtllib_priv(dev);
1128 if (priv->IC_Cut >= IC_VersionCut_D)
1129 dm_CCKTxPowerAdjust_TSSI(dev, binch14);
1131 dm_CCKTxPowerAdjust_ThermalMeter(dev, binch14);
1134 static void dm_txpower_reset_recovery(struct net_device *dev)
1136 struct r8192_priv *priv = rtllib_priv(dev);
1138 RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1139 rtl8192_setBBreg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
1140 dm_tx_bb_gain[priv->rfa_txpowertrackingindex]);
1141 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",
1142 dm_tx_bb_gain[priv->rfa_txpowertrackingindex]);
1143 RT_TRACE(COMP_POWER_TRACKING,
1144 "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",
1145 priv->rfa_txpowertrackingindex);
1146 RT_TRACE(COMP_POWER_TRACKING,
1147 "Reset Recovery : RF A I/Q Amplify Gain is %d\n",
1148 dm_tx_bb_gain_idx_to_amplify(priv->rfa_txpowertrackingindex));
1149 RT_TRACE(COMP_POWER_TRACKING,
1150 "Reset Recovery: CCK Attenuation is %d dB\n",
1151 priv->CCKPresentAttentuation);
1152 dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1154 rtl8192_setBBreg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord,
1155 dm_tx_bb_gain[priv->rfc_txpowertrackingindex]);
1156 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",
1157 dm_tx_bb_gain[priv->rfc_txpowertrackingindex]);
1158 RT_TRACE(COMP_POWER_TRACKING,
1159 "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",
1160 priv->rfc_txpowertrackingindex);
1161 RT_TRACE(COMP_POWER_TRACKING,
1162 "Reset Recovery : RF C I/Q Amplify Gain is %d\n",
1163 dm_tx_bb_gain_idx_to_amplify(priv->rfc_txpowertrackingindex));
1166 void dm_restore_dynamic_mechanism_state(struct net_device *dev)
1168 struct r8192_priv *priv = rtllib_priv(dev);
1169 u32 reg_ratr = priv->rate_adaptive.last_ratr;
1173 RT_TRACE(COMP_RATE, "<---- dm_restore_dynamic_mechanism_state(): driver is going to unload\n");
1177 if (priv->rate_adaptive.rate_adaptive_disabled)
1179 if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
1180 priv->rtllib->mode == WIRELESS_MODE_N_5G))
1182 ratr_value = reg_ratr;
1183 if (priv->rf_type == RF_1T2R)
1184 ratr_value &= ~(RATE_ALL_OFDM_2SS);
1185 write_nic_dword(dev, RATR0, ratr_value);
1186 write_nic_byte(dev, UFWP, 1);
1187 if (priv->btxpower_trackingInit && priv->btxpower_tracking)
1188 dm_txpower_reset_recovery(dev);
1190 dm_bb_initialgain_restore(dev);
1194 static void dm_bb_initialgain_restore(struct net_device *dev)
1196 struct r8192_priv *priv = rtllib_priv(dev);
1197 u32 bit_mask = 0x7f;
1199 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1202 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1203 rtl8192_setBBreg(dev, rOFDM0_XAAGCCore1, bit_mask, (u32)priv->initgain_backup.xaagccore1);
1204 rtl8192_setBBreg(dev, rOFDM0_XBAGCCore1, bit_mask, (u32)priv->initgain_backup.xbagccore1);
1205 rtl8192_setBBreg(dev, rOFDM0_XCAGCCore1, bit_mask, (u32)priv->initgain_backup.xcagccore1);
1206 rtl8192_setBBreg(dev, rOFDM0_XDAGCCore1, bit_mask, (u32)priv->initgain_backup.xdagccore1);
1207 bit_mask = bMaskByte2;
1208 rtl8192_setBBreg(dev, rCCK0_CCA, bit_mask, (u32)priv->initgain_backup.cca);
1210 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1211 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1212 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1213 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1214 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n", priv->initgain_backup.cca);
1215 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1220 void dm_backup_dynamic_mechanism_state(struct net_device *dev)
1222 struct r8192_priv *priv = rtllib_priv(dev);
1224 priv->bswitch_fsync = false;
1225 priv->bfsync_processing = false;
1226 dm_bb_initialgain_backup(dev);
1231 static void dm_bb_initialgain_backup(struct net_device *dev)
1233 struct r8192_priv *priv = rtllib_priv(dev);
1234 u32 bit_mask = bMaskByte0;
1236 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1239 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1240 priv->initgain_backup.xaagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XAAGCCore1, bit_mask);
1241 priv->initgain_backup.xbagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XBAGCCore1, bit_mask);
1242 priv->initgain_backup.xcagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XCAGCCore1, bit_mask);
1243 priv->initgain_backup.xdagccore1 = (u8)rtl8192_QueryBBReg(dev, rOFDM0_XDAGCCore1, bit_mask);
1244 bit_mask = bMaskByte2;
1245 priv->initgain_backup.cca = (u8)rtl8192_QueryBBReg(dev, rCCK0_CCA, bit_mask);
1247 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n", priv->initgain_backup.xaagccore1);
1248 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n", priv->initgain_backup.xbagccore1);
1249 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n", priv->initgain_backup.xcagccore1);
1250 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n", priv->initgain_backup.xdagccore1);
1251 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n", priv->initgain_backup.cca);
1255 void dm_change_dynamic_initgain_thresh(struct net_device *dev,
1256 u32 dm_type, u32 dm_value)
1258 if (dm_type == DIG_TYPE_THRESH_HIGH) {
1259 dm_digtable.rssi_high_thresh = dm_value;
1260 } else if (dm_type == DIG_TYPE_THRESH_LOW) {
1261 dm_digtable.rssi_low_thresh = dm_value;
1262 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_HIGH) {
1263 dm_digtable.rssi_high_power_highthresh = dm_value;
1264 } else if (dm_type == DIG_TYPE_THRESH_HIGHPWR_LOW) {
1265 dm_digtable.rssi_high_power_lowthresh = dm_value;
1266 } else if (dm_type == DIG_TYPE_ENABLE) {
1267 dm_digtable.dig_state = DM_STA_DIG_MAX;
1268 dm_digtable.dig_enable_flag = true;
1269 } else if (dm_type == DIG_TYPE_DISABLE) {
1270 dm_digtable.dig_state = DM_STA_DIG_MAX;
1271 dm_digtable.dig_enable_flag = false;
1272 } else if (dm_type == DIG_TYPE_DBG_MODE) {
1273 if (dm_value >= DM_DBG_MAX)
1274 dm_value = DM_DBG_OFF;
1275 dm_digtable.dbg_mode = (u8)dm_value;
1276 } else if (dm_type == DIG_TYPE_RSSI) {
1279 dm_digtable.rssi_val = (long)dm_value;
1280 } else if (dm_type == DIG_TYPE_ALGORITHM) {
1281 if (dm_value >= DIG_ALGO_MAX)
1282 dm_value = DIG_ALGO_BY_FALSE_ALARM;
1283 if (dm_digtable.dig_algorithm != (u8)dm_value)
1284 dm_digtable.dig_algorithm_switch = 1;
1285 dm_digtable.dig_algorithm = (u8)dm_value;
1286 } else if (dm_type == DIG_TYPE_BACKOFF) {
1289 dm_digtable.backoff_val = (u8)dm_value;
1290 } else if (dm_type == DIG_TYPE_RX_GAIN_MIN) {
1293 dm_digtable.rx_gain_range_min = (u8)dm_value;
1294 } else if (dm_type == DIG_TYPE_RX_GAIN_MAX) {
1295 if (dm_value > 0x50)
1297 dm_digtable.rx_gain_range_max = (u8)dm_value;
1301 static void dm_dig_init(struct net_device *dev)
1303 struct r8192_priv *priv = rtllib_priv(dev);
1305 dm_digtable.dig_enable_flag = true;
1306 dm_digtable.Backoff_Enable_Flag = true;
1308 dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1310 dm_digtable.Dig_TwoPort_Algorithm = DIG_TWO_PORT_ALGO_RSSI;
1311 dm_digtable.Dig_Ext_Port_Stage = DIG_EXT_PORT_STAGE_MAX;
1312 dm_digtable.dbg_mode = DM_DBG_OFF;
1313 dm_digtable.dig_algorithm_switch = 0;
1315 dm_digtable.dig_state = DM_STA_DIG_MAX;
1316 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1317 dm_digtable.CurSTAConnectState = dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT;
1318 dm_digtable.CurAPConnectState = dm_digtable.PreAPConnectState = DIG_AP_DISCONNECT;
1319 dm_digtable.initialgain_lowerbound_state = false;
1321 dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW;
1322 dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH;
1324 dm_digtable.FALowThresh = DM_FALSEALARM_THRESH_LOW;
1325 dm_digtable.FAHighThresh = DM_FALSEALARM_THRESH_HIGH;
1327 dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1328 dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1330 dm_digtable.rssi_val = 50;
1331 dm_digtable.backoff_val = DM_DIG_BACKOFF;
1332 dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1333 if (priv->CustomerID == RT_CID_819x_Netcore)
1334 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1336 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1338 dm_digtable.BackoffVal_range_max = DM_DIG_BACKOFF_MAX;
1339 dm_digtable.BackoffVal_range_min = DM_DIG_BACKOFF_MIN;
1342 static void dm_ctrl_initgain_byrssi(struct net_device *dev)
1345 if (dm_digtable.dig_enable_flag == false)
1348 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1349 dm_ctrl_initgain_byrssi_by_fwfalse_alarm(dev);
1350 else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1351 dm_ctrl_initgain_byrssi_by_driverrssi(dev);
1356 /*-----------------------------------------------------------------------------
1357 * Function: dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm()
1359 * Overview: Driver monitor RSSI and False Alarm to change initial gain.
1360 Only change initial gain during link in progress.
1362 * Input: IN PADAPTER pAdapter
1370 * 03/04/2009 hpfan Create Version 0.
1372 *---------------------------------------------------------------------------*/
1374 static void dm_ctrl_initgain_byrssi_by_driverrssi(
1375 struct net_device *dev)
1377 struct r8192_priv *priv = rtllib_priv(dev);
1381 if (dm_digtable.dig_enable_flag == false)
1384 if (dm_digtable.dig_algorithm_switch)
1387 for (i = 0; i < 3; i++)
1388 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1390 dm_digtable.dig_state = DM_STA_DIG_OFF;
1393 if (priv->rtllib->state == RTLLIB_LINKED)
1394 dm_digtable.CurSTAConnectState = DIG_STA_CONNECT;
1396 dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT;
1399 if (dm_digtable.dbg_mode == DM_DBG_OFF)
1400 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1401 dm_initial_gain(dev);
1404 if (dm_digtable.dig_algorithm_switch)
1405 dm_digtable.dig_algorithm_switch = 0;
1406 dm_digtable.PreSTAConnectState = dm_digtable.CurSTAConnectState;
1410 static void dm_ctrl_initgain_byrssi_by_fwfalse_alarm(
1411 struct net_device *dev)
1413 struct r8192_priv *priv = rtllib_priv(dev);
1414 static u32 reset_cnt;
1417 if (dm_digtable.dig_enable_flag == false)
1420 if (dm_digtable.dig_algorithm_switch) {
1421 dm_digtable.dig_state = DM_STA_DIG_MAX;
1422 for (i = 0; i < 3; i++)
1423 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1424 dm_digtable.dig_algorithm_switch = 0;
1427 if (priv->rtllib->state != RTLLIB_LINKED)
1430 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1431 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1433 if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
1434 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1435 (priv->reset_count == reset_cnt))
1437 reset_cnt = priv->reset_count;
1439 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1440 dm_digtable.dig_state = DM_STA_DIG_OFF;
1442 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x8);
1444 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x17);
1445 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x17);
1446 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x17);
1447 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x17);
1449 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1450 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
1452 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1454 write_nic_byte(dev, 0xa0a, 0x08);
1459 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1462 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1463 (priv->reset_count == reset_cnt)) {
1464 dm_ctrl_initgain_byrssi_highpwr(dev);
1467 if (priv->reset_count != reset_cnt)
1470 reset_cnt = priv->reset_count;
1472 dm_digtable.dig_state = DM_STA_DIG_ON;
1474 if (reset_flag == 1) {
1475 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x2c);
1476 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x2c);
1477 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x2c);
1478 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x2c);
1480 write_nic_byte(dev, rOFDM0_XAAGCCore1, 0x20);
1481 write_nic_byte(dev, rOFDM0_XBAGCCore1, 0x20);
1482 write_nic_byte(dev, rOFDM0_XCAGCCore1, 0x20);
1483 write_nic_byte(dev, rOFDM0_XDAGCCore1, 0x20);
1486 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1487 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1489 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1491 write_nic_byte(dev, 0xa0a, 0xcd);
1493 rtl8192_setBBreg(dev, UFWP, bMaskByte1, 0x1);
1495 dm_ctrl_initgain_byrssi_highpwr(dev);
1499 static void dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev)
1501 struct r8192_priv *priv = rtllib_priv(dev);
1502 static u32 reset_cnt_highpwr;
1504 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_high_power_lowthresh) &&
1505 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_highthresh))
1508 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_power_highthresh) {
1509 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1510 (priv->reset_count == reset_cnt_highpwr))
1512 dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1514 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1515 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
1517 write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
1519 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
1520 (priv->reset_count == reset_cnt_highpwr))
1522 dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1524 if (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_power_lowthresh &&
1525 priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1526 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1527 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1529 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1532 reset_cnt_highpwr = priv->reset_count;
1535 static void dm_initial_gain(struct net_device *dev)
1537 struct r8192_priv *priv = rtllib_priv(dev);
1538 u8 initial_gain = 0;
1539 static u8 initialized, force_write;
1540 static u32 reset_cnt;
1542 if (dm_digtable.dig_algorithm_switch) {
1547 if (rtllib_act_scanning(priv->rtllib, true) == true) {
1552 if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1553 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1554 if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) > dm_digtable.rx_gain_range_max)
1555 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_max;
1556 else if ((dm_digtable.rssi_val+10-dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
1557 dm_digtable.cur_ig_value = dm_digtable.rx_gain_range_min;
1559 dm_digtable.cur_ig_value = dm_digtable.rssi_val+10-dm_digtable.backoff_val;
1561 if (dm_digtable.cur_ig_value == 0)
1562 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1564 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1567 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1568 dm_digtable.pre_ig_value = 0;
1571 if (priv->reset_count != reset_cnt) {
1573 reset_cnt = priv->reset_count;
1576 if (dm_digtable.pre_ig_value != read_nic_byte(dev, rOFDM0_XAAGCCore1))
1579 if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1580 || !initialized || force_write) {
1581 initial_gain = (u8)dm_digtable.cur_ig_value;
1582 write_nic_byte(dev, rOFDM0_XAAGCCore1, initial_gain);
1583 write_nic_byte(dev, rOFDM0_XBAGCCore1, initial_gain);
1584 write_nic_byte(dev, rOFDM0_XCAGCCore1, initial_gain);
1585 write_nic_byte(dev, rOFDM0_XDAGCCore1, initial_gain);
1586 dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1592 static void dm_pd_th(struct net_device *dev)
1594 struct r8192_priv *priv = rtllib_priv(dev);
1595 static u8 initialized, force_write;
1596 static u32 reset_cnt;
1598 if (dm_digtable.dig_algorithm_switch) {
1603 if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1604 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1605 if (dm_digtable.rssi_val >= dm_digtable.rssi_high_power_highthresh)
1606 dm_digtable.curpd_thstate = DIG_PD_AT_HIGH_POWER;
1607 else if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
1608 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1609 else if ((dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh) &&
1610 (dm_digtable.rssi_val < dm_digtable.rssi_high_power_lowthresh))
1611 dm_digtable.curpd_thstate = DIG_PD_AT_NORMAL_POWER;
1613 dm_digtable.curpd_thstate = dm_digtable.prepd_thstate;
1615 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1618 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1621 if (priv->reset_count != reset_cnt) {
1623 reset_cnt = priv->reset_count;
1626 if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
1627 (initialized <= 3) || force_write) {
1628 if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
1629 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1630 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x00);
1632 write_nic_byte(dev, rOFDM0_RxDetector1, 0x42);
1633 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_NORMAL_POWER) {
1634 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1635 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x20);
1637 write_nic_byte(dev, rOFDM0_RxDetector1, 0x44);
1638 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
1639 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1640 write_nic_byte(dev, (rOFDM0_XATxAFE+3), 0x10);
1642 write_nic_byte(dev, rOFDM0_RxDetector1, 0x43);
1644 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
1645 if (initialized <= 3)
1651 static void dm_cs_ratio(struct net_device *dev)
1653 struct r8192_priv *priv = rtllib_priv(dev);
1654 static u8 initialized, force_write;
1655 static u32 reset_cnt;
1657 if (dm_digtable.dig_algorithm_switch) {
1662 if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1663 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1664 if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
1665 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1666 else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
1667 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
1669 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
1671 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1674 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1677 if (priv->reset_count != reset_cnt) {
1679 reset_cnt = priv->reset_count;
1683 if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
1684 !initialized || force_write) {
1685 if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
1686 write_nic_byte(dev, 0xa0a, 0x08);
1687 else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
1688 write_nic_byte(dev, 0xa0a, 0xcd);
1689 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
1695 void dm_init_edca_turbo(struct net_device *dev)
1697 struct r8192_priv *priv = rtllib_priv(dev);
1699 priv->bcurrent_turbo_EDCA = false;
1700 priv->rtllib->bis_any_nonbepkts = false;
1701 priv->bis_cur_rdlstate = false;
1704 static void dm_check_edca_turbo(struct net_device *dev)
1706 struct r8192_priv *priv = rtllib_priv(dev);
1707 struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1709 static unsigned long lastTxOkCnt;
1710 static unsigned long lastRxOkCnt;
1711 unsigned long curTxOkCnt = 0;
1712 unsigned long curRxOkCnt = 0;
1714 if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
1715 goto dm_CheckEdcaTurbo_EXIT;
1716 if (priv->rtllib->state != RTLLIB_LINKED)
1717 goto dm_CheckEdcaTurbo_EXIT;
1718 if (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
1719 goto dm_CheckEdcaTurbo_EXIT;
1722 u8 *peername[11] = {
1723 "unknown", "realtek_90", "realtek_92se", "broadcom",
1724 "ralink", "atheros", "cisco", "marvell", "92u_softap",
1731 "%s():iot peer is %s, bssid: %pM\n",
1732 __func__, peername[pHTInfo->IOTPeer],
1733 priv->rtllib->current_network.bssid);
1737 if (!priv->rtllib->bis_any_nonbepkts) {
1738 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1739 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1740 if (pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX) {
1741 if (curTxOkCnt > 4*curRxOkCnt) {
1742 if (priv->bis_cur_rdlstate ||
1743 !priv->bcurrent_turbo_EDCA) {
1744 write_nic_dword(dev, EDCAPARA_BE,
1745 edca_setting_UL[pHTInfo->IOTPeer]);
1746 priv->bis_cur_rdlstate = false;
1749 if (!priv->bis_cur_rdlstate ||
1750 !priv->bcurrent_turbo_EDCA) {
1751 if (priv->rtllib->mode == WIRELESS_MODE_G)
1752 write_nic_dword(dev, EDCAPARA_BE,
1753 edca_setting_DL_GMode[pHTInfo->IOTPeer]);
1755 write_nic_dword(dev, EDCAPARA_BE,
1756 edca_setting_DL[pHTInfo->IOTPeer]);
1757 priv->bis_cur_rdlstate = true;
1760 priv->bcurrent_turbo_EDCA = true;
1762 if (curRxOkCnt > 4*curTxOkCnt) {
1763 if (!priv->bis_cur_rdlstate || !priv->bcurrent_turbo_EDCA) {
1764 if (priv->rtllib->mode == WIRELESS_MODE_G)
1765 write_nic_dword(dev, EDCAPARA_BE,
1766 edca_setting_DL_GMode[pHTInfo->IOTPeer]);
1768 write_nic_dword(dev, EDCAPARA_BE,
1769 edca_setting_DL[pHTInfo->IOTPeer]);
1770 priv->bis_cur_rdlstate = true;
1773 if (priv->bis_cur_rdlstate ||
1774 !priv->bcurrent_turbo_EDCA) {
1775 write_nic_dword(dev, EDCAPARA_BE,
1776 edca_setting_UL[pHTInfo->IOTPeer]);
1777 priv->bis_cur_rdlstate = false;
1782 priv->bcurrent_turbo_EDCA = true;
1785 if (priv->bcurrent_turbo_EDCA) {
1788 priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM, (u8 *)(&tmp));
1789 priv->bcurrent_turbo_EDCA = false;
1794 dm_CheckEdcaTurbo_EXIT:
1795 priv->rtllib->bis_any_nonbepkts = false;
1796 lastTxOkCnt = priv->stats.txbytesunicast;
1797 lastRxOkCnt = priv->stats.rxbytesunicast;
1800 static void dm_init_ctstoself(struct net_device *dev)
1802 struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1804 priv->rtllib->bCTSToSelfEnable = true;
1805 priv->rtllib->CTSToSelfTH = CTSToSelfTHVal;
1808 static void dm_ctstoself(struct net_device *dev)
1810 struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1811 struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1812 static unsigned long lastTxOkCnt;
1813 static unsigned long lastRxOkCnt;
1814 unsigned long curTxOkCnt = 0;
1815 unsigned long curRxOkCnt = 0;
1817 if (priv->rtllib->bCTSToSelfEnable != true) {
1818 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1821 if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
1822 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1823 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1824 if (curRxOkCnt > 4*curTxOkCnt)
1825 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1827 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
1829 lastTxOkCnt = priv->stats.txbytesunicast;
1830 lastRxOkCnt = priv->stats.rxbytesunicast;
1835 static void dm_Init_WA_Broadcom_IOT(struct net_device *dev)
1837 struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1838 struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1840 pHTInfo->bWAIotBroadcom = false;
1841 pHTInfo->WAIotTH = WAIotTHVal;
1844 static void dm_check_pbc_gpio(struct net_device *dev)
1848 void dm_CheckRfCtrlGPIO(void *data)
1850 struct r8192_priv *priv = container_of_dwork_rsl(data,
1851 struct r8192_priv, gpio_change_rf_wq);
1852 struct net_device *dev = priv->rtllib->dev;
1854 enum rt_rf_power_state eRfPowerStateToSet;
1855 bool bActuallySet = false;
1857 static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
1858 static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin", NULL};
1860 bActuallySet = false;
1862 if ((priv->up_first_time == 1) || (priv->being_init_adapter))
1865 if (priv->bfirst_after_down) {
1866 priv->bfirst_after_down = true;
1870 tmp1byte = read_nic_byte(dev, GPI);
1872 eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff;
1874 if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
1875 RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n");
1876 netdev_info(dev, "gpiochangeRF - HW Radio ON\n");
1877 priv->bHwRadioOff = false;
1878 bActuallySet = true;
1879 } else if (!priv->bHwRadioOff && (eRfPowerStateToSet == eRfOff)) {
1880 RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n");
1881 netdev_info(dev, "gpiochangeRF - HW Radio OFF\n");
1882 priv->bHwRadioOff = true;
1883 bActuallySet = true;
1888 priv->bHwRfOffAction = 1;
1889 MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW, true);
1890 if (priv->bHwRadioOff)
1895 argv[0] = RadioPowerPath;
1897 call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
1901 void dm_rf_pathcheck_workitemcallback(void *data)
1903 struct r8192_priv *priv = container_of_dwork_rsl(data,
1906 struct net_device *dev = priv->rtllib->dev;
1909 rfpath = read_nic_byte(dev, 0xc04);
1911 for (i = 0; i < RF90_PATH_MAX; i++) {
1912 if (rfpath & (0x01<<i))
1913 priv->brfpath_rxenable[i] = true;
1915 priv->brfpath_rxenable[i] = false;
1917 if (!DM_RxPathSelTable.Enable)
1920 dm_rxpath_sel_byrssi(dev);
1923 static void dm_init_rxpath_selection(struct net_device *dev)
1926 struct r8192_priv *priv = rtllib_priv(dev);
1928 DM_RxPathSelTable.Enable = 1;
1929 DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
1930 DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
1931 if (priv->CustomerID == RT_CID_819x_Netcore)
1932 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1934 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
1935 DM_RxPathSelTable.DbgMode = DM_DBG_OFF;
1936 DM_RxPathSelTable.disabledRF = 0;
1937 for (i = 0; i < 4; i++) {
1938 DM_RxPathSelTable.rf_rssi[i] = 50;
1939 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
1940 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
1944 #define PWDB_IN_RANGE ((cur_cck_pwdb < tmp_cck_max_pwdb) && \
1945 (cur_cck_pwdb > tmp_cck_sec_pwdb))
1947 static void dm_rxpath_sel_byrssi(struct net_device *dev)
1949 struct r8192_priv *priv = rtllib_priv(dev);
1950 u8 i, max_rssi_index = 0, min_rssi_index = 0;
1951 u8 sec_rssi_index = 0, rf_num = 0;
1952 u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
1953 u8 cck_default_Rx = 0x2;
1954 u8 cck_optional_Rx = 0x3;
1955 long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
1956 u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0;
1957 u8 cck_rx_ver2_sec_index = 0;
1960 static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
1961 u8 update_cck_rx_path;
1963 if (priv->rf_type != RF_2T4R)
1966 if (!cck_Rx_Path_initialized) {
1967 DM_RxPathSelTable.cck_Rx_path = (read_nic_byte(dev, 0xa07)&0xf);
1968 cck_Rx_Path_initialized = 1;
1971 DM_RxPathSelTable.disabledRF = 0xf;
1972 DM_RxPathSelTable.disabledRF &= ~(read_nic_byte(dev, 0xc04));
1974 if (priv->rtllib->mode == WIRELESS_MODE_B)
1975 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1977 for (i = 0; i < RF90_PATH_MAX; i++) {
1978 if (!DM_RxPathSelTable.DbgMode)
1979 DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
1981 if (priv->brfpath_rxenable[i]) {
1983 cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
1986 max_rssi_index = min_rssi_index = sec_rssi_index = i;
1987 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
1988 } else if (rf_num == 2) {
1989 if (cur_rf_rssi >= tmp_max_rssi) {
1990 tmp_max_rssi = cur_rf_rssi;
1993 tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
1994 sec_rssi_index = min_rssi_index = i;
1997 if (cur_rf_rssi > tmp_max_rssi) {
1998 tmp_sec_rssi = tmp_max_rssi;
1999 sec_rssi_index = max_rssi_index;
2000 tmp_max_rssi = cur_rf_rssi;
2002 } else if (cur_rf_rssi == tmp_max_rssi) {
2003 tmp_sec_rssi = cur_rf_rssi;
2005 } else if ((cur_rf_rssi < tmp_max_rssi) &&
2006 (cur_rf_rssi > tmp_sec_rssi)) {
2007 tmp_sec_rssi = cur_rf_rssi;
2009 } else if (cur_rf_rssi == tmp_sec_rssi) {
2010 if (tmp_sec_rssi == tmp_min_rssi) {
2011 tmp_sec_rssi = cur_rf_rssi;
2014 } else if ((cur_rf_rssi < tmp_sec_rssi) &&
2015 (cur_rf_rssi > tmp_min_rssi)) {
2017 } else if (cur_rf_rssi == tmp_min_rssi) {
2018 if (tmp_sec_rssi == tmp_min_rssi) {
2019 tmp_min_rssi = cur_rf_rssi;
2022 } else if (cur_rf_rssi < tmp_min_rssi) {
2023 tmp_min_rssi = cur_rf_rssi;
2031 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2032 for (i = 0; i < RF90_PATH_MAX; i++) {
2033 if (priv->brfpath_rxenable[i]) {
2036 DM_RxPathSelTable.cck_pwdb_sta[i];
2039 cck_rx_ver2_max_index = i;
2040 cck_rx_ver2_min_index = i;
2041 cck_rx_ver2_sec_index = i;
2042 tmp_cck_max_pwdb = cur_cck_pwdb;
2043 tmp_cck_min_pwdb = cur_cck_pwdb;
2044 tmp_cck_sec_pwdb = cur_cck_pwdb;
2045 } else if (rf_num == 2) {
2046 if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
2047 tmp_cck_max_pwdb = cur_cck_pwdb;
2048 cck_rx_ver2_max_index = i;
2050 tmp_cck_sec_pwdb = cur_cck_pwdb;
2051 tmp_cck_min_pwdb = cur_cck_pwdb;
2052 cck_rx_ver2_sec_index = i;
2053 cck_rx_ver2_min_index = i;
2056 if (cur_cck_pwdb > tmp_cck_max_pwdb) {
2059 cck_rx_ver2_sec_index =
2060 cck_rx_ver2_max_index;
2061 tmp_cck_max_pwdb = cur_cck_pwdb;
2062 cck_rx_ver2_max_index = i;
2063 } else if (cur_cck_pwdb ==
2065 tmp_cck_sec_pwdb = cur_cck_pwdb;
2066 cck_rx_ver2_sec_index = i;
2067 } else if (PWDB_IN_RANGE) {
2068 tmp_cck_sec_pwdb = cur_cck_pwdb;
2069 cck_rx_ver2_sec_index = i;
2070 } else if (cur_cck_pwdb ==
2072 if (tmp_cck_sec_pwdb ==
2076 cck_rx_ver2_sec_index =
2079 } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) &&
2080 (cur_cck_pwdb > tmp_cck_min_pwdb)) {
2082 } else if (cur_cck_pwdb == tmp_cck_min_pwdb) {
2083 if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2084 tmp_cck_min_pwdb = cur_cck_pwdb;
2085 cck_rx_ver2_min_index = i;
2087 } else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
2088 tmp_cck_min_pwdb = cur_cck_pwdb;
2089 cck_rx_ver2_min_index = i;
2097 update_cck_rx_path = 0;
2098 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2099 cck_default_Rx = cck_rx_ver2_max_index;
2100 cck_optional_Rx = cck_rx_ver2_sec_index;
2101 if (tmp_cck_max_pwdb != -64)
2102 update_cck_rx_path = 1;
2105 if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) {
2106 if ((tmp_max_rssi - tmp_min_rssi) >=
2107 DM_RxPathSelTable.diff_TH) {
2108 DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] =
2110 rtl8192_setBBreg(dev, rOFDM0_TRxPathEnable,
2111 0x1<<min_rssi_index, 0x0);
2112 rtl8192_setBBreg(dev, rOFDM1_TRxPathEnable,
2113 0x1<<min_rssi_index, 0x0);
2116 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) {
2117 cck_default_Rx = max_rssi_index;
2118 cck_optional_Rx = sec_rssi_index;
2120 update_cck_rx_path = 1;
2124 if (update_cck_rx_path) {
2125 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2) |
2127 rtl8192_setBBreg(dev, rCCK0_AFESetting, 0x0f000000,
2128 DM_RxPathSelTable.cck_Rx_path);
2131 if (DM_RxPathSelTable.disabledRF) {
2132 for (i = 0; i < 4; i++) {
2133 if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) {
2135 DM_RxPathSelTable.rf_enable_rssi_th[i]) {
2136 rtl8192_setBBreg(dev,
2137 rOFDM0_TRxPathEnable, 0x1 << i,
2139 rtl8192_setBBreg(dev,
2140 rOFDM1_TRxPathEnable,
2142 DM_RxPathSelTable.rf_enable_rssi_th[i]
2151 static void dm_check_rx_path_selection(struct net_device *dev)
2153 struct r8192_priv *priv = rtllib_priv(dev);
2155 queue_delayed_work_rsl(priv->priv_wq, &priv->rfpath_check_wq, 0);
2159 static void dm_init_fsync(struct net_device *dev)
2161 struct r8192_priv *priv = rtllib_priv(dev);
2163 priv->rtllib->fsync_time_interval = 500;
2164 priv->rtllib->fsync_rate_bitmap = 0x0f000800;
2165 priv->rtllib->fsync_rssi_threshold = 30;
2166 priv->rtllib->bfsync_enable = false;
2167 priv->rtllib->fsync_multiple_timeinterval = 3;
2168 priv->rtllib->fsync_firstdiff_ratethreshold = 100;
2169 priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2170 priv->rtllib->fsync_state = Default_Fsync;
2171 priv->framesyncMonitor = 1;
2173 init_timer(&priv->fsync_timer);
2174 setup_timer(&priv->fsync_timer, dm_fsync_timer_callback,
2175 (unsigned long) dev);
2179 static void dm_deInit_fsync(struct net_device *dev)
2181 struct r8192_priv *priv = rtllib_priv(dev);
2183 del_timer_sync(&priv->fsync_timer);
2186 void dm_fsync_timer_callback(unsigned long data)
2188 struct net_device *dev = (struct net_device *)data;
2189 struct r8192_priv *priv = rtllib_priv((struct net_device *)data);
2190 u32 rate_index, rate_count = 0, rate_count_diff = 0;
2191 bool bSwitchFromCountDiff = false;
2192 bool bDoubleTimeInterval = false;
2194 if (priv->rtllib->state == RTLLIB_LINKED &&
2195 priv->rtllib->bfsync_enable &&
2196 (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2199 for (rate_index = 0; rate_index <= 27; rate_index++) {
2200 rate_bitmap = 1 << rate_index;
2201 if (priv->rtllib->fsync_rate_bitmap & rate_bitmap)
2203 priv->stats.received_rate_histogram[1]
2207 if (rate_count < priv->rate_record)
2208 rate_count_diff = 0xffffffff - rate_count +
2211 rate_count_diff = rate_count - priv->rate_record;
2212 if (rate_count_diff < priv->rateCountDiffRecord) {
2214 u32 DiffNum = priv->rateCountDiffRecord -
2217 priv->rtllib->fsync_seconddiff_ratethreshold)
2218 priv->ContinueDiffCount++;
2220 priv->ContinueDiffCount = 0;
2222 if (priv->ContinueDiffCount >= 2) {
2223 bSwitchFromCountDiff = true;
2224 priv->ContinueDiffCount = 0;
2227 priv->ContinueDiffCount = 0;
2230 if (rate_count_diff <=
2231 priv->rtllib->fsync_firstdiff_ratethreshold) {
2232 bSwitchFromCountDiff = true;
2233 priv->ContinueDiffCount = 0;
2235 priv->rate_record = rate_count;
2236 priv->rateCountDiffRecord = rate_count_diff;
2237 RT_TRACE(COMP_HALDM,
2238 "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n",
2239 priv->rate_record, rate_count, rate_count_diff,
2240 priv->bswitch_fsync);
2241 if (priv->undecorated_smoothed_pwdb >
2242 priv->rtllib->fsync_rssi_threshold &&
2243 bSwitchFromCountDiff) {
2244 bDoubleTimeInterval = true;
2245 priv->bswitch_fsync = !priv->bswitch_fsync;
2246 if (priv->bswitch_fsync) {
2247 write_nic_byte(dev, 0xC36, 0x1c);
2248 write_nic_byte(dev, 0xC3e, 0x90);
2250 write_nic_byte(dev, 0xC36, 0x5c);
2251 write_nic_byte(dev, 0xC3e, 0x96);
2253 } else if (priv->undecorated_smoothed_pwdb <=
2254 priv->rtllib->fsync_rssi_threshold) {
2255 if (priv->bswitch_fsync) {
2256 priv->bswitch_fsync = false;
2257 write_nic_byte(dev, 0xC36, 0x5c);
2258 write_nic_byte(dev, 0xC3e, 0x96);
2261 if (bDoubleTimeInterval) {
2262 if (timer_pending(&priv->fsync_timer))
2263 del_timer_sync(&priv->fsync_timer);
2264 priv->fsync_timer.expires = jiffies +
2265 msecs_to_jiffies(priv->rtllib->fsync_time_interval *
2266 priv->rtllib->fsync_multiple_timeinterval);
2267 add_timer(&priv->fsync_timer);
2269 if (timer_pending(&priv->fsync_timer))
2270 del_timer_sync(&priv->fsync_timer);
2271 priv->fsync_timer.expires = jiffies +
2272 msecs_to_jiffies(priv->rtllib->fsync_time_interval);
2273 add_timer(&priv->fsync_timer);
2276 if (priv->bswitch_fsync) {
2277 priv->bswitch_fsync = false;
2278 write_nic_byte(dev, 0xC36, 0x5c);
2279 write_nic_byte(dev, 0xC3e, 0x96);
2281 priv->ContinueDiffCount = 0;
2282 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2284 RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
2285 RT_TRACE(COMP_HALDM,
2286 "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n",
2287 priv->rate_record, rate_count, rate_count_diff,
2288 priv->bswitch_fsync);
2291 static void dm_StartHWFsync(struct net_device *dev)
2293 u8 rf_timing = 0x77;
2294 struct r8192_priv *priv = rtllib_priv(dev);
2296 RT_TRACE(COMP_HALDM, "%s\n", __func__);
2297 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cf);
2298 priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING,
2299 (u8 *)(&rf_timing));
2300 write_nic_byte(dev, 0xc3b, 0x41);
2303 static void dm_EndHWFsync(struct net_device *dev)
2305 u8 rf_timing = 0xaa;
2306 struct r8192_priv *priv = rtllib_priv(dev);
2308 RT_TRACE(COMP_HALDM, "%s\n", __func__);
2309 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2310 priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, (u8 *)
2312 write_nic_byte(dev, 0xc3b, 0x49);
2315 static void dm_EndSWFsync(struct net_device *dev)
2317 struct r8192_priv *priv = rtllib_priv(dev);
2319 RT_TRACE(COMP_HALDM, "%s\n", __func__);
2320 del_timer_sync(&(priv->fsync_timer));
2322 if (priv->bswitch_fsync) {
2323 priv->bswitch_fsync = false;
2325 write_nic_byte(dev, 0xC36, 0x5c);
2327 write_nic_byte(dev, 0xC3e, 0x96);
2330 priv->ContinueDiffCount = 0;
2331 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c52cd);
2334 static void dm_StartSWFsync(struct net_device *dev)
2336 struct r8192_priv *priv = rtllib_priv(dev);
2340 RT_TRACE(COMP_HALDM, "%s\n", __func__);
2341 priv->rate_record = 0;
2342 priv->ContinueDiffCount = 0;
2343 priv->rateCountDiffRecord = 0;
2344 priv->bswitch_fsync = false;
2346 if (priv->rtllib->mode == WIRELESS_MODE_N_24G) {
2347 priv->rtllib->fsync_firstdiff_ratethreshold = 600;
2348 priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff;
2350 priv->rtllib->fsync_firstdiff_ratethreshold = 200;
2351 priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2353 for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
2354 rateBitmap = 1 << rateIndex;
2355 if (priv->rtllib->fsync_rate_bitmap & rateBitmap)
2356 priv->rate_record +=
2357 priv->stats.received_rate_histogram[1]
2360 if (timer_pending(&priv->fsync_timer))
2361 del_timer_sync(&priv->fsync_timer);
2362 priv->fsync_timer.expires = jiffies +
2363 msecs_to_jiffies(priv->rtllib->fsync_time_interval);
2364 add_timer(&priv->fsync_timer);
2366 write_nic_dword(dev, rOFDM0_RxDetector2, 0x465c12cd);
2370 void dm_check_fsync(struct net_device *dev)
2372 #define RegC38_Default 0
2373 #define RegC38_NonFsync_Other_AP 1
2374 #define RegC38_Fsync_AP_BCM 2
2375 struct r8192_priv *priv = rtllib_priv(dev);
2376 static u8 reg_c38_State = RegC38_Default;
2377 static u32 reset_cnt;
2379 RT_TRACE(COMP_HALDM,
2380 "RSSI %d TimeInterval %d MultipleTimeInterval %d\n",
2381 priv->rtllib->fsync_rssi_threshold,
2382 priv->rtllib->fsync_time_interval,
2383 priv->rtllib->fsync_multiple_timeinterval);
2384 RT_TRACE(COMP_HALDM,
2385 "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n",
2386 priv->rtllib->fsync_rate_bitmap,
2387 priv->rtllib->fsync_firstdiff_ratethreshold,
2388 priv->rtllib->fsync_seconddiff_ratethreshold);
2390 if (priv->rtllib->state == RTLLIB_LINKED &&
2391 priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2392 if (priv->rtllib->bfsync_enable == 0) {
2393 switch (priv->rtllib->fsync_state) {
2395 dm_StartHWFsync(dev);
2396 priv->rtllib->fsync_state = HW_Fsync;
2400 dm_StartHWFsync(dev);
2401 priv->rtllib->fsync_state = HW_Fsync;
2408 switch (priv->rtllib->fsync_state) {
2410 dm_StartSWFsync(dev);
2411 priv->rtllib->fsync_state = SW_Fsync;
2415 dm_StartSWFsync(dev);
2416 priv->rtllib->fsync_state = SW_Fsync;
2424 if (priv->framesyncMonitor) {
2425 if (reg_c38_State != RegC38_Fsync_AP_BCM) {
2426 write_nic_byte(dev, rOFDM0_RxDetector3, 0x95);
2428 reg_c38_State = RegC38_Fsync_AP_BCM;
2432 switch (priv->rtllib->fsync_state) {
2435 priv->rtllib->fsync_state = Default_Fsync;
2439 priv->rtllib->fsync_state = Default_Fsync;
2446 if (priv->framesyncMonitor) {
2447 if (priv->rtllib->state == RTLLIB_LINKED) {
2448 if (priv->undecorated_smoothed_pwdb <=
2450 if (reg_c38_State !=
2451 RegC38_NonFsync_Other_AP) {
2457 RegC38_NonFsync_Other_AP;
2459 } else if (priv->undecorated_smoothed_pwdb >=
2461 if (reg_c38_State) {
2465 reg_c38_State = RegC38_Default;
2469 if (reg_c38_State) {
2470 write_nic_byte(dev, rOFDM0_RxDetector3,
2472 reg_c38_State = RegC38_Default;
2477 if (priv->framesyncMonitor) {
2478 if (priv->reset_count != reset_cnt) {
2479 write_nic_byte(dev, rOFDM0_RxDetector3,
2481 reg_c38_State = RegC38_Default;
2482 reset_cnt = priv->reset_count;
2485 if (reg_c38_State) {
2486 write_nic_byte(dev, rOFDM0_RxDetector3,
2488 reg_c38_State = RegC38_Default;
2493 void dm_shadow_init(struct net_device *dev)
2498 for (page = 0; page < 5; page++)
2499 for (offset = 0; offset < 256; offset++)
2500 dm_shadow[page][offset] = read_nic_byte(dev,
2503 for (page = 8; page < 11; page++)
2504 for (offset = 0; offset < 256; offset++)
2505 dm_shadow[page][offset] = read_nic_byte(dev,
2508 for (page = 12; page < 15; page++)
2509 for (offset = 0; offset < 256; offset++)
2510 dm_shadow[page][offset] = read_nic_byte(dev,
2515 /*---------------------------Define function prototype------------------------*/
2516 static void dm_init_dynamic_txpower(struct net_device *dev)
2518 struct r8192_priv *priv = rtllib_priv(dev);
2520 priv->rtllib->bdynamic_txpower_enable = true;
2521 priv->bLastDTPFlag_High = false;
2522 priv->bLastDTPFlag_Low = false;
2523 priv->bDynamicTxHighPower = false;
2524 priv->bDynamicTxLowPower = false;
2527 static void dm_dynamic_txpower(struct net_device *dev)
2529 struct r8192_priv *priv = rtllib_priv(dev);
2530 unsigned int txhipower_threshhold = 0;
2531 unsigned int txlowpower_threshold = 0;
2533 if (priv->rtllib->bdynamic_txpower_enable != true) {
2534 priv->bDynamicTxHighPower = false;
2535 priv->bDynamicTxLowPower = false;
2538 if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) &&
2539 (priv->rtllib->mode == IEEE_G)) {
2540 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
2541 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2543 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2544 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2547 RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n",
2548 priv->undecorated_smoothed_pwdb);
2550 if (priv->rtllib->state == RTLLIB_LINKED) {
2551 if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
2552 priv->bDynamicTxHighPower = true;
2553 priv->bDynamicTxLowPower = false;
2555 if (priv->undecorated_smoothed_pwdb <
2556 txlowpower_threshold && priv->bDynamicTxHighPower)
2557 priv->bDynamicTxHighPower = false;
2558 if (priv->undecorated_smoothed_pwdb < 35)
2559 priv->bDynamicTxLowPower = true;
2560 else if (priv->undecorated_smoothed_pwdb >= 40)
2561 priv->bDynamicTxLowPower = false;
2564 priv->bDynamicTxHighPower = false;
2565 priv->bDynamicTxLowPower = false;
2568 if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
2569 (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
2570 RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n",
2571 priv->rtllib->current_network.channel);
2573 rtl8192_phy_setTxPower(dev,
2574 priv->rtllib->current_network.channel);
2576 priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2577 priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2581 static void dm_check_txrateandretrycount(struct net_device *dev)
2583 struct r8192_priv *priv = rtllib_priv(dev);
2584 struct rtllib_device *ieee = priv->rtllib;
2586 ieee->softmac_stats.CurrentShowTxate = read_nic_byte(dev,
2587 Current_Tx_Rate_Reg);
2589 ieee->softmac_stats.last_packet_rate = read_nic_byte(dev,
2590 Initial_Tx_Rate_Reg);
2592 ieee->softmac_stats.txretrycount = read_nic_dword(dev,
2593 Tx_Retry_Count_Reg);
2596 static void dm_send_rssi_tofw(struct net_device *dev)
2598 struct r8192_priv *priv = rtllib_priv(dev);
2600 write_nic_byte(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);