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