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 if (dm_digtable->rssi_val_min <= dig_maxofmin)
472 current_igi = dm_digtable->rssi_val_min;
473 else
474 current_igi = dig_maxofmin;
475
476 dm_digtable->large_fa_hit = 0;
477 } else {
478 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
479 current_igi += 4;
480 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
481 current_igi += 2;
482 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
483 current_igi -= 2;
484 }
485 } else {
486 if (bfirstdisconnect) {
487 current_igi = dm_digtable->rx_gain_min;
488 } else {
489 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
490 current_igi += 4;
491 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
492 current_igi += 2;
493 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
494 current_igi -= 2;
495 }
496 }
497
498 if (current_igi > dm_digtable->rx_gain_max)
499 current_igi = dm_digtable->rx_gain_max;
500 else if (current_igi < dm_digtable->rx_gain_min)
501 current_igi = dm_digtable->rx_gain_min;
502
503 rtl8723be_dm_write_dig(hw, current_igi);
504 dm_digtable->media_connect_0 =
505 ((mac->link_state >= MAC80211_LINKED) ? true : false);
506 dm_digtable->dig_min_0 = dig_min_0;
507 }
508
rtl8723be_dm_false_alarm_counter_statistics(struct ieee80211_hw * hw)509 static void rtl8723be_dm_false_alarm_counter_statistics(
510 struct ieee80211_hw *hw)
511 {
512 u32 ret_value;
513 struct rtl_priv *rtlpriv = rtl_priv(hw);
514 struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
515
516 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
517 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
518
519 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
520 falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff;
521 falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16;
522
523 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
524 falsealm_cnt->cnt_ofdm_cca = ret_value & 0xffff;
525 falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16;
526
527 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
528 falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff;
529 falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16;
530
531 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
532 falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff;
533
534 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
535 falsealm_cnt->cnt_rate_illegal +
536 falsealm_cnt->cnt_crc8_fail +
537 falsealm_cnt->cnt_mcs_fail +
538 falsealm_cnt->cnt_fast_fsync_fail +
539 falsealm_cnt->cnt_sb_search_fail;
540
541 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1);
542 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1);
543
544 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_RST_11N, MASKBYTE0);
545 falsealm_cnt->cnt_cck_fail = ret_value;
546
547 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
548 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
549
550 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD);
551 falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
552 ((ret_value & 0xff00) >> 8);
553
554 falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
555 falsealm_cnt->cnt_sb_search_fail +
556 falsealm_cnt->cnt_parity_fail +
557 falsealm_cnt->cnt_rate_illegal +
558 falsealm_cnt->cnt_crc8_fail +
559 falsealm_cnt->cnt_mcs_fail +
560 falsealm_cnt->cnt_cck_fail;
561
562 falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
563 falsealm_cnt->cnt_cck_cca;
564
565 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
566 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
567 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
568 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
569
570 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
571 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
572
573 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
574 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
575
576 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
577 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
578
579 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
580 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
581 falsealm_cnt->cnt_parity_fail,
582 falsealm_cnt->cnt_rate_illegal,
583 falsealm_cnt->cnt_crc8_fail,
584 falsealm_cnt->cnt_mcs_fail);
585
586 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
587 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
588 falsealm_cnt->cnt_ofdm_fail,
589 falsealm_cnt->cnt_cck_fail,
590 falsealm_cnt->cnt_all);
591 }
592
rtl8723be_dm_dynamic_txpower(struct ieee80211_hw * hw)593 static void rtl8723be_dm_dynamic_txpower(struct ieee80211_hw *hw)
594 {
595 /* 8723BE does not support ODM_BB_DYNAMIC_TXPWR*/
596 return;
597 }
598
rtl8723be_set_iqk_matrix(struct ieee80211_hw * hw,u8 ofdm_index,u8 rfpath,long iqk_result_x,long iqk_result_y)599 static void rtl8723be_set_iqk_matrix(struct ieee80211_hw *hw, u8 ofdm_index,
600 u8 rfpath, long iqk_result_x,
601 long iqk_result_y)
602 {
603 long ele_a = 0, ele_d, ele_c = 0, value32;
604
605 if (ofdm_index >= 43)
606 ofdm_index = 43 - 1;
607
608 ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000) >> 22;
609
610 if (iqk_result_x != 0) {
611 if ((iqk_result_x & 0x00000200) != 0)
612 iqk_result_x = iqk_result_x | 0xFFFFFC00;
613 ele_a = ((iqk_result_x * ele_d) >> 8) & 0x000003FF;
614
615 if ((iqk_result_y & 0x00000200) != 0)
616 iqk_result_y = iqk_result_y | 0xFFFFFC00;
617 ele_c = ((iqk_result_y * ele_d) >> 8) & 0x000003FF;
618
619 switch (rfpath) {
620 case RF90_PATH_A:
621 value32 = (ele_d << 22) |
622 ((ele_c & 0x3F) << 16) | ele_a;
623 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
624 value32);
625 value32 = (ele_c & 0x000003C0) >> 6;
626 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32);
627 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
628 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
629 value32);
630 break;
631 default:
632 break;
633 }
634 } else {
635 switch (rfpath) {
636 case RF90_PATH_A:
637 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
638 ofdmswing_table[ofdm_index]);
639 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00);
640 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00);
641 break;
642 default:
643 break;
644 }
645 }
646 }
647
rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw * hw,enum pwr_track_control_method method,u8 rfpath,u8 idx)648 static void rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw *hw,
649 enum pwr_track_control_method method,
650 u8 rfpath, u8 idx)
651 {
652 struct rtl_priv *rtlpriv = rtl_priv(hw);
653 struct rtl_phy *rtlphy = &rtlpriv->phy;
654 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
655 u8 swing_idx_ofdm_limit = 36;
656
657 if (method == TXAGC) {
658 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
659 } else if (method == BBSWING) {
660 if (rtldm->swing_idx_cck >= CCK_TABLE_SIZE)
661 rtldm->swing_idx_cck = CCK_TABLE_SIZE - 1;
662
663 if (!rtldm->cck_inch14) {
664 rtl_write_byte(rtlpriv, 0xa22,
665 cckswing_table_ch1ch13[rtldm->swing_idx_cck][0]);
666 rtl_write_byte(rtlpriv, 0xa23,
667 cckswing_table_ch1ch13[rtldm->swing_idx_cck][1]);
668 rtl_write_byte(rtlpriv, 0xa24,
669 cckswing_table_ch1ch13[rtldm->swing_idx_cck][2]);
670 rtl_write_byte(rtlpriv, 0xa25,
671 cckswing_table_ch1ch13[rtldm->swing_idx_cck][3]);
672 rtl_write_byte(rtlpriv, 0xa26,
673 cckswing_table_ch1ch13[rtldm->swing_idx_cck][4]);
674 rtl_write_byte(rtlpriv, 0xa27,
675 cckswing_table_ch1ch13[rtldm->swing_idx_cck][5]);
676 rtl_write_byte(rtlpriv, 0xa28,
677 cckswing_table_ch1ch13[rtldm->swing_idx_cck][6]);
678 rtl_write_byte(rtlpriv, 0xa29,
679 cckswing_table_ch1ch13[rtldm->swing_idx_cck][7]);
680 } else {
681 rtl_write_byte(rtlpriv, 0xa22,
682 cckswing_table_ch14[rtldm->swing_idx_cck][0]);
683 rtl_write_byte(rtlpriv, 0xa23,
684 cckswing_table_ch14[rtldm->swing_idx_cck][1]);
685 rtl_write_byte(rtlpriv, 0xa24,
686 cckswing_table_ch14[rtldm->swing_idx_cck][2]);
687 rtl_write_byte(rtlpriv, 0xa25,
688 cckswing_table_ch14[rtldm->swing_idx_cck][3]);
689 rtl_write_byte(rtlpriv, 0xa26,
690 cckswing_table_ch14[rtldm->swing_idx_cck][4]);
691 rtl_write_byte(rtlpriv, 0xa27,
692 cckswing_table_ch14[rtldm->swing_idx_cck][5]);
693 rtl_write_byte(rtlpriv, 0xa28,
694 cckswing_table_ch14[rtldm->swing_idx_cck][6]);
695 rtl_write_byte(rtlpriv, 0xa29,
696 cckswing_table_ch14[rtldm->swing_idx_cck][7]);
697 }
698
699 if (rfpath == RF90_PATH_A) {
700 if (rtldm->swing_idx_ofdm[RF90_PATH_A] <
701 swing_idx_ofdm_limit)
702 swing_idx_ofdm_limit =
703 rtldm->swing_idx_ofdm[RF90_PATH_A];
704
705 rtl8723be_set_iqk_matrix(hw,
706 rtldm->swing_idx_ofdm[rfpath], rfpath,
707 rtlphy->iqk_matrix[idx].value[0][0],
708 rtlphy->iqk_matrix[idx].value[0][1]);
709 } else if (rfpath == RF90_PATH_B) {
710 if (rtldm->swing_idx_ofdm[RF90_PATH_B] <
711 swing_idx_ofdm_limit)
712 swing_idx_ofdm_limit =
713 rtldm->swing_idx_ofdm[RF90_PATH_B];
714
715 rtl8723be_set_iqk_matrix(hw,
716 rtldm->swing_idx_ofdm[rfpath], rfpath,
717 rtlphy->iqk_matrix[idx].value[0][4],
718 rtlphy->iqk_matrix[idx].value[0][5]);
719 }
720 } else {
721 return;
722 }
723 }
724
rtl8723be_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw * hw)725 static void rtl8723be_dm_txpower_tracking_callback_thermalmeter(
726 struct ieee80211_hw *hw)
727 {
728 struct rtl_priv *rtlpriv = rtl_priv(hw);
729 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
730 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
731 u8 thermalvalue = 0, delta, delta_lck, delta_iqk;
732 u8 thermalvalue_avg_count = 0;
733 u32 thermalvalue_avg = 0;
734 int i = 0;
735
736 u8 ofdm_min_index = 6;
737 u8 index_for_channel = 0;
738
739 static const s8 delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = {
740 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
741 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10,
742 10, 11, 11, 12, 12, 13, 14, 15};
743 static const s8 delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = {
744 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
745 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9,
746 9, 10, 10, 11, 12, 13, 14, 15};
747
748 /*Initilization ( 7 steps in total )*/
749 rtlpriv->dm.txpower_trackinginit = true;
750 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
751 "%s\n", __func__);
752
753 thermalvalue = (u8)rtl_get_rfreg(hw,
754 RF90_PATH_A, RF_T_METER, 0xfc00);
755 if (!rtlpriv->dm.txpower_track_control || thermalvalue == 0 ||
756 rtlefuse->eeprom_thermalmeter == 0xFF)
757 return;
758 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
759 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
760 thermalvalue, rtldm->thermalvalue,
761 rtlefuse->eeprom_thermalmeter);
762 /*3 Initialize ThermalValues of RFCalibrateInfo*/
763 if (!rtldm->thermalvalue) {
764 rtlpriv->dm.thermalvalue_lck = thermalvalue;
765 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
766 }
767
768 /*4 Calculate average thermal meter*/
769 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
770 rtldm->thermalvalue_avg_index++;
771 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8723BE)
772 rtldm->thermalvalue_avg_index = 0;
773
774 for (i = 0; i < AVG_THERMAL_NUM_8723BE; i++) {
775 if (rtldm->thermalvalue_avg[i]) {
776 thermalvalue_avg += rtldm->thermalvalue_avg[i];
777 thermalvalue_avg_count++;
778 }
779 }
780
781 if (thermalvalue_avg_count)
782 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
783
784 /* 5 Calculate delta, delta_LCK, delta_IQK.*/
785 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
786 (thermalvalue - rtlpriv->dm.thermalvalue) :
787 (rtlpriv->dm.thermalvalue - thermalvalue);
788 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
789 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
790 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
791 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
792 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
793 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
794
795 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
796 "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",
797 thermalvalue, rtlpriv->dm.thermalvalue,
798 rtlefuse->eeprom_thermalmeter, delta, delta_lck, delta_iqk);
799 /* 6 If necessary, do LCK.*/
800 if (delta_lck >= IQK_THRESHOLD) {
801 rtlpriv->dm.thermalvalue_lck = thermalvalue;
802 rtl8723be_phy_lc_calibrate(hw);
803 }
804
805 /* 7 If necessary, move the index of
806 * swing table to adjust Tx power.
807 */
808 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
809 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
810 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
811 (rtlefuse->eeprom_thermalmeter - thermalvalue);
812
813 if (delta >= TXSCALE_TABLE_SIZE)
814 delta = TXSCALE_TABLE_SIZE - 1;
815 /* 7.1 Get the final CCK_index and
816 * OFDM_index for each swing table.
817 */
818 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
819 rtldm->delta_power_index_last[RF90_PATH_A] =
820 rtldm->delta_power_index[RF90_PATH_A];
821 rtldm->delta_power_index[RF90_PATH_A] =
822 delta_swing_table_idx_tup_a[delta];
823 } else {
824 rtldm->delta_power_index_last[RF90_PATH_A] =
825 rtldm->delta_power_index[RF90_PATH_A];
826 rtldm->delta_power_index[RF90_PATH_A] =
827 -1 * delta_swing_table_idx_tdown_a[delta];
828 }
829
830 /* 7.2 Handle boundary conditions of index.*/
831 if (rtldm->delta_power_index[RF90_PATH_A] ==
832 rtldm->delta_power_index_last[RF90_PATH_A])
833 rtldm->power_index_offset[RF90_PATH_A] = 0;
834 else
835 rtldm->power_index_offset[RF90_PATH_A] =
836 rtldm->delta_power_index[RF90_PATH_A] -
837 rtldm->delta_power_index_last[RF90_PATH_A];
838
839 rtldm->ofdm_index[0] =
840 rtldm->swing_idx_ofdm_base[RF90_PATH_A] +
841 rtldm->power_index_offset[RF90_PATH_A];
842 rtldm->cck_index = rtldm->swing_idx_cck_base +
843 rtldm->power_index_offset[RF90_PATH_A];
844
845 rtldm->swing_idx_cck = rtldm->cck_index;
846 rtldm->swing_idx_ofdm[0] = rtldm->ofdm_index[0];
847
848 if (rtldm->ofdm_index[0] > OFDM_TABLE_SIZE - 1)
849 rtldm->ofdm_index[0] = OFDM_TABLE_SIZE - 1;
850 else if (rtldm->ofdm_index[0] < ofdm_min_index)
851 rtldm->ofdm_index[0] = ofdm_min_index;
852
853 if (rtldm->cck_index > CCK_TABLE_SIZE - 1)
854 rtldm->cck_index = CCK_TABLE_SIZE - 1;
855 else if (rtldm->cck_index < 0)
856 rtldm->cck_index = 0;
857 } else {
858 rtldm->power_index_offset[RF90_PATH_A] = 0;
859 }
860
861 if ((rtldm->power_index_offset[RF90_PATH_A] != 0) &&
862 (rtldm->txpower_track_control)) {
863 rtldm->done_txpower = true;
864 rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0,
865 index_for_channel);
866
867 rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
868 rtldm->swing_idx_ofdm_base[RF90_PATH_A] =
869 rtldm->swing_idx_ofdm[0];
870 rtldm->thermalvalue = thermalvalue;
871 }
872
873 if (delta_iqk >= IQK_THRESHOLD) {
874 rtldm->thermalvalue_iqk = thermalvalue;
875 rtl8723be_phy_iq_calibrate(hw, false);
876 }
877
878 rtldm->txpowercount = 0;
879 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
880
881 }
882
rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw * hw)883 void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw)
884 {
885 struct rtl_priv *rtlpriv = rtl_priv(hw);
886
887 if (!rtlpriv->dm.txpower_tracking)
888 return;
889
890 if (!rtlpriv->dm.tm_trigger) {
891 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16),
892 0x03);
893 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
894 "Trigger 8723be Thermal Meter!!\n");
895 rtlpriv->dm.tm_trigger = 1;
896 return;
897 } else {
898 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
899 "Schedule TxPowerTracking !!\n");
900 rtl8723be_dm_txpower_tracking_callback_thermalmeter(hw);
901 rtlpriv->dm.tm_trigger = 0;
902 }
903 }
904
rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw * hw)905 static void rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
906 {
907 struct rtl_priv *rtlpriv = rtl_priv(hw);
908 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
909 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
910 struct rate_adaptive *p_ra = &rtlpriv->ra;
911 u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m;
912 u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
913 u8 go_up_gap = 5;
914 struct ieee80211_sta *sta = NULL;
915
916 if (is_hal_stop(rtlhal)) {
917 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
918 "driver is going to unload\n");
919 return;
920 }
921
922 if (!rtlpriv->dm.useramask) {
923 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
924 "driver does not control rate adaptive mask\n");
925 return;
926 }
927
928 if (mac->link_state == MAC80211_LINKED &&
929 mac->opmode == NL80211_IFTYPE_STATION) {
930 switch (p_ra->pre_ratr_state) {
931 case DM_RATR_STA_MIDDLE:
932 high_rssithresh_for_ra += go_up_gap;
933 break;
934 case DM_RATR_STA_LOW:
935 high_rssithresh_for_ra += go_up_gap;
936 low_rssithresh_for_ra += go_up_gap;
937 break;
938 default:
939 break;
940 }
941
942 if (rtlpriv->dm.undec_sm_pwdb >
943 (long)high_rssithresh_for_ra)
944 p_ra->ratr_state = DM_RATR_STA_HIGH;
945 else if (rtlpriv->dm.undec_sm_pwdb >
946 (long)low_rssithresh_for_ra)
947 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
948 else
949 p_ra->ratr_state = DM_RATR_STA_LOW;
950
951 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
952 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
953 "RSSI = %ld\n",
954 rtlpriv->dm.undec_sm_pwdb);
955 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
956 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
957 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
958 "PreState = %d, CurState = %d\n",
959 p_ra->pre_ratr_state, p_ra->ratr_state);
960
961 rcu_read_lock();
962 sta = rtl_find_sta(hw, mac->bssid);
963 if (sta)
964 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
965 p_ra->ratr_state,
966 true);
967 rcu_read_unlock();
968
969 p_ra->pre_ratr_state = p_ra->ratr_state;
970 }
971 }
972 }
973
rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw * hw)974 static bool rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
975 {
976 struct rtl_priv *rtlpriv = rtl_priv(hw);
977
978 if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
979 return true;
980
981 return false;
982 }
983
rtl8723be_dm_check_edca_turbo(struct ieee80211_hw * hw)984 static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw)
985 {
986 struct rtl_priv *rtlpriv = rtl_priv(hw);
987 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
988
989 static u64 last_txok_cnt;
990 static u64 last_rxok_cnt;
991 u64 cur_txok_cnt = 0;
992 u64 cur_rxok_cnt = 0;
993 u32 edca_be_ul = 0x6ea42b;
994 u32 edca_be_dl = 0x6ea42b;/*not sure*/
995 u32 edca_be = 0x5ea42b;
996 u32 iot_peer = 0;
997 bool b_is_cur_rdlstate;
998 bool b_bias_on_rx = false;
999 bool b_edca_turbo_on = false;
1000
1001 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
1002 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
1003
1004 iot_peer = rtlpriv->mac80211.vendor;
1005 b_bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ?
1006 true : false;
1007 b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
1008 (!rtlpriv->dm.disable_framebursting)) ?
1009 true : false;
1010
1011 if ((iot_peer == PEER_CISCO) &&
1012 (mac->mode == WIRELESS_MODE_N_24G)) {
1013 edca_be_dl = edca_setting_dl[iot_peer];
1014 edca_be_ul = edca_setting_ul[iot_peer];
1015 }
1016 if (rtl8723be_dm_is_edca_turbo_disable(hw))
1017 goto exit;
1018
1019 if (b_edca_turbo_on) {
1020 if (b_bias_on_rx)
1021 b_is_cur_rdlstate = (cur_txok_cnt > cur_rxok_cnt * 4) ?
1022 false : true;
1023 else
1024 b_is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
1025 true : false;
1026
1027 edca_be = (b_is_cur_rdlstate) ? edca_be_dl : edca_be_ul;
1028 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be);
1029 rtlpriv->dm.is_cur_rdlstate = b_is_cur_rdlstate;
1030 rtlpriv->dm.current_turbo_edca = true;
1031 } else {
1032 if (rtlpriv->dm.current_turbo_edca) {
1033 u8 tmp = AC0_BE;
1034 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
1035 (u8 *)(&tmp));
1036 }
1037 rtlpriv->dm.current_turbo_edca = false;
1038 }
1039
1040 exit:
1041 rtlpriv->dm.is_any_nonbepkts = false;
1042 last_txok_cnt = rtlpriv->stats.txbytesunicast;
1043 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
1044 }
1045
rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw * hw)1046 static void rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
1047 {
1048 struct rtl_priv *rtlpriv = rtl_priv(hw);
1049 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1050 u8 cur_cck_cca_thresh;
1051
1052 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1053 if (dm_digtable->rssi_val_min > 25) {
1054 cur_cck_cca_thresh = 0xcd;
1055 } else if ((dm_digtable->rssi_val_min <= 25) &&
1056 (dm_digtable->rssi_val_min > 10)) {
1057 cur_cck_cca_thresh = 0x83;
1058 } else {
1059 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1060 cur_cck_cca_thresh = 0x83;
1061 else
1062 cur_cck_cca_thresh = 0x40;
1063 }
1064 } else {
1065 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1066 cur_cck_cca_thresh = 0x83;
1067 else
1068 cur_cck_cca_thresh = 0x40;
1069 }
1070
1071 if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh)
1072 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
1073
1074 dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
1075 dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh;
1076 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
1077 "CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres);
1078 }
1079
rtl8723be_dm_dynamic_edcca(struct ieee80211_hw * hw)1080 static void rtl8723be_dm_dynamic_edcca(struct ieee80211_hw *hw)
1081 {
1082 struct rtl_priv *rtlpriv = rtl_priv(hw);
1083 u8 reg_c50, reg_c58;
1084 bool fw_current_in_ps_mode = false;
1085
1086 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1087 (u8 *)(&fw_current_in_ps_mode));
1088 if (fw_current_in_ps_mode)
1089 return;
1090
1091 reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
1092 reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
1093
1094 if (reg_c50 > 0x28 && reg_c58 > 0x28) {
1095 if (!rtlpriv->rtlhal.pre_edcca_enable) {
1096 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03);
1097 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00);
1098 }
1099 } else if (reg_c50 < 0x25 && reg_c58 < 0x25) {
1100 if (rtlpriv->rtlhal.pre_edcca_enable) {
1101 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f);
1102 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f);
1103 }
1104 }
1105 }
1106
rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw * hw)1107 static void rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
1108 {
1109 struct rtl_priv *rtlpriv = rtl_priv(hw);
1110 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1111 u8 crystal_cap;
1112 u32 packet_count;
1113 int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
1114 int cfo_ave_diff;
1115
1116 if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1117 if (rtldm->atc_status == ATC_STATUS_OFF) {
1118 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1119 ATC_STATUS_ON);
1120 rtldm->atc_status = ATC_STATUS_ON;
1121 }
1122 if (rtlpriv->cfg->ops->get_btc_status()) {
1123 if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) {
1124 rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
1125 "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n");
1126 return;
1127 }
1128 }
1129
1130 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
1131 rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
1132 crystal_cap = rtldm->crystal_cap & 0x3f;
1133 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1134 (crystal_cap | (crystal_cap << 6)));
1135 }
1136 } else {
1137 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
1138 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
1139 packet_count = rtldm->packet_count;
1140
1141 if (packet_count == rtldm->packet_count_pre)
1142 return;
1143
1144 rtldm->packet_count_pre = packet_count;
1145
1146 if (rtlpriv->phy.rf_type == RF_1T1R)
1147 cfo_ave = cfo_khz_a;
1148 else
1149 cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
1150
1151 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
1152 (rtldm->cfo_ave_pre - cfo_ave) :
1153 (cfo_ave - rtldm->cfo_ave_pre);
1154
1155 if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) {
1156 rtldm->large_cfo_hit = true;
1157 return;
1158 } else
1159 rtldm->large_cfo_hit = false;
1160
1161 rtldm->cfo_ave_pre = cfo_ave;
1162
1163 if (cfo_ave >= -rtldm->cfo_threshold &&
1164 cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) {
1165 if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
1166 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
1167 rtldm->is_freeze = 1;
1168 } else {
1169 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
1170 }
1171 }
1172
1173 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
1174 adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 1) + 1;
1175 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
1176 rtlpriv->dm.crystal_cap > 0)
1177 adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 1) - 1;
1178
1179 if (adjust_xtal != 0) {
1180 rtldm->is_freeze = 0;
1181 rtldm->crystal_cap += adjust_xtal;
1182
1183 if (rtldm->crystal_cap > 0x3f)
1184 rtldm->crystal_cap = 0x3f;
1185 else if (rtldm->crystal_cap < 0)
1186 rtldm->crystal_cap = 0;
1187
1188 crystal_cap = rtldm->crystal_cap & 0x3f;
1189 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1190 (crystal_cap | (crystal_cap << 6)));
1191 }
1192
1193 if (cfo_ave < CFO_THRESHOLD_ATC &&
1194 cfo_ave > -CFO_THRESHOLD_ATC) {
1195 if (rtldm->atc_status == ATC_STATUS_ON) {
1196 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1197 ATC_STATUS_OFF);
1198 rtldm->atc_status = ATC_STATUS_OFF;
1199 }
1200 } else {
1201 if (rtldm->atc_status == ATC_STATUS_OFF) {
1202 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1203 ATC_STATUS_ON);
1204 rtldm->atc_status = ATC_STATUS_ON;
1205 }
1206 }
1207 }
1208 }
1209
rtl8723be_dm_common_info_self_update(struct ieee80211_hw * hw)1210 static void rtl8723be_dm_common_info_self_update(struct ieee80211_hw *hw)
1211 {
1212 struct rtl_priv *rtlpriv = rtl_priv(hw);
1213 u8 cnt;
1214
1215 rtlpriv->dm.one_entry_only = false;
1216
1217 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
1218 rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
1219 rtlpriv->dm.one_entry_only = true;
1220 return;
1221 }
1222
1223 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
1224 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
1225 rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
1226 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1227 cnt = list_count_nodes(&rtlpriv->entry_list);
1228 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1229
1230 if (cnt == 1)
1231 rtlpriv->dm.one_entry_only = true;
1232 }
1233 }
1234
rtl8723be_dm_watchdog(struct ieee80211_hw * hw)1235 void rtl8723be_dm_watchdog(struct ieee80211_hw *hw)
1236 {
1237 struct rtl_priv *rtlpriv = rtl_priv(hw);
1238 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1239 bool fw_current_inpsmode = false;
1240 bool fw_ps_awake = true;
1241
1242 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1243 (u8 *)(&fw_current_inpsmode));
1244
1245 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1246 (u8 *)(&fw_ps_awake));
1247
1248 if (ppsc->p2p_ps_info.p2p_ps_mode)
1249 fw_ps_awake = false;
1250
1251 spin_lock(&rtlpriv->locks.rf_ps_lock);
1252 if ((ppsc->rfpwr_state == ERFON) &&
1253 ((!fw_current_inpsmode) && fw_ps_awake) &&
1254 (!ppsc->rfchange_inprogress)) {
1255 rtl8723be_dm_common_info_self_update(hw);
1256 rtl8723be_dm_false_alarm_counter_statistics(hw);
1257 rtl8723be_dm_check_rssi_monitor(hw);
1258 rtl8723be_dm_dig(hw);
1259 rtl8723be_dm_dynamic_edcca(hw);
1260 rtl8723be_dm_cck_packet_detection_thresh(hw);
1261 rtl8723be_dm_refresh_rate_adaptive_mask(hw);
1262 rtl8723be_dm_check_edca_turbo(hw);
1263 rtl8723be_dm_dynamic_atc_switch(hw);
1264 rtl8723be_dm_check_txpower_tracking(hw);
1265 rtl8723be_dm_dynamic_txpower(hw);
1266 }
1267 spin_unlock(&rtlpriv->locks.rf_ps_lock);
1268 rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
1269 }
1270