16f3fcdc8SLarry Finger // SPDX-License-Identifier: GPL-2.0
26f3fcdc8SLarry Finger /* Copyright(c) 2009-2012 Realtek Corporation.*/
3f1d2b4d3SLarry Finger
4f1d2b4d3SLarry Finger #include "../wifi.h"
5f1d2b4d3SLarry Finger #include "../base.h"
6f1d2b4d3SLarry Finger #include "../core.h"
7f1d2b4d3SLarry Finger #include "reg.h"
8f1d2b4d3SLarry Finger #include "def.h"
9f1d2b4d3SLarry Finger #include "phy.h"
10f1d2b4d3SLarry Finger #include "dm.h"
11f1d2b4d3SLarry Finger #include "fw.h"
12f1d2b4d3SLarry Finger
13f1d2b4d3SLarry Finger static const u32 edca_setting_dl[PEER_MAX] = {
14f1d2b4d3SLarry Finger 0xa44f, /* 0 UNKNOWN */
15f1d2b4d3SLarry Finger 0x5ea44f, /* 1 REALTEK_90 */
16f1d2b4d3SLarry Finger 0x5ea44f, /* 2 REALTEK_92SE */
17f1d2b4d3SLarry Finger 0xa630, /* 3 BROAD */
18f1d2b4d3SLarry Finger 0xa44f, /* 4 RAL */
19f1d2b4d3SLarry Finger 0xa630, /* 5 ATH */
20f1d2b4d3SLarry Finger 0xa630, /* 6 CISCO */
21f1d2b4d3SLarry Finger 0xa42b, /* 7 MARV */
22f1d2b4d3SLarry Finger };
23f1d2b4d3SLarry Finger
24f1d2b4d3SLarry Finger static const u32 edca_setting_dl_gmode[PEER_MAX] = {
25f1d2b4d3SLarry Finger 0x4322, /* 0 UNKNOWN */
26f1d2b4d3SLarry Finger 0xa44f, /* 1 REALTEK_90 */
27f1d2b4d3SLarry Finger 0x5ea44f, /* 2 REALTEK_92SE */
28f1d2b4d3SLarry Finger 0xa42b, /* 3 BROAD */
29f1d2b4d3SLarry Finger 0x5e4322, /* 4 RAL */
30f1d2b4d3SLarry Finger 0x4322, /* 5 ATH */
31f1d2b4d3SLarry Finger 0xa430, /* 6 CISCO */
32f1d2b4d3SLarry Finger 0x5ea44f, /* 7 MARV */
33f1d2b4d3SLarry Finger };
34f1d2b4d3SLarry Finger
35f1d2b4d3SLarry Finger static const u32 edca_setting_ul[PEER_MAX] = {
36f1d2b4d3SLarry Finger 0x5e4322, /* 0 UNKNOWN */
37f1d2b4d3SLarry Finger 0xa44f, /* 1 REALTEK_90 */
38f1d2b4d3SLarry Finger 0x5ea44f, /* 2 REALTEK_92SE */
39f1d2b4d3SLarry Finger 0x5ea322, /* 3 BROAD */
40f1d2b4d3SLarry Finger 0x5ea422, /* 4 RAL */
41f1d2b4d3SLarry Finger 0x5ea322, /* 5 ATH */
42f1d2b4d3SLarry Finger 0x3ea44f, /* 6 CISCO */
43f1d2b4d3SLarry Finger 0x5ea44f, /* 7 MARV */
44f1d2b4d3SLarry Finger };
45f1d2b4d3SLarry Finger
_rtl92s_dm_check_edca_turbo(struct ieee80211_hw * hw)46f1d2b4d3SLarry Finger static void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw)
47f1d2b4d3SLarry Finger {
48f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
49f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
50f1d2b4d3SLarry Finger
51f1d2b4d3SLarry Finger static u64 last_txok_cnt;
52f1d2b4d3SLarry Finger static u64 last_rxok_cnt;
53f1d2b4d3SLarry Finger u64 cur_txok_cnt = 0;
54f1d2b4d3SLarry Finger u64 cur_rxok_cnt = 0;
55f1d2b4d3SLarry Finger
56f1d2b4d3SLarry Finger u32 edca_be_ul = edca_setting_ul[mac->vendor];
57f1d2b4d3SLarry Finger u32 edca_be_dl = edca_setting_dl[mac->vendor];
58f1d2b4d3SLarry Finger u32 edca_gmode = edca_setting_dl_gmode[mac->vendor];
59f1d2b4d3SLarry Finger
60f1d2b4d3SLarry Finger if (mac->link_state != MAC80211_LINKED) {
61f1d2b4d3SLarry Finger rtlpriv->dm.current_turbo_edca = false;
62f1d2b4d3SLarry Finger goto dm_checkedcaturbo_exit;
63f1d2b4d3SLarry Finger }
64f1d2b4d3SLarry Finger
65f1d2b4d3SLarry Finger if ((!rtlpriv->dm.is_any_nonbepkts) &&
66f1d2b4d3SLarry Finger (!rtlpriv->dm.disable_framebursting)) {
67f1d2b4d3SLarry Finger cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
68f1d2b4d3SLarry Finger cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
69f1d2b4d3SLarry Finger
70f1d2b4d3SLarry Finger if (rtlpriv->phy.rf_type == RF_1T2R) {
71f1d2b4d3SLarry Finger if (cur_txok_cnt > 4 * cur_rxok_cnt) {
72f1d2b4d3SLarry Finger /* Uplink TP is present. */
73f1d2b4d3SLarry Finger if (rtlpriv->dm.is_cur_rdlstate ||
74f1d2b4d3SLarry Finger !rtlpriv->dm.current_turbo_edca) {
75f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, EDCAPARA_BE,
76f1d2b4d3SLarry Finger edca_be_ul);
77f1d2b4d3SLarry Finger rtlpriv->dm.is_cur_rdlstate = false;
78f1d2b4d3SLarry Finger }
79f1d2b4d3SLarry Finger } else {/* Balance TP is present. */
80f1d2b4d3SLarry Finger if (!rtlpriv->dm.is_cur_rdlstate ||
81f1d2b4d3SLarry Finger !rtlpriv->dm.current_turbo_edca) {
82f1d2b4d3SLarry Finger if (mac->mode == WIRELESS_MODE_G ||
83f1d2b4d3SLarry Finger mac->mode == WIRELESS_MODE_B)
84f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv,
85f1d2b4d3SLarry Finger EDCAPARA_BE,
86f1d2b4d3SLarry Finger edca_gmode);
87f1d2b4d3SLarry Finger else
88f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv,
89f1d2b4d3SLarry Finger EDCAPARA_BE,
90f1d2b4d3SLarry Finger edca_be_dl);
91f1d2b4d3SLarry Finger rtlpriv->dm.is_cur_rdlstate = true;
92f1d2b4d3SLarry Finger }
93f1d2b4d3SLarry Finger }
94f1d2b4d3SLarry Finger rtlpriv->dm.current_turbo_edca = true;
95f1d2b4d3SLarry Finger } else {
96f1d2b4d3SLarry Finger if (cur_rxok_cnt > 4 * cur_txok_cnt) {
97f1d2b4d3SLarry Finger if (!rtlpriv->dm.is_cur_rdlstate ||
98f1d2b4d3SLarry Finger !rtlpriv->dm.current_turbo_edca) {
99f1d2b4d3SLarry Finger if (mac->mode == WIRELESS_MODE_G ||
100f1d2b4d3SLarry Finger mac->mode == WIRELESS_MODE_B)
101f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv,
102f1d2b4d3SLarry Finger EDCAPARA_BE,
103f1d2b4d3SLarry Finger edca_gmode);
104f1d2b4d3SLarry Finger else
105f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv,
106f1d2b4d3SLarry Finger EDCAPARA_BE,
107f1d2b4d3SLarry Finger edca_be_dl);
108f1d2b4d3SLarry Finger rtlpriv->dm.is_cur_rdlstate = true;
109f1d2b4d3SLarry Finger }
110f1d2b4d3SLarry Finger } else {
111f1d2b4d3SLarry Finger if (rtlpriv->dm.is_cur_rdlstate ||
112f1d2b4d3SLarry Finger !rtlpriv->dm.current_turbo_edca) {
113f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, EDCAPARA_BE,
114f1d2b4d3SLarry Finger edca_be_ul);
115f1d2b4d3SLarry Finger rtlpriv->dm.is_cur_rdlstate = false;
116f1d2b4d3SLarry Finger }
117f1d2b4d3SLarry Finger }
118f1d2b4d3SLarry Finger rtlpriv->dm.current_turbo_edca = true;
119f1d2b4d3SLarry Finger }
120f1d2b4d3SLarry Finger } else {
121f1d2b4d3SLarry Finger if (rtlpriv->dm.current_turbo_edca) {
122f1d2b4d3SLarry Finger u8 tmp = AC0_BE;
123f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
124f1d2b4d3SLarry Finger &tmp);
125f1d2b4d3SLarry Finger rtlpriv->dm.current_turbo_edca = false;
126f1d2b4d3SLarry Finger }
127f1d2b4d3SLarry Finger }
128f1d2b4d3SLarry Finger
129f1d2b4d3SLarry Finger dm_checkedcaturbo_exit:
130f1d2b4d3SLarry Finger rtlpriv->dm.is_any_nonbepkts = false;
131f1d2b4d3SLarry Finger last_txok_cnt = rtlpriv->stats.txbytesunicast;
132f1d2b4d3SLarry Finger last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
133f1d2b4d3SLarry Finger }
134f1d2b4d3SLarry Finger
_rtl92s_dm_txpowertracking_callback_thermalmeter(struct ieee80211_hw * hw)135f1d2b4d3SLarry Finger static void _rtl92s_dm_txpowertracking_callback_thermalmeter(
136f1d2b4d3SLarry Finger struct ieee80211_hw *hw)
137f1d2b4d3SLarry Finger {
138f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
139f1d2b4d3SLarry Finger struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
140f1d2b4d3SLarry Finger u8 thermalvalue = 0;
141f1d2b4d3SLarry Finger u32 fw_cmd = 0;
142f1d2b4d3SLarry Finger
143f1d2b4d3SLarry Finger rtlpriv->dm.txpower_trackinginit = true;
144f1d2b4d3SLarry Finger
145f1d2b4d3SLarry Finger thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
146f1d2b4d3SLarry Finger
147*fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
148f1d2b4d3SLarry Finger "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n",
149f1d2b4d3SLarry Finger thermalvalue,
150f1d2b4d3SLarry Finger rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
151f1d2b4d3SLarry Finger
152f1d2b4d3SLarry Finger if (thermalvalue) {
153f1d2b4d3SLarry Finger rtlpriv->dm.thermalvalue = thermalvalue;
154f1d2b4d3SLarry Finger if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
155f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL);
156f1d2b4d3SLarry Finger } else {
157f1d2b4d3SLarry Finger fw_cmd = (FW_TXPWR_TRACK_THERMAL |
158f1d2b4d3SLarry Finger (rtlpriv->efuse.thermalmeter[0] << 8) |
159f1d2b4d3SLarry Finger (thermalvalue << 16));
160f1d2b4d3SLarry Finger
161*fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
162f1d2b4d3SLarry Finger "Write to FW Thermal Val = 0x%x\n", fw_cmd);
163f1d2b4d3SLarry Finger
164f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, fw_cmd);
165f1d2b4d3SLarry Finger rtl92s_phy_chk_fwcmd_iodone(hw);
166f1d2b4d3SLarry Finger }
167f1d2b4d3SLarry Finger }
168f1d2b4d3SLarry Finger
169f1d2b4d3SLarry Finger rtlpriv->dm.txpowercount = 0;
170f1d2b4d3SLarry Finger }
171f1d2b4d3SLarry Finger
_rtl92s_dm_check_txpowertracking_thermalmeter(struct ieee80211_hw * hw)172f1d2b4d3SLarry Finger static void _rtl92s_dm_check_txpowertracking_thermalmeter(
173f1d2b4d3SLarry Finger struct ieee80211_hw *hw)
174f1d2b4d3SLarry Finger {
175f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
176f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
177f1d2b4d3SLarry Finger u8 tx_power_checkcnt = 5;
178f1d2b4d3SLarry Finger
179f1d2b4d3SLarry Finger /* 2T2R TP issue */
180f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_2T2R)
181f1d2b4d3SLarry Finger return;
182f1d2b4d3SLarry Finger
183f1d2b4d3SLarry Finger if (!rtlpriv->dm.txpower_tracking)
184f1d2b4d3SLarry Finger return;
185f1d2b4d3SLarry Finger
186f1d2b4d3SLarry Finger if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) {
187f1d2b4d3SLarry Finger rtlpriv->dm.txpowercount++;
188f1d2b4d3SLarry Finger return;
189f1d2b4d3SLarry Finger }
190f1d2b4d3SLarry Finger
191f1d2b4d3SLarry Finger if (!rtlpriv->dm.tm_trigger) {
192f1d2b4d3SLarry Finger rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER,
193f1d2b4d3SLarry Finger RFREG_OFFSET_MASK, 0x60);
194f1d2b4d3SLarry Finger rtlpriv->dm.tm_trigger = 1;
195f1d2b4d3SLarry Finger } else {
196f1d2b4d3SLarry Finger _rtl92s_dm_txpowertracking_callback_thermalmeter(hw);
197f1d2b4d3SLarry Finger rtlpriv->dm.tm_trigger = 0;
198f1d2b4d3SLarry Finger }
199f1d2b4d3SLarry Finger }
200f1d2b4d3SLarry Finger
_rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw * hw)201f1d2b4d3SLarry Finger static void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
202f1d2b4d3SLarry Finger {
203f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
204f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
205f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
206f1d2b4d3SLarry Finger struct rate_adaptive *ra = &(rtlpriv->ra);
207f1d2b4d3SLarry Finger struct ieee80211_sta *sta = NULL;
208f1d2b4d3SLarry Finger u32 low_rssi_thresh = 0;
209f1d2b4d3SLarry Finger u32 middle_rssi_thresh = 0;
210f1d2b4d3SLarry Finger u32 high_rssi_thresh = 0;
211f1d2b4d3SLarry Finger
212f1d2b4d3SLarry Finger if (is_hal_stop(rtlhal))
213f1d2b4d3SLarry Finger return;
214f1d2b4d3SLarry Finger
215f1d2b4d3SLarry Finger if (!rtlpriv->dm.useramask)
216f1d2b4d3SLarry Finger return;
217f1d2b4d3SLarry Finger
218f1d2b4d3SLarry Finger if (hal_get_firmwareversion(rtlpriv) >= 61 &&
219f1d2b4d3SLarry Finger !rtlpriv->dm.inform_fw_driverctrldm) {
220f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER);
221f1d2b4d3SLarry Finger rtlpriv->dm.inform_fw_driverctrldm = true;
222f1d2b4d3SLarry Finger }
223f1d2b4d3SLarry Finger
224f1d2b4d3SLarry Finger if ((mac->link_state == MAC80211_LINKED) &&
225f1d2b4d3SLarry Finger (mac->opmode == NL80211_IFTYPE_STATION)) {
226f1d2b4d3SLarry Finger switch (ra->pre_ratr_state) {
227f1d2b4d3SLarry Finger case DM_RATR_STA_HIGH:
228f1d2b4d3SLarry Finger high_rssi_thresh = 40;
229f1d2b4d3SLarry Finger middle_rssi_thresh = 30;
230f1d2b4d3SLarry Finger low_rssi_thresh = 20;
231f1d2b4d3SLarry Finger break;
232f1d2b4d3SLarry Finger case DM_RATR_STA_MIDDLE:
233f1d2b4d3SLarry Finger high_rssi_thresh = 44;
234f1d2b4d3SLarry Finger middle_rssi_thresh = 30;
235f1d2b4d3SLarry Finger low_rssi_thresh = 20;
236f1d2b4d3SLarry Finger break;
237f1d2b4d3SLarry Finger case DM_RATR_STA_LOW:
238f1d2b4d3SLarry Finger high_rssi_thresh = 44;
239f1d2b4d3SLarry Finger middle_rssi_thresh = 34;
240f1d2b4d3SLarry Finger low_rssi_thresh = 20;
241f1d2b4d3SLarry Finger break;
242f1d2b4d3SLarry Finger case DM_RATR_STA_ULTRALOW:
243f1d2b4d3SLarry Finger high_rssi_thresh = 44;
244f1d2b4d3SLarry Finger middle_rssi_thresh = 34;
245f1d2b4d3SLarry Finger low_rssi_thresh = 24;
246f1d2b4d3SLarry Finger break;
247f1d2b4d3SLarry Finger default:
248f1d2b4d3SLarry Finger high_rssi_thresh = 44;
249f1d2b4d3SLarry Finger middle_rssi_thresh = 34;
250f1d2b4d3SLarry Finger low_rssi_thresh = 24;
251f1d2b4d3SLarry Finger break;
252f1d2b4d3SLarry Finger }
253f1d2b4d3SLarry Finger
254f1d2b4d3SLarry Finger if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) {
255f1d2b4d3SLarry Finger ra->ratr_state = DM_RATR_STA_HIGH;
256f1d2b4d3SLarry Finger } else if (rtlpriv->dm.undec_sm_pwdb >
257f1d2b4d3SLarry Finger (long)middle_rssi_thresh) {
258f1d2b4d3SLarry Finger ra->ratr_state = DM_RATR_STA_LOW;
259f1d2b4d3SLarry Finger } else if (rtlpriv->dm.undec_sm_pwdb >
260f1d2b4d3SLarry Finger (long)low_rssi_thresh) {
261f1d2b4d3SLarry Finger ra->ratr_state = DM_RATR_STA_LOW;
262f1d2b4d3SLarry Finger } else {
263f1d2b4d3SLarry Finger ra->ratr_state = DM_RATR_STA_ULTRALOW;
264f1d2b4d3SLarry Finger }
265f1d2b4d3SLarry Finger
266f1d2b4d3SLarry Finger if (ra->pre_ratr_state != ra->ratr_state) {
267*fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
268f1d2b4d3SLarry Finger "RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
269f1d2b4d3SLarry Finger rtlpriv->dm.undec_sm_pwdb, ra->ratr_state,
270f1d2b4d3SLarry Finger ra->pre_ratr_state, ra->ratr_state);
271f1d2b4d3SLarry Finger
272f1d2b4d3SLarry Finger rcu_read_lock();
273f1d2b4d3SLarry Finger sta = rtl_find_sta(hw, mac->bssid);
274f1d2b4d3SLarry Finger if (sta)
275f1d2b4d3SLarry Finger rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
2761d22b177SPing-Ke Shih ra->ratr_state,
2771d22b177SPing-Ke Shih true);
278f1d2b4d3SLarry Finger rcu_read_unlock();
279f1d2b4d3SLarry Finger
280f1d2b4d3SLarry Finger ra->pre_ratr_state = ra->ratr_state;
281f1d2b4d3SLarry Finger }
282f1d2b4d3SLarry Finger }
283f1d2b4d3SLarry Finger }
284f1d2b4d3SLarry Finger
_rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw * hw)285f1d2b4d3SLarry Finger static void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw)
286f1d2b4d3SLarry Finger {
287f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
288f1d2b4d3SLarry Finger struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
289f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
290f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
291f1d2b4d3SLarry Finger bool current_mrc;
292f1d2b4d3SLarry Finger bool enable_mrc = true;
293f1d2b4d3SLarry Finger long tmpentry_maxpwdb = 0;
294f1d2b4d3SLarry Finger u8 rssi_a = 0;
295f1d2b4d3SLarry Finger u8 rssi_b = 0;
296f1d2b4d3SLarry Finger
297f1d2b4d3SLarry Finger if (is_hal_stop(rtlhal))
298f1d2b4d3SLarry Finger return;
299f1d2b4d3SLarry Finger
300f1d2b4d3SLarry Finger if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R))
301f1d2b4d3SLarry Finger return;
302f1d2b4d3SLarry Finger
303f1d2b4d3SLarry Finger rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(¤t_mrc));
304f1d2b4d3SLarry Finger
305f1d2b4d3SLarry Finger if (mac->link_state >= MAC80211_LINKED) {
306f1d2b4d3SLarry Finger if (rtlpriv->dm.undec_sm_pwdb > tmpentry_maxpwdb) {
307f1d2b4d3SLarry Finger rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A];
308f1d2b4d3SLarry Finger rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B];
309f1d2b4d3SLarry Finger }
310f1d2b4d3SLarry Finger }
311f1d2b4d3SLarry Finger
312f1d2b4d3SLarry Finger /* MRC settings would NOT affect TP on Wireless B mode. */
313f1d2b4d3SLarry Finger if (mac->mode != WIRELESS_MODE_B) {
314f1d2b4d3SLarry Finger if ((rssi_a == 0) && (rssi_b == 0)) {
315f1d2b4d3SLarry Finger enable_mrc = true;
316f1d2b4d3SLarry Finger } else if (rssi_b > 30) {
317f1d2b4d3SLarry Finger /* Turn on B-Path */
318f1d2b4d3SLarry Finger enable_mrc = true;
319f1d2b4d3SLarry Finger } else if (rssi_b < 5) {
320f1d2b4d3SLarry Finger /* Turn off B-path */
321f1d2b4d3SLarry Finger enable_mrc = false;
322f1d2b4d3SLarry Finger /* Take care of RSSI differentiation. */
323f1d2b4d3SLarry Finger } else if (rssi_a > 15 && (rssi_a >= rssi_b)) {
324f1d2b4d3SLarry Finger if ((rssi_a - rssi_b) > 15)
325f1d2b4d3SLarry Finger /* Turn off B-path */
326f1d2b4d3SLarry Finger enable_mrc = false;
327f1d2b4d3SLarry Finger else if ((rssi_a - rssi_b) < 10)
328f1d2b4d3SLarry Finger /* Turn on B-Path */
329f1d2b4d3SLarry Finger enable_mrc = true;
330f1d2b4d3SLarry Finger else
331f1d2b4d3SLarry Finger enable_mrc = current_mrc;
332f1d2b4d3SLarry Finger } else {
333f1d2b4d3SLarry Finger /* Turn on B-Path */
334f1d2b4d3SLarry Finger enable_mrc = true;
335f1d2b4d3SLarry Finger }
336f1d2b4d3SLarry Finger }
337f1d2b4d3SLarry Finger
338f1d2b4d3SLarry Finger /* Update MRC settings if needed. */
339f1d2b4d3SLarry Finger if (enable_mrc != current_mrc)
340f1d2b4d3SLarry Finger rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC,
341f1d2b4d3SLarry Finger (u8 *)&enable_mrc);
342f1d2b4d3SLarry Finger
343f1d2b4d3SLarry Finger }
344f1d2b4d3SLarry Finger
rtl92s_dm_init_edca_turbo(struct ieee80211_hw * hw)345f1d2b4d3SLarry Finger void rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw)
346f1d2b4d3SLarry Finger {
347f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
348f1d2b4d3SLarry Finger
349f1d2b4d3SLarry Finger rtlpriv->dm.current_turbo_edca = false;
350f1d2b4d3SLarry Finger rtlpriv->dm.is_any_nonbepkts = false;
351f1d2b4d3SLarry Finger rtlpriv->dm.is_cur_rdlstate = false;
352f1d2b4d3SLarry Finger }
353f1d2b4d3SLarry Finger
_rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw * hw)354f1d2b4d3SLarry Finger static void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
355f1d2b4d3SLarry Finger {
356f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
357f1d2b4d3SLarry Finger struct rate_adaptive *ra = &(rtlpriv->ra);
358f1d2b4d3SLarry Finger
359f1d2b4d3SLarry Finger ra->ratr_state = DM_RATR_STA_MAX;
360f1d2b4d3SLarry Finger ra->pre_ratr_state = DM_RATR_STA_MAX;
361f1d2b4d3SLarry Finger
362f1d2b4d3SLarry Finger if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER &&
363f1d2b4d3SLarry Finger hal_get_firmwareversion(rtlpriv) >= 60)
364f1d2b4d3SLarry Finger rtlpriv->dm.useramask = true;
365f1d2b4d3SLarry Finger else
366f1d2b4d3SLarry Finger rtlpriv->dm.useramask = false;
367f1d2b4d3SLarry Finger
368f1d2b4d3SLarry Finger rtlpriv->dm.useramask = false;
369f1d2b4d3SLarry Finger rtlpriv->dm.inform_fw_driverctrldm = false;
370f1d2b4d3SLarry Finger }
371f1d2b4d3SLarry Finger
_rtl92s_dm_init_txpowertracking_thermalmeter(struct ieee80211_hw * hw)372f1d2b4d3SLarry Finger static void _rtl92s_dm_init_txpowertracking_thermalmeter(
373f1d2b4d3SLarry Finger struct ieee80211_hw *hw)
374f1d2b4d3SLarry Finger {
375f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
376f1d2b4d3SLarry Finger
377f1d2b4d3SLarry Finger rtlpriv->dm.txpower_tracking = true;
378f1d2b4d3SLarry Finger rtlpriv->dm.txpowercount = 0;
379f1d2b4d3SLarry Finger rtlpriv->dm.txpower_trackinginit = false;
380f1d2b4d3SLarry Finger }
381f1d2b4d3SLarry Finger
_rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw * hw)382f1d2b4d3SLarry Finger static void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
383f1d2b4d3SLarry Finger {
384f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
385f1d2b4d3SLarry Finger struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
386f1d2b4d3SLarry Finger u32 ret_value;
387f1d2b4d3SLarry Finger
388f1d2b4d3SLarry Finger ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
389f1d2b4d3SLarry Finger falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
390f1d2b4d3SLarry Finger
391f1d2b4d3SLarry Finger ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
392f1d2b4d3SLarry Finger falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
393f1d2b4d3SLarry Finger falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
394f1d2b4d3SLarry Finger ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
395f1d2b4d3SLarry Finger falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
396f1d2b4d3SLarry Finger
397f1d2b4d3SLarry Finger falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
398f1d2b4d3SLarry Finger falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail +
399f1d2b4d3SLarry Finger falsealm_cnt->cnt_mcs_fail;
400f1d2b4d3SLarry Finger
401f1d2b4d3SLarry Finger /* read CCK false alarm */
402f1d2b4d3SLarry Finger ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD);
403f1d2b4d3SLarry Finger falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff);
404f1d2b4d3SLarry Finger falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
405f1d2b4d3SLarry Finger falsealm_cnt->cnt_cck_fail;
406f1d2b4d3SLarry Finger }
407f1d2b4d3SLarry Finger
rtl92s_backoff_enable_flag(struct ieee80211_hw * hw)408f1d2b4d3SLarry Finger static void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw)
409f1d2b4d3SLarry Finger {
410f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
411f1d2b4d3SLarry Finger struct dig_t *digtable = &rtlpriv->dm_digtable;
412f1d2b4d3SLarry Finger struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
413f1d2b4d3SLarry Finger
414f1d2b4d3SLarry Finger if (falsealm_cnt->cnt_all > digtable->fa_highthresh) {
415f1d2b4d3SLarry Finger if ((digtable->back_val - 6) <
416f1d2b4d3SLarry Finger digtable->backoffval_range_min)
417f1d2b4d3SLarry Finger digtable->back_val = digtable->backoffval_range_min;
418f1d2b4d3SLarry Finger else
419f1d2b4d3SLarry Finger digtable->back_val -= 6;
420f1d2b4d3SLarry Finger } else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) {
421f1d2b4d3SLarry Finger if ((digtable->back_val + 6) >
422f1d2b4d3SLarry Finger digtable->backoffval_range_max)
423f1d2b4d3SLarry Finger digtable->back_val =
424f1d2b4d3SLarry Finger digtable->backoffval_range_max;
425f1d2b4d3SLarry Finger else
426f1d2b4d3SLarry Finger digtable->back_val += 6;
427f1d2b4d3SLarry Finger }
428f1d2b4d3SLarry Finger }
429f1d2b4d3SLarry Finger
_rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw * hw)430f1d2b4d3SLarry Finger static void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
431f1d2b4d3SLarry Finger {
432f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
433f1d2b4d3SLarry Finger struct dig_t *digtable = &rtlpriv->dm_digtable;
434f1d2b4d3SLarry Finger struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
435f1d2b4d3SLarry Finger static u8 initialized, force_write;
436f1d2b4d3SLarry Finger u8 initial_gain = 0;
437f1d2b4d3SLarry Finger
438f1d2b4d3SLarry Finger if ((digtable->pre_sta_cstate == digtable->cur_sta_cstate) ||
439f1d2b4d3SLarry Finger (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT)) {
440f1d2b4d3SLarry Finger if (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) {
441f1d2b4d3SLarry Finger if (rtlpriv->psc.rfpwr_state != ERFON)
442f1d2b4d3SLarry Finger return;
443f1d2b4d3SLarry Finger
444f1d2b4d3SLarry Finger if (digtable->backoff_enable_flag)
445f1d2b4d3SLarry Finger rtl92s_backoff_enable_flag(hw);
446f1d2b4d3SLarry Finger else
447f1d2b4d3SLarry Finger digtable->back_val = DM_DIG_BACKOFF_MAX;
448f1d2b4d3SLarry Finger
449f1d2b4d3SLarry Finger if ((digtable->rssi_val + 10 - digtable->back_val) >
450f1d2b4d3SLarry Finger digtable->rx_gain_max)
451f1d2b4d3SLarry Finger digtable->cur_igvalue =
452f1d2b4d3SLarry Finger digtable->rx_gain_max;
453f1d2b4d3SLarry Finger else if ((digtable->rssi_val + 10 - digtable->back_val)
454f1d2b4d3SLarry Finger < digtable->rx_gain_min)
455f1d2b4d3SLarry Finger digtable->cur_igvalue =
456f1d2b4d3SLarry Finger digtable->rx_gain_min;
457f1d2b4d3SLarry Finger else
458f1d2b4d3SLarry Finger digtable->cur_igvalue = digtable->rssi_val + 10
459f1d2b4d3SLarry Finger - digtable->back_val;
460f1d2b4d3SLarry Finger
461f1d2b4d3SLarry Finger if (falsealm_cnt->cnt_all > 10000)
462f1d2b4d3SLarry Finger digtable->cur_igvalue =
463f1d2b4d3SLarry Finger (digtable->cur_igvalue > 0x33) ?
464f1d2b4d3SLarry Finger digtable->cur_igvalue : 0x33;
465f1d2b4d3SLarry Finger
466f1d2b4d3SLarry Finger if (falsealm_cnt->cnt_all > 16000)
467f1d2b4d3SLarry Finger digtable->cur_igvalue =
468f1d2b4d3SLarry Finger digtable->rx_gain_max;
469f1d2b4d3SLarry Finger /* connected -> connected or disconnected -> disconnected */
470f1d2b4d3SLarry Finger } else {
471f1d2b4d3SLarry Finger /* Firmware control DIG, do nothing in driver dm */
472f1d2b4d3SLarry Finger return;
473f1d2b4d3SLarry Finger }
474f1d2b4d3SLarry Finger /* disconnected -> connected or connected ->
475f1d2b4d3SLarry Finger * disconnected or beforeconnect->(dis)connected */
476f1d2b4d3SLarry Finger } else {
477f1d2b4d3SLarry Finger /* Enable FW DIG */
478f1d2b4d3SLarry Finger digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
479f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE);
480f1d2b4d3SLarry Finger
481f1d2b4d3SLarry Finger digtable->back_val = DM_DIG_BACKOFF_MAX;
482f1d2b4d3SLarry Finger digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0];
483f1d2b4d3SLarry Finger digtable->pre_igvalue = 0;
484f1d2b4d3SLarry Finger return;
485f1d2b4d3SLarry Finger }
486f1d2b4d3SLarry Finger
487f1d2b4d3SLarry Finger /* Forced writing to prevent from fw-dig overwriting. */
488f1d2b4d3SLarry Finger if (digtable->pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
489f1d2b4d3SLarry Finger MASKBYTE0))
490f1d2b4d3SLarry Finger force_write = 1;
491f1d2b4d3SLarry Finger
492f1d2b4d3SLarry Finger if ((digtable->pre_igvalue != digtable->cur_igvalue) ||
493f1d2b4d3SLarry Finger !initialized || force_write) {
494f1d2b4d3SLarry Finger /* Disable FW DIG */
495f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE);
496f1d2b4d3SLarry Finger
497f1d2b4d3SLarry Finger initial_gain = (u8)digtable->cur_igvalue;
498f1d2b4d3SLarry Finger
499f1d2b4d3SLarry Finger /* Set initial gain. */
500f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain);
501f1d2b4d3SLarry Finger rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain);
502f1d2b4d3SLarry Finger digtable->pre_igvalue = digtable->cur_igvalue;
503f1d2b4d3SLarry Finger initialized = 1;
504f1d2b4d3SLarry Finger force_write = 0;
505f1d2b4d3SLarry Finger }
506f1d2b4d3SLarry Finger }
507f1d2b4d3SLarry Finger
_rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw * hw)508f1d2b4d3SLarry Finger static void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
509f1d2b4d3SLarry Finger {
510f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
511f1d2b4d3SLarry Finger struct dig_t *dig = &rtlpriv->dm_digtable;
512f1d2b4d3SLarry Finger
513f1d2b4d3SLarry Finger if (rtlpriv->mac80211.act_scanning)
514f1d2b4d3SLarry Finger return;
515f1d2b4d3SLarry Finger
516f1d2b4d3SLarry Finger /* Decide the current status and if modify initial gain or not */
517f1d2b4d3SLarry Finger if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
518f1d2b4d3SLarry Finger rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
519f1d2b4d3SLarry Finger dig->cur_sta_cstate = DIG_STA_CONNECT;
520f1d2b4d3SLarry Finger else
521f1d2b4d3SLarry Finger dig->cur_sta_cstate = DIG_STA_DISCONNECT;
522f1d2b4d3SLarry Finger
523f1d2b4d3SLarry Finger dig->rssi_val = rtlpriv->dm.undec_sm_pwdb;
524f1d2b4d3SLarry Finger
525f1d2b4d3SLarry Finger /* Change dig mode to rssi */
526f1d2b4d3SLarry Finger if (dig->cur_sta_cstate != DIG_STA_DISCONNECT) {
527f1d2b4d3SLarry Finger if (dig->dig_twoport_algorithm ==
528f1d2b4d3SLarry Finger DIG_TWO_PORT_ALGO_FALSE_ALARM) {
529f1d2b4d3SLarry Finger dig->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
530f1d2b4d3SLarry Finger rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS);
531f1d2b4d3SLarry Finger }
532f1d2b4d3SLarry Finger }
533f1d2b4d3SLarry Finger
534f1d2b4d3SLarry Finger _rtl92s_dm_false_alarm_counter_statistics(hw);
535f1d2b4d3SLarry Finger _rtl92s_dm_initial_gain_sta_beforeconnect(hw);
536f1d2b4d3SLarry Finger
537f1d2b4d3SLarry Finger dig->pre_sta_cstate = dig->cur_sta_cstate;
538f1d2b4d3SLarry Finger }
539f1d2b4d3SLarry Finger
_rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw * hw)540f1d2b4d3SLarry Finger static void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)
541f1d2b4d3SLarry Finger {
542f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
543f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
544f1d2b4d3SLarry Finger struct dig_t *digtable = &rtlpriv->dm_digtable;
545f1d2b4d3SLarry Finger
546f1d2b4d3SLarry Finger /* 2T2R TP issue */
547f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_2T2R)
548f1d2b4d3SLarry Finger return;
549f1d2b4d3SLarry Finger
550f1d2b4d3SLarry Finger if (!rtlpriv->dm.dm_initialgain_enable)
551f1d2b4d3SLarry Finger return;
552f1d2b4d3SLarry Finger
553f1d2b4d3SLarry Finger if (digtable->dig_enable_flag == false)
554f1d2b4d3SLarry Finger return;
555f1d2b4d3SLarry Finger
556f1d2b4d3SLarry Finger _rtl92s_dm_ctrl_initgain_bytwoport(hw);
557f1d2b4d3SLarry Finger }
558f1d2b4d3SLarry Finger
_rtl92s_dm_dynamic_txpower(struct ieee80211_hw * hw)559f1d2b4d3SLarry Finger static void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
560f1d2b4d3SLarry Finger {
561f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
562f1d2b4d3SLarry Finger struct rtl_phy *rtlphy = &(rtlpriv->phy);
563f1d2b4d3SLarry Finger struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
564f1d2b4d3SLarry Finger long undec_sm_pwdb;
565f1d2b4d3SLarry Finger long txpwr_threshold_lv1, txpwr_threshold_lv2;
566f1d2b4d3SLarry Finger
567f1d2b4d3SLarry Finger /* 2T2R TP issue */
568f1d2b4d3SLarry Finger if (rtlphy->rf_type == RF_2T2R)
569f1d2b4d3SLarry Finger return;
570f1d2b4d3SLarry Finger
571f1d2b4d3SLarry Finger if (!rtlpriv->dm.dynamic_txpower_enable ||
572f1d2b4d3SLarry Finger rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
573f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
574f1d2b4d3SLarry Finger return;
575f1d2b4d3SLarry Finger }
576f1d2b4d3SLarry Finger
577f1d2b4d3SLarry Finger if ((mac->link_state < MAC80211_LINKED) &&
578f1d2b4d3SLarry Finger (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
579*fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
580f1d2b4d3SLarry Finger "Not connected to any\n");
581f1d2b4d3SLarry Finger
582f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
583f1d2b4d3SLarry Finger
584f1d2b4d3SLarry Finger rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
585f1d2b4d3SLarry Finger return;
586f1d2b4d3SLarry Finger }
587f1d2b4d3SLarry Finger
588f1d2b4d3SLarry Finger if (mac->link_state >= MAC80211_LINKED) {
589f1d2b4d3SLarry Finger if (mac->opmode == NL80211_IFTYPE_ADHOC) {
590f1d2b4d3SLarry Finger undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
591*fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
592f1d2b4d3SLarry Finger "AP Client PWDB = 0x%lx\n",
593f1d2b4d3SLarry Finger undec_sm_pwdb);
594f1d2b4d3SLarry Finger } else {
595f1d2b4d3SLarry Finger undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
596*fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
597f1d2b4d3SLarry Finger "STA Default Port PWDB = 0x%lx\n",
598f1d2b4d3SLarry Finger undec_sm_pwdb);
599f1d2b4d3SLarry Finger }
600f1d2b4d3SLarry Finger } else {
601f1d2b4d3SLarry Finger undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
602f1d2b4d3SLarry Finger
603*fca8218dSLarry Finger rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
604f1d2b4d3SLarry Finger "AP Ext Port PWDB = 0x%lx\n",
605f1d2b4d3SLarry Finger undec_sm_pwdb);
606f1d2b4d3SLarry Finger }
607f1d2b4d3SLarry Finger
608f1d2b4d3SLarry Finger txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
609f1d2b4d3SLarry Finger txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1;
610f1d2b4d3SLarry Finger
611f1d2b4d3SLarry Finger if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1)
612f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
613f1d2b4d3SLarry Finger else if (undec_sm_pwdb >= txpwr_threshold_lv2)
614f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2;
615f1d2b4d3SLarry Finger else if ((undec_sm_pwdb < (txpwr_threshold_lv2 - 3)) &&
616f1d2b4d3SLarry Finger (undec_sm_pwdb >= txpwr_threshold_lv1))
617f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1;
618f1d2b4d3SLarry Finger else if (undec_sm_pwdb < (txpwr_threshold_lv1 - 3))
619f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
620f1d2b4d3SLarry Finger
621f1d2b4d3SLarry Finger if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl))
622f1d2b4d3SLarry Finger rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
623f1d2b4d3SLarry Finger
624f1d2b4d3SLarry Finger rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
625f1d2b4d3SLarry Finger }
626f1d2b4d3SLarry Finger
_rtl92s_dm_init_dig(struct ieee80211_hw * hw)627f1d2b4d3SLarry Finger static void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
628f1d2b4d3SLarry Finger {
629f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
630f1d2b4d3SLarry Finger struct dig_t *digtable = &rtlpriv->dm_digtable;
631f1d2b4d3SLarry Finger
632f1d2b4d3SLarry Finger /* Disable DIG scheme now.*/
633f1d2b4d3SLarry Finger digtable->dig_enable_flag = true;
634f1d2b4d3SLarry Finger digtable->backoff_enable_flag = true;
635f1d2b4d3SLarry Finger
636f1d2b4d3SLarry Finger if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) &&
637f1d2b4d3SLarry Finger (hal_get_firmwareversion(rtlpriv) >= 0x3c))
638f1d2b4d3SLarry Finger digtable->dig_algorithm = DIG_ALGO_BY_TOW_PORT;
639f1d2b4d3SLarry Finger else
640f1d2b4d3SLarry Finger digtable->dig_algorithm =
641f1d2b4d3SLarry Finger DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM;
642f1d2b4d3SLarry Finger
643f1d2b4d3SLarry Finger digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
644f1d2b4d3SLarry Finger digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
645f1d2b4d3SLarry Finger /* off=by real rssi value, on=by digtable->rssi_val for new dig */
646f1d2b4d3SLarry Finger digtable->dig_dbgmode = DM_DBG_OFF;
647f1d2b4d3SLarry Finger digtable->dig_slgorithm_switch = 0;
648f1d2b4d3SLarry Finger
649f1d2b4d3SLarry Finger /* 2007/10/04 MH Define init gain threshol. */
650f1d2b4d3SLarry Finger digtable->dig_state = DM_STA_DIG_MAX;
651f1d2b4d3SLarry Finger digtable->dig_highpwrstate = DM_STA_DIG_MAX;
652f1d2b4d3SLarry Finger
653f1d2b4d3SLarry Finger digtable->cur_sta_cstate = DIG_STA_DISCONNECT;
654f1d2b4d3SLarry Finger digtable->pre_sta_cstate = DIG_STA_DISCONNECT;
655f1d2b4d3SLarry Finger digtable->cur_ap_cstate = DIG_AP_DISCONNECT;
656f1d2b4d3SLarry Finger digtable->pre_ap_cstate = DIG_AP_DISCONNECT;
657f1d2b4d3SLarry Finger
658f1d2b4d3SLarry Finger digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
659f1d2b4d3SLarry Finger digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
660f1d2b4d3SLarry Finger
661f1d2b4d3SLarry Finger digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
662f1d2b4d3SLarry Finger digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
663f1d2b4d3SLarry Finger
664f1d2b4d3SLarry Finger digtable->rssi_highpower_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
665f1d2b4d3SLarry Finger digtable->rssi_highpower_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
666f1d2b4d3SLarry Finger
667f1d2b4d3SLarry Finger /* for dig debug rssi value */
668f1d2b4d3SLarry Finger digtable->rssi_val = 50;
669f1d2b4d3SLarry Finger digtable->back_val = DM_DIG_BACKOFF_MAX;
670f1d2b4d3SLarry Finger digtable->rx_gain_max = DM_DIG_MAX;
671f1d2b4d3SLarry Finger
672f1d2b4d3SLarry Finger digtable->rx_gain_min = DM_DIG_MIN;
673f1d2b4d3SLarry Finger
674f1d2b4d3SLarry Finger digtable->backoffval_range_max = DM_DIG_BACKOFF_MAX;
675f1d2b4d3SLarry Finger digtable->backoffval_range_min = DM_DIG_BACKOFF_MIN;
676f1d2b4d3SLarry Finger }
677f1d2b4d3SLarry Finger
_rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw * hw)678f1d2b4d3SLarry Finger static void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
679f1d2b4d3SLarry Finger {
680f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
681f1d2b4d3SLarry Finger
682f1d2b4d3SLarry Finger if ((hal_get_firmwareversion(rtlpriv) >= 60) &&
683f1d2b4d3SLarry Finger (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER))
684f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txpower_enable = true;
685f1d2b4d3SLarry Finger else
686f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txpower_enable = false;
687f1d2b4d3SLarry Finger
688f1d2b4d3SLarry Finger rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
689f1d2b4d3SLarry Finger rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
690f1d2b4d3SLarry Finger }
691f1d2b4d3SLarry Finger
rtl92s_dm_init(struct ieee80211_hw * hw)692f1d2b4d3SLarry Finger void rtl92s_dm_init(struct ieee80211_hw *hw)
693f1d2b4d3SLarry Finger {
694f1d2b4d3SLarry Finger struct rtl_priv *rtlpriv = rtl_priv(hw);
695f1d2b4d3SLarry Finger
696f1d2b4d3SLarry Finger rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
697f1d2b4d3SLarry Finger rtlpriv->dm.undec_sm_pwdb = -1;
698f1d2b4d3SLarry Finger
699f1d2b4d3SLarry Finger _rtl92s_dm_init_dynamic_txpower(hw);
700f1d2b4d3SLarry Finger rtl92s_dm_init_edca_turbo(hw);
701f1d2b4d3SLarry Finger _rtl92s_dm_init_rate_adaptive_mask(hw);
702f1d2b4d3SLarry Finger _rtl92s_dm_init_txpowertracking_thermalmeter(hw);
703f1d2b4d3SLarry Finger _rtl92s_dm_init_dig(hw);
704f1d2b4d3SLarry Finger
705f1d2b4d3SLarry Finger rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE);
706f1d2b4d3SLarry Finger }
707f1d2b4d3SLarry Finger
rtl92s_dm_watchdog(struct ieee80211_hw * hw)708f1d2b4d3SLarry Finger void rtl92s_dm_watchdog(struct ieee80211_hw *hw)
709f1d2b4d3SLarry Finger {
710f1d2b4d3SLarry Finger _rtl92s_dm_check_edca_turbo(hw);
711f1d2b4d3SLarry Finger _rtl92s_dm_check_txpowertracking_thermalmeter(hw);
712f1d2b4d3SLarry Finger _rtl92s_dm_ctrl_initgain_byrssi(hw);
713f1d2b4d3SLarry Finger _rtl92s_dm_dynamic_txpower(hw);
714f1d2b4d3SLarry Finger _rtl92s_dm_refresh_rateadaptive_mask(hw);
715f1d2b4d3SLarry Finger _rtl92s_dm_switch_baseband_mrc(hw);
716f1d2b4d3SLarry Finger }
717f1d2b4d3SLarry Finger
718