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;
226 struct ieee80211_sta
*sta
= NULL
;
228 if (is_hal_stop(rtlhal
))
231 if (!rtlpriv
->dm
.useramask
)
234 if (!rtlpriv
->dm
.inform_fw_driverctrldm
) {
235 rtl92s_phy_set_fw_cmd(hw
, FW_CMD_CTRL_DM_BY_DRIVER
);
236 rtlpriv
->dm
.inform_fw_driverctrldm
= true;
240 if (mac
->opmode
== NL80211_IFTYPE_STATION
)
241 sta
= get_sta(hw
, mac
->vif
, mac
->bssid
);
242 if ((mac
->link_state
== MAC80211_LINKED
) &&
243 (mac
->opmode
== NL80211_IFTYPE_STATION
)) {
244 switch (ra
->pre_ratr_state
) {
245 case DM_RATR_STA_HIGH
:
246 high_rssi_thresh
= 40;
247 middle_rssi_thresh
= 30;
248 low_rssi_thresh
= 20;
250 case DM_RATR_STA_MIDDLE
:
251 high_rssi_thresh
= 44;
252 middle_rssi_thresh
= 30;
253 low_rssi_thresh
= 20;
255 case DM_RATR_STA_LOW
:
256 high_rssi_thresh
= 44;
257 middle_rssi_thresh
= 34;
258 low_rssi_thresh
= 20;
260 case DM_RATR_STA_ULTRALOW
:
261 high_rssi_thresh
= 44;
262 middle_rssi_thresh
= 34;
263 low_rssi_thresh
= 24;
266 high_rssi_thresh
= 44;
267 middle_rssi_thresh
= 34;
268 low_rssi_thresh
= 24;
272 if (rtlpriv
->dm
.undecorated_smoothed_pwdb
>
273 (long)high_rssi_thresh
) {
274 ra
->ratr_state
= DM_RATR_STA_HIGH
;
276 } else if (rtlpriv
->dm
.undecorated_smoothed_pwdb
>
277 (long)middle_rssi_thresh
) {
278 ra
->ratr_state
= DM_RATR_STA_LOW
;
280 } else if (rtlpriv
->dm
.undecorated_smoothed_pwdb
>
281 (long)low_rssi_thresh
) {
282 ra
->ratr_state
= DM_RATR_STA_LOW
;
285 ra
->ratr_state
= DM_RATR_STA_ULTRALOW
;
289 if (ra
->pre_ratr_state
!= ra
->ratr_state
) {
290 RT_TRACE(rtlpriv
, COMP_RATE
, DBG_LOUD
, ("RSSI = %ld "
291 "RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
292 rtlpriv
->dm
.undecorated_smoothed_pwdb
,
294 ra
->pre_ratr_state
, ra
->ratr_state
));
296 rtlpriv
->cfg
->ops
->update_rate_tbl(hw
, sta
,
298 ra
->pre_ratr_state
= ra
->ratr_state
;
304 static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw
*hw
)
306 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
307 struct rtl_hal
*rtlhal
= rtl_hal(rtl_priv(hw
));
308 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
309 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
311 bool enable_mrc
= true;
312 long tmpentry_maxpwdb
= 0;
316 if (is_hal_stop(rtlhal
))
319 if ((rtlphy
->rf_type
== RF_1T1R
) || (rtlphy
->rf_type
== RF_2T2R
))
322 rtlpriv
->cfg
->ops
->get_hw_reg(hw
, HW_VAR_MRC
, (u8
*)(¤t_mrc
));
324 if (mac
->link_state
>= MAC80211_LINKED
) {
325 if (rtlpriv
->dm
.undecorated_smoothed_pwdb
> tmpentry_maxpwdb
) {
326 rssi_a
= rtlpriv
->stats
.rx_rssi_percentage
[RF90_PATH_A
];
327 rssi_b
= rtlpriv
->stats
.rx_rssi_percentage
[RF90_PATH_B
];
331 /* MRC settings would NOT affect TP on Wireless B mode. */
332 if (mac
->mode
!= WIRELESS_MODE_B
) {
333 if ((rssi_a
== 0) && (rssi_b
== 0)) {
335 } else if (rssi_b
> 30) {
338 } else if (rssi_b
< 5) {
339 /* Turn off B-path */
341 /* Take care of RSSI differentiation. */
342 } else if (rssi_a
> 15 && (rssi_a
>= rssi_b
)) {
343 if ((rssi_a
- rssi_b
) > 15)
344 /* Turn off B-path */
346 else if ((rssi_a
- rssi_b
) < 10)
350 enable_mrc
= current_mrc
;
357 /* Update MRC settings if needed. */
358 if (enable_mrc
!= current_mrc
)
359 rtlpriv
->cfg
->ops
->set_hw_reg(hw
, HW_VAR_MRC
,
364 void rtl92s_dm_init_edca_turbo(struct ieee80211_hw
*hw
)
366 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
368 rtlpriv
->dm
.current_turbo_edca
= false;
369 rtlpriv
->dm
.is_any_nonbepkts
= false;
370 rtlpriv
->dm
.is_cur_rdlstate
= false;
373 static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw
*hw
)
375 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
376 struct rate_adaptive
*ra
= &(rtlpriv
->ra
);
378 ra
->ratr_state
= DM_RATR_STA_MAX
;
379 ra
->pre_ratr_state
= DM_RATR_STA_MAX
;
381 if (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
)
382 rtlpriv
->dm
.useramask
= true;
384 rtlpriv
->dm
.useramask
= false;
386 rtlpriv
->dm
.useramask
= false;
387 rtlpriv
->dm
.inform_fw_driverctrldm
= false;
390 static void _rtl92s_dm_init_txpowertracking_thermalmeter(
391 struct ieee80211_hw
*hw
)
393 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
395 rtlpriv
->dm
.txpower_tracking
= true;
396 rtlpriv
->dm
.txpowercount
= 0;
397 rtlpriv
->dm
.txpower_trackinginit
= false;
400 static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw
*hw
)
402 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
403 struct false_alarm_statistics
*falsealm_cnt
= &(rtlpriv
->falsealm_cnt
);
406 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER1
, MASKDWORD
);
407 falsealm_cnt
->cnt_parity_fail
= ((ret_value
& 0xffff0000) >> 16);
409 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER2
, MASKDWORD
);
410 falsealm_cnt
->cnt_rate_illegal
= (ret_value
& 0xffff);
411 falsealm_cnt
->cnt_crc8_fail
= ((ret_value
& 0xffff0000) >> 16);
412 ret_value
= rtl_get_bbreg(hw
, ROFDM_PHYCOUNTER3
, MASKDWORD
);
413 falsealm_cnt
->cnt_mcs_fail
= (ret_value
& 0xffff);
415 falsealm_cnt
->cnt_ofdm_fail
= falsealm_cnt
->cnt_parity_fail
+
416 falsealm_cnt
->cnt_rate_illegal
+ falsealm_cnt
->cnt_crc8_fail
+
417 falsealm_cnt
->cnt_mcs_fail
;
419 /* read CCK false alarm */
420 ret_value
= rtl_get_bbreg(hw
, 0xc64, MASKDWORD
);
421 falsealm_cnt
->cnt_cck_fail
= (ret_value
& 0xffff);
422 falsealm_cnt
->cnt_all
= falsealm_cnt
->cnt_ofdm_fail
+
423 falsealm_cnt
->cnt_cck_fail
;
426 static void rtl92s_backoff_enable_flag(struct ieee80211_hw
*hw
)
428 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
429 struct false_alarm_statistics
*falsealm_cnt
= &(rtlpriv
->falsealm_cnt
);
431 if (falsealm_cnt
->cnt_all
> digtable
.fa_highthresh
) {
432 if ((digtable
.backoff_val
- 6) <
433 digtable
.backoffval_range_min
)
434 digtable
.backoff_val
= digtable
.backoffval_range_min
;
436 digtable
.backoff_val
-= 6;
437 } else if (falsealm_cnt
->cnt_all
< digtable
.fa_lowthresh
) {
438 if ((digtable
.backoff_val
+ 6) >
439 digtable
.backoffval_range_max
)
440 digtable
.backoff_val
=
441 digtable
.backoffval_range_max
;
443 digtable
.backoff_val
+= 6;
447 static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw
*hw
)
449 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
450 struct false_alarm_statistics
*falsealm_cnt
= &(rtlpriv
->falsealm_cnt
);
451 static u8 initialized
, force_write
;
454 if ((digtable
.pre_sta_connectstate
== digtable
.cur_sta_connectstate
) ||
455 (digtable
.cur_sta_connectstate
== DIG_STA_BEFORE_CONNECT
)) {
456 if (digtable
.cur_sta_connectstate
== DIG_STA_BEFORE_CONNECT
) {
457 if (rtlpriv
->psc
.rfpwr_state
!= ERFON
)
460 if (digtable
.backoff_enable_flag
== true)
461 rtl92s_backoff_enable_flag(hw
);
463 digtable
.backoff_val
= DM_DIG_BACKOFF
;
465 if ((digtable
.rssi_val
+ 10 - digtable
.backoff_val
) >
466 digtable
.rx_gain_range_max
)
467 digtable
.cur_igvalue
=
468 digtable
.rx_gain_range_max
;
469 else if ((digtable
.rssi_val
+ 10 - digtable
.backoff_val
)
470 < digtable
.rx_gain_range_min
)
471 digtable
.cur_igvalue
=
472 digtable
.rx_gain_range_min
;
474 digtable
.cur_igvalue
= digtable
.rssi_val
+ 10 -
475 digtable
.backoff_val
;
477 if (falsealm_cnt
->cnt_all
> 10000)
478 digtable
.cur_igvalue
=
479 (digtable
.cur_igvalue
> 0x33) ?
480 digtable
.cur_igvalue
: 0x33;
482 if (falsealm_cnt
->cnt_all
> 16000)
483 digtable
.cur_igvalue
=
484 digtable
.rx_gain_range_max
;
485 /* connected -> connected or disconnected -> disconnected */
487 /* Firmware control DIG, do nothing in driver dm */
490 /* disconnected -> connected or connected ->
491 * disconnected or beforeconnect->(dis)connected */
494 digtable
.dig_ext_port_stage
= DIG_EXT_PORT_STAGE_MAX
;
495 rtl92s_phy_set_fw_cmd(hw
, FW_CMD_DIG_ENABLE
);
497 digtable
.backoff_val
= DM_DIG_BACKOFF
;
498 digtable
.cur_igvalue
= rtlpriv
->phy
.default_initialgain
[0];
499 digtable
.pre_igvalue
= 0;
503 /* Forced writing to prevent from fw-dig overwriting. */
504 if (digtable
.pre_igvalue
!= rtl_get_bbreg(hw
, ROFDM0_XAAGCCORE1
,
508 if ((digtable
.pre_igvalue
!= digtable
.cur_igvalue
) ||
509 !initialized
|| force_write
) {
511 rtl92s_phy_set_fw_cmd(hw
, FW_CMD_DIG_DISABLE
);
513 initial_gain
= (u8
)digtable
.cur_igvalue
;
515 /* Set initial gain. */
516 rtl_set_bbreg(hw
, ROFDM0_XAAGCCORE1
, MASKBYTE0
, initial_gain
);
517 rtl_set_bbreg(hw
, ROFDM0_XBAGCCORE1
, MASKBYTE0
, initial_gain
);
518 digtable
.pre_igvalue
= digtable
.cur_igvalue
;
524 static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw
*hw
)
526 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
528 if (rtlpriv
->mac80211
.act_scanning
)
531 /* Decide the current status and if modify initial gain or not */
532 if (rtlpriv
->mac80211
.link_state
>= MAC80211_LINKED
||
533 rtlpriv
->mac80211
.opmode
== NL80211_IFTYPE_ADHOC
)
534 digtable
.cur_sta_connectstate
= DIG_STA_CONNECT
;
536 digtable
.cur_sta_connectstate
= DIG_STA_DISCONNECT
;
538 digtable
.rssi_val
= rtlpriv
->dm
.undecorated_smoothed_pwdb
;
540 /* Change dig mode to rssi */
541 if (digtable
.cur_sta_connectstate
!= DIG_STA_DISCONNECT
) {
542 if (digtable
.dig_twoport_algorithm
==
543 DIG_TWO_PORT_ALGO_FALSE_ALARM
) {
544 digtable
.dig_twoport_algorithm
= DIG_TWO_PORT_ALGO_RSSI
;
545 rtl92s_phy_set_fw_cmd(hw
, FW_CMD_DIG_MODE_SS
);
549 _rtl92s_dm_false_alarm_counter_statistics(hw
);
550 _rtl92s_dm_initial_gain_sta_beforeconnect(hw
);
552 digtable
.pre_sta_connectstate
= digtable
.cur_sta_connectstate
;
555 static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw
*hw
)
557 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
558 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
561 if (rtlphy
->rf_type
== RF_2T2R
)
564 if (!rtlpriv
->dm
.dm_initialgain_enable
)
567 if (digtable
.dig_enable_flag
== false)
570 _rtl92s_dm_ctrl_initgain_bytwoport(hw
);
573 static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw
*hw
)
575 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
576 struct rtl_phy
*rtlphy
= &(rtlpriv
->phy
);
577 struct rtl_mac
*mac
= rtl_mac(rtl_priv(hw
));
578 long undecorated_smoothed_pwdb
;
579 long txpwr_threshold_lv1
, txpwr_threshold_lv2
;
582 if (rtlphy
->rf_type
== RF_2T2R
)
585 if (!rtlpriv
->dm
.dynamic_txpower_enable
||
586 rtlpriv
->dm
.dm_flag
& HAL_DM_HIPWR_DISABLE
) {
587 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
591 if ((mac
->link_state
< MAC80211_LINKED
) &&
592 (rtlpriv
->dm
.entry_min_undecoratedsmoothed_pwdb
== 0)) {
593 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_TRACE
,
594 ("Not connected to any\n"));
596 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
598 rtlpriv
->dm
.last_dtp_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
602 if (mac
->link_state
>= MAC80211_LINKED
) {
603 if (mac
->opmode
== NL80211_IFTYPE_ADHOC
) {
604 undecorated_smoothed_pwdb
=
605 rtlpriv
->dm
.entry_min_undecoratedsmoothed_pwdb
;
606 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
607 ("AP Client PWDB = 0x%lx\n",
608 undecorated_smoothed_pwdb
));
610 undecorated_smoothed_pwdb
=
611 rtlpriv
->dm
.undecorated_smoothed_pwdb
;
612 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
613 ("STA Default Port PWDB = 0x%lx\n",
614 undecorated_smoothed_pwdb
));
617 undecorated_smoothed_pwdb
=
618 rtlpriv
->dm
.entry_min_undecoratedsmoothed_pwdb
;
620 RT_TRACE(rtlpriv
, COMP_POWER
, DBG_LOUD
,
621 ("AP Ext Port PWDB = 0x%lx\n",
622 undecorated_smoothed_pwdb
));
625 txpwr_threshold_lv2
= TX_POWER_NEAR_FIELD_THRESH_LVL2
;
626 txpwr_threshold_lv1
= TX_POWER_NEAR_FIELD_THRESH_LVL1
;
628 if (rtl_get_bbreg(hw
, 0xc90, MASKBYTE0
) == 1)
629 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
630 else if (undecorated_smoothed_pwdb
>= txpwr_threshold_lv2
)
631 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL2
;
632 else if ((undecorated_smoothed_pwdb
< (txpwr_threshold_lv2
- 3)) &&
633 (undecorated_smoothed_pwdb
>= txpwr_threshold_lv1
))
634 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL1
;
635 else if (undecorated_smoothed_pwdb
< (txpwr_threshold_lv1
- 3))
636 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
638 if ((rtlpriv
->dm
.dynamic_txhighpower_lvl
!= rtlpriv
->dm
.last_dtp_lvl
))
639 rtl92s_phy_set_txpower(hw
, rtlphy
->current_channel
);
641 rtlpriv
->dm
.last_dtp_lvl
= rtlpriv
->dm
.dynamic_txhighpower_lvl
;
644 static void _rtl92s_dm_init_dig(struct ieee80211_hw
*hw
)
646 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
648 /* Disable DIG scheme now.*/
649 digtable
.dig_enable_flag
= true;
650 digtable
.backoff_enable_flag
= true;
652 if ((rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
) &&
653 (hal_get_firmwareversion(rtlpriv
) >= 0x3c))
654 digtable
.dig_algorithm
= DIG_ALGO_BY_TOW_PORT
;
656 digtable
.dig_algorithm
=
657 DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM
;
659 digtable
.dig_twoport_algorithm
= DIG_TWO_PORT_ALGO_RSSI
;
660 digtable
.dig_ext_port_stage
= DIG_EXT_PORT_STAGE_MAX
;
661 /* off=by real rssi value, on=by digtable.rssi_val for new dig */
662 digtable
.dig_dbgmode
= DM_DBG_OFF
;
663 digtable
.dig_slgorithm_switch
= 0;
665 /* 2007/10/04 MH Define init gain threshol. */
666 digtable
.dig_state
= DM_STA_DIG_MAX
;
667 digtable
.dig_highpwrstate
= DM_STA_DIG_MAX
;
669 digtable
.cur_sta_connectstate
= DIG_STA_DISCONNECT
;
670 digtable
.pre_sta_connectstate
= DIG_STA_DISCONNECT
;
671 digtable
.cur_ap_connectstate
= DIG_AP_DISCONNECT
;
672 digtable
.pre_ap_connectstate
= DIG_AP_DISCONNECT
;
674 digtable
.rssi_lowthresh
= DM_DIG_THRESH_LOW
;
675 digtable
.rssi_highthresh
= DM_DIG_THRESH_HIGH
;
677 digtable
.fa_lowthresh
= DM_FALSEALARM_THRESH_LOW
;
678 digtable
.fa_highthresh
= DM_FALSEALARM_THRESH_HIGH
;
680 digtable
.rssi_highpower_lowthresh
= DM_DIG_HIGH_PWR_THRESH_LOW
;
681 digtable
.rssi_highpower_highthresh
= DM_DIG_HIGH_PWR_THRESH_HIGH
;
683 /* for dig debug rssi value */
684 digtable
.rssi_val
= 50;
685 digtable
.backoff_val
= DM_DIG_BACKOFF
;
686 digtable
.rx_gain_range_max
= DM_DIG_MAX
;
688 digtable
.rx_gain_range_min
= DM_DIG_MIN
;
690 digtable
.backoffval_range_max
= DM_DIG_BACKOFF_MAX
;
691 digtable
.backoffval_range_min
= DM_DIG_BACKOFF_MIN
;
694 static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw
*hw
)
696 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
698 if ((hal_get_firmwareversion(rtlpriv
) >= 60) &&
699 (rtlpriv
->dm
.dm_type
== DM_TYPE_BYDRIVER
))
700 rtlpriv
->dm
.dynamic_txpower_enable
= true;
702 rtlpriv
->dm
.dynamic_txpower_enable
= false;
704 rtlpriv
->dm
.last_dtp_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
705 rtlpriv
->dm
.dynamic_txhighpower_lvl
= TX_HIGHPWR_LEVEL_NORMAL
;
708 void rtl92s_dm_init(struct ieee80211_hw
*hw
)
710 struct rtl_priv
*rtlpriv
= rtl_priv(hw
);
712 rtlpriv
->dm
.dm_type
= DM_TYPE_BYDRIVER
;
713 rtlpriv
->dm
.undecorated_smoothed_pwdb
= -1;
715 _rtl92s_dm_init_dynamic_txpower(hw
);
716 rtl92s_dm_init_edca_turbo(hw
);
717 _rtl92s_dm_init_rate_adaptive_mask(hw
);
718 _rtl92s_dm_init_txpowertracking_thermalmeter(hw
);
719 _rtl92s_dm_init_dig(hw
);
721 rtl_write_dword(rtlpriv
, WFM5
, FW_CCA_CHK_ENABLE
);
724 void rtl92s_dm_watchdog(struct ieee80211_hw
*hw
)
726 _rtl92s_dm_check_edca_turbo(hw
);
727 _rtl92s_dm_check_txpowertracking_thermalmeter(hw
);
728 _rtl92s_dm_ctrl_initgain_byrssi(hw
);
729 _rtl92s_dm_dynamic_txpower(hw
);
730 _rtl92s_dm_refresh_rateadaptive_mask(hw
);
731 _rtl92s_dm_switch_baseband_mrc(hw
);