1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2014 Realtek Corporation.*/
3
4 #include "../wifi.h"
5 #include "../base.h"
6 #include "../pci.h"
7 #include "../core.h"
8 #include "reg.h"
9 #include "def.h"
10 #include "phy.h"
11 #include "dm.h"
12 #include "../rtl8723com/dm_common.h"
13 #include "fw.h"
14 #include "trx.h"
15 #include "../btcoexist/rtl_btc.h"
16
17 static const u32 ofdmswing_table[] = {
18 0x0b40002d, /* 0, -15.0dB */
19 0x0c000030, /* 1, -14.5dB */
20 0x0cc00033, /* 2, -14.0dB */
21 0x0d800036, /* 3, -13.5dB */
22 0x0e400039, /* 4, -13.0dB */
23 0x0f00003c, /* 5, -12.5dB */
24 0x10000040, /* 6, -12.0dB */
25 0x11000044, /* 7, -11.5dB */
26 0x12000048, /* 8, -11.0dB */
27 0x1300004c, /* 9, -10.5dB */
28 0x14400051, /* 10, -10.0dB */
29 0x15800056, /* 11, -9.5dB */
30 0x16c0005b, /* 12, -9.0dB */
31 0x18000060, /* 13, -8.5dB */
32 0x19800066, /* 14, -8.0dB */
33 0x1b00006c, /* 15, -7.5dB */
34 0x1c800072, /* 16, -7.0dB */
35 0x1e400079, /* 17, -6.5dB */
36 0x20000080, /* 18, -6.0dB */
37 0x22000088, /* 19, -5.5dB */
38 0x24000090, /* 20, -5.0dB */
39 0x26000098, /* 21, -4.5dB */
40 0x288000a2, /* 22, -4.0dB */
41 0x2ac000ab, /* 23, -3.5dB */
42 0x2d4000b5, /* 24, -3.0dB */
43 0x300000c0, /* 25, -2.5dB */
44 0x32c000cb, /* 26, -2.0dB */
45 0x35c000d7, /* 27, -1.5dB */
46 0x390000e4, /* 28, -1.0dB */
47 0x3c8000f2, /* 29, -0.5dB */
48 0x40000100, /* 30, +0dB */
49 0x43c0010f, /* 31, +0.5dB */
50 0x47c0011f, /* 32, +1.0dB */
51 0x4c000130, /* 33, +1.5dB */
52 0x50800142, /* 34, +2.0dB */
53 0x55400155, /* 35, +2.5dB */
54 0x5a400169, /* 36, +3.0dB */
55 0x5fc0017f, /* 37, +3.5dB */
56 0x65400195, /* 38, +4.0dB */
57 0x6b8001ae, /* 39, +4.5dB */
58 0x71c001c7, /* 40, +5.0dB */
59 0x788001e2, /* 41, +5.5dB */
60 0x7f8001fe /* 42, +6.0dB */
61 };
62
63 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
64 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /* 0, -16.0dB */
65 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /* 1, -15.5dB */
66 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 2, -15.0dB */
67 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /* 3, -14.5dB */
68 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 4, -14.0dB */
69 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /* 5, -13.5dB */
70 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /* 6, -13.0dB */
71 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /* 7, -12.5dB */
72 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /* 8, -12.0dB */
73 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /* 9, -11.5dB */
74 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB */
75 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB */
76 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB */
77 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB */
78 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */
79 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB */
80 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
81 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB */
82 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */
83 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB */
84 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 20, -6.0dB */
85 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB */
86 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */
87 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB */
88 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */
89 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB */
90 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB */
91 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB */
92 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */
93 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB */
94 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB */
95 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB */
96 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04} /* 32, +0dB */
97 };
98
99 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
100 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /* 0, -16.0dB */
101 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 1, -15.5dB */
102 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 2, -15.0dB */
103 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 3, -14.5dB */
104 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /* 4, -14.0dB */
105 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 5, -13.5dB */
106 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 6, -13.0dB */
107 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /* 7, -12.5dB */
108 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 8, -12.0dB */
109 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /* 9, -11.5dB */
110 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB */
111 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 11, -10.5dB */
112 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB */
113 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB */
114 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 14, -9.0dB */
115 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB */
116 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
117 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB */
118 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */
119 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */
120 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */
121 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB */
122 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */
123 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 23, -4.5dB */
124 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */
125 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */
126 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */
127 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 27, -2.5dB */
128 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */
129 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 29, -1.5dB */
130 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */
131 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */
132 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00} /* 32, +0dB */
133 };
134
135 static const u32 edca_setting_dl[PEER_MAX] = {
136 0xa44f, /* 0 UNKNOWN */
137 0x5ea44f, /* 1 REALTEK_90 */
138 0x5e4322, /* 2 REALTEK_92SE */
139 0x5ea42b, /* 3 BROAD */
140 0xa44f, /* 4 RAL */
141 0xa630, /* 5 ATH */
142 0x5ea630, /* 6 CISCO */
143 0x5ea42b, /* 7 MARVELL */
144 };
145
146 static const u32 edca_setting_ul[PEER_MAX] = {
147 0x5e4322, /* 0 UNKNOWN */
148 0xa44f, /* 1 REALTEK_90 */
149 0x5ea44f, /* 2 REALTEK_92SE */
150 0x5ea32b, /* 3 BROAD */
151 0x5ea422, /* 4 RAL */
152 0x5ea322, /* 5 ATH */
153 0x3ea430, /* 6 CISCO */
154 0x5ea44f, /* 7 MARV */
155 };
156
rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw * hw,u8 type,u8 * pdirection,u32 * poutwrite_val)157 void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type,
158 u8 *pdirection, u32 *poutwrite_val)
159 {
160 struct rtl_priv *rtlpriv = rtl_priv(hw);
161 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
162 u8 pwr_val = 0;
163 u8 ofdm_base = rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A];
164 u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
165 u8 cck_base = rtldm->swing_idx_cck_base;
166 u8 cck_val = rtldm->swing_idx_cck;
167
168 if (type == 0) {
169 if (ofdm_val <= ofdm_base) {
170 *pdirection = 1;
171 pwr_val = ofdm_base - ofdm_val;
172 } else {
173 *pdirection = 2;
174 pwr_val = ofdm_val - ofdm_base;
175 }
176 } else if (type == 1) {
177 if (cck_val <= cck_base) {
178 *pdirection = 1;
179 pwr_val = cck_base - cck_val;
180 } else {
181 *pdirection = 2;
182 pwr_val = cck_val - cck_base;
183 }
184 }
185
186 if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
187 pwr_val = TXPWRTRACK_MAX_IDX;
188
189 *poutwrite_val = pwr_val | (pwr_val << 8) |
190 (pwr_val << 16) | (pwr_val << 24);
191 }
192
rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw * hw)193 void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
194 {
195 struct rtl_priv *rtlpriv = rtl_priv(hw);
196 struct rate_adaptive *p_ra = &rtlpriv->ra;
197
198 p_ra->ratr_state = DM_RATR_STA_INIT;
199 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
200
201 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
202 rtlpriv->dm.useramask = true;
203 else
204 rtlpriv->dm.useramask = false;
205
206 p_ra->high_rssi_thresh_for_ra = 50;
207 p_ra->low_rssi_thresh_for_ra40m = 20;
208 }
209
rtl8723be_dm_init_txpower_tracking(struct ieee80211_hw * hw)210 static void rtl8723be_dm_init_txpower_tracking(struct ieee80211_hw *hw)
211 {
212 struct rtl_priv *rtlpriv = rtl_priv(hw);
213
214 rtlpriv->dm.txpower_tracking = true;
215 rtlpriv->dm.txpower_track_control = true;
216 rtlpriv->dm.thermalvalue = 0;
217
218 rtlpriv->dm.ofdm_index[0] = 30;
219 rtlpriv->dm.cck_index = 20;
220
221 rtlpriv->dm.swing_idx_cck_base = rtlpriv->dm.cck_index;
222
223 rtlpriv->dm.swing_idx_ofdm_base[0] = rtlpriv->dm.ofdm_index[0];
224 rtlpriv->dm.delta_power_index[RF90_PATH_A] = 0;
225 rtlpriv->dm.delta_power_index_last[RF90_PATH_A] = 0;
226 rtlpriv->dm.power_index_offset[RF90_PATH_A] = 0;
227
228 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
229 "rtlpriv->dm.txpower_tracking = %d\n",
230 rtlpriv->dm.txpower_tracking);
231 }
232
rtl8723be_dm_init_dynamic_atc_switch(struct ieee80211_hw * hw)233 static void rtl8723be_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
234 {
235 struct rtl_priv *rtlpriv = rtl_priv(hw);
236
237 rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
238
239 rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, 0x800);
240 rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
241 }
242
rtl8723be_dm_init(struct ieee80211_hw * hw)243 void rtl8723be_dm_init(struct ieee80211_hw *hw)
244 {
245 struct rtl_priv *rtlpriv = rtl_priv(hw);
246 u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
247
248 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
249 rtl_dm_diginit(hw, cur_igvalue);
250 rtl8723be_dm_init_rate_adaptive_mask(hw);
251 rtl8723_dm_init_edca_turbo(hw);
252 rtl8723_dm_init_dynamic_bb_powersaving(hw);
253 rtl8723_dm_init_dynamic_txpower(hw);
254 rtl8723be_dm_init_txpower_tracking(hw);
255 rtl8723be_dm_init_dynamic_atc_switch(hw);
256 }
257
rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw * hw)258 static void rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw *hw)
259 {
260 struct rtl_priv *rtlpriv = rtl_priv(hw);
261 struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable;
262 struct rtl_mac *mac = rtl_mac(rtlpriv);
263
264 /* Determine the minimum RSSI */
265 if ((mac->link_state < MAC80211_LINKED) &&
266 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
267 rtl_dm_dig->min_undec_pwdb_for_dm = 0;
268 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
269 "Not connected to any\n");
270 }
271 if (mac->link_state >= MAC80211_LINKED) {
272 if (mac->opmode == NL80211_IFTYPE_AP ||
273 mac->opmode == NL80211_IFTYPE_ADHOC) {
274 rtl_dm_dig->min_undec_pwdb_for_dm =
275 rtlpriv->dm.entry_min_undec_sm_pwdb;
276 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
277 "AP Client PWDB = 0x%lx\n",
278 rtlpriv->dm.entry_min_undec_sm_pwdb);
279 } else {
280 rtl_dm_dig->min_undec_pwdb_for_dm =
281 rtlpriv->dm.undec_sm_pwdb;
282 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
283 "STA Default Port PWDB = 0x%x\n",
284 rtl_dm_dig->min_undec_pwdb_for_dm);
285 }
286 } else {
287 rtl_dm_dig->min_undec_pwdb_for_dm =
288 rtlpriv->dm.entry_min_undec_sm_pwdb;
289 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
290 "AP Ext Port or disconnect PWDB = 0x%x\n",
291 rtl_dm_dig->min_undec_pwdb_for_dm);
292 }
293 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
294 rtl_dm_dig->min_undec_pwdb_for_dm);
295 }
296
rtl8723be_dm_check_rssi_monitor(struct ieee80211_hw * hw)297 static void rtl8723be_dm_check_rssi_monitor(struct ieee80211_hw *hw)
298 {
299 struct rtl_priv *rtlpriv = rtl_priv(hw);
300 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
301 struct rtl_sta_info *drv_priv;
302 u8 h2c_parameter[3] = { 0 };
303 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
304
305 /* AP & ADHOC & MESH */
306 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
307 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
308 if (drv_priv->rssi_stat.undec_sm_pwdb <
309 tmp_entry_min_pwdb)
310 tmp_entry_min_pwdb =
311 drv_priv->rssi_stat.undec_sm_pwdb;
312 if (drv_priv->rssi_stat.undec_sm_pwdb >
313 tmp_entry_max_pwdb)
314 tmp_entry_max_pwdb =
315 drv_priv->rssi_stat.undec_sm_pwdb;
316 }
317 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
318
319 /* If associated entry is found */
320 if (tmp_entry_max_pwdb != 0) {
321 rtlpriv->dm.entry_max_undec_sm_pwdb =
322 tmp_entry_max_pwdb;
323 RTPRINT(rtlpriv, FDM, DM_PWDB,
324 "EntryMaxPWDB = 0x%lx(%ld)\n",
325 tmp_entry_max_pwdb, tmp_entry_max_pwdb);
326 } else {
327 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
328 }
329 /* If associated entry is found */
330 if (tmp_entry_min_pwdb != 0xff) {
331 rtlpriv->dm.entry_min_undec_sm_pwdb =
332 tmp_entry_min_pwdb;
333 RTPRINT(rtlpriv, FDM, DM_PWDB,
334 "EntryMinPWDB = 0x%lx(%ld)\n",
335 tmp_entry_min_pwdb, tmp_entry_min_pwdb);
336 } else {
337 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
338 }
339 /* Indicate Rx signal strength to FW. */
340 if (rtlpriv->dm.useramask) {
341 h2c_parameter[2] =
342 (u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF);
343 h2c_parameter[1] = 0x20;
344 h2c_parameter[0] = 0;
345 rtl8723be_fill_h2c_cmd(hw, H2C_RSSIBE_REPORT, 3, h2c_parameter);
346 } else {
347 rtl_write_byte(rtlpriv, 0x4fe,
348 rtlpriv->dm.undec_sm_pwdb);
349 }
350 rtl8723be_dm_find_minimum_rssi(hw);
351 dm_digtable->rssi_val_min =
352 rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
353 }
354
rtl8723be_dm_write_dig(struct ieee80211_hw * hw,u8 current_igi)355 void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
356 {
357 struct rtl_priv *rtlpriv = rtl_priv(hw);
358 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
359
360 if (dm_digtable->stop_dig)
361 return;
362
363 if (dm_digtable->cur_igvalue != current_igi) {
364 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi);
365 if (rtlpriv->phy.rf_type != RF_1T1R)
366 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1,
367 0x7f, current_igi);
368 }
369 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
370 dm_digtable->cur_igvalue = current_igi;
371 }
372
rtl8723be_dm_dig(struct ieee80211_hw * hw)373 static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
374 {
375 struct rtl_priv *rtlpriv = rtl_priv(hw);
376 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
377 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
378 u8 dig_min_0, dig_maxofmin;
379 bool bfirstconnect, bfirstdisconnect;
380 u8 dm_dig_max, dm_dig_min;
381 u8 current_igi = dm_digtable->cur_igvalue;
382 u8 offset;
383
384 /* AP,BT */
385 if (mac->act_scanning)
386 return;
387
388 dig_min_0 = dm_digtable->dig_min_0;
389 bfirstconnect = (mac->link_state >= MAC80211_LINKED) &&
390 !dm_digtable->media_connect_0;
391 bfirstdisconnect = (mac->link_state < MAC80211_LINKED) &&
392 (dm_digtable->media_connect_0);
393
394 dm_dig_max = 0x5a;
395 dm_dig_min = DM_DIG_MIN;
396 dig_maxofmin = DM_DIG_MAX_AP;
397
398 if (mac->link_state >= MAC80211_LINKED) {
399 if ((dm_digtable->rssi_val_min + 10) > dm_dig_max)
400 dm_digtable->rx_gain_max = dm_dig_max;
401 else if ((dm_digtable->rssi_val_min + 10) < dm_dig_min)
402 dm_digtable->rx_gain_max = dm_dig_min;
403 else
404 dm_digtable->rx_gain_max =
405 dm_digtable->rssi_val_min + 10;
406
407 if (rtlpriv->dm.one_entry_only) {
408 offset = 12;
409 if (dm_digtable->rssi_val_min - offset < dm_dig_min)
410 dig_min_0 = dm_dig_min;
411 else if (dm_digtable->rssi_val_min - offset >
412 dig_maxofmin)
413 dig_min_0 = dig_maxofmin;
414 else
415 dig_min_0 =
416 dm_digtable->rssi_val_min - offset;
417 } else {
418 dig_min_0 = dm_dig_min;
419 }
420
421 } else {
422 dm_digtable->rx_gain_max = dm_dig_max;
423 dig_min_0 = dm_dig_min;
424 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
425 }
426
427 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
428 if (dm_digtable->large_fa_hit != 3)
429 dm_digtable->large_fa_hit++;
430 if (dm_digtable->forbidden_igi < current_igi) {
431 dm_digtable->forbidden_igi = current_igi;
432 dm_digtable->large_fa_hit = 1;
433 }
434
435 if (dm_digtable->large_fa_hit >= 3) {
436 if ((dm_digtable->forbidden_igi + 1) >
437 dm_digtable->rx_gain_max)
438 dm_digtable->rx_gain_min =
439 dm_digtable->rx_gain_max;
440 else
441 dm_digtable->rx_gain_min =
442 dm_digtable->forbidden_igi + 1;
443 dm_digtable->recover_cnt = 3600;
444 }
445 } else {
446 if (dm_digtable->recover_cnt != 0) {
447 dm_digtable->recover_cnt--;
448 } else {
449 if (dm_digtable->large_fa_hit < 3) {
450 if ((dm_digtable->forbidden_igi - 1) <
451 dig_min_0) {
452 dm_digtable->forbidden_igi =
453 dig_min_0;
454 dm_digtable->rx_gain_min =
455 dig_min_0;
456 } else {
457 dm_digtable->forbidden_igi--;
458 dm_digtable->rx_gain_min =
459 dm_digtable->forbidden_igi + 1;
460 }
461 } else {
462 dm_digtable->large_fa_hit = 0;
463 }
464 }
465 }
466 if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max)
467 dm_digtable->rx_gain_min = dm_digtable->rx_gain_max;
468
469 if (mac->link_state >= MAC80211_LINKED) {
470 if (bfirstconnect) {
471 current_igi = min(dm_digtable->rssi_val_min, dig_maxofmin);
472
473 dm_digtable->large_fa_hit = 0;
474 } else {
475 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
476 current_igi += 4;
477 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
478 current_igi += 2;
479 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
480 current_igi -= 2;
481 }
482 } else {
483 if (bfirstdisconnect) {
484 current_igi = dm_digtable->rx_gain_min;
485 } else {
486 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
487 current_igi += 4;
488 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
489 current_igi += 2;
490 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
491 current_igi -= 2;
492 }
493 }
494
495 if (current_igi > dm_digtable->rx_gain_max)
496 current_igi = dm_digtable->rx_gain_max;
497 else if (current_igi < dm_digtable->rx_gain_min)
498 current_igi = dm_digtable->rx_gain_min;
499
500 rtl8723be_dm_write_dig(hw, current_igi);
501 dm_digtable->media_connect_0 =
502 ((mac->link_state >= MAC80211_LINKED) ? true : false);
503 dm_digtable->dig_min_0 = dig_min_0;
504 }
505
rtl8723be_dm_false_alarm_counter_statistics(struct ieee80211_hw * hw)506 static void rtl8723be_dm_false_alarm_counter_statistics(
507 struct ieee80211_hw *hw)
508 {
509 u32 ret_value;
510 struct rtl_priv *rtlpriv = rtl_priv(hw);
511 struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
512
513 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
514 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
515
516 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
517 falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff;
518 falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16;
519
520 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
521 falsealm_cnt->cnt_ofdm_cca = ret_value & 0xffff;
522 falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16;
523
524 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
525 falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff;
526 falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16;
527
528 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
529 falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff;
530
531 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
532 falsealm_cnt->cnt_rate_illegal +
533 falsealm_cnt->cnt_crc8_fail +
534 falsealm_cnt->cnt_mcs_fail +
535 falsealm_cnt->cnt_fast_fsync_fail +
536 falsealm_cnt->cnt_sb_search_fail;
537
538 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1);
539 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1);
540
541 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_RST_11N, MASKBYTE0);
542 falsealm_cnt->cnt_cck_fail = ret_value;
543
544 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
545 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
546
547 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD);
548 falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
549 ((ret_value & 0xff00) >> 8);
550
551 falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
552 falsealm_cnt->cnt_sb_search_fail +
553 falsealm_cnt->cnt_parity_fail +
554 falsealm_cnt->cnt_rate_illegal +
555 falsealm_cnt->cnt_crc8_fail +
556 falsealm_cnt->cnt_mcs_fail +
557 falsealm_cnt->cnt_cck_fail;
558
559 falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
560 falsealm_cnt->cnt_cck_cca;
561
562 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
563 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
564 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
565 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
566
567 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
568 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
569
570 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
571 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
572
573 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
574 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
575
576 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
577 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
578 falsealm_cnt->cnt_parity_fail,
579 falsealm_cnt->cnt_rate_illegal,
580 falsealm_cnt->cnt_crc8_fail,
581 falsealm_cnt->cnt_mcs_fail);
582
583 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
584 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
585 falsealm_cnt->cnt_ofdm_fail,
586 falsealm_cnt->cnt_cck_fail,
587 falsealm_cnt->cnt_all);
588 }
589
rtl8723be_dm_dynamic_txpower(struct ieee80211_hw * hw)590 static void rtl8723be_dm_dynamic_txpower(struct ieee80211_hw *hw)
591 {
592 /* 8723BE does not support ODM_BB_DYNAMIC_TXPWR*/
593 return;
594 }
595
rtl8723be_set_iqk_matrix(struct ieee80211_hw * hw,u8 ofdm_index,u8 rfpath,long iqk_result_x,long iqk_result_y)596 static void rtl8723be_set_iqk_matrix(struct ieee80211_hw *hw, u8 ofdm_index,
597 u8 rfpath, long iqk_result_x,
598 long iqk_result_y)
599 {
600 long ele_a = 0, ele_d, ele_c = 0, value32;
601
602 if (ofdm_index >= 43)
603 ofdm_index = 43 - 1;
604
605 ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000) >> 22;
606
607 if (iqk_result_x != 0) {
608 if ((iqk_result_x & 0x00000200) != 0)
609 iqk_result_x = iqk_result_x | 0xFFFFFC00;
610 ele_a = ((iqk_result_x * ele_d) >> 8) & 0x000003FF;
611
612 if ((iqk_result_y & 0x00000200) != 0)
613 iqk_result_y = iqk_result_y | 0xFFFFFC00;
614 ele_c = ((iqk_result_y * ele_d) >> 8) & 0x000003FF;
615
616 switch (rfpath) {
617 case RF90_PATH_A:
618 value32 = (ele_d << 22) |
619 ((ele_c & 0x3F) << 16) | ele_a;
620 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
621 value32);
622 value32 = (ele_c & 0x000003C0) >> 6;
623 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32);
624 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
625 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
626 value32);
627 break;
628 default:
629 break;
630 }
631 } else {
632 switch (rfpath) {
633 case RF90_PATH_A:
634 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
635 ofdmswing_table[ofdm_index]);
636 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00);
637 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00);
638 break;
639 default:
640 break;
641 }
642 }
643 }
644
rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw * hw,enum pwr_track_control_method method,u8 rfpath,u8 idx)645 static void rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw *hw,
646 enum pwr_track_control_method method,
647 u8 rfpath, u8 idx)
648 {
649 struct rtl_priv *rtlpriv = rtl_priv(hw);
650 struct rtl_phy *rtlphy = &rtlpriv->phy;
651 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
652 u8 swing_idx_ofdm_limit = 36;
653
654 if (method == TXAGC) {
655 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
656 } else if (method == BBSWING) {
657 if (rtldm->swing_idx_cck >= CCK_TABLE_SIZE)
658 rtldm->swing_idx_cck = CCK_TABLE_SIZE - 1;
659
660 if (!rtldm->cck_inch14) {
661 rtl_write_byte(rtlpriv, 0xa22,
662 cckswing_table_ch1ch13[rtldm->swing_idx_cck][0]);
663 rtl_write_byte(rtlpriv, 0xa23,
664 cckswing_table_ch1ch13[rtldm->swing_idx_cck][1]);
665 rtl_write_byte(rtlpriv, 0xa24,
666 cckswing_table_ch1ch13[rtldm->swing_idx_cck][2]);
667 rtl_write_byte(rtlpriv, 0xa25,
668 cckswing_table_ch1ch13[rtldm->swing_idx_cck][3]);
669 rtl_write_byte(rtlpriv, 0xa26,
670 cckswing_table_ch1ch13[rtldm->swing_idx_cck][4]);
671 rtl_write_byte(rtlpriv, 0xa27,
672 cckswing_table_ch1ch13[rtldm->swing_idx_cck][5]);
673 rtl_write_byte(rtlpriv, 0xa28,
674 cckswing_table_ch1ch13[rtldm->swing_idx_cck][6]);
675 rtl_write_byte(rtlpriv, 0xa29,
676 cckswing_table_ch1ch13[rtldm->swing_idx_cck][7]);
677 } else {
678 rtl_write_byte(rtlpriv, 0xa22,
679 cckswing_table_ch14[rtldm->swing_idx_cck][0]);
680 rtl_write_byte(rtlpriv, 0xa23,
681 cckswing_table_ch14[rtldm->swing_idx_cck][1]);
682 rtl_write_byte(rtlpriv, 0xa24,
683 cckswing_table_ch14[rtldm->swing_idx_cck][2]);
684 rtl_write_byte(rtlpriv, 0xa25,
685 cckswing_table_ch14[rtldm->swing_idx_cck][3]);
686 rtl_write_byte(rtlpriv, 0xa26,
687 cckswing_table_ch14[rtldm->swing_idx_cck][4]);
688 rtl_write_byte(rtlpriv, 0xa27,
689 cckswing_table_ch14[rtldm->swing_idx_cck][5]);
690 rtl_write_byte(rtlpriv, 0xa28,
691 cckswing_table_ch14[rtldm->swing_idx_cck][6]);
692 rtl_write_byte(rtlpriv, 0xa29,
693 cckswing_table_ch14[rtldm->swing_idx_cck][7]);
694 }
695
696 if (rfpath == RF90_PATH_A) {
697 if (rtldm->swing_idx_ofdm[RF90_PATH_A] <
698 swing_idx_ofdm_limit)
699 swing_idx_ofdm_limit =
700 rtldm->swing_idx_ofdm[RF90_PATH_A];
701
702 rtl8723be_set_iqk_matrix(hw,
703 rtldm->swing_idx_ofdm[rfpath], rfpath,
704 rtlphy->iqk_matrix[idx].value[0][0],
705 rtlphy->iqk_matrix[idx].value[0][1]);
706 } else if (rfpath == RF90_PATH_B) {
707 if (rtldm->swing_idx_ofdm[RF90_PATH_B] <
708 swing_idx_ofdm_limit)
709 swing_idx_ofdm_limit =
710 rtldm->swing_idx_ofdm[RF90_PATH_B];
711
712 rtl8723be_set_iqk_matrix(hw,
713 rtldm->swing_idx_ofdm[rfpath], rfpath,
714 rtlphy->iqk_matrix[idx].value[0][4],
715 rtlphy->iqk_matrix[idx].value[0][5]);
716 }
717 } else {
718 return;
719 }
720 }
721
rtl8723be_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw * hw)722 static void rtl8723be_dm_txpower_tracking_callback_thermalmeter(
723 struct ieee80211_hw *hw)
724 {
725 struct rtl_priv *rtlpriv = rtl_priv(hw);
726 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
727 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
728 u8 thermalvalue = 0, delta, delta_lck, delta_iqk;
729 u8 thermalvalue_avg_count = 0;
730 u32 thermalvalue_avg = 0;
731 int i = 0;
732
733 u8 ofdm_min_index = 6;
734 u8 index_for_channel = 0;
735
736 static const s8 delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = {
737 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
738 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10,
739 10, 11, 11, 12, 12, 13, 14, 15};
740 static const s8 delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = {
741 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
742 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9,
743 9, 10, 10, 11, 12, 13, 14, 15};
744
745 /*Initilization ( 7 steps in total )*/
746 rtlpriv->dm.txpower_trackinginit = true;
747 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
748 "%s\n", __func__);
749
750 thermalvalue = (u8)rtl_get_rfreg(hw,
751 RF90_PATH_A, RF_T_METER, 0xfc00);
752 if (!rtlpriv->dm.txpower_track_control || thermalvalue == 0 ||
753 rtlefuse->eeprom_thermalmeter == 0xFF)
754 return;
755 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
756 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
757 thermalvalue, rtldm->thermalvalue,
758 rtlefuse->eeprom_thermalmeter);
759 /*3 Initialize ThermalValues of RFCalibrateInfo*/
760 if (!rtldm->thermalvalue) {
761 rtlpriv->dm.thermalvalue_lck = thermalvalue;
762 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
763 }
764
765 /*4 Calculate average thermal meter*/
766 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
767 rtldm->thermalvalue_avg_index++;
768 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8723BE)
769 rtldm->thermalvalue_avg_index = 0;
770
771 for (i = 0; i < AVG_THERMAL_NUM_8723BE; i++) {
772 if (rtldm->thermalvalue_avg[i]) {
773 thermalvalue_avg += rtldm->thermalvalue_avg[i];
774 thermalvalue_avg_count++;
775 }
776 }
777
778 if (thermalvalue_avg_count)
779 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
780
781 /* 5 Calculate delta, delta_LCK, delta_IQK.*/
782 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
783 (thermalvalue - rtlpriv->dm.thermalvalue) :
784 (rtlpriv->dm.thermalvalue - thermalvalue);
785 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
786 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
787 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
788 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
789 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
790 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
791
792 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
793 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",
794 thermalvalue, rtlpriv->dm.thermalvalue,
795 rtlefuse->eeprom_thermalmeter, delta, delta_lck, delta_iqk);
796 /* 6 If necessary, do LCK.*/
797 if (delta_lck >= IQK_THRESHOLD) {
798 rtlpriv->dm.thermalvalue_lck = thermalvalue;
799 rtl8723be_phy_lc_calibrate(hw);
800 }
801
802 /* 7 If necessary, move the index of
803 * swing table to adjust Tx power.
804 */
805 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
806 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
807 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
808 (rtlefuse->eeprom_thermalmeter - thermalvalue);
809
810 if (delta >= TXSCALE_TABLE_SIZE)
811 delta = TXSCALE_TABLE_SIZE - 1;
812 /* 7.1 Get the final CCK_index and
813 * OFDM_index for each swing table.
814 */
815 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
816 rtldm->delta_power_index_last[RF90_PATH_A] =
817 rtldm->delta_power_index[RF90_PATH_A];
818 rtldm->delta_power_index[RF90_PATH_A] =
819 delta_swing_table_idx_tup_a[delta];
820 } else {
821 rtldm->delta_power_index_last[RF90_PATH_A] =
822 rtldm->delta_power_index[RF90_PATH_A];
823 rtldm->delta_power_index[RF90_PATH_A] =
824 -1 * delta_swing_table_idx_tdown_a[delta];
825 }
826
827 /* 7.2 Handle boundary conditions of index.*/
828 if (rtldm->delta_power_index[RF90_PATH_A] ==
829 rtldm->delta_power_index_last[RF90_PATH_A])
830 rtldm->power_index_offset[RF90_PATH_A] = 0;
831 else
832 rtldm->power_index_offset[RF90_PATH_A] =
833 rtldm->delta_power_index[RF90_PATH_A] -
834 rtldm->delta_power_index_last[RF90_PATH_A];
835
836 rtldm->ofdm_index[0] =
837 rtldm->swing_idx_ofdm_base[RF90_PATH_A] +
838 rtldm->power_index_offset[RF90_PATH_A];
839 rtldm->cck_index = rtldm->swing_idx_cck_base +
840 rtldm->power_index_offset[RF90_PATH_A];
841
842 rtldm->swing_idx_cck = rtldm->cck_index;
843 rtldm->swing_idx_ofdm[0] = rtldm->ofdm_index[0];
844
845 if (rtldm->ofdm_index[0] > OFDM_TABLE_SIZE - 1)
846 rtldm->ofdm_index[0] = OFDM_TABLE_SIZE - 1;
847 else if (rtldm->ofdm_index[0] < ofdm_min_index)
848 rtldm->ofdm_index[0] = ofdm_min_index;
849
850 if (rtldm->cck_index > CCK_TABLE_SIZE - 1)
851 rtldm->cck_index = CCK_TABLE_SIZE - 1;
852 else if (rtldm->cck_index < 0)
853 rtldm->cck_index = 0;
854 } else {
855 rtldm->power_index_offset[RF90_PATH_A] = 0;
856 }
857
858 if ((rtldm->power_index_offset[RF90_PATH_A] != 0) &&
859 (rtldm->txpower_track_control)) {
860 rtldm->done_txpower = true;
861 rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0,
862 index_for_channel);
863
864 rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
865 rtldm->swing_idx_ofdm_base[RF90_PATH_A] =
866 rtldm->swing_idx_ofdm[0];
867 rtldm->thermalvalue = thermalvalue;
868 }
869
870 if (delta_iqk >= IQK_THRESHOLD) {
871 rtldm->thermalvalue_iqk = thermalvalue;
872 rtl8723be_phy_iq_calibrate(hw, false);
873 }
874
875 rtldm->txpowercount = 0;
876 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
877
878 }
879
rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw * hw)880 void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw)
881 {
882 struct rtl_priv *rtlpriv = rtl_priv(hw);
883
884 if (!rtlpriv->dm.txpower_tracking)
885 return;
886
887 if (!rtlpriv->dm.tm_trigger) {
888 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16),
889 0x03);
890 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
891 "Trigger 8723be Thermal Meter!!\n");
892 rtlpriv->dm.tm_trigger = 1;
893 return;
894 } else {
895 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
896 "Schedule TxPowerTracking !!\n");
897 rtl8723be_dm_txpower_tracking_callback_thermalmeter(hw);
898 rtlpriv->dm.tm_trigger = 0;
899 }
900 }
901
rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw * hw)902 static void rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
903 {
904 struct rtl_priv *rtlpriv = rtl_priv(hw);
905 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
906 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
907 struct rate_adaptive *p_ra = &rtlpriv->ra;
908 u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m;
909 u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
910 u8 go_up_gap = 5;
911 struct ieee80211_sta *sta = NULL;
912
913 if (is_hal_stop(rtlhal)) {
914 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
915 "driver is going to unload\n");
916 return;
917 }
918
919 if (!rtlpriv->dm.useramask) {
920 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
921 "driver does not control rate adaptive mask\n");
922 return;
923 }
924
925 if (mac->link_state == MAC80211_LINKED &&
926 mac->opmode == NL80211_IFTYPE_STATION) {
927 switch (p_ra->pre_ratr_state) {
928 case DM_RATR_STA_MIDDLE:
929 high_rssithresh_for_ra += go_up_gap;
930 break;
931 case DM_RATR_STA_LOW:
932 high_rssithresh_for_ra += go_up_gap;
933 low_rssithresh_for_ra += go_up_gap;
934 break;
935 default:
936 break;
937 }
938
939 if (rtlpriv->dm.undec_sm_pwdb >
940 (long)high_rssithresh_for_ra)
941 p_ra->ratr_state = DM_RATR_STA_HIGH;
942 else if (rtlpriv->dm.undec_sm_pwdb >
943 (long)low_rssithresh_for_ra)
944 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
945 else
946 p_ra->ratr_state = DM_RATR_STA_LOW;
947
948 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
949 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
950 "RSSI = %ld\n",
951 rtlpriv->dm.undec_sm_pwdb);
952 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
953 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
954 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
955 "PreState = %d, CurState = %d\n",
956 p_ra->pre_ratr_state, p_ra->ratr_state);
957
958 rcu_read_lock();
959 sta = rtl_find_sta(hw, mac->bssid);
960 if (sta)
961 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
962 p_ra->ratr_state,
963 true);
964 rcu_read_unlock();
965
966 p_ra->pre_ratr_state = p_ra->ratr_state;
967 }
968 }
969 }
970
rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw * hw)971 static bool rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
972 {
973 struct rtl_priv *rtlpriv = rtl_priv(hw);
974
975 if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
976 return true;
977
978 return false;
979 }
980
rtl8723be_dm_check_edca_turbo(struct ieee80211_hw * hw)981 static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw)
982 {
983 struct rtl_priv *rtlpriv = rtl_priv(hw);
984 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
985
986 static u64 last_txok_cnt;
987 static u64 last_rxok_cnt;
988 u64 cur_txok_cnt = 0;
989 u64 cur_rxok_cnt = 0;
990 u32 edca_be_ul = 0x6ea42b;
991 u32 edca_be_dl = 0x6ea42b;/*not sure*/
992 u32 edca_be = 0x5ea42b;
993 u32 iot_peer = 0;
994 bool b_is_cur_rdlstate;
995 bool b_bias_on_rx = false;
996 bool b_edca_turbo_on = false;
997
998 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
999 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
1000
1001 iot_peer = rtlpriv->mac80211.vendor;
1002 b_bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ?
1003 true : false;
1004 b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
1005 (!rtlpriv->dm.disable_framebursting)) ?
1006 true : false;
1007
1008 if ((iot_peer == PEER_CISCO) &&
1009 (mac->mode == WIRELESS_MODE_N_24G)) {
1010 edca_be_dl = edca_setting_dl[iot_peer];
1011 edca_be_ul = edca_setting_ul[iot_peer];
1012 }
1013 if (rtl8723be_dm_is_edca_turbo_disable(hw))
1014 goto exit;
1015
1016 if (b_edca_turbo_on) {
1017 if (b_bias_on_rx)
1018 b_is_cur_rdlstate = (cur_txok_cnt > cur_rxok_cnt * 4) ?
1019 false : true;
1020 else
1021 b_is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
1022 true : false;
1023
1024 edca_be = (b_is_cur_rdlstate) ? edca_be_dl : edca_be_ul;
1025 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be);
1026 rtlpriv->dm.is_cur_rdlstate = b_is_cur_rdlstate;
1027 rtlpriv->dm.current_turbo_edca = true;
1028 } else {
1029 if (rtlpriv->dm.current_turbo_edca) {
1030 u8 tmp = AC0_BE;
1031 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
1032 (u8 *)(&tmp));
1033 }
1034 rtlpriv->dm.current_turbo_edca = false;
1035 }
1036
1037 exit:
1038 rtlpriv->dm.is_any_nonbepkts = false;
1039 last_txok_cnt = rtlpriv->stats.txbytesunicast;
1040 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
1041 }
1042
rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw * hw)1043 static void rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
1044 {
1045 struct rtl_priv *rtlpriv = rtl_priv(hw);
1046 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1047 u8 cur_cck_cca_thresh;
1048
1049 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1050 if (dm_digtable->rssi_val_min > 25) {
1051 cur_cck_cca_thresh = 0xcd;
1052 } else if ((dm_digtable->rssi_val_min <= 25) &&
1053 (dm_digtable->rssi_val_min > 10)) {
1054 cur_cck_cca_thresh = 0x83;
1055 } else {
1056 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1057 cur_cck_cca_thresh = 0x83;
1058 else
1059 cur_cck_cca_thresh = 0x40;
1060 }
1061 } else {
1062 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1063 cur_cck_cca_thresh = 0x83;
1064 else
1065 cur_cck_cca_thresh = 0x40;
1066 }
1067
1068 if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh)
1069 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
1070
1071 dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
1072 dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh;
1073 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
1074 "CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres);
1075 }
1076
rtl8723be_dm_dynamic_edcca(struct ieee80211_hw * hw)1077 static void rtl8723be_dm_dynamic_edcca(struct ieee80211_hw *hw)
1078 {
1079 struct rtl_priv *rtlpriv = rtl_priv(hw);
1080 u8 reg_c50, reg_c58;
1081 bool fw_current_in_ps_mode = false;
1082
1083 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1084 (u8 *)(&fw_current_in_ps_mode));
1085 if (fw_current_in_ps_mode)
1086 return;
1087
1088 reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
1089 reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
1090
1091 if (reg_c50 > 0x28 && reg_c58 > 0x28) {
1092 if (!rtlpriv->rtlhal.pre_edcca_enable) {
1093 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03);
1094 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00);
1095 }
1096 } else if (reg_c50 < 0x25 && reg_c58 < 0x25) {
1097 if (rtlpriv->rtlhal.pre_edcca_enable) {
1098 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f);
1099 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f);
1100 }
1101 }
1102 }
1103
rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw * hw)1104 static void rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
1105 {
1106 struct rtl_priv *rtlpriv = rtl_priv(hw);
1107 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1108 u8 crystal_cap;
1109 u32 packet_count;
1110 int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
1111 int cfo_ave_diff;
1112
1113 if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1114 if (rtldm->atc_status == ATC_STATUS_OFF) {
1115 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1116 ATC_STATUS_ON);
1117 rtldm->atc_status = ATC_STATUS_ON;
1118 }
1119 if (rtlpriv->cfg->ops->get_btc_status()) {
1120 if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) {
1121 rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1122 "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n");
1123 return;
1124 }
1125 }
1126
1127 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
1128 rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
1129 crystal_cap = rtldm->crystal_cap & 0x3f;
1130 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1131 (crystal_cap | (crystal_cap << 6)));
1132 }
1133 } else {
1134 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
1135 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
1136 packet_count = rtldm->packet_count;
1137
1138 if (packet_count == rtldm->packet_count_pre)
1139 return;
1140
1141 rtldm->packet_count_pre = packet_count;
1142
1143 if (rtlpriv->phy.rf_type == RF_1T1R)
1144 cfo_ave = cfo_khz_a;
1145 else
1146 cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
1147
1148 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
1149 (rtldm->cfo_ave_pre - cfo_ave) :
1150 (cfo_ave - rtldm->cfo_ave_pre);
1151
1152 if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) {
1153 rtldm->large_cfo_hit = true;
1154 return;
1155 } else
1156 rtldm->large_cfo_hit = false;
1157
1158 rtldm->cfo_ave_pre = cfo_ave;
1159
1160 if (cfo_ave >= -rtldm->cfo_threshold &&
1161 cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) {
1162 if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
1163 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
1164 rtldm->is_freeze = 1;
1165 } else {
1166 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
1167 }
1168 }
1169
1170 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
1171 adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 1) + 1;
1172 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
1173 rtlpriv->dm.crystal_cap > 0)
1174 adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 1) - 1;
1175
1176 if (adjust_xtal != 0) {
1177 rtldm->is_freeze = 0;
1178 rtldm->crystal_cap += adjust_xtal;
1179
1180 if (rtldm->crystal_cap > 0x3f)
1181 rtldm->crystal_cap = 0x3f;
1182 else if (rtldm->crystal_cap < 0)
1183 rtldm->crystal_cap = 0;
1184
1185 crystal_cap = rtldm->crystal_cap & 0x3f;
1186 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1187 (crystal_cap | (crystal_cap << 6)));
1188 }
1189
1190 if (cfo_ave < CFO_THRESHOLD_ATC &&
1191 cfo_ave > -CFO_THRESHOLD_ATC) {
1192 if (rtldm->atc_status == ATC_STATUS_ON) {
1193 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1194 ATC_STATUS_OFF);
1195 rtldm->atc_status = ATC_STATUS_OFF;
1196 }
1197 } else {
1198 if (rtldm->atc_status == ATC_STATUS_OFF) {
1199 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1200 ATC_STATUS_ON);
1201 rtldm->atc_status = ATC_STATUS_ON;
1202 }
1203 }
1204 }
1205 }
1206
rtl8723be_dm_common_info_self_update(struct ieee80211_hw * hw)1207 static void rtl8723be_dm_common_info_self_update(struct ieee80211_hw *hw)
1208 {
1209 struct rtl_priv *rtlpriv = rtl_priv(hw);
1210 u8 cnt;
1211
1212 rtlpriv->dm.one_entry_only = false;
1213
1214 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
1215 rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1216 rtlpriv->dm.one_entry_only = true;
1217 return;
1218 }
1219
1220 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1221 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
1222 rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
1223 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1224 cnt = list_count_nodes(&rtlpriv->entry_list);
1225 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1226
1227 if (cnt == 1)
1228 rtlpriv->dm.one_entry_only = true;
1229 }
1230 }
1231
rtl8723be_dm_watchdog(struct ieee80211_hw * hw)1232 void rtl8723be_dm_watchdog(struct ieee80211_hw *hw)
1233 {
1234 struct rtl_priv *rtlpriv = rtl_priv(hw);
1235 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1236 bool fw_current_inpsmode = false;
1237 bool fw_ps_awake = true;
1238
1239 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1240 (u8 *)(&fw_current_inpsmode));
1241
1242 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1243 (u8 *)(&fw_ps_awake));
1244
1245 if (ppsc->p2p_ps_info.p2p_ps_mode)
1246 fw_ps_awake = false;
1247
1248 spin_lock(&rtlpriv->locks.rf_ps_lock);
1249 if ((ppsc->rfpwr_state == ERFON) &&
1250 ((!fw_current_inpsmode) && fw_ps_awake) &&
1251 (!ppsc->rfchange_inprogress)) {
1252 rtl8723be_dm_common_info_self_update(hw);
1253 rtl8723be_dm_false_alarm_counter_statistics(hw);
1254 rtl8723be_dm_check_rssi_monitor(hw);
1255 rtl8723be_dm_dig(hw);
1256 rtl8723be_dm_dynamic_edcca(hw);
1257 rtl8723be_dm_cck_packet_detection_thresh(hw);
1258 rtl8723be_dm_refresh_rate_adaptive_mask(hw);
1259 rtl8723be_dm_check_edca_turbo(hw);
1260 rtl8723be_dm_dynamic_atc_switch(hw);
1261 rtl8723be_dm_check_txpower_tracking(hw);
1262 rtl8723be_dm_dynamic_txpower(hw);
1263 }
1264 spin_unlock(&rtlpriv->locks.rf_ps_lock);
1265 rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
1266 }
1267