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