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 * The full GNU General Public License is included in this distribution in the
10 * file called LICENSE.
12 * Contact Information:
13 * wlanfae <wlanfae@realtek.com>
14 ******************************************************************************/
17 #include "r8192E_hw.h"
18 #include "r8192E_phy.h"
19 #include "r8192E_phyreg.h"
20 #include "r8190P_rtl8256.h"
21 #include "r8192E_cmdpkt.h"
23 /*---------------------------Define Local Constant---------------------------*/
24 static u32 edca_setting_DL[HT_IOT_PEER_MAX] = {
35 static u32 edca_setting_DL_GMode[HT_IOT_PEER_MAX] = {
46 static u32 edca_setting_UL[HT_IOT_PEER_MAX] = {
57 const u32 dm_tx_bb_gain[TxBBGainTableLength] = {
58 0x7f8001fe, /* 12 dB */
59 0x788001e2, /* 11 dB */
94 0x10000040, /* -24 dB */
97 const u8 dm_cck_tx_bb_gain[CCKTxBBGainTableLength][8] = {
98 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
99 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
100 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
101 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
102 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
103 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
104 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
105 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
106 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
107 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
108 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
109 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
110 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
111 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
112 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
113 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
114 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
115 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
116 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
117 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
118 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
119 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
120 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
123 const u8 dm_cck_tx_bb_gain_ch14[CCKTxBBGainTableLength][8] = {
124 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
125 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
126 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
127 {0x2d, 0x2d, 0x27, 0x17, 0x00, 0x00, 0x00, 0x00},
128 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
129 {0x28, 0x28, 0x22, 0x14, 0x00, 0x00, 0x00, 0x00},
130 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
131 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
132 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
133 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
134 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
135 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
136 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
137 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
138 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
139 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
140 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
141 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
142 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
143 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
144 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
145 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
146 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
149 /*---------------------------Define Local Constant---------------------------*/
152 /*------------------------Define global variable-----------------------------*/
153 struct dig_t dm_digtable;
155 struct drx_path_sel DM_RxPathSelTable;
156 /*------------------------Define global variable-----------------------------*/
159 /*------------------------Define local variable------------------------------*/
160 /*------------------------Define local variable------------------------------*/
164 /*---------------------Define local function prototype-----------------------*/
165 static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev);
167 static void _rtl92e_dm_init_bandwidth_autoswitch(struct net_device *dev);
168 static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev);
171 static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev);
173 static void _rtl92e_dm_bb_initialgain_restore(struct net_device *dev);
174 static void _rtl92e_dm_bb_initialgain_backup(struct net_device *dev);
176 static void _rtl92e_dm_dig_init(struct net_device *dev);
177 static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev);
178 static void _rtl92e_dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev);
179 static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev);
180 static void _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(struct net_device *dev);
181 static void _rtl92e_dm_initial_gain(struct net_device *dev);
182 static void _rtl92e_dm_pd_th(struct net_device *dev);
183 static void _rtl92e_dm_cs_ratio(struct net_device *dev);
185 static void _rtl92e_dm_init_cts_to_self(struct net_device *dev);
186 static void _rtl92e_dm_init_wa_broadcom_iot(struct net_device *dev);
188 static void _rtl92e_dm_check_edca_turbo(struct net_device *dev);
190 static void _rtl92e_dm_check_pbc_gpio(struct net_device *dev);
193 static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev);
194 static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev);
195 static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev);
198 static void _rtl92e_dm_init_fsync(struct net_device *dev);
199 static void _rtl92e_dm_deinit_fsync(struct net_device *dev);
201 static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev);
202 static void _rtl92e_dm_check_ac_dc_power(struct net_device *dev);
203 static void _rtl92e_dm_check_fsync(struct net_device *dev);
204 static void _rtl92e_dm_check_rf_ctrl_gpio(void *data);
205 static void _rtl92e_dm_fsync_timer_callback(unsigned long data);
207 /*---------------------Define local function prototype-----------------------*/
209 static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev);
210 static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev);
212 static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev);
213 static void _rtl92e_dm_cts_to_self(struct net_device *dev);
214 /*---------------------------Define function prototype------------------------*/
216 void rtl92e_dm_init(struct net_device *dev)
218 struct r8192_priv *priv = rtllib_priv(dev);
220 priv->DM_Type = DM_Type_ByDriver;
222 priv->undecorated_smoothed_pwdb = -1;
224 _rtl92e_dm_init_dynamic_tx_power(dev);
226 rtl92e_init_adaptive_rate(dev);
228 _rtl92e_dm_dig_init(dev);
229 rtl92e_dm_init_edca_turbo(dev);
230 _rtl92e_dm_init_bandwidth_autoswitch(dev);
231 _rtl92e_dm_init_fsync(dev);
232 _rtl92e_dm_init_rx_path_selection(dev);
233 _rtl92e_dm_init_cts_to_self(dev);
234 if (IS_HARDWARE_TYPE_8192SE(dev))
235 _rtl92e_dm_init_wa_broadcom_iot(dev);
237 INIT_DELAYED_WORK_RSL(&priv->gpio_change_rf_wq,
238 (void *)_rtl92e_dm_check_rf_ctrl_gpio, dev);
241 void rtl92e_dm_deinit(struct net_device *dev)
244 _rtl92e_dm_deinit_fsync(dev);
248 void rtl92e_dm_watchdog(struct net_device *dev)
250 struct r8192_priv *priv = rtllib_priv(dev);
252 if (priv->being_init_adapter)
255 _rtl92e_dm_check_ac_dc_power(dev);
257 _rtl92e_dm_check_pbc_gpio(dev);
258 _rtl92e_dm_check_txrateandretrycount(dev);
259 _rtl92e_dm_check_edca_turbo(dev);
261 _rtl92e_dm_check_rate_adaptive(dev);
262 _rtl92e_dm_dynamic_tx_power(dev);
263 _rtl92e_dm_check_tx_power_tracking(dev);
265 _rtl92e_dm_ctrl_initgain_byrssi(dev);
266 _rtl92e_dm_bandwidth_autoswitch(dev);
268 _rtl92e_dm_check_rx_path_selection(dev);
269 _rtl92e_dm_check_fsync(dev);
271 _rtl92e_dm_send_rssi_to_fw(dev);
272 _rtl92e_dm_cts_to_self(dev);
275 static void _rtl92e_dm_check_ac_dc_power(struct net_device *dev)
277 struct r8192_priv *priv = rtllib_priv(dev);
278 static char *ac_dc_script = "/etc/acpi/wireless-rtl-ac-dc-power.sh";
279 char *argv[] = {ac_dc_script, DRV_NAME, NULL};
280 static char *envp[] = {"HOME=/",
282 "PATH=/usr/bin:/bin",
285 if (priv->ResetProgress == RESET_TYPE_SILENT) {
286 RT_TRACE((COMP_INIT | COMP_POWER | COMP_RF),
287 "GPIOChangeRFWorkItemCallBack(): Silent Reset!!!!!!!\n");
291 if (priv->rtllib->state != RTLLIB_LINKED)
293 call_usermodehelper(ac_dc_script, argv, envp, UMH_WAIT_PROC);
299 void rtl92e_init_adaptive_rate(struct net_device *dev)
302 struct r8192_priv *priv = rtllib_priv(dev);
303 struct rate_adaptive *pra = &priv->rate_adaptive;
305 pra->ratr_state = DM_RATR_STA_MAX;
306 pra->high2low_rssi_thresh_for_ra = RateAdaptiveTH_High;
307 pra->low2high_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M+5;
308 pra->low2high_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M+5;
310 pra->high_rssi_thresh_for_ra = RateAdaptiveTH_High+5;
311 pra->low_rssi_thresh_for_ra20M = RateAdaptiveTH_Low_20M;
312 pra->low_rssi_thresh_for_ra40M = RateAdaptiveTH_Low_40M;
314 if (priv->CustomerID == RT_CID_819x_Netcore)
315 pra->ping_rssi_enable = 1;
317 pra->ping_rssi_enable = 0;
318 pra->ping_rssi_thresh_for_ra = 15;
321 if (priv->rf_type == RF_2T4R) {
322 pra->upper_rssi_threshold_ratr = 0x8f0f0000;
323 pra->middle_rssi_threshold_ratr = 0x8f0ff000;
324 pra->low_rssi_threshold_ratr = 0x8f0ff001;
325 pra->low_rssi_threshold_ratr_40M = 0x8f0ff005;
326 pra->low_rssi_threshold_ratr_20M = 0x8f0ff001;
327 pra->ping_rssi_ratr = 0x0000000d;
328 } else if (priv->rf_type == RF_1T2R) {
329 pra->upper_rssi_threshold_ratr = 0x000fc000;
330 pra->middle_rssi_threshold_ratr = 0x000ff000;
331 pra->low_rssi_threshold_ratr = 0x000ff001;
332 pra->low_rssi_threshold_ratr_40M = 0x000ff005;
333 pra->low_rssi_threshold_ratr_20M = 0x000ff001;
334 pra->ping_rssi_ratr = 0x0000000d;
340 static void _rtl92e_dm_check_rate_adaptive(struct net_device *dev)
342 struct r8192_priv *priv = rtllib_priv(dev);
343 struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
344 struct rate_adaptive *pra = &priv->rate_adaptive;
345 u32 currentRATR, targetRATR = 0;
346 u32 LowRSSIThreshForRA = 0, HighRSSIThreshForRA = 0;
347 bool bshort_gi_enabled = false;
348 static u8 ping_rssi_state;
352 "<---- _rtl92e_dm_check_rate_adaptive(): driver is going to unload\n");
356 if (pra->rate_adaptive_disabled)
359 if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
360 priv->rtllib->mode == WIRELESS_MODE_N_5G))
363 if (priv->rtllib->state == RTLLIB_LINKED) {
365 bshort_gi_enabled = (pHTInfo->bCurTxBW40MHz &&
366 pHTInfo->bCurShortGI40MHz) ||
367 (!pHTInfo->bCurTxBW40MHz &&
368 pHTInfo->bCurShortGI20MHz);
370 pra->upper_rssi_threshold_ratr =
371 (pra->upper_rssi_threshold_ratr & (~BIT31)) |
372 ((bshort_gi_enabled) ? BIT31 : 0);
374 pra->middle_rssi_threshold_ratr =
375 (pra->middle_rssi_threshold_ratr & (~BIT31)) |
376 ((bshort_gi_enabled) ? BIT31 : 0);
378 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) {
379 pra->low_rssi_threshold_ratr =
380 (pra->low_rssi_threshold_ratr_40M & (~BIT31)) |
381 ((bshort_gi_enabled) ? BIT31 : 0);
383 pra->low_rssi_threshold_ratr =
384 (pra->low_rssi_threshold_ratr_20M & (~BIT31)) |
385 ((bshort_gi_enabled) ? BIT31 : 0);
387 pra->ping_rssi_ratr =
388 (pra->ping_rssi_ratr & (~BIT31)) |
389 ((bshort_gi_enabled) ? BIT31 : 0);
391 if (pra->ratr_state == DM_RATR_STA_HIGH) {
392 HighRSSIThreshForRA = pra->high2low_rssi_thresh_for_ra;
393 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
394 (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
395 } else if (pra->ratr_state == DM_RATR_STA_LOW) {
396 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
397 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
398 (pra->low2high_rssi_thresh_for_ra40M) : (pra->low2high_rssi_thresh_for_ra20M);
400 HighRSSIThreshForRA = pra->high_rssi_thresh_for_ra;
401 LowRSSIThreshForRA = (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20) ?
402 (pra->low_rssi_thresh_for_ra40M) : (pra->low_rssi_thresh_for_ra20M);
405 if (priv->undecorated_smoothed_pwdb >=
406 (long)HighRSSIThreshForRA) {
407 pra->ratr_state = DM_RATR_STA_HIGH;
408 targetRATR = pra->upper_rssi_threshold_ratr;
409 } else if (priv->undecorated_smoothed_pwdb >=
410 (long)LowRSSIThreshForRA) {
411 pra->ratr_state = DM_RATR_STA_MIDDLE;
412 targetRATR = pra->middle_rssi_threshold_ratr;
414 pra->ratr_state = DM_RATR_STA_LOW;
415 targetRATR = pra->low_rssi_threshold_ratr;
418 if (pra->ping_rssi_enable) {
419 if (priv->undecorated_smoothed_pwdb <
420 (long)(pra->ping_rssi_thresh_for_ra+5)) {
421 if ((priv->undecorated_smoothed_pwdb <
422 (long)pra->ping_rssi_thresh_for_ra) ||
424 pra->ratr_state = DM_RATR_STA_LOW;
425 targetRATR = pra->ping_rssi_ratr;
433 if (priv->rtllib->GetHalfNmodeSupportByAPsHandler(dev))
434 targetRATR &= 0xf00fffff;
436 currentRATR = rtl92e_readl(dev, RATR0);
437 if (targetRATR != currentRATR) {
440 ratr_value = targetRATR;
442 "currentRATR = %x, targetRATR = %x\n",
443 currentRATR, targetRATR);
444 if (priv->rf_type == RF_1T2R)
445 ratr_value &= ~(RATE_ALL_OFDM_2SS);
446 rtl92e_writel(dev, RATR0, ratr_value);
447 rtl92e_writeb(dev, UFWP, 1);
449 pra->last_ratr = targetRATR;
453 pra->ratr_state = DM_RATR_STA_MAX;
457 static void _rtl92e_dm_init_bandwidth_autoswitch(struct net_device *dev)
459 struct r8192_priv *priv = rtllib_priv(dev);
461 priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz = BW_AUTO_SWITCH_LOW_HIGH;
462 priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz = BW_AUTO_SWITCH_HIGH_LOW;
463 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
464 priv->rtllib->bandwidth_auto_switch.bautoswitch_enable = false;
467 static void _rtl92e_dm_bandwidth_autoswitch(struct net_device *dev)
469 struct r8192_priv *priv = rtllib_priv(dev);
471 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20 ||
472 !priv->rtllib->bandwidth_auto_switch.bautoswitch_enable)
474 if (priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz == false) {
475 if (priv->undecorated_smoothed_pwdb <=
476 priv->rtllib->bandwidth_auto_switch.threshold_40Mhzto20Mhz)
477 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = true;
479 if (priv->undecorated_smoothed_pwdb >=
480 priv->rtllib->bandwidth_auto_switch.threshold_20Mhzto40Mhz)
481 priv->rtllib->bandwidth_auto_switch.bforced_tx20Mhz = false;
485 static u32 OFDMSwingTable[OFDM_Table_Length] = {
507 static u8 CCKSwingTable_Ch1_Ch13[CCK_Table_length][8] = {
508 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
509 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
510 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
511 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
512 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
513 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
514 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
515 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
516 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
517 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
518 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
519 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}
522 static u8 CCKSwingTable_Ch14[CCK_Table_length][8] = {
523 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
524 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
525 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
526 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
527 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
528 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
529 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
530 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
531 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
532 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
533 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
534 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}
537 #define Pw_Track_Flag 0x11d
538 #define Tssi_Mea_Value 0x13c
539 #define Tssi_Report_Value1 0x134
540 #define Tssi_Report_Value2 0x13e
541 #define FW_Busy_Flag 0x13f
543 static void _rtl92e_dm_tx_update_tssi_weak_signal(struct net_device *dev,
546 struct r8192_priv *p = rtllib_priv(dev);
548 if (RF_Type == RF_2T4R) {
549 if ((p->rfa_txpowertrackingindex > 0) &&
550 (p->rfc_txpowertrackingindex > 0)) {
551 p->rfa_txpowertrackingindex--;
552 if (p->rfa_txpowertrackingindex_real > 4) {
553 p->rfa_txpowertrackingindex_real--;
554 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
556 dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
559 p->rfc_txpowertrackingindex--;
560 if (p->rfc_txpowertrackingindex_real > 4) {
561 p->rfc_txpowertrackingindex_real--;
562 rtl92e_set_bb_reg(dev,
563 rOFDM0_XCTxIQImbalance,
565 dm_tx_bb_gain[p->rfc_txpowertrackingindex_real]);
568 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
571 rtl92e_set_bb_reg(dev,
572 rOFDM0_XCTxIQImbalance,
573 bMaskDWord, dm_tx_bb_gain[4]);
576 if (p->rfa_txpowertrackingindex > 0) {
577 p->rfa_txpowertrackingindex--;
578 if (p->rfa_txpowertrackingindex_real > 4) {
579 p->rfa_txpowertrackingindex_real--;
580 rtl92e_set_bb_reg(dev,
581 rOFDM0_XATxIQImbalance,
583 dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
586 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
587 bMaskDWord, dm_tx_bb_gain[4]);
592 static void _rtl92e_dm_tx_update_tssi_strong_signal(struct net_device *dev,
595 struct r8192_priv *p = rtllib_priv(dev);
597 if (RF_Type == RF_2T4R) {
598 if ((p->rfa_txpowertrackingindex < TxBBGainTableLength - 1) &&
599 (p->rfc_txpowertrackingindex < TxBBGainTableLength - 1)) {
600 p->rfa_txpowertrackingindex++;
601 p->rfa_txpowertrackingindex_real++;
602 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
604 dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
605 p->rfc_txpowertrackingindex++;
606 p->rfc_txpowertrackingindex_real++;
607 rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance,
609 dm_tx_bb_gain[p->rfc_txpowertrackingindex_real]);
611 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
613 dm_tx_bb_gain[TxBBGainTableLength - 1]);
614 rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance,
616 dm_tx_bb_gain[TxBBGainTableLength - 1]);
619 if (p->rfa_txpowertrackingindex < (TxBBGainTableLength - 1)) {
620 p->rfa_txpowertrackingindex++;
621 p->rfa_txpowertrackingindex_real++;
622 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
624 dm_tx_bb_gain[p->rfa_txpowertrackingindex_real]);
626 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance,
628 dm_tx_bb_gain[TxBBGainTableLength - 1]);
633 static void _rtl92e_dm_tx_power_tracking_callback_tssi(struct net_device *dev)
635 struct r8192_priv *priv = rtllib_priv(dev);
636 bool bHighpowerstate, viviflag = false;
637 struct dcmd_txcmd tx_cmd;
638 u8 powerlevelOFDM24G;
639 int i = 0, j = 0, k = 0;
640 u8 RF_Type, tmp_report[5] = {0, 0, 0, 0, 0};
643 u16 Avg_TSSI_Meas, TSSI_13dBm, Avg_TSSI_Meas_from_driver = 0;
646 RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__);
647 rtl92e_writeb(dev, Pw_Track_Flag, 0);
648 rtl92e_writeb(dev, FW_Busy_Flag, 0);
649 priv->rtllib->bdynamic_txpower_enable = false;
650 bHighpowerstate = priv->bDynamicTxHighPower;
652 powerlevelOFDM24G = (u8)(priv->Pwr_Track>>24);
653 RF_Type = priv->rf_type;
654 Value = (RF_Type<<8) | powerlevelOFDM24G;
656 RT_TRACE(COMP_POWER_TRACKING, "powerlevelOFDM24G = %x\n",
660 for (j = 0; j <= 30; j++) {
662 tx_cmd.Op = TXCMD_SET_TX_PWR_TRACKING;
664 tx_cmd.Value = Value;
665 rtl92e_send_cmd_pkt(dev, (u8 *)&tx_cmd, DESC_PACKET_TYPE_INIT,
666 sizeof(struct dcmd_txcmd));
668 for (i = 0; i <= 30; i++) {
669 Pwr_Flag = rtl92e_readb(dev, Pw_Track_Flag);
674 if (priv->bResetInProgress) {
675 RT_TRACE(COMP_POWER_TRACKING,
676 "we are in silent reset progress, so return\n");
677 rtl92e_writeb(dev, Pw_Track_Flag, 0);
678 rtl92e_writeb(dev, FW_Busy_Flag, 0);
681 if (priv->rtllib->eRFPowerState != eRfOn) {
682 RT_TRACE(COMP_POWER_TRACKING,
683 "we are in power save, so return\n");
684 rtl92e_writeb(dev, Pw_Track_Flag, 0);
685 rtl92e_writeb(dev, FW_Busy_Flag, 0);
692 Avg_TSSI_Meas = rtl92e_readw(dev, Tssi_Mea_Value);
694 if (Avg_TSSI_Meas == 0) {
695 rtl92e_writeb(dev, Pw_Track_Flag, 0);
696 rtl92e_writeb(dev, FW_Busy_Flag, 0);
700 for (k = 0; k < 5; k++) {
702 tmp_report[k] = rtl92e_readb(dev,
703 Tssi_Report_Value1+k);
705 tmp_report[k] = rtl92e_readb(dev,
708 RT_TRACE(COMP_POWER_TRACKING,
709 "TSSI_report_value = %d\n",
712 if (tmp_report[k] <= 20) {
719 rtl92e_writeb(dev, Pw_Track_Flag, 0);
721 RT_TRACE(COMP_POWER_TRACKING,
722 "we filted this data\n");
723 for (k = 0; k < 5; k++)
728 for (k = 0; k < 5; k++)
729 Avg_TSSI_Meas_from_driver += tmp_report[k];
731 Avg_TSSI_Meas_from_driver *= 100 / 5;
732 RT_TRACE(COMP_POWER_TRACKING,
733 "Avg_TSSI_Meas_from_driver = %d\n",
734 Avg_TSSI_Meas_from_driver);
735 TSSI_13dBm = priv->TSSI_13dBm;
736 RT_TRACE(COMP_POWER_TRACKING, "TSSI_13dBm = %d\n",
739 if (Avg_TSSI_Meas_from_driver > TSSI_13dBm)
740 delta = Avg_TSSI_Meas_from_driver - TSSI_13dBm;
742 delta = TSSI_13dBm - Avg_TSSI_Meas_from_driver;
744 if (delta <= E_FOR_TX_POWER_TRACK) {
745 priv->rtllib->bdynamic_txpower_enable = true;
746 rtl92e_writeb(dev, Pw_Track_Flag, 0);
747 rtl92e_writeb(dev, FW_Busy_Flag, 0);
748 RT_TRACE(COMP_POWER_TRACKING,
749 "tx power track is done\n");
750 RT_TRACE(COMP_POWER_TRACKING,
751 "priv->rfa_txpowertrackingindex = %d\n",
752 priv->rfa_txpowertrackingindex);
753 RT_TRACE(COMP_POWER_TRACKING,
754 "priv->rfa_txpowertrackingindex_real = %d\n",
755 priv->rfa_txpowertrackingindex_real);
756 RT_TRACE(COMP_POWER_TRACKING,
757 "priv->CCKPresentAttentuation_difference = %d\n",
758 priv->CCKPresentAttentuation_difference);
759 RT_TRACE(COMP_POWER_TRACKING,
760 "priv->CCKPresentAttentuation = %d\n",
761 priv->CCKPresentAttentuation);
764 if (Avg_TSSI_Meas_from_driver < TSSI_13dBm - E_FOR_TX_POWER_TRACK)
765 _rtl92e_dm_tx_update_tssi_weak_signal(dev,
768 _rtl92e_dm_tx_update_tssi_strong_signal(dev, RF_Type);
770 if (RF_Type == RF_2T4R) {
771 priv->CCKPresentAttentuation_difference
772 = priv->rfa_txpowertrackingindex - priv->rfa_txpowertracking_default;
774 priv->CCKPresentAttentuation_difference
775 = priv->rfa_txpowertrackingindex_real - priv->rfa_txpowertracking_default;
778 if (priv->CurrentChannelBW == HT_CHANNEL_WIDTH_20)
779 priv->CCKPresentAttentuation =
780 priv->CCKPresentAttentuation_20Mdefault +
781 priv->CCKPresentAttentuation_difference;
783 priv->CCKPresentAttentuation =
784 priv->CCKPresentAttentuation_40Mdefault +
785 priv->CCKPresentAttentuation_difference;
787 if (priv->CCKPresentAttentuation > (CCKTxBBGainTableLength-1))
788 priv->CCKPresentAttentuation = CCKTxBBGainTableLength-1;
789 if (priv->CCKPresentAttentuation < 0)
790 priv->CCKPresentAttentuation = 0;
792 if (priv->CCKPresentAttentuation > -1 &&
793 priv->CCKPresentAttentuation < CCKTxBBGainTableLength) {
794 if (priv->rtllib->current_network.channel == 14 &&
795 !priv->bcck_in_ch14) {
796 priv->bcck_in_ch14 = true;
797 rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
798 } else if (priv->rtllib->current_network.channel != 14 && priv->bcck_in_ch14) {
799 priv->bcck_in_ch14 = false;
800 rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
802 rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
804 RT_TRACE(COMP_POWER_TRACKING,
805 "priv->rfa_txpowertrackingindex = %d\n",
806 priv->rfa_txpowertrackingindex);
807 RT_TRACE(COMP_POWER_TRACKING,
808 "priv->rfa_txpowertrackingindex_real = %d\n",
809 priv->rfa_txpowertrackingindex_real);
810 RT_TRACE(COMP_POWER_TRACKING,
811 "priv->CCKPresentAttentuation_difference = %d\n",
812 priv->CCKPresentAttentuation_difference);
813 RT_TRACE(COMP_POWER_TRACKING,
814 "priv->CCKPresentAttentuation = %d\n",
815 priv->CCKPresentAttentuation);
817 if (priv->CCKPresentAttentuation_difference <= -12 ||
818 priv->CCKPresentAttentuation_difference >= 24) {
819 priv->rtllib->bdynamic_txpower_enable = true;
820 rtl92e_writeb(dev, Pw_Track_Flag, 0);
821 rtl92e_writeb(dev, FW_Busy_Flag, 0);
822 RT_TRACE(COMP_POWER_TRACKING,
823 "tx power track--->limited\n");
827 rtl92e_writeb(dev, Pw_Track_Flag, 0);
828 Avg_TSSI_Meas_from_driver = 0;
829 for (k = 0; k < 5; k++)
833 rtl92e_writeb(dev, FW_Busy_Flag, 0);
835 priv->rtllib->bdynamic_txpower_enable = true;
836 rtl92e_writeb(dev, Pw_Track_Flag, 0);
839 static void _rtl92e_dm_tx_power_tracking_cb_thermal(struct net_device *dev)
841 #define ThermalMeterVal 9
842 struct r8192_priv *priv = rtllib_priv(dev);
843 u32 tmpRegA, TempCCk;
844 u8 tmpOFDMindex, tmpCCKindex, tmpCCK20Mindex, tmpCCK40Mindex, tmpval;
845 int i = 0, CCKSwingNeedUpdate = 0;
847 if (!priv->btxpower_trackingInit) {
848 tmpRegA = rtl92e_get_bb_reg(dev, rOFDM0_XATxIQImbalance,
850 for (i = 0; i < OFDM_Table_Length; i++) {
851 if (tmpRegA == OFDMSwingTable[i]) {
852 priv->OFDM_index[0] = (u8)i;
853 RT_TRACE(COMP_POWER_TRACKING,
854 "Initial reg0x%x = 0x%x, OFDM_index = 0x%x\n",
855 rOFDM0_XATxIQImbalance, tmpRegA,
856 priv->OFDM_index[0]);
860 TempCCk = rtl92e_get_bb_reg(dev, rCCK0_TxFilter1, bMaskByte2);
861 for (i = 0; i < CCK_Table_length; i++) {
862 if (TempCCk == (u32)CCKSwingTable_Ch1_Ch13[i][0]) {
863 priv->CCK_index = (u8) i;
864 RT_TRACE(COMP_POWER_TRACKING,
865 "Initial reg0x%x = 0x%x, CCK_index = 0x%x\n",
866 rCCK0_TxFilter1, TempCCk,
871 priv->btxpower_trackingInit = true;
875 tmpRegA = rtl92e_get_rf_reg(dev, RF90_PATH_A, 0x12, 0x078);
876 RT_TRACE(COMP_POWER_TRACKING, "Readback ThermalMeterA = %d\n", tmpRegA);
877 if (tmpRegA < 3 || tmpRegA > 13)
881 RT_TRACE(COMP_POWER_TRACKING, "Valid ThermalMeterA = %d\n", tmpRegA);
882 priv->ThermalMeter[0] = ThermalMeterVal;
883 priv->ThermalMeter[1] = ThermalMeterVal;
885 if (priv->ThermalMeter[0] >= (u8)tmpRegA) {
886 tmpOFDMindex = tmpCCK20Mindex = 6+(priv->ThermalMeter[0] -
888 tmpCCK40Mindex = tmpCCK20Mindex - 6;
889 if (tmpOFDMindex >= OFDM_Table_Length)
890 tmpOFDMindex = OFDM_Table_Length-1;
891 if (tmpCCK20Mindex >= CCK_Table_length)
892 tmpCCK20Mindex = CCK_Table_length-1;
893 if (tmpCCK40Mindex >= CCK_Table_length)
894 tmpCCK40Mindex = CCK_Table_length-1;
896 tmpval = ((u8)tmpRegA - priv->ThermalMeter[0]);
898 tmpOFDMindex = tmpCCK20Mindex = 0;
900 tmpOFDMindex = tmpCCK20Mindex = 6 - tmpval;
903 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
904 tmpCCKindex = tmpCCK40Mindex;
906 tmpCCKindex = tmpCCK20Mindex;
908 priv->Record_CCK_20Mindex = tmpCCK20Mindex;
909 priv->Record_CCK_40Mindex = tmpCCK40Mindex;
910 RT_TRACE(COMP_POWER_TRACKING,
911 "Record_CCK_20Mindex / Record_CCK_40Mindex = %d / %d.\n",
912 priv->Record_CCK_20Mindex, priv->Record_CCK_40Mindex);
914 if (priv->rtllib->current_network.channel == 14 &&
915 !priv->bcck_in_ch14) {
916 priv->bcck_in_ch14 = true;
917 CCKSwingNeedUpdate = 1;
918 } else if (priv->rtllib->current_network.channel != 14 &&
919 priv->bcck_in_ch14) {
920 priv->bcck_in_ch14 = false;
921 CCKSwingNeedUpdate = 1;
924 if (priv->CCK_index != tmpCCKindex) {
925 priv->CCK_index = tmpCCKindex;
926 CCKSwingNeedUpdate = 1;
929 if (CCKSwingNeedUpdate)
930 rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
931 if (priv->OFDM_index[0] != tmpOFDMindex) {
932 priv->OFDM_index[0] = tmpOFDMindex;
933 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
934 OFDMSwingTable[priv->OFDM_index[0]]);
935 RT_TRACE(COMP_POWER_TRACKING, "Update OFDMSwing[%d] = 0x%x\n",
937 OFDMSwingTable[priv->OFDM_index[0]]);
939 priv->txpower_count = 0;
942 void rtl92e_dm_txpower_tracking_wq(void *data)
944 struct r8192_priv *priv = container_of_dwork_rsl(data,
945 struct r8192_priv, txpower_tracking_wq);
946 struct net_device *dev = priv->rtllib->dev;
948 if (priv->IC_Cut >= IC_VersionCut_D)
949 _rtl92e_dm_tx_power_tracking_callback_tssi(dev);
951 _rtl92e_dm_tx_power_tracking_cb_thermal(dev);
954 static void _rtl92e_dm_initialize_tx_power_tracking_tssi(struct net_device *dev)
957 struct r8192_priv *priv = rtllib_priv(dev);
959 priv->btxpower_tracking = true;
960 priv->txpower_count = 0;
961 priv->btxpower_trackingInit = false;
965 static void _rtl92e_dm_init_tx_power_tracking_thermal(struct net_device *dev)
967 struct r8192_priv *priv = rtllib_priv(dev);
970 if (priv->rtllib->FwRWRF)
971 priv->btxpower_tracking = true;
973 priv->btxpower_tracking = false;
974 priv->txpower_count = 0;
975 priv->btxpower_trackingInit = false;
976 RT_TRACE(COMP_POWER_TRACKING, "pMgntInfo->bTXPowerTracking = %d\n",
977 priv->btxpower_tracking);
980 void rtl92e_dm_init_txpower_tracking(struct net_device *dev)
982 struct r8192_priv *priv = rtllib_priv(dev);
984 if (priv->IC_Cut >= IC_VersionCut_D)
985 _rtl92e_dm_initialize_tx_power_tracking_tssi(dev);
987 _rtl92e_dm_init_tx_power_tracking_thermal(dev);
990 static void _rtl92e_dm_check_tx_power_tracking_tssi(struct net_device *dev)
992 struct r8192_priv *priv = rtllib_priv(dev);
993 static u32 tx_power_track_counter;
995 RT_TRACE(COMP_POWER_TRACKING, "%s()\n", __func__);
996 if (rtl92e_readb(dev, 0x11e) == 1)
998 if (!priv->btxpower_tracking)
1000 tx_power_track_counter++;
1003 if (tx_power_track_counter >= 180) {
1004 queue_delayed_work_rsl(priv->priv_wq,
1005 &priv->txpower_tracking_wq, 0);
1006 tx_power_track_counter = 0;
1011 static void _rtl92e_dm_check_tx_power_tracking_thermal(struct net_device *dev)
1013 struct r8192_priv *priv = rtllib_priv(dev);
1014 static u8 TM_Trigger;
1015 u8 TxPowerCheckCnt = 0;
1017 if (IS_HARDWARE_TYPE_8192SE(dev))
1018 TxPowerCheckCnt = 5;
1020 TxPowerCheckCnt = 2;
1021 if (!priv->btxpower_tracking)
1024 if (priv->txpower_count <= TxPowerCheckCnt) {
1025 priv->txpower_count++;
1031 rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1032 rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1033 rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4d);
1034 rtl92e_set_rf_reg(dev, RF90_PATH_A, 0x02, bMask12Bits, 0x4f);
1039 netdev_info(dev, "===============>Schedule TxPowerTrackingWorkItem\n");
1040 queue_delayed_work_rsl(priv->priv_wq, &priv->txpower_tracking_wq, 0);
1045 static void _rtl92e_dm_check_tx_power_tracking(struct net_device *dev)
1047 struct r8192_priv *priv = rtllib_priv(dev);
1049 if (priv->IC_Cut >= IC_VersionCut_D)
1050 _rtl92e_dm_check_tx_power_tracking_tssi(dev);
1052 _rtl92e_dm_check_tx_power_tracking_thermal(dev);
1055 static void _rtl92e_dm_cck_tx_power_adjust_tssi(struct net_device *dev,
1059 struct r8192_priv *priv = rtllib_priv(dev);
1060 u8 attenuation = (u8)priv->CCKPresentAttentuation;
1064 TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][0] +
1065 (dm_cck_tx_bb_gain[attenuation][1] << 8));
1067 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1068 TempVal = (u32)((dm_cck_tx_bb_gain[attenuation][2]) +
1069 (dm_cck_tx_bb_gain[attenuation][3] << 8) +
1070 (dm_cck_tx_bb_gain[attenuation][4] << 16)+
1071 (dm_cck_tx_bb_gain[attenuation][5] << 24));
1072 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1073 TempVal = (u32)(dm_cck_tx_bb_gain[attenuation][6] +
1074 (dm_cck_tx_bb_gain[attenuation][7] << 8));
1076 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1078 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][0]) +
1079 (dm_cck_tx_bb_gain_ch14[attenuation][1] << 8));
1081 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1082 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][2]) +
1083 (dm_cck_tx_bb_gain_ch14[attenuation][3] << 8) +
1084 (dm_cck_tx_bb_gain_ch14[attenuation][4] << 16)+
1085 (dm_cck_tx_bb_gain_ch14[attenuation][5] << 24));
1086 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1087 TempVal = (u32)((dm_cck_tx_bb_gain_ch14[attenuation][6]) +
1088 (dm_cck_tx_bb_gain_ch14[attenuation][7] << 8));
1090 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1094 static void _rtl92e_dm_cck_tx_power_adjust_thermal_meter(struct net_device *dev,
1098 struct r8192_priv *priv = rtllib_priv(dev);
1102 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][0] +
1103 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][1] << 8);
1104 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1105 RT_TRACE(COMP_POWER_TRACKING,
1106 "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter1,
1108 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][2] +
1109 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][3] << 8) +
1110 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][4] << 16)+
1111 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][5] << 24);
1112 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1113 RT_TRACE(COMP_POWER_TRACKING,
1114 "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_TxFilter2,
1116 TempVal = CCKSwingTable_Ch1_Ch13[priv->CCK_index][6] +
1117 (CCKSwingTable_Ch1_Ch13[priv->CCK_index][7] << 8);
1119 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1120 RT_TRACE(COMP_POWER_TRACKING,
1121 "CCK not chnl 14, reg 0x%x = 0x%x\n", rCCK0_DebugPort,
1124 TempVal = CCKSwingTable_Ch14[priv->CCK_index][0] +
1125 (CCKSwingTable_Ch14[priv->CCK_index][1] << 8);
1127 rtl92e_set_bb_reg(dev, rCCK0_TxFilter1, bMaskHWord, TempVal);
1128 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1129 rCCK0_TxFilter1, TempVal);
1130 TempVal = CCKSwingTable_Ch14[priv->CCK_index][2] +
1131 (CCKSwingTable_Ch14[priv->CCK_index][3] << 8) +
1132 (CCKSwingTable_Ch14[priv->CCK_index][4] << 16)+
1133 (CCKSwingTable_Ch14[priv->CCK_index][5] << 24);
1134 rtl92e_set_bb_reg(dev, rCCK0_TxFilter2, bMaskDWord, TempVal);
1135 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1136 rCCK0_TxFilter2, TempVal);
1137 TempVal = CCKSwingTable_Ch14[priv->CCK_index][6] +
1138 (CCKSwingTable_Ch14[priv->CCK_index][7]<<8);
1140 rtl92e_set_bb_reg(dev, rCCK0_DebugPort, bMaskLWord, TempVal);
1141 RT_TRACE(COMP_POWER_TRACKING, "CCK chnl 14, reg 0x%x = 0x%x\n",
1142 rCCK0_DebugPort, TempVal);
1146 void rtl92e_dm_cck_txpower_adjust(struct net_device *dev, bool binch14)
1148 struct r8192_priv *priv = rtllib_priv(dev);
1150 if (priv->IC_Cut >= IC_VersionCut_D)
1151 _rtl92e_dm_cck_tx_power_adjust_tssi(dev, binch14);
1153 _rtl92e_dm_cck_tx_power_adjust_thermal_meter(dev, binch14);
1156 static void _rtl92e_dm_tx_power_reset_recovery(struct net_device *dev)
1158 struct r8192_priv *priv = rtllib_priv(dev);
1160 RT_TRACE(COMP_POWER_TRACKING, "Start Reset Recovery ==>\n");
1161 rtl92e_set_bb_reg(dev, rOFDM0_XATxIQImbalance, bMaskDWord,
1162 dm_tx_bb_gain[priv->rfa_txpowertrackingindex]);
1163 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc80 is %08x\n",
1164 dm_tx_bb_gain[priv->rfa_txpowertrackingindex]);
1165 RT_TRACE(COMP_POWER_TRACKING,
1166 "Reset Recovery: Fill in RFA_txPowerTrackingIndex is %x\n",
1167 priv->rfa_txpowertrackingindex);
1168 RT_TRACE(COMP_POWER_TRACKING,
1169 "Reset Recovery : RF A I/Q Amplify Gain is %d\n",
1170 dm_tx_bb_gain_idx_to_amplify(priv->rfa_txpowertrackingindex));
1171 RT_TRACE(COMP_POWER_TRACKING,
1172 "Reset Recovery: CCK Attenuation is %d dB\n",
1173 priv->CCKPresentAttentuation);
1174 rtl92e_dm_cck_txpower_adjust(dev, priv->bcck_in_ch14);
1176 rtl92e_set_bb_reg(dev, rOFDM0_XCTxIQImbalance, bMaskDWord,
1177 dm_tx_bb_gain[priv->rfc_txpowertrackingindex]);
1178 RT_TRACE(COMP_POWER_TRACKING, "Reset Recovery: Fill in 0xc90 is %08x\n",
1179 dm_tx_bb_gain[priv->rfc_txpowertrackingindex]);
1180 RT_TRACE(COMP_POWER_TRACKING,
1181 "Reset Recovery: Fill in RFC_txPowerTrackingIndex is %x\n",
1182 priv->rfc_txpowertrackingindex);
1183 RT_TRACE(COMP_POWER_TRACKING,
1184 "Reset Recovery : RF C I/Q Amplify Gain is %d\n",
1185 dm_tx_bb_gain_idx_to_amplify(priv->rfc_txpowertrackingindex));
1188 void rtl92e_dm_restore_state(struct net_device *dev)
1190 struct r8192_priv *priv = rtllib_priv(dev);
1191 u32 reg_ratr = priv->rate_adaptive.last_ratr;
1196 "<---- rtl92e_dm_restore_state(): driver is going to unload\n");
1200 if (priv->rate_adaptive.rate_adaptive_disabled)
1202 if (!(priv->rtllib->mode == WIRELESS_MODE_N_24G ||
1203 priv->rtllib->mode == WIRELESS_MODE_N_5G))
1205 ratr_value = reg_ratr;
1206 if (priv->rf_type == RF_1T2R)
1207 ratr_value &= ~(RATE_ALL_OFDM_2SS);
1208 rtl92e_writel(dev, RATR0, ratr_value);
1209 rtl92e_writeb(dev, UFWP, 1);
1210 if (priv->btxpower_trackingInit && priv->btxpower_tracking)
1211 _rtl92e_dm_tx_power_reset_recovery(dev);
1213 _rtl92e_dm_bb_initialgain_restore(dev);
1217 static void _rtl92e_dm_bb_initialgain_restore(struct net_device *dev)
1219 struct r8192_priv *priv = rtllib_priv(dev);
1220 u32 bit_mask = 0x7f;
1222 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1225 rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1226 rtl92e_set_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask,
1227 (u32)priv->initgain_backup.xaagccore1);
1228 rtl92e_set_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask,
1229 (u32)priv->initgain_backup.xbagccore1);
1230 rtl92e_set_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask,
1231 (u32)priv->initgain_backup.xcagccore1);
1232 rtl92e_set_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask,
1233 (u32)priv->initgain_backup.xdagccore1);
1234 bit_mask = bMaskByte2;
1235 rtl92e_set_bb_reg(dev, rCCK0_CCA, bit_mask,
1236 (u32)priv->initgain_backup.cca);
1238 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc50 is %x\n",
1239 priv->initgain_backup.xaagccore1);
1240 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc58 is %x\n",
1241 priv->initgain_backup.xbagccore1);
1242 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc60 is %x\n",
1243 priv->initgain_backup.xcagccore1);
1244 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xc68 is %x\n",
1245 priv->initgain_backup.xdagccore1);
1246 RT_TRACE(COMP_DIG, "dm_BBInitialGainRestore 0xa0a is %x\n",
1247 priv->initgain_backup.cca);
1248 rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
1253 void rtl92e_dm_backup_state(struct net_device *dev)
1255 struct r8192_priv *priv = rtllib_priv(dev);
1257 priv->bswitch_fsync = false;
1258 priv->bfsync_processing = false;
1259 _rtl92e_dm_bb_initialgain_backup(dev);
1264 static void _rtl92e_dm_bb_initialgain_backup(struct net_device *dev)
1266 struct r8192_priv *priv = rtllib_priv(dev);
1267 u32 bit_mask = bMaskByte0;
1269 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1272 rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1273 priv->initgain_backup.xaagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XAAGCCore1, bit_mask);
1274 priv->initgain_backup.xbagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XBAGCCore1, bit_mask);
1275 priv->initgain_backup.xcagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XCAGCCore1, bit_mask);
1276 priv->initgain_backup.xdagccore1 = (u8)rtl92e_get_bb_reg(dev, rOFDM0_XDAGCCore1, bit_mask);
1277 bit_mask = bMaskByte2;
1278 priv->initgain_backup.cca = (u8)rtl92e_get_bb_reg(dev, rCCK0_CCA, bit_mask);
1280 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc50 is %x\n",
1281 priv->initgain_backup.xaagccore1);
1282 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc58 is %x\n",
1283 priv->initgain_backup.xbagccore1);
1284 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc60 is %x\n",
1285 priv->initgain_backup.xcagccore1);
1286 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xc68 is %x\n",
1287 priv->initgain_backup.xdagccore1);
1288 RT_TRACE(COMP_DIG, "BBInitialGainBackup 0xa0a is %x\n",
1289 priv->initgain_backup.cca);
1293 static void _rtl92e_dm_dig_init(struct net_device *dev)
1295 struct r8192_priv *priv = rtllib_priv(dev);
1297 dm_digtable.dig_enable_flag = true;
1299 dm_digtable.dig_algorithm = DIG_ALGO_BY_RSSI;
1301 dm_digtable.dig_algorithm_switch = 0;
1303 dm_digtable.dig_state = DM_STA_DIG_MAX;
1304 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1305 dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT;
1306 dm_digtable.PreSTAConnectState = DIG_STA_DISCONNECT;
1308 dm_digtable.rssi_low_thresh = DM_DIG_THRESH_LOW;
1309 dm_digtable.rssi_high_thresh = DM_DIG_THRESH_HIGH;
1311 dm_digtable.rssi_high_power_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
1312 dm_digtable.rssi_high_power_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
1314 dm_digtable.rssi_val = 50;
1315 dm_digtable.backoff_val = DM_DIG_BACKOFF;
1316 dm_digtable.rx_gain_range_max = DM_DIG_MAX;
1317 if (priv->CustomerID == RT_CID_819x_Netcore)
1318 dm_digtable.rx_gain_range_min = DM_DIG_MIN_Netcore;
1320 dm_digtable.rx_gain_range_min = DM_DIG_MIN;
1323 static void _rtl92e_dm_ctrl_initgain_byrssi(struct net_device *dev)
1326 if (dm_digtable.dig_enable_flag == false)
1329 if (dm_digtable.dig_algorithm == DIG_ALGO_BY_FALSE_ALARM)
1330 _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(dev);
1331 else if (dm_digtable.dig_algorithm == DIG_ALGO_BY_RSSI)
1332 _rtl92e_dm_ctrl_initgain_byrssi_driver(dev);
1337 /*-----------------------------------------------------------------------------
1338 * Function: dm_CtrlInitGainBeforeConnectByRssiAndFalseAlarm()
1340 * Overview: Driver monitor RSSI and False Alarm to change initial gain.
1341 Only change initial gain during link in progress.
1343 * Input: IN PADAPTER pAdapter
1351 * 03/04/2009 hpfan Create Version 0.
1353 *---------------------------------------------------------------------------*/
1355 static void _rtl92e_dm_ctrl_initgain_byrssi_driver(struct net_device *dev)
1357 struct r8192_priv *priv = rtllib_priv(dev);
1361 if (dm_digtable.dig_enable_flag == false)
1364 if (dm_digtable.dig_algorithm_switch)
1367 for (i = 0; i < 3; i++)
1368 rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1370 dm_digtable.dig_state = DM_STA_DIG_OFF;
1373 if (priv->rtllib->state == RTLLIB_LINKED)
1374 dm_digtable.CurSTAConnectState = DIG_STA_CONNECT;
1376 dm_digtable.CurSTAConnectState = DIG_STA_DISCONNECT;
1379 dm_digtable.rssi_val = priv->undecorated_smoothed_pwdb;
1380 _rtl92e_dm_initial_gain(dev);
1381 _rtl92e_dm_pd_th(dev);
1382 _rtl92e_dm_cs_ratio(dev);
1383 if (dm_digtable.dig_algorithm_switch)
1384 dm_digtable.dig_algorithm_switch = 0;
1385 dm_digtable.PreSTAConnectState = dm_digtable.CurSTAConnectState;
1389 static void _rtl92e_dm_ctrl_initgain_byrssi_false_alarm(struct net_device *dev)
1391 struct r8192_priv *priv = rtllib_priv(dev);
1392 static u32 reset_cnt;
1395 if (dm_digtable.dig_enable_flag == false)
1398 if (dm_digtable.dig_algorithm_switch) {
1399 dm_digtable.dig_state = DM_STA_DIG_MAX;
1400 for (i = 0; i < 3; i++)
1401 rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
1402 dm_digtable.dig_algorithm_switch = 0;
1405 if (priv->rtllib->state != RTLLIB_LINKED)
1408 if ((priv->undecorated_smoothed_pwdb > dm_digtable.rssi_low_thresh) &&
1409 (priv->undecorated_smoothed_pwdb < dm_digtable.rssi_high_thresh))
1411 if (priv->undecorated_smoothed_pwdb <= dm_digtable.rssi_low_thresh) {
1412 if (dm_digtable.dig_state == DM_STA_DIG_OFF &&
1413 (priv->reset_count == reset_cnt))
1415 reset_cnt = priv->reset_count;
1417 dm_digtable.dig_highpwr_state = DM_STA_DIG_MAX;
1418 dm_digtable.dig_state = DM_STA_DIG_OFF;
1420 rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x8);
1422 rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x17);
1423 rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x17);
1424 rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x17);
1425 rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x17);
1427 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1428 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x00);
1430 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42);
1432 rtl92e_writeb(dev, 0xa0a, 0x08);
1437 if (priv->undecorated_smoothed_pwdb >= dm_digtable.rssi_high_thresh) {
1440 if (dm_digtable.dig_state == DM_STA_DIG_ON &&
1441 (priv->reset_count == reset_cnt)) {
1442 _rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev);
1445 if (priv->reset_count != reset_cnt)
1448 reset_cnt = priv->reset_count;
1450 dm_digtable.dig_state = DM_STA_DIG_ON;
1452 if (reset_flag == 1) {
1453 rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x2c);
1454 rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x2c);
1455 rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x2c);
1456 rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x2c);
1458 rtl92e_writeb(dev, rOFDM0_XAAGCCore1, 0x20);
1459 rtl92e_writeb(dev, rOFDM0_XBAGCCore1, 0x20);
1460 rtl92e_writeb(dev, rOFDM0_XCAGCCore1, 0x20);
1461 rtl92e_writeb(dev, rOFDM0_XDAGCCore1, 0x20);
1464 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1465 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20);
1467 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1469 rtl92e_writeb(dev, 0xa0a, 0xcd);
1471 rtl92e_set_bb_reg(dev, UFWP, bMaskByte1, 0x1);
1473 _rtl92e_dm_ctrl_initgain_byrssi_highpwr(dev);
1477 static void _rtl92e_dm_ctrl_initgain_byrssi_highpwr(struct net_device *dev)
1479 struct r8192_priv *priv = rtllib_priv(dev);
1480 static u32 reset_cnt_highpwr;
1482 if ((priv->undecorated_smoothed_pwdb >
1483 dm_digtable.rssi_high_power_lowthresh) &&
1484 (priv->undecorated_smoothed_pwdb <
1485 dm_digtable.rssi_high_power_highthresh))
1488 if (priv->undecorated_smoothed_pwdb >=
1489 dm_digtable.rssi_high_power_highthresh) {
1490 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_ON &&
1491 (priv->reset_count == reset_cnt_highpwr))
1493 dm_digtable.dig_highpwr_state = DM_STA_DIG_ON;
1495 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1496 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x10);
1498 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43);
1500 if (dm_digtable.dig_highpwr_state == DM_STA_DIG_OFF &&
1501 (priv->reset_count == reset_cnt_highpwr))
1503 dm_digtable.dig_highpwr_state = DM_STA_DIG_OFF;
1505 if ((priv->undecorated_smoothed_pwdb <
1506 dm_digtable.rssi_high_power_lowthresh) &&
1507 (priv->undecorated_smoothed_pwdb >=
1508 dm_digtable.rssi_high_thresh)) {
1509 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1510 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20);
1512 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1515 reset_cnt_highpwr = priv->reset_count;
1518 static void _rtl92e_dm_initial_gain(struct net_device *dev)
1520 struct r8192_priv *priv = rtllib_priv(dev);
1521 u8 initial_gain = 0;
1522 static u8 initialized, force_write;
1523 static u32 reset_cnt;
1525 if (dm_digtable.dig_algorithm_switch) {
1530 if (rtllib_act_scanning(priv->rtllib, true) == true) {
1535 if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1536 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1537 long gain_range = dm_digtable.rssi_val + 10 -
1538 dm_digtable.backoff_val;
1539 gain_range = clamp_t(long, gain_range,
1540 dm_digtable.rx_gain_range_min,
1541 dm_digtable.rx_gain_range_max);
1542 dm_digtable.cur_ig_value = gain_range;
1544 if (dm_digtable.cur_ig_value == 0)
1545 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1547 dm_digtable.cur_ig_value = dm_digtable.pre_ig_value;
1550 dm_digtable.cur_ig_value = priv->DefaultInitialGain[0];
1551 dm_digtable.pre_ig_value = 0;
1554 if (priv->reset_count != reset_cnt) {
1556 reset_cnt = priv->reset_count;
1559 if (dm_digtable.pre_ig_value != rtl92e_readb(dev, rOFDM0_XAAGCCore1))
1562 if ((dm_digtable.pre_ig_value != dm_digtable.cur_ig_value)
1563 || !initialized || force_write) {
1564 initial_gain = (u8)dm_digtable.cur_ig_value;
1565 rtl92e_writeb(dev, rOFDM0_XAAGCCore1, initial_gain);
1566 rtl92e_writeb(dev, rOFDM0_XBAGCCore1, initial_gain);
1567 rtl92e_writeb(dev, rOFDM0_XCAGCCore1, initial_gain);
1568 rtl92e_writeb(dev, rOFDM0_XDAGCCore1, initial_gain);
1569 dm_digtable.pre_ig_value = dm_digtable.cur_ig_value;
1575 static void _rtl92e_dm_pd_th(struct net_device *dev)
1577 struct r8192_priv *priv = rtllib_priv(dev);
1578 static u8 initialized, force_write;
1579 static u32 reset_cnt;
1581 if (dm_digtable.dig_algorithm_switch) {
1586 if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1587 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1588 if (dm_digtable.rssi_val >=
1589 dm_digtable.rssi_high_power_highthresh)
1590 dm_digtable.curpd_thstate =
1591 DIG_PD_AT_HIGH_POWER;
1592 else if (dm_digtable.rssi_val <=
1593 dm_digtable.rssi_low_thresh)
1594 dm_digtable.curpd_thstate =
1595 DIG_PD_AT_LOW_POWER;
1596 else if ((dm_digtable.rssi_val >=
1597 dm_digtable.rssi_high_thresh) &&
1598 (dm_digtable.rssi_val <
1599 dm_digtable.rssi_high_power_lowthresh))
1600 dm_digtable.curpd_thstate =
1601 DIG_PD_AT_NORMAL_POWER;
1603 dm_digtable.curpd_thstate =
1604 dm_digtable.prepd_thstate;
1606 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1609 dm_digtable.curpd_thstate = DIG_PD_AT_LOW_POWER;
1612 if (priv->reset_count != reset_cnt) {
1614 reset_cnt = priv->reset_count;
1617 if ((dm_digtable.prepd_thstate != dm_digtable.curpd_thstate) ||
1618 (initialized <= 3) || force_write) {
1619 if (dm_digtable.curpd_thstate == DIG_PD_AT_LOW_POWER) {
1620 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1621 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x00);
1623 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x42);
1624 } else if (dm_digtable.curpd_thstate ==
1625 DIG_PD_AT_NORMAL_POWER) {
1626 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1627 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x20);
1629 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x44);
1630 } else if (dm_digtable.curpd_thstate == DIG_PD_AT_HIGH_POWER) {
1631 if (priv->CurrentChannelBW != HT_CHANNEL_WIDTH_20)
1632 rtl92e_writeb(dev, (rOFDM0_XATxAFE+3), 0x10);
1634 rtl92e_writeb(dev, rOFDM0_RxDetector1, 0x43);
1636 dm_digtable.prepd_thstate = dm_digtable.curpd_thstate;
1637 if (initialized <= 3)
1643 static void _rtl92e_dm_cs_ratio(struct net_device *dev)
1645 struct r8192_priv *priv = rtllib_priv(dev);
1646 static u8 initialized, force_write;
1647 static u32 reset_cnt;
1649 if (dm_digtable.dig_algorithm_switch) {
1654 if (dm_digtable.PreSTAConnectState == dm_digtable.CurSTAConnectState) {
1655 if (dm_digtable.CurSTAConnectState == DIG_STA_CONNECT) {
1656 if (dm_digtable.rssi_val <= dm_digtable.rssi_low_thresh)
1657 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1658 else if (dm_digtable.rssi_val >= dm_digtable.rssi_high_thresh)
1659 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_HIGHER;
1661 dm_digtable.curcs_ratio_state = dm_digtable.precs_ratio_state;
1663 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1666 dm_digtable.curcs_ratio_state = DIG_CS_RATIO_LOWER;
1669 if (priv->reset_count != reset_cnt) {
1671 reset_cnt = priv->reset_count;
1675 if ((dm_digtable.precs_ratio_state != dm_digtable.curcs_ratio_state) ||
1676 !initialized || force_write) {
1677 if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_LOWER)
1678 rtl92e_writeb(dev, 0xa0a, 0x08);
1679 else if (dm_digtable.curcs_ratio_state == DIG_CS_RATIO_HIGHER)
1680 rtl92e_writeb(dev, 0xa0a, 0xcd);
1681 dm_digtable.precs_ratio_state = dm_digtable.curcs_ratio_state;
1687 void rtl92e_dm_init_edca_turbo(struct net_device *dev)
1689 struct r8192_priv *priv = rtllib_priv(dev);
1691 priv->bcurrent_turbo_EDCA = false;
1692 priv->rtllib->bis_any_nonbepkts = false;
1693 priv->bis_cur_rdlstate = false;
1696 static void _rtl92e_dm_check_edca_turbo(struct net_device *dev)
1698 struct r8192_priv *priv = rtllib_priv(dev);
1699 struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1701 static unsigned long lastTxOkCnt;
1702 static unsigned long lastRxOkCnt;
1703 unsigned long curTxOkCnt = 0;
1704 unsigned long curRxOkCnt = 0;
1706 if (priv->rtllib->iw_mode == IW_MODE_ADHOC)
1707 goto dm_CheckEdcaTurbo_EXIT;
1708 if (priv->rtllib->state != RTLLIB_LINKED)
1709 goto dm_CheckEdcaTurbo_EXIT;
1710 if (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_DISABLE_EDCA_TURBO)
1711 goto dm_CheckEdcaTurbo_EXIT;
1714 u8 *peername[11] = {
1715 "unknown", "realtek_90", "realtek_92se", "broadcom",
1716 "ralink", "atheros", "cisco", "marvell", "92u_softap",
1723 "%s():iot peer is %s, bssid: %pM\n",
1724 __func__, peername[pHTInfo->IOTPeer],
1725 priv->rtllib->current_network.bssid);
1729 if (!priv->rtllib->bis_any_nonbepkts) {
1730 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1731 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1732 if (pHTInfo->IOTAction & HT_IOT_ACT_EDCA_BIAS_ON_RX) {
1733 if (curTxOkCnt > 4*curRxOkCnt) {
1734 if (priv->bis_cur_rdlstate ||
1735 !priv->bcurrent_turbo_EDCA) {
1736 rtl92e_writel(dev, EDCAPARA_BE,
1737 edca_setting_UL[pHTInfo->IOTPeer]);
1738 priv->bis_cur_rdlstate = false;
1741 if (!priv->bis_cur_rdlstate ||
1742 !priv->bcurrent_turbo_EDCA) {
1743 if (priv->rtllib->mode == WIRELESS_MODE_G)
1744 rtl92e_writel(dev, EDCAPARA_BE,
1745 edca_setting_DL_GMode[pHTInfo->IOTPeer]);
1747 rtl92e_writel(dev, EDCAPARA_BE,
1748 edca_setting_DL[pHTInfo->IOTPeer]);
1749 priv->bis_cur_rdlstate = true;
1752 priv->bcurrent_turbo_EDCA = true;
1754 if (curRxOkCnt > 4*curTxOkCnt) {
1755 if (!priv->bis_cur_rdlstate ||
1756 !priv->bcurrent_turbo_EDCA) {
1757 if (priv->rtllib->mode == WIRELESS_MODE_G)
1758 rtl92e_writel(dev, EDCAPARA_BE,
1759 edca_setting_DL_GMode[pHTInfo->IOTPeer]);
1761 rtl92e_writel(dev, EDCAPARA_BE,
1762 edca_setting_DL[pHTInfo->IOTPeer]);
1763 priv->bis_cur_rdlstate = true;
1766 if (priv->bis_cur_rdlstate ||
1767 !priv->bcurrent_turbo_EDCA) {
1768 rtl92e_writel(dev, EDCAPARA_BE,
1769 edca_setting_UL[pHTInfo->IOTPeer]);
1770 priv->bis_cur_rdlstate = false;
1775 priv->bcurrent_turbo_EDCA = true;
1778 if (priv->bcurrent_turbo_EDCA) {
1781 priv->rtllib->SetHwRegHandler(dev, HW_VAR_AC_PARAM,
1783 priv->bcurrent_turbo_EDCA = false;
1788 dm_CheckEdcaTurbo_EXIT:
1789 priv->rtllib->bis_any_nonbepkts = false;
1790 lastTxOkCnt = priv->stats.txbytesunicast;
1791 lastRxOkCnt = priv->stats.rxbytesunicast;
1794 static void _rtl92e_dm_init_cts_to_self(struct net_device *dev)
1796 struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1798 priv->rtllib->bCTSToSelfEnable = true;
1801 static void _rtl92e_dm_cts_to_self(struct net_device *dev)
1803 struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1804 struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1805 static unsigned long lastTxOkCnt;
1806 static unsigned long lastRxOkCnt;
1807 unsigned long curTxOkCnt = 0;
1808 unsigned long curRxOkCnt = 0;
1810 if (priv->rtllib->bCTSToSelfEnable != true) {
1811 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1814 if (pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
1815 curTxOkCnt = priv->stats.txbytesunicast - lastTxOkCnt;
1816 curRxOkCnt = priv->stats.rxbytesunicast - lastRxOkCnt;
1817 if (curRxOkCnt > 4*curTxOkCnt)
1818 pHTInfo->IOTAction &= ~HT_IOT_ACT_FORCED_CTS2SELF;
1820 pHTInfo->IOTAction |= HT_IOT_ACT_FORCED_CTS2SELF;
1822 lastTxOkCnt = priv->stats.txbytesunicast;
1823 lastRxOkCnt = priv->stats.rxbytesunicast;
1828 static void _rtl92e_dm_init_wa_broadcom_iot(struct net_device *dev)
1830 struct r8192_priv *priv = rtllib_priv((struct net_device *)dev);
1831 struct rt_hi_throughput *pHTInfo = priv->rtllib->pHTInfo;
1833 pHTInfo->bWAIotBroadcom = false;
1834 pHTInfo->WAIotTH = WAIotTHVal;
1837 static void _rtl92e_dm_check_pbc_gpio(struct net_device *dev)
1841 static void _rtl92e_dm_check_rf_ctrl_gpio(void *data)
1843 struct r8192_priv *priv = container_of_dwork_rsl(data,
1844 struct r8192_priv, gpio_change_rf_wq);
1845 struct net_device *dev = priv->rtllib->dev;
1847 enum rt_rf_power_state eRfPowerStateToSet;
1848 bool bActuallySet = false;
1850 static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
1851 static char *envp[] = {"HOME=/", "TERM=linux", "PATH=/usr/bin:/bin",
1854 bActuallySet = false;
1856 if ((priv->up_first_time == 1) || (priv->being_init_adapter))
1859 if (priv->bfirst_after_down) {
1860 priv->bfirst_after_down = true;
1864 tmp1byte = rtl92e_readb(dev, GPI);
1866 eRfPowerStateToSet = (tmp1byte&BIT1) ? eRfOn : eRfOff;
1868 if (priv->bHwRadioOff && (eRfPowerStateToSet == eRfOn)) {
1869 RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio ON\n");
1870 netdev_info(dev, "gpiochangeRF - HW Radio ON\n");
1871 priv->bHwRadioOff = false;
1872 bActuallySet = true;
1873 } else if (!priv->bHwRadioOff && (eRfPowerStateToSet == eRfOff)) {
1874 RT_TRACE(COMP_RF, "gpiochangeRF - HW Radio OFF\n");
1875 netdev_info(dev, "gpiochangeRF - HW Radio OFF\n");
1876 priv->bHwRadioOff = true;
1877 bActuallySet = true;
1882 priv->bHwRfOffAction = 1;
1883 rtl92e_set_rf_state(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
1884 if (priv->bHwRadioOff)
1889 argv[0] = RadioPowerPath;
1891 call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
1895 void rtl92e_dm_rf_pathcheck_wq(void *data)
1897 struct r8192_priv *priv = container_of_dwork_rsl(data,
1900 struct net_device *dev = priv->rtllib->dev;
1903 rfpath = rtl92e_readb(dev, 0xc04);
1905 for (i = 0; i < RF90_PATH_MAX; i++) {
1906 if (rfpath & (0x01<<i))
1907 priv->brfpath_rxenable[i] = true;
1909 priv->brfpath_rxenable[i] = false;
1911 if (!DM_RxPathSelTable.Enable)
1914 _rtl92e_dm_rx_path_sel_byrssi(dev);
1917 static void _rtl92e_dm_init_rx_path_selection(struct net_device *dev)
1920 struct r8192_priv *priv = rtllib_priv(dev);
1922 DM_RxPathSelTable.Enable = 1;
1923 DM_RxPathSelTable.SS_TH_low = RxPathSelection_SS_TH_low;
1924 DM_RxPathSelTable.diff_TH = RxPathSelection_diff_TH;
1925 if (priv->CustomerID == RT_CID_819x_Netcore)
1926 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1928 DM_RxPathSelTable.cck_method = CCK_Rx_Version_1;
1929 DM_RxPathSelTable.disabledRF = 0;
1930 for (i = 0; i < 4; i++) {
1931 DM_RxPathSelTable.rf_rssi[i] = 50;
1932 DM_RxPathSelTable.cck_pwdb_sta[i] = -64;
1933 DM_RxPathSelTable.rf_enable_rssi_th[i] = 100;
1937 #define PWDB_IN_RANGE ((cur_cck_pwdb < tmp_cck_max_pwdb) && \
1938 (cur_cck_pwdb > tmp_cck_sec_pwdb))
1940 static void _rtl92e_dm_rx_path_sel_byrssi(struct net_device *dev)
1942 struct r8192_priv *priv = rtllib_priv(dev);
1943 u8 i, max_rssi_index = 0, min_rssi_index = 0;
1944 u8 sec_rssi_index = 0, rf_num = 0;
1945 u8 tmp_max_rssi = 0, tmp_min_rssi = 0, tmp_sec_rssi = 0;
1946 u8 cck_default_Rx = 0x2;
1947 u8 cck_optional_Rx = 0x3;
1948 long tmp_cck_max_pwdb = 0, tmp_cck_min_pwdb = 0, tmp_cck_sec_pwdb = 0;
1949 u8 cck_rx_ver2_max_index = 0, cck_rx_ver2_min_index = 0;
1950 u8 cck_rx_ver2_sec_index = 0;
1953 static u8 disabled_rf_cnt, cck_Rx_Path_initialized;
1954 u8 update_cck_rx_path;
1956 if (priv->rf_type != RF_2T4R)
1959 if (!cck_Rx_Path_initialized) {
1960 DM_RxPathSelTable.cck_Rx_path = (rtl92e_readb(dev, 0xa07)&0xf);
1961 cck_Rx_Path_initialized = 1;
1964 DM_RxPathSelTable.disabledRF = 0xf;
1965 DM_RxPathSelTable.disabledRF &= ~(rtl92e_readb(dev, 0xc04));
1967 if (priv->rtllib->mode == WIRELESS_MODE_B)
1968 DM_RxPathSelTable.cck_method = CCK_Rx_Version_2;
1970 for (i = 0; i < RF90_PATH_MAX; i++) {
1971 DM_RxPathSelTable.rf_rssi[i] = priv->stats.rx_rssi_percentage[i];
1973 if (priv->brfpath_rxenable[i]) {
1975 cur_rf_rssi = DM_RxPathSelTable.rf_rssi[i];
1978 max_rssi_index = min_rssi_index = sec_rssi_index = i;
1979 tmp_max_rssi = tmp_min_rssi = tmp_sec_rssi = cur_rf_rssi;
1980 } else if (rf_num == 2) {
1981 if (cur_rf_rssi >= tmp_max_rssi) {
1982 tmp_max_rssi = cur_rf_rssi;
1985 tmp_sec_rssi = tmp_min_rssi = cur_rf_rssi;
1986 sec_rssi_index = min_rssi_index = i;
1989 if (cur_rf_rssi > tmp_max_rssi) {
1990 tmp_sec_rssi = tmp_max_rssi;
1991 sec_rssi_index = max_rssi_index;
1992 tmp_max_rssi = cur_rf_rssi;
1994 } else if (cur_rf_rssi == tmp_max_rssi) {
1995 tmp_sec_rssi = cur_rf_rssi;
1997 } else if ((cur_rf_rssi < tmp_max_rssi) &&
1998 (cur_rf_rssi > tmp_sec_rssi)) {
1999 tmp_sec_rssi = cur_rf_rssi;
2001 } else if (cur_rf_rssi == tmp_sec_rssi) {
2002 if (tmp_sec_rssi == tmp_min_rssi) {
2003 tmp_sec_rssi = cur_rf_rssi;
2006 } else if ((cur_rf_rssi < tmp_sec_rssi) &&
2007 (cur_rf_rssi > tmp_min_rssi)) {
2009 } else if (cur_rf_rssi == tmp_min_rssi) {
2010 if (tmp_sec_rssi == tmp_min_rssi) {
2011 tmp_min_rssi = cur_rf_rssi;
2014 } else if (cur_rf_rssi < tmp_min_rssi) {
2015 tmp_min_rssi = cur_rf_rssi;
2023 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2024 for (i = 0; i < RF90_PATH_MAX; i++) {
2025 if (priv->brfpath_rxenable[i]) {
2028 DM_RxPathSelTable.cck_pwdb_sta[i];
2031 cck_rx_ver2_max_index = i;
2032 cck_rx_ver2_min_index = i;
2033 cck_rx_ver2_sec_index = i;
2034 tmp_cck_max_pwdb = cur_cck_pwdb;
2035 tmp_cck_min_pwdb = cur_cck_pwdb;
2036 tmp_cck_sec_pwdb = cur_cck_pwdb;
2037 } else if (rf_num == 2) {
2038 if (cur_cck_pwdb >= tmp_cck_max_pwdb) {
2039 tmp_cck_max_pwdb = cur_cck_pwdb;
2040 cck_rx_ver2_max_index = i;
2042 tmp_cck_sec_pwdb = cur_cck_pwdb;
2043 tmp_cck_min_pwdb = cur_cck_pwdb;
2044 cck_rx_ver2_sec_index = i;
2045 cck_rx_ver2_min_index = i;
2048 if (cur_cck_pwdb > tmp_cck_max_pwdb) {
2051 cck_rx_ver2_sec_index =
2052 cck_rx_ver2_max_index;
2053 tmp_cck_max_pwdb = cur_cck_pwdb;
2054 cck_rx_ver2_max_index = i;
2055 } else if (cur_cck_pwdb ==
2057 tmp_cck_sec_pwdb = cur_cck_pwdb;
2058 cck_rx_ver2_sec_index = i;
2059 } else if (PWDB_IN_RANGE) {
2060 tmp_cck_sec_pwdb = cur_cck_pwdb;
2061 cck_rx_ver2_sec_index = i;
2062 } else if (cur_cck_pwdb ==
2064 if (tmp_cck_sec_pwdb ==
2068 cck_rx_ver2_sec_index =
2071 } else if ((cur_cck_pwdb < tmp_cck_sec_pwdb) &&
2072 (cur_cck_pwdb > tmp_cck_min_pwdb)) {
2074 } else if (cur_cck_pwdb == tmp_cck_min_pwdb) {
2075 if (tmp_cck_sec_pwdb == tmp_cck_min_pwdb) {
2076 tmp_cck_min_pwdb = cur_cck_pwdb;
2077 cck_rx_ver2_min_index = i;
2079 } else if (cur_cck_pwdb < tmp_cck_min_pwdb) {
2080 tmp_cck_min_pwdb = cur_cck_pwdb;
2081 cck_rx_ver2_min_index = i;
2089 update_cck_rx_path = 0;
2090 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_2) {
2091 cck_default_Rx = cck_rx_ver2_max_index;
2092 cck_optional_Rx = cck_rx_ver2_sec_index;
2093 if (tmp_cck_max_pwdb != -64)
2094 update_cck_rx_path = 1;
2097 if (tmp_min_rssi < DM_RxPathSelTable.SS_TH_low && disabled_rf_cnt < 2) {
2098 if ((tmp_max_rssi - tmp_min_rssi) >=
2099 DM_RxPathSelTable.diff_TH) {
2100 DM_RxPathSelTable.rf_enable_rssi_th[min_rssi_index] =
2102 rtl92e_set_bb_reg(dev, rOFDM0_TRxPathEnable,
2103 0x1<<min_rssi_index, 0x0);
2104 rtl92e_set_bb_reg(dev, rOFDM1_TRxPathEnable,
2105 0x1<<min_rssi_index, 0x0);
2108 if (DM_RxPathSelTable.cck_method == CCK_Rx_Version_1) {
2109 cck_default_Rx = max_rssi_index;
2110 cck_optional_Rx = sec_rssi_index;
2112 update_cck_rx_path = 1;
2116 if (update_cck_rx_path) {
2117 DM_RxPathSelTable.cck_Rx_path = (cck_default_Rx<<2) |
2119 rtl92e_set_bb_reg(dev, rCCK0_AFESetting, 0x0f000000,
2120 DM_RxPathSelTable.cck_Rx_path);
2123 if (DM_RxPathSelTable.disabledRF) {
2124 for (i = 0; i < 4; i++) {
2125 if ((DM_RxPathSelTable.disabledRF>>i) & 0x1) {
2127 DM_RxPathSelTable.rf_enable_rssi_th[i]) {
2128 rtl92e_set_bb_reg(dev,
2129 rOFDM0_TRxPathEnable,
2131 rtl92e_set_bb_reg(dev,
2132 rOFDM1_TRxPathEnable,
2134 DM_RxPathSelTable.rf_enable_rssi_th[i]
2143 static void _rtl92e_dm_check_rx_path_selection(struct net_device *dev)
2145 struct r8192_priv *priv = rtllib_priv(dev);
2147 queue_delayed_work_rsl(priv->priv_wq, &priv->rfpath_check_wq, 0);
2151 static void _rtl92e_dm_init_fsync(struct net_device *dev)
2153 struct r8192_priv *priv = rtllib_priv(dev);
2155 priv->rtllib->fsync_time_interval = 500;
2156 priv->rtllib->fsync_rate_bitmap = 0x0f000800;
2157 priv->rtllib->fsync_rssi_threshold = 30;
2158 priv->rtllib->bfsync_enable = false;
2159 priv->rtllib->fsync_multiple_timeinterval = 3;
2160 priv->rtllib->fsync_firstdiff_ratethreshold = 100;
2161 priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2162 priv->rtllib->fsync_state = Default_Fsync;
2163 priv->framesyncMonitor = 1;
2165 setup_timer(&priv->fsync_timer, _rtl92e_dm_fsync_timer_callback,
2166 (unsigned long)dev);
2170 static void _rtl92e_dm_deinit_fsync(struct net_device *dev)
2172 struct r8192_priv *priv = rtllib_priv(dev);
2174 del_timer_sync(&priv->fsync_timer);
2177 static void _rtl92e_dm_fsync_timer_callback(unsigned long data)
2179 struct net_device *dev = (struct net_device *)data;
2180 struct r8192_priv *priv = rtllib_priv((struct net_device *)data);
2181 u32 rate_index, rate_count = 0, rate_count_diff = 0;
2182 bool bSwitchFromCountDiff = false;
2183 bool bDoubleTimeInterval = false;
2185 if (priv->rtllib->state == RTLLIB_LINKED &&
2186 priv->rtllib->bfsync_enable &&
2187 (priv->rtllib->pHTInfo->IOTAction & HT_IOT_ACT_CDD_FSYNC)) {
2190 for (rate_index = 0; rate_index <= 27; rate_index++) {
2191 rate_bitmap = 1 << rate_index;
2192 if (priv->rtllib->fsync_rate_bitmap & rate_bitmap)
2194 priv->stats.received_rate_histogram[1]
2198 if (rate_count < priv->rate_record)
2199 rate_count_diff = 0xffffffff - rate_count +
2202 rate_count_diff = rate_count - priv->rate_record;
2203 if (rate_count_diff < priv->rateCountDiffRecord) {
2205 u32 DiffNum = priv->rateCountDiffRecord -
2208 priv->rtllib->fsync_seconddiff_ratethreshold)
2209 priv->ContinueDiffCount++;
2211 priv->ContinueDiffCount = 0;
2213 if (priv->ContinueDiffCount >= 2) {
2214 bSwitchFromCountDiff = true;
2215 priv->ContinueDiffCount = 0;
2218 priv->ContinueDiffCount = 0;
2221 if (rate_count_diff <=
2222 priv->rtllib->fsync_firstdiff_ratethreshold) {
2223 bSwitchFromCountDiff = true;
2224 priv->ContinueDiffCount = 0;
2226 priv->rate_record = rate_count;
2227 priv->rateCountDiffRecord = rate_count_diff;
2228 RT_TRACE(COMP_HALDM,
2229 "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n",
2230 priv->rate_record, rate_count, rate_count_diff,
2231 priv->bswitch_fsync);
2232 if (priv->undecorated_smoothed_pwdb >
2233 priv->rtllib->fsync_rssi_threshold &&
2234 bSwitchFromCountDiff) {
2235 bDoubleTimeInterval = true;
2236 priv->bswitch_fsync = !priv->bswitch_fsync;
2237 if (priv->bswitch_fsync) {
2238 rtl92e_writeb(dev, 0xC36, 0x1c);
2239 rtl92e_writeb(dev, 0xC3e, 0x90);
2241 rtl92e_writeb(dev, 0xC36, 0x5c);
2242 rtl92e_writeb(dev, 0xC3e, 0x96);
2244 } else if (priv->undecorated_smoothed_pwdb <=
2245 priv->rtllib->fsync_rssi_threshold) {
2246 if (priv->bswitch_fsync) {
2247 priv->bswitch_fsync = false;
2248 rtl92e_writeb(dev, 0xC36, 0x5c);
2249 rtl92e_writeb(dev, 0xC3e, 0x96);
2252 if (bDoubleTimeInterval) {
2253 if (timer_pending(&priv->fsync_timer))
2254 del_timer_sync(&priv->fsync_timer);
2255 priv->fsync_timer.expires = jiffies +
2256 msecs_to_jiffies(priv->rtllib->fsync_time_interval *
2257 priv->rtllib->fsync_multiple_timeinterval);
2258 add_timer(&priv->fsync_timer);
2260 if (timer_pending(&priv->fsync_timer))
2261 del_timer_sync(&priv->fsync_timer);
2262 priv->fsync_timer.expires = jiffies +
2263 msecs_to_jiffies(priv->rtllib->fsync_time_interval);
2264 add_timer(&priv->fsync_timer);
2267 if (priv->bswitch_fsync) {
2268 priv->bswitch_fsync = false;
2269 rtl92e_writeb(dev, 0xC36, 0x5c);
2270 rtl92e_writeb(dev, 0xC3e, 0x96);
2272 priv->ContinueDiffCount = 0;
2273 rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
2275 RT_TRACE(COMP_HALDM, "ContinueDiffCount %d\n", priv->ContinueDiffCount);
2276 RT_TRACE(COMP_HALDM,
2277 "rateRecord %d rateCount %d, rateCountdiff %d bSwitchFsync %d\n",
2278 priv->rate_record, rate_count, rate_count_diff,
2279 priv->bswitch_fsync);
2282 static void _rtl92e_dm_start_hw_fsync(struct net_device *dev)
2284 u8 rf_timing = 0x77;
2285 struct r8192_priv *priv = rtllib_priv(dev);
2287 RT_TRACE(COMP_HALDM, "%s\n", __func__);
2288 rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cf);
2289 priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING,
2290 (u8 *)(&rf_timing));
2291 rtl92e_writeb(dev, 0xc3b, 0x41);
2294 static void _rtl92e_dm_end_hw_fsync(struct net_device *dev)
2296 u8 rf_timing = 0xaa;
2297 struct r8192_priv *priv = rtllib_priv(dev);
2299 RT_TRACE(COMP_HALDM, "%s\n", __func__);
2300 rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
2301 priv->rtllib->SetHwRegHandler(dev, HW_VAR_RF_TIMING, (u8 *)
2303 rtl92e_writeb(dev, 0xc3b, 0x49);
2306 static void _rtl92e_dm_end_sw_fsync(struct net_device *dev)
2308 struct r8192_priv *priv = rtllib_priv(dev);
2310 RT_TRACE(COMP_HALDM, "%s\n", __func__);
2311 del_timer_sync(&(priv->fsync_timer));
2313 if (priv->bswitch_fsync) {
2314 priv->bswitch_fsync = false;
2316 rtl92e_writeb(dev, 0xC36, 0x5c);
2318 rtl92e_writeb(dev, 0xC3e, 0x96);
2321 priv->ContinueDiffCount = 0;
2322 rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c52cd);
2325 static void _rtl92e_dm_start_sw_fsync(struct net_device *dev)
2327 struct r8192_priv *priv = rtllib_priv(dev);
2331 RT_TRACE(COMP_HALDM, "%s\n", __func__);
2332 priv->rate_record = 0;
2333 priv->ContinueDiffCount = 0;
2334 priv->rateCountDiffRecord = 0;
2335 priv->bswitch_fsync = false;
2337 if (priv->rtllib->mode == WIRELESS_MODE_N_24G) {
2338 priv->rtllib->fsync_firstdiff_ratethreshold = 600;
2339 priv->rtllib->fsync_seconddiff_ratethreshold = 0xffff;
2341 priv->rtllib->fsync_firstdiff_ratethreshold = 200;
2342 priv->rtllib->fsync_seconddiff_ratethreshold = 200;
2344 for (rateIndex = 0; rateIndex <= 27; rateIndex++) {
2345 rateBitmap = 1 << rateIndex;
2346 if (priv->rtllib->fsync_rate_bitmap & rateBitmap)
2347 priv->rate_record +=
2348 priv->stats.received_rate_histogram[1]
2351 if (timer_pending(&priv->fsync_timer))
2352 del_timer_sync(&priv->fsync_timer);
2353 priv->fsync_timer.expires = jiffies +
2354 msecs_to_jiffies(priv->rtllib->fsync_time_interval);
2355 add_timer(&priv->fsync_timer);
2357 rtl92e_writel(dev, rOFDM0_RxDetector2, 0x465c12cd);
2361 static void _rtl92e_dm_check_fsync(struct net_device *dev)
2363 #define RegC38_Default 0
2364 #define RegC38_NonFsync_Other_AP 1
2365 #define RegC38_Fsync_AP_BCM 2
2366 struct r8192_priv *priv = rtllib_priv(dev);
2367 static u8 reg_c38_State = RegC38_Default;
2368 static u32 reset_cnt;
2370 RT_TRACE(COMP_HALDM,
2371 "RSSI %d TimeInterval %d MultipleTimeInterval %d\n",
2372 priv->rtllib->fsync_rssi_threshold,
2373 priv->rtllib->fsync_time_interval,
2374 priv->rtllib->fsync_multiple_timeinterval);
2375 RT_TRACE(COMP_HALDM,
2376 "RateBitmap 0x%x FirstDiffRateThreshold %d SecondDiffRateThreshold %d\n",
2377 priv->rtllib->fsync_rate_bitmap,
2378 priv->rtllib->fsync_firstdiff_ratethreshold,
2379 priv->rtllib->fsync_seconddiff_ratethreshold);
2381 if (priv->rtllib->state == RTLLIB_LINKED &&
2382 priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_BROADCOM) {
2383 if (priv->rtllib->bfsync_enable == 0) {
2384 switch (priv->rtllib->fsync_state) {
2386 _rtl92e_dm_start_hw_fsync(dev);
2387 priv->rtllib->fsync_state = HW_Fsync;
2390 _rtl92e_dm_end_sw_fsync(dev);
2391 _rtl92e_dm_start_hw_fsync(dev);
2392 priv->rtllib->fsync_state = HW_Fsync;
2399 switch (priv->rtllib->fsync_state) {
2401 _rtl92e_dm_start_sw_fsync(dev);
2402 priv->rtllib->fsync_state = SW_Fsync;
2405 _rtl92e_dm_end_hw_fsync(dev);
2406 _rtl92e_dm_start_sw_fsync(dev);
2407 priv->rtllib->fsync_state = SW_Fsync;
2415 if (priv->framesyncMonitor) {
2416 if (reg_c38_State != RegC38_Fsync_AP_BCM) {
2417 rtl92e_writeb(dev, rOFDM0_RxDetector3, 0x95);
2419 reg_c38_State = RegC38_Fsync_AP_BCM;
2423 switch (priv->rtllib->fsync_state) {
2425 _rtl92e_dm_end_hw_fsync(dev);
2426 priv->rtllib->fsync_state = Default_Fsync;
2429 _rtl92e_dm_end_sw_fsync(dev);
2430 priv->rtllib->fsync_state = Default_Fsync;
2437 if (priv->framesyncMonitor) {
2438 if (priv->rtllib->state == RTLLIB_LINKED) {
2439 if (priv->undecorated_smoothed_pwdb <=
2441 if (reg_c38_State !=
2442 RegC38_NonFsync_Other_AP) {
2448 RegC38_NonFsync_Other_AP;
2450 } else if (priv->undecorated_smoothed_pwdb >=
2452 if (reg_c38_State) {
2456 reg_c38_State = RegC38_Default;
2460 if (reg_c38_State) {
2461 rtl92e_writeb(dev, rOFDM0_RxDetector3,
2463 reg_c38_State = RegC38_Default;
2468 if (priv->framesyncMonitor) {
2469 if (priv->reset_count != reset_cnt) {
2470 rtl92e_writeb(dev, rOFDM0_RxDetector3,
2472 reg_c38_State = RegC38_Default;
2473 reset_cnt = priv->reset_count;
2476 if (reg_c38_State) {
2477 rtl92e_writeb(dev, rOFDM0_RxDetector3,
2479 reg_c38_State = RegC38_Default;
2484 /*---------------------------Define function prototype------------------------*/
2485 static void _rtl92e_dm_init_dynamic_tx_power(struct net_device *dev)
2487 struct r8192_priv *priv = rtllib_priv(dev);
2489 priv->rtllib->bdynamic_txpower_enable = true;
2490 priv->bLastDTPFlag_High = false;
2491 priv->bLastDTPFlag_Low = false;
2492 priv->bDynamicTxHighPower = false;
2493 priv->bDynamicTxLowPower = false;
2496 static void _rtl92e_dm_dynamic_tx_power(struct net_device *dev)
2498 struct r8192_priv *priv = rtllib_priv(dev);
2499 unsigned int txhipower_threshhold = 0;
2500 unsigned int txlowpower_threshold = 0;
2502 if (priv->rtllib->bdynamic_txpower_enable != true) {
2503 priv->bDynamicTxHighPower = false;
2504 priv->bDynamicTxLowPower = false;
2507 if ((priv->rtllib->pHTInfo->IOTPeer == HT_IOT_PEER_ATHEROS) &&
2508 (priv->rtllib->mode == IEEE_G)) {
2509 txhipower_threshhold = TX_POWER_ATHEROAP_THRESH_HIGH;
2510 txlowpower_threshold = TX_POWER_ATHEROAP_THRESH_LOW;
2512 txhipower_threshhold = TX_POWER_NEAR_FIELD_THRESH_HIGH;
2513 txlowpower_threshold = TX_POWER_NEAR_FIELD_THRESH_LOW;
2516 RT_TRACE(COMP_TXAGC, "priv->undecorated_smoothed_pwdb = %ld\n",
2517 priv->undecorated_smoothed_pwdb);
2519 if (priv->rtllib->state == RTLLIB_LINKED) {
2520 if (priv->undecorated_smoothed_pwdb >= txhipower_threshhold) {
2521 priv->bDynamicTxHighPower = true;
2522 priv->bDynamicTxLowPower = false;
2524 if (priv->undecorated_smoothed_pwdb <
2525 txlowpower_threshold && priv->bDynamicTxHighPower)
2526 priv->bDynamicTxHighPower = false;
2527 if (priv->undecorated_smoothed_pwdb < 35)
2528 priv->bDynamicTxLowPower = true;
2529 else if (priv->undecorated_smoothed_pwdb >= 40)
2530 priv->bDynamicTxLowPower = false;
2533 priv->bDynamicTxHighPower = false;
2534 priv->bDynamicTxLowPower = false;
2537 if ((priv->bDynamicTxHighPower != priv->bLastDTPFlag_High) ||
2538 (priv->bDynamicTxLowPower != priv->bLastDTPFlag_Low)) {
2539 RT_TRACE(COMP_TXAGC, "SetTxPowerLevel8190() channel = %d\n",
2540 priv->rtllib->current_network.channel);
2542 rtl92e_set_tx_power(dev, priv->rtllib->current_network.channel);
2544 priv->bLastDTPFlag_High = priv->bDynamicTxHighPower;
2545 priv->bLastDTPFlag_Low = priv->bDynamicTxLowPower;
2549 static void _rtl92e_dm_check_txrateandretrycount(struct net_device *dev)
2551 struct r8192_priv *priv = rtllib_priv(dev);
2552 struct rtllib_device *ieee = priv->rtllib;
2554 ieee->softmac_stats.CurrentShowTxate = rtl92e_readb(dev,
2555 Current_Tx_Rate_Reg);
2557 ieee->softmac_stats.last_packet_rate = rtl92e_readb(dev,
2558 Initial_Tx_Rate_Reg);
2560 ieee->softmac_stats.txretrycount = rtl92e_readl(dev,
2561 Tx_Retry_Count_Reg);
2564 static void _rtl92e_dm_send_rssi_to_fw(struct net_device *dev)
2566 struct r8192_priv *priv = rtllib_priv(dev);
2568 rtl92e_writeb(dev, DRIVER_RSSI, (u8)priv->undecorated_smoothed_pwdb);