1 /******************************************************************************
3 * Copyright(c) 2009-2010 Realtek Corporation.
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
18 * The full GNU General Public License is included in this distribution in the
19 * file called LICENSE.
21 * Contact Information:
22 * wlanfae <wlanfae@realtek.com>
23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24 * Hsinchu 300, Taiwan.
26 * Larry Finger <Larry.Finger@lwfinger.net>
28 *****************************************************************************/
38 struct dig_t digtable
;
39 static const u32 edca_setting_dl
[PEER_MAX
] = {
40 0xa44f, /* 0 UNKNOWN */
41 0x5ea44f, /* 1 REALTEK_90 */
42 0x5ea44f, /* 2 REALTEK_92SE */
50 static const u32 edca_setting_dl_gmode
[PEER_MAX
] = {
51 0x4322, /* 0 UNKNOWN */
52 0xa44f, /* 1 REALTEK_90 */
53 0x5ea44f, /* 2 REALTEK_92SE */
58 0x5ea44f, /* 7 MARV */
61 static const u32 edca_setting_ul
[PEER_MAX
] = {
62 0x5e4322, /* 0 UNKNOWN */
63 0xa44f, /* 1 REALTEK_90 */
64 0x5ea44f, /* 2 REALTEK_92SE */
65 0x5ea322, /* 3 BROAD */
68 0x3ea44f, /* 6 CISCO */
69 0x5ea44f, /* 7 MARV */
72 static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw
*hw
)
74 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
75 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
77 static u64 last_txok_cnt
;
78 static u64 last_rxok_cnt
;
82 u32 edca_be_ul
= edca_setting_ul
[mac
->vendor
];
83 u32 edca_be_dl
= edca_setting_dl
[mac
->vendor
];
84 u32 edca_gmode
= edca_setting_dl_gmode
[mac
->vendor
];
86 if (mac
->link_state
!= MAC80211_LINKED
) {
87 rtlpriv
->dm
.current_turbo_edca
= false;
88 goto dm_checkedcaturbo_exit
;
91 if ((!rtlpriv
->dm
.is_any_nonbepkts
) &&
92 (!rtlpriv
->dm
.disable_framebursting
)) {
93 cur_txok_cnt
= rtlpriv
->stats
.txbytesunicast
- last_txok_cnt
;
94 cur_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
- last_rxok_cnt
;
96 if (rtlpriv
->phy
.rf_type
== RF_1T2R
) {
97 if (cur_txok_cnt
> 4 * cur_rxok_cnt
) {
98 /* Uplink TP is present. */
99 if (rtlpriv
->dm
.is_cur_rdlstate
||
100 !rtlpriv
->dm
.current_turbo_edca
) {
101 rtl_write_dword(rtlpriv
, EDCAPARA_BE
,
103 rtlpriv
->dm
.is_cur_rdlstate
= false;
105 } else {/* Balance TP is present. */
106 if (!rtlpriv
->dm
.is_cur_rdlstate
||
107 !rtlpriv
->dm
.current_turbo_edca
) {
108 if (mac
->mode
== WIRELESS_MODE_G
||
109 mac
->mode
== WIRELESS_MODE_B
)
110 rtl_write_dword(rtlpriv
,
114 rtl_write_dword(rtlpriv
,
117 rtlpriv
->dm
.is_cur_rdlstate
= true;
120 rtlpriv
->dm
.current_turbo_edca
= true;
122 if (cur_rxok_cnt
> 4 * cur_txok_cnt
) {
123 if (!rtlpriv
->dm
.is_cur_rdlstate
||
124 !rtlpriv
->dm
.current_turbo_edca
) {
125 if (mac
->mode
== WIRELESS_MODE_G
||
126 mac
->mode
== WIRELESS_MODE_B
)
127 rtl_write_dword(rtlpriv
,
131 rtl_write_dword(rtlpriv
,
134 rtlpriv
->dm
.is_cur_rdlstate
= true;
137 if (rtlpriv
->dm
.is_cur_rdlstate
||
138 !rtlpriv
->dm
.current_turbo_edca
) {
139 rtl_write_dword(rtlpriv
, EDCAPARA_BE
,
141 rtlpriv
->dm
.is_cur_rdlstate
= false;
144 rtlpriv
->dm
.current_turbo_edca
= true;
147 if (rtlpriv
->dm
.current_turbo_edca
) {
149 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_AC_PARAM
,
151 rtlpriv
->dm
.current_turbo_edca
= false;
155 dm_checkedcaturbo_exit
:
156 rtlpriv
->dm
.is_any_nonbepkts
= false;
157 last_txok_cnt
= rtlpriv
->stats
.txbytesunicast
;
158 last_rxok_cnt
= rtlpriv
->stats
.rxbytesunicast
;
161 static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
162 struct ieee80211_hw
*hw
)
164 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
165 struct rtl_efuse
*rtlefuse
= rtl_efuse(rtl_priv(hw
));
168 rtlpriv
->dm
.txpower_trackinginit
= true;
170 thermalvalue
= (u8
)rtl_get_rfreg(hw
, RF90_PATH_A
, RF_T_METER
, 0x1f);
172 RT_TRACE(rtlpriv
, COMP_POWER_TRACKING
, DBG_LOUD
,
173 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
174 "eeprom_thermalmeter 0x%x\n", thermalvalue
,
175 rtlpriv
->dm
.thermalvalue
, rtlefuse
->eeprom_thermalmeter
));
178 rtlpriv
->dm
.thermalvalue
= thermalvalue
;
179 rtl92s_phy_set_fw_cmd(hw
, FW_CMD_TXPWR_TRACK_THERMAL
);
182 rtlpriv
->dm
.txpowercount
= 0;
185 static void _rtl92s_dm_check_txpowertracking_thermalmeter(
186 struct ieee80211_hw
*hw
)
188 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
189 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
190 static u8 tm_trigger
;
191 u8 tx_power_checkcnt
= 5;
194 if (rtlphy
->rf_type
== RF_2T2R
)
197 if (!rtlpriv
->dm
.txpower_tracking
)
200 if (rtlpriv
->dm
.txpowercount
<= tx_power_checkcnt
) {
201 rtlpriv
->dm
.txpowercount
++;
206 rtl_set_rfreg(hw
, RF90_PATH_A
, RF_T_METER
,
207 RFREG_OFFSET_MASK
, 0x60);
210 _rtl92s_dm_txpowertracking_callback_thermalmeter(hw
);
215 static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw
*hw
)
217 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
218 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
219 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
220 struct rate_adaptive
*ra
= &(rtlpriv
->ra
);
222 u32 low_rssi_thresh
= 0;
223 u32 middle_rssi_thresh
= 0;
224 u32 high_rssi_thresh
= 0;
225 struct ieee80211_sta
*sta
= NULL
;
227 if (is_hal_stop(rtlhal
))
230 if (!rtlpriv
->dm
.useramask
)
233 if (!rtlpriv
->dm
.inform_fw_driverctrldm
) {
234 rtl92s_phy_set_fw_cmd(hw
, FW_CMD_CTRL_DM_BY_DRIVER
);
235 rtlpriv
->dm
.inform_fw_driverctrldm
= true;
239 if (mac
->opmode
== NL80211_IFTYPE_STATION
)
240 sta
= get_sta(hw
, mac
->vif
, mac
->bssid
);
241 if ((mac
->link_state
== MAC80211_LINKED
) &&
242 (mac
->opmode
== NL80211_IFTYPE_STATION
)) {
243 switch (ra
->pre_ratr_state
) {
244 case DM_RATR_STA_HIGH
:
245 high_rssi_thresh
= 40;
246 middle_rssi_thresh
= 30;
247 low_rssi_thresh
= 20;
249 case DM_RATR_STA_MIDDLE
:
250 high_rssi_thresh
= 44;
251 middle_rssi_thresh
= 30;
252 low_rssi_thresh
= 20;
254 case DM_RATR_STA_LOW
:
255 high_rssi_thresh
= 44;
256 middle_rssi_thresh
= 34;
257 low_rssi_thresh
= 20;
259 case DM_RATR_STA_ULTRALOW
:
260 high_rssi_thresh
= 44;
261 middle_rssi_thresh
= 34;
262 low_rssi_thresh
= 24;
265 high_rssi_thresh
= 44;
266 middle_rssi_thresh
= 34;
267 low_rssi_thresh
= 24;
271 if (rtlpriv
->dm
.undecorated_smoothed_pwdb
>
272 (long)high_rssi_thresh
) {
273 ra
->ratr_state
= DM_RATR_STA_HIGH
;
274 } else if (rtlpriv
->dm
.undecorated_smoothed_pwdb
>
275 (long)middle_rssi_thresh
) {
276 ra
->ratr_state
= DM_RATR_STA_LOW
;
277 } else if (rtlpriv
->dm
.undecorated_smoothed_pwdb
>
278 (long)low_rssi_thresh
) {
279 ra
->ratr_state
= DM_RATR_STA_LOW
;
281 ra
->ratr_state
= DM_RATR_STA_ULTRALOW
;
284 if (ra
->pre_ratr_state
!= ra
->ratr_state
) {
285 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
, ("RSSI = %ld "
286 "RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
287 rtlpriv
->dm
.undecorated_smoothed_pwdb
,
289 ra
->pre_ratr_state
, ra
->ratr_state
));
291 rtlpriv
->cfg
->ops
->update_rate_tbl(hw
, sta
,
293 ra
->pre_ratr_state
= ra
->ratr_state
;
299 static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw
*hw
)
301 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
302 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
303 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
304 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
306 bool enable_mrc
= true;
307 long tmpentry_maxpwdb
= 0;
311 if (is_hal_stop(rtlhal
))
314 if ((rtlphy
->rf_type
== RF_1T1R
) || (rtlphy
->rf_type
== RF_2T2R
))
317 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_MRC
, (u8
*)(¤t_mrc
));
319 if (mac
->link_state
>= MAC80211_LINKED
) {
320 if (rtlpriv
->dm
.undecorated_smoothed_pwdb
> tmpentry_maxpwdb
) {
321 rssi_a
= rtlpriv
->stats
.rx_rssi_percentage
[RF90_PATH_A
];
322 rssi_b
= rtlpriv
->stats
.rx_rssi_percentage
[RF90_PATH_B
];
326 /* MRC settings would NOT affect TP on Wireless B mode. */
327 if (mac
->mode
!= WIRELESS_MODE_B
) {
328 if ((rssi_a
== 0) && (rssi_b
== 0)) {
330 } else if (rssi_b
> 30) {
333 } else if (rssi_b
< 5) {
334 /* Turn off B-path */
336 /* Take care of RSSI differentiation. */
337 } else if (rssi_a
> 15 && (rssi_a
>= rssi_b
)) {
338 if ((rssi_a
- rssi_b
) > 15)
339 /* Turn off B-path */
341 else if ((rssi_a
- rssi_b
) < 10)
345 enable_mrc
= current_mrc
;
352 /* Update MRC settings if needed. */
353 if (enable_mrc
!= current_mrc
)
354 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_MRC
,
359 void rtl92s_dm_init_edca_turbo(struct ieee80211_hw
*hw
)
361 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
363 rtlpriv
->dm
.current_turbo_edca
= false;
364 rtlpriv
->dm
.is_any_nonbepkts
= false;
365 rtlpriv
->dm
.is_cur_rdlstate
= false;
368 static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw
*hw
)
370 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
371 struct rate_adaptive
*ra
= &(rtlpriv
->ra
);
373 ra
->ratr_state
= DM_RATR_STA_MAX
;
374 ra
->pre_ratr_state
= DM_RATR_STA_MAX
;
376 if (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
)
377 rtlpriv
->dm
.useramask
= true;
379 rtlpriv
->dm
.useramask
= false;
381 rtlpriv
->dm
.useramask
= false;
382 rtlpriv
->dm
.inform_fw_driverctrldm
= false;
385 static void _rtl92s_dm_init_txpowertracking_thermalmeter(
386 struct ieee80211_hw
*hw
)
388 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
390 rtlpriv
->dm
.txpower_tracking
= true;
391 rtlpriv
->dm
.txpowercount
= 0;
392 rtlpriv
->dm
.txpower_trackinginit
= false;
395 static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw
*hw
)
397 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
398 struct false_alarm_statistics
*falsealm_cnt
= &(rtlpriv
->falsealm_cnt
);
401 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER1
, MASKDWORD
);
402 falsealm_cnt
->cnt_parity_fail
= ((ret_value
& 0xffff0000) >> 16);
404 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER2
, MASKDWORD
);
405 falsealm_cnt
->cnt_rate_illegal
= (ret_value
& 0xffff);
406 falsealm_cnt
->cnt_crc8_fail
= ((ret_value
& 0xffff0000) >> 16);
407 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER3
, MASKDWORD
);
408 falsealm_cnt
->cnt_mcs_fail
= (ret_value
& 0xffff);
410 falsealm_cnt
->cnt_ofdm_fail
= falsealm_cnt
->cnt_parity_fail
+
411 falsealm_cnt
->cnt_rate_illegal
+ falsealm_cnt
->cnt_crc8_fail
+
412 falsealm_cnt
->cnt_mcs_fail
;
414 /* read CCK false alarm */
415 ret_value
= rtl_get_bbreg(hw
, 0xc64, MASKDWORD
);
416 falsealm_cnt
->cnt_cck_fail
= (ret_value
& 0xffff);
417 falsealm_cnt
->cnt_all
= falsealm_cnt
->cnt_ofdm_fail
+
418 falsealm_cnt
->cnt_cck_fail
;
421 static void rtl92s_backoff_enable_flag(struct ieee80211_hw
*hw
)
423 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
424 struct false_alarm_statistics
*falsealm_cnt
= &(rtlpriv
->falsealm_cnt
);
426 if (falsealm_cnt
->cnt_all
> digtable
.fa_highthresh
) {
427 if ((digtable
.backoff_val
- 6) <
428 digtable
.backoffval_range_min
)
429 digtable
.backoff_val
= digtable
.backoffval_range_min
;
431 digtable
.backoff_val
-= 6;
432 } else if (falsealm_cnt
->cnt_all
< digtable
.fa_lowthresh
) {
433 if ((digtable
.backoff_val
+ 6) >
434 digtable
.backoffval_range_max
)
435 digtable
.backoff_val
=
436 digtable
.backoffval_range_max
;
438 digtable
.backoff_val
+= 6;
442 static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw
*hw
)
444 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
445 struct false_alarm_statistics
*falsealm_cnt
= &(rtlpriv
->falsealm_cnt
);
446 static u8 initialized
, force_write
;
449 if ((digtable
.pre_sta_connectstate
== digtable
.cur_sta_connectstate
) ||
450 (digtable
.cur_sta_connectstate
== DIG_STA_BEFORE_CONNECT
)) {
451 if (digtable
.cur_sta_connectstate
== DIG_STA_BEFORE_CONNECT
) {
452 if (rtlpriv
->psc
.rfpwr_state
!= ERFON
)
455 if (digtable
.backoff_enable_flag
)
456 rtl92s_backoff_enable_flag(hw
);
458 digtable
.backoff_val
= DM_DIG_BACKOFF
;
460 if ((digtable
.rssi_val
+ 10 - digtable
.backoff_val
) >
461 digtable
.rx_gain_range_max
)
462 digtable
.cur_igvalue
=
463 digtable
.rx_gain_range_max
;
464 else if ((digtable
.rssi_val
+ 10 - digtable
.backoff_val
)
465 < digtable
.rx_gain_range_min
)
466 digtable
.cur_igvalue
=
467 digtable
.rx_gain_range_min
;
469 digtable
.cur_igvalue
= digtable
.rssi_val
+ 10 -
470 digtable
.backoff_val
;
472 if (falsealm_cnt
->cnt_all
> 10000)
473 digtable
.cur_igvalue
=
474 (digtable
.cur_igvalue
> 0x33) ?
475 digtable
.cur_igvalue
: 0x33;
477 if (falsealm_cnt
->cnt_all
> 16000)
478 digtable
.cur_igvalue
=
479 digtable
.rx_gain_range_max
;
480 /* connected -> connected or disconnected -> disconnected */
482 /* Firmware control DIG, do nothing in driver dm */
485 /* disconnected -> connected or connected ->
486 * disconnected or beforeconnect->(dis)connected */
489 digtable
.dig_ext_port_stage
= DIG_EXT_PORT_STAGE_MAX
;
490 rtl92s_phy_set_fw_cmd(hw
, FW_CMD_DIG_ENABLE
);
492 digtable
.backoff_val
= DM_DIG_BACKOFF
;
493 digtable
.cur_igvalue
= rtlpriv
->phy
.default_initialgain
[0];
494 digtable
.pre_igvalue
= 0;
498 /* Forced writing to prevent from fw-dig overwriting. */
499 if (digtable
.pre_igvalue
!= rtl_get_bbreg(hw
, ROFDM0_XAAGCCORE1
,
503 if ((digtable
.pre_igvalue
!= digtable
.cur_igvalue
) ||
504 !initialized
|| force_write
) {
506 rtl92s_phy_set_fw_cmd(hw
, FW_CMD_DIG_DISABLE
);
508 initial_gain
= (u8
)digtable
.cur_igvalue
;
510 /* Set initial gain. */
511 rtl_set_bbreg(hw
, ROFDM0_XAAGCCORE1
, MASKBYTE0
, initial_gain
);
512 rtl_set_bbreg(hw
, ROFDM0_XBAGCCORE1
, MASKBYTE0
, initial_gain
);
513 digtable
.pre_igvalue
= digtable
.cur_igvalue
;
519 static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw
*hw
)
521 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
523 if (rtlpriv
->mac80211
.act_scanning
)
526 /* Decide the current status and if modify initial gain or not */
527 if (rtlpriv
->mac80211
.link_state
>= MAC80211_LINKED
||
528 rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_ADHOC
)
529 digtable
.cur_sta_connectstate
= DIG_STA_CONNECT
;
531 digtable
.cur_sta_connectstate
= DIG_STA_DISCONNECT
;
533 digtable
.rssi_val
= rtlpriv
->dm
.undecorated_smoothed_pwdb
;
535 /* Change dig mode to rssi */
536 if (digtable
.cur_sta_connectstate
!= DIG_STA_DISCONNECT
) {
537 if (digtable
.dig_twoport_algorithm
==
538 DIG_TWO_PORT_ALGO_FALSE_ALARM
) {
539 digtable
.dig_twoport_algorithm
= DIG_TWO_PORT_ALGO_RSSI
;
540 rtl92s_phy_set_fw_cmd(hw
, FW_CMD_DIG_MODE_SS
);
544 _rtl92s_dm_false_alarm_counter_statistics(hw
);
545 _rtl92s_dm_initial_gain_sta_beforeconnect(hw
);
547 digtable
.pre_sta_connectstate
= digtable
.cur_sta_connectstate
;
550 static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw
*hw
)
552 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
553 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
556 if (rtlphy
->rf_type
== RF_2T2R
)
559 if (!rtlpriv
->dm
.dm_initialgain_enable
)
562 if (digtable
.dig_enable_flag
== false)
565 _rtl92s_dm_ctrl_initgain_bytwoport(hw
);
568 static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw
*hw
)
570 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
571 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
572 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
573 long undecorated_smoothed_pwdb
;
574 long txpwr_threshold_lv1
, txpwr_threshold_lv2
;
577 if (rtlphy
->rf_type
== RF_2T2R
)
580 if (!rtlpriv
->dm
.dynamic_txpower_enable
||
581 rtlpriv
->dm
.dm_flag
& HAL_DM_HIPWR_DISABLE
) {
582 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
586 if ((mac
->link_state
< MAC80211_LINKED
) &&
587 (rtlpriv
->dm
.entry_min_undecoratedsmoothed_pwdb
== 0)) {
588 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_TRACE
,
589 ("Not connected to any\n"));
591 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
593 rtlpriv
->dm
.last_dtp_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
597 if (mac
->link_state
>= MAC80211_LINKED
) {
598 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
) {
599 undecorated_smoothed_pwdb
=
600 rtlpriv
->dm
.entry_min_undecoratedsmoothed_pwdb
;
601 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
602 ("AP Client PWDB = 0x%lx\n",
603 undecorated_smoothed_pwdb
));
605 undecorated_smoothed_pwdb
=
606 rtlpriv
->dm
.undecorated_smoothed_pwdb
;
607 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
608 ("STA Default Port PWDB = 0x%lx\n",
609 undecorated_smoothed_pwdb
));
612 undecorated_smoothed_pwdb
=
613 rtlpriv
->dm
.entry_min_undecoratedsmoothed_pwdb
;
615 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
616 ("AP Ext Port PWDB = 0x%lx\n",
617 undecorated_smoothed_pwdb
));
620 txpwr_threshold_lv2
= TX_POWER_NEAR_FIELD_THRESH_LVL2
;
621 txpwr_threshold_lv1
= TX_POWER_NEAR_FIELD_THRESH_LVL1
;
623 if (rtl_get_bbreg(hw
, 0xc90, MASKBYTE0
) == 1)
624 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
625 else if (undecorated_smoothed_pwdb
>= txpwr_threshold_lv2
)
626 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL2
;
627 else if ((undecorated_smoothed_pwdb
< (txpwr_threshold_lv2
- 3)) &&
628 (undecorated_smoothed_pwdb
>= txpwr_threshold_lv1
))
629 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL1
;
630 else if (undecorated_smoothed_pwdb
< (txpwr_threshold_lv1
- 3))
631 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
633 if ((rtlpriv
->dm
.dynamic_txhighpower_lvl
!= rtlpriv
->dm
.last_dtp_lvl
))
634 rtl92s_phy_set_txpower(hw
, rtlphy
->current_channel
);
636 rtlpriv
->dm
.last_dtp_lvl
= rtlpriv
->dm
.dynamic_txhighpower_lvl
;
639 static void _rtl92s_dm_init_dig(struct ieee80211_hw
*hw
)
641 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
643 /* Disable DIG scheme now.*/
644 digtable
.dig_enable_flag
= true;
645 digtable
.backoff_enable_flag
= true;
647 if ((rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
) &&
648 (hal_get_firmwareversion(rtlpriv
) >= 0x3c))
649 digtable
.dig_algorithm
= DIG_ALGO_BY_TOW_PORT
;
651 digtable
.dig_algorithm
=
652 DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM
;
654 digtable
.dig_twoport_algorithm
= DIG_TWO_PORT_ALGO_RSSI
;
655 digtable
.dig_ext_port_stage
= DIG_EXT_PORT_STAGE_MAX
;
656 /* off=by real rssi value, on=by digtable.rssi_val for new dig */
657 digtable
.dig_dbgmode
= DM_DBG_OFF
;
658 digtable
.dig_slgorithm_switch
= 0;
660 /* 2007/10/04 MH Define init gain threshol. */
661 digtable
.dig_state
= DM_STA_DIG_MAX
;
662 digtable
.dig_highpwrstate
= DM_STA_DIG_MAX
;
664 digtable
.cur_sta_connectstate
= DIG_STA_DISCONNECT
;
665 digtable
.pre_sta_connectstate
= DIG_STA_DISCONNECT
;
666 digtable
.cur_ap_connectstate
= DIG_AP_DISCONNECT
;
667 digtable
.pre_ap_connectstate
= DIG_AP_DISCONNECT
;
669 digtable
.rssi_lowthresh
= DM_DIG_THRESH_LOW
;
670 digtable
.rssi_highthresh
= DM_DIG_THRESH_HIGH
;
672 digtable
.fa_lowthresh
= DM_FALSEALARM_THRESH_LOW
;
673 digtable
.fa_highthresh
= DM_FALSEALARM_THRESH_HIGH
;
675 digtable
.rssi_highpower_lowthresh
= DM_DIG_HIGH_PWR_THRESH_LOW
;
676 digtable
.rssi_highpower_highthresh
= DM_DIG_HIGH_PWR_THRESH_HIGH
;
678 /* for dig debug rssi value */
679 digtable
.rssi_val
= 50;
680 digtable
.backoff_val
= DM_DIG_BACKOFF
;
681 digtable
.rx_gain_range_max
= DM_DIG_MAX
;
683 digtable
.rx_gain_range_min
= DM_DIG_MIN
;
685 digtable
.backoffval_range_max
= DM_DIG_BACKOFF_MAX
;
686 digtable
.backoffval_range_min
= DM_DIG_BACKOFF_MIN
;
689 static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw
*hw
)
691 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
693 if ((hal_get_firmwareversion(rtlpriv
) >= 60) &&
694 (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
))
695 rtlpriv
->dm
.dynamic_txpower_enable
= true;
697 rtlpriv
->dm
.dynamic_txpower_enable
= false;
699 rtlpriv
->dm
.last_dtp_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
700 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
703 void rtl92s_dm_init(struct ieee80211_hw
*hw
)
705 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
707 rtlpriv
->dm
.dm_type
= DM_TYPE_BYDRIVER
;
708 rtlpriv
->dm
.undecorated_smoothed_pwdb
= -1;
710 _rtl92s_dm_init_dynamic_txpower(hw
);
711 rtl92s_dm_init_edca_turbo(hw
);
712 _rtl92s_dm_init_rate_adaptive_mask(hw
);
713 _rtl92s_dm_init_txpowertracking_thermalmeter(hw
);
714 _rtl92s_dm_init_dig(hw
);
716 rtl_write_dword(rtlpriv
, WFM5
, FW_CCA_CHK_ENABLE
);
719 void rtl92s_dm_watchdog(struct ieee80211_hw
*hw
)
721 _rtl92s_dm_check_edca_turbo(hw
);
722 _rtl92s_dm_check_txpowertracking_thermalmeter(hw
);
723 _rtl92s_dm_ctrl_initgain_byrssi(hw
);
724 _rtl92s_dm_dynamic_txpower(hw
);
725 _rtl92s_dm_refresh_rateadaptive_mask(hw
);
726 _rtl92s_dm_switch_baseband_mrc(hw
);