blob: 2367e8f47a5b57bd1c3ee9ce6080ecf4986cf168 [file] [log] [blame]
Larry Fingera619d1a2014-02-28 15:16:50 -06001/******************************************************************************
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"
Larry Finger6f8214b2015-01-06 09:58:04 -060029#include "../core.h"
Larry Fingera619d1a2014-02-28 15:16:50 -060030#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"
Larry Fingera619d1a2014-02-28 15:16:50 -060036#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) |
Larry Finger5c99f042014-09-26 16:40:25 -0500212 (pwr_val << 16) | (pwr_val << 24);
Larry Fingera619d1a2014-02-28 15:16:50 -0600213}
214
Larry Fingera619d1a2014-02-28 15:16:50 -0600215void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
216{
217 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500218 struct rate_adaptive *p_ra = &rtlpriv->ra;
Larry Fingera619d1a2014-02-28 15:16:50 -0600219
Larry Finger5c99f042014-09-26 16:40:25 -0500220 p_ra->ratr_state = DM_RATR_STA_INIT;
221 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
Larry Fingera619d1a2014-02-28 15:16:50 -0600222
223 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
224 rtlpriv->dm.useramask = true;
225 else
226 rtlpriv->dm.useramask = false;
227
Larry Finger5c99f042014-09-26 16:40:25 -0500228 p_ra->high_rssi_thresh_for_ra = 50;
229 p_ra->low_rssi_thresh_for_ra40m = 20;
Larry Fingera619d1a2014-02-28 15:16:50 -0600230}
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",
Larry Finger5c99f042014-09-26 16:40:25 -0500252 rtlpriv->dm.txpower_tracking);
Larry Fingera619d1a2014-02-28 15:16:50 -0600253}
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;
Larry Finger5c99f042014-09-26 16:40:25 -0500260
Larry Fingera619d1a2014-02-28 15:16:50 -0600261 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);
Larry Fingerac2f0ba2015-01-06 09:58:10 -0600268 u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
Larry Fingera619d1a2014-02-28 15:16:50 -0600269
270 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
Larry Fingerac2f0ba2015-01-06 09:58:10 -0600271 rtl_dm_diginit(hw, cur_igvalue);
Larry Fingera619d1a2014-02-28 15:16:50 -0600272 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);
Larry Finger5c99f042014-09-26 16:40:25 -0500283 struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable;
Larry Fingera619d1a2014-02-28 15:16:50 -0600284 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",
Larry Finger5c99f042014-09-26 16:40:25 -0500300 rtlpriv->dm.entry_min_undec_sm_pwdb);
Larry Fingera619d1a2014-02-28 15:16:50 -0600301 } 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",
Larry Finger5c99f042014-09-26 16:40:25 -0500306 rtl_dm_dig->min_undec_pwdb_for_dm);
Larry Fingera619d1a2014-02-28 15:16:50 -0600307 }
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 disconnet PWDB = 0x%x\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500313 rtl_dm_dig->min_undec_pwdb_for_dm);
Larry Fingera619d1a2014-02-28 15:16:50 -0600314 }
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);
Larry Finger5c99f042014-09-26 16:40:25 -0500322 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
Larry Fingera619d1a2014-02-28 15:16:50 -0600323 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) {
Larry Finger5c99f042014-09-26 16:40:25 -0500343 rtlpriv->dm.entry_max_undec_sm_pwdb =
344 tmp_entry_max_pwdb;
345 RTPRINT(rtlpriv, FDM, DM_PWDB,
346 "EntryMaxPWDB = 0x%lx(%ld)\n",
Larry Fingera619d1a2014-02-28 15:16:50 -0600347 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) {
Larry Finger5c99f042014-09-26 16:40:25 -0500353 rtlpriv->dm.entry_min_undec_sm_pwdb =
354 tmp_entry_min_pwdb;
355 RTPRINT(rtlpriv, FDM, DM_PWDB,
356 "EntryMinPWDB = 0x%lx(%ld)\n",
Larry Fingera619d1a2014-02-28 15:16:50 -0600357 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) {
Larry Finger5c99f042014-09-26 16:40:25 -0500363 h2c_parameter[2] =
364 (u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF);
Larry Fingera619d1a2014-02-28 15:16:50 -0600365 h2c_parameter[1] = 0x20;
366 h2c_parameter[0] = 0;
Larry Finger5c99f042014-09-26 16:40:25 -0500367 rtl8723be_fill_h2c_cmd(hw, H2C_RSSIBE_REPORT, 3, h2c_parameter);
Larry Fingera619d1a2014-02-28 15:16:50 -0600368 } else {
Larry Finger5c99f042014-09-26 16:40:25 -0500369 rtl_write_byte(rtlpriv, 0x4fe,
370 rtlpriv->dm.undec_sm_pwdb);
Larry Fingera619d1a2014-02-28 15:16:50 -0600371 }
372 rtl8723be_dm_find_minimum_rssi(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500373 dm_digtable->rssi_val_min =
374 rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
Larry Fingera619d1a2014-02-28 15:16:50 -0600375}
376
377void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
378{
379 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500380 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
Larry Fingera619d1a2014-02-28 15:16:50 -0600381
Larry Finger5c99f042014-09-26 16:40:25 -0500382 if (dm_digtable->stop_dig)
383 return;
384
385 if (dm_digtable->cur_igvalue != current_igi) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600386 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi);
387 if (rtlpriv->phy.rf_type != RF_1T1R)
Larry Finger5c99f042014-09-26 16:40:25 -0500388 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1,
389 0x7f, current_igi);
Larry Fingera619d1a2014-02-28 15:16:50 -0600390 }
Larry Finger5c99f042014-09-26 16:40:25 -0500391 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
392 dm_digtable->cur_igvalue = current_igi;
Larry Fingera619d1a2014-02-28 15:16:50 -0600393}
394
395static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
396{
397 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500398 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
Larry Fingera619d1a2014-02-28 15:16:50 -0600399 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
Larry Finger1f6969f2015-01-06 09:58:02 -0600400 u8 dig_min_0, dig_maxofmin;
Larry Finger5c99f042014-09-26 16:40:25 -0500401 bool bfirstconnect, bfirstdisconnect;
Larry Fingera619d1a2014-02-28 15:16:50 -0600402 u8 dm_dig_max, dm_dig_min;
403 u8 current_igi = dm_digtable->cur_igvalue;
404 u8 offset;
405
Larry Finger5c99f042014-09-26 16:40:25 -0500406 /* AP,BT */
Larry Fingera619d1a2014-02-28 15:16:50 -0600407 if (mac->act_scanning)
408 return;
409
Larry Finger1f6969f2015-01-06 09:58:02 -0600410 dig_min_0 = dm_digtable->dig_min_0;
Larry Finger5c99f042014-09-26 16:40:25 -0500411 bfirstconnect = (mac->link_state >= MAC80211_LINKED) &&
Larry Fingera619d1a2014-02-28 15:16:50 -0600412 !dm_digtable->media_connect_0;
Larry Finger5c99f042014-09-26 16:40:25 -0500413 bfirstdisconnect = (mac->link_state < MAC80211_LINKED) &&
414 (dm_digtable->media_connect_0);
Larry Fingera619d1a2014-02-28 15:16:50 -0600415
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)
Larry Finger1f6969f2015-01-06 09:58:02 -0600432 dig_min_0 = dm_dig_min;
Larry Fingera619d1a2014-02-28 15:16:50 -0600433 else if (dm_digtable->rssi_val_min - offset >
434 dig_maxofmin)
Larry Finger1f6969f2015-01-06 09:58:02 -0600435 dig_min_0 = dig_maxofmin;
Larry Fingera619d1a2014-02-28 15:16:50 -0600436 else
Larry Finger1f6969f2015-01-06 09:58:02 -0600437 dig_min_0 =
Larry Fingera619d1a2014-02-28 15:16:50 -0600438 dm_digtable->rssi_val_min - offset;
439 } else {
Larry Finger1f6969f2015-01-06 09:58:02 -0600440 dig_min_0 = dm_dig_min;
Larry Fingera619d1a2014-02-28 15:16:50 -0600441 }
Larry Finger5c99f042014-09-26 16:40:25 -0500442
Larry Fingera619d1a2014-02-28 15:16:50 -0600443 } else {
444 dm_digtable->rx_gain_max = dm_dig_max;
Larry Finger1f6969f2015-01-06 09:58:02 -0600445 dig_min_0 = dm_dig_min;
Larry Fingera619d1a2014-02-28 15:16:50 -0600446 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) <
Larry Finger1f6969f2015-01-06 09:58:02 -0600473 dig_min_0) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600474 dm_digtable->forbidden_igi =
Larry Finger1f6969f2015-01-06 09:58:02 -0600475 dig_min_0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600476 dm_digtable->rx_gain_min =
Larry Finger1f6969f2015-01-06 09:58:02 -0600477 dig_min_0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600478 } 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) {
Larry Finger5c99f042014-09-26 16:40:25 -0500492 if (bfirstconnect) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600493 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 {
Larry Finger5c99f042014-09-26 16:40:25 -0500508 if (bfirstdisconnect) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600509 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);
Larry Finger1f6969f2015-01-06 09:58:02 -0600528 dm_digtable->dig_min_0 = dig_min_0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600529}
530
Larry Finger5c99f042014-09-26 16:40:25 -0500531static void rtl8723be_dm_false_alarm_counter_statistics(
532 struct ieee80211_hw *hw)
Larry Fingera619d1a2014-02-28 15:16:50 -0600533{
534 u32 ret_value;
535 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -0500536 struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
Larry Fingera619d1a2014-02-28 15:16:50 -0600537
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,
Larry Finger5c99f042014-09-26 16:40:25 -0500602 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
Larry Fingera619d1a2014-02-28 15:16:50 -0600603 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,
Larry Finger5c99f042014-09-26 16:40:25 -0500609 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
Larry Fingera619d1a2014-02-28 15:16:50 -0600610 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);
Larry Finger5c99f042014-09-26 16:40:25 -0500675 struct rtl_phy *rtlphy = &rtlpriv->phy;
Larry Fingera619d1a2014-02-28 15:16:50 -0600676 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
Larry Finger5c99f042014-09-26 16:40:25 -0500747static void rtl8723be_dm_txpower_tracking_callback_thermalmeter(
748 struct ieee80211_hw *hw)
Larry Fingera619d1a2014-02-28 15:16:50 -0600749{
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;
Larry Finger5c99f042014-09-26 16:40:25 -0500759 u8 index_for_channel = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -0600760
Larry Finger5c99f042014-09-26 16:40:25 -0500761 char delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = {
Larry Fingera619d1a2014-02-28 15:16:50 -0600762 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};
Larry Finger5c99f042014-09-26 16:40:25 -0500765 char delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = {
Larry Fingera619d1a2014-02-28 15:16:50 -0600766 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
Larry Finger5c99f042014-09-26 16:40:25 -0500770 /*Initilization ( 7 steps in total )*/
Larry Fingera619d1a2014-02-28 15:16:50 -0600771 rtlpriv->dm.txpower_trackinginit = true;
772 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -0500773 "rtl8723be_dm_txpower_tracking_callback_thermalmeter\n");
Larry Fingera619d1a2014-02-28 15:16:50 -0600774
Larry Finger5c99f042014-09-26 16:40:25 -0500775 thermalvalue = (u8)rtl_get_rfreg(hw,
776 RF90_PATH_A, RF_T_METER, 0xfc00);
Larry Fingera619d1a2014-02-28 15:16:50 -0600777 if (!rtlpriv->dm.txpower_track_control || thermalvalue == 0 ||
778 rtlefuse->eeprom_thermalmeter == 0xFF)
779 return;
780 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -0500781 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
Larry Fingera619d1a2014-02-28 15:16:50 -0600782 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,
Larry Finger5c99f042014-09-26 16:40:25 -0500818 "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",
Larry Fingera619d1a2014-02-28 15:16:50 -0600819 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,
Larry Finger5c99f042014-09-26 16:40:25 -0500888 index_for_channel);
Larry Fingera619d1a2014-02-28 15:16:50 -0600889 else
890 rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0,
Larry Finger5c99f042014-09-26 16:40:25 -0500891 index_for_channel);
Larry Fingera619d1a2014-02-28 15:16:50 -0600892
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");
Larry Finger5c99f042014-09-26 16:40:25 -0500906
Larry Fingera619d1a2014-02-28 15:16:50 -0600907}
908
909void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw)
910{
911 struct rtl_priv *rtlpriv = rtl_priv(hw);
912 static u8 tm_trigger;
913
914 if (!rtlpriv->dm.txpower_tracking)
915 return;
916
917 if (!tm_trigger) {
918 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16),
919 0x03);
920 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
921 "Trigger 8723be Thermal Meter!!\n");
922 tm_trigger = 1;
923 return;
924 } else {
925 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
926 "Schedule TxPowerTracking !!\n");
Larry Finger5c99f042014-09-26 16:40:25 -0500927 rtl8723be_dm_txpower_tracking_callback_thermalmeter(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -0600928 tm_trigger = 0;
929 }
930}
931
932static void rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
933{
934 struct rtl_priv *rtlpriv = rtl_priv(hw);
935 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
936 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -0500937 struct rate_adaptive *p_ra = &rtlpriv->ra;
938 u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m;
939 u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
Larry Fingera619d1a2014-02-28 15:16:50 -0600940 u8 go_up_gap = 5;
Larry Finger5c99f042014-09-26 16:40:25 -0500941 struct ieee80211_sta *sta = NULL;
Larry Fingera619d1a2014-02-28 15:16:50 -0600942
943 if (is_hal_stop(rtlhal)) {
944 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
945 "driver is going to unload\n");
946 return;
947 }
948
949 if (!rtlpriv->dm.useramask) {
950 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
951 "driver does not control rate adaptive mask\n");
952 return;
953 }
954
955 if (mac->link_state == MAC80211_LINKED &&
Larry Finger5c99f042014-09-26 16:40:25 -0500956 mac->opmode == NL80211_IFTYPE_STATION) {
957 switch (p_ra->pre_ratr_state) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600958 case DM_RATR_STA_MIDDLE:
959 high_rssithresh_for_ra += go_up_gap;
960 break;
961 case DM_RATR_STA_LOW:
962 high_rssithresh_for_ra += go_up_gap;
963 low_rssithresh_for_ra += go_up_gap;
964 break;
965 default:
966 break;
967 }
968
969 if (rtlpriv->dm.undec_sm_pwdb >
970 (long)high_rssithresh_for_ra)
Larry Finger5c99f042014-09-26 16:40:25 -0500971 p_ra->ratr_state = DM_RATR_STA_HIGH;
Larry Fingera619d1a2014-02-28 15:16:50 -0600972 else if (rtlpriv->dm.undec_sm_pwdb >
973 (long)low_rssithresh_for_ra)
Larry Finger5c99f042014-09-26 16:40:25 -0500974 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
Larry Fingera619d1a2014-02-28 15:16:50 -0600975 else
Larry Finger5c99f042014-09-26 16:40:25 -0500976 p_ra->ratr_state = DM_RATR_STA_LOW;
Larry Fingera619d1a2014-02-28 15:16:50 -0600977
Larry Finger5c99f042014-09-26 16:40:25 -0500978 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
Larry Fingera619d1a2014-02-28 15:16:50 -0600979 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
980 "RSSI = %ld\n",
981 rtlpriv->dm.undec_sm_pwdb);
982 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -0500983 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
Larry Fingera619d1a2014-02-28 15:16:50 -0600984 RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
985 "PreState = %d, CurState = %d\n",
Larry Finger5c99f042014-09-26 16:40:25 -0500986 p_ra->pre_ratr_state, p_ra->ratr_state);
Larry Fingera619d1a2014-02-28 15:16:50 -0600987
988 rcu_read_lock();
989 sta = rtl_find_sta(hw, mac->bssid);
990 if (sta)
991 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
Larry Finger5c99f042014-09-26 16:40:25 -0500992 p_ra->ratr_state);
Larry Fingera619d1a2014-02-28 15:16:50 -0600993 rcu_read_unlock();
994
Larry Finger5c99f042014-09-26 16:40:25 -0500995 p_ra->pre_ratr_state = p_ra->ratr_state;
Larry Fingera619d1a2014-02-28 15:16:50 -0600996 }
997 }
998}
999
1000static bool rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
1001{
1002 struct rtl_priv *rtlpriv = rtl_priv(hw);
1003
Larry Fingera619d1a2014-02-28 15:16:50 -06001004 if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
1005 return true;
1006
1007 return false;
1008}
1009
1010static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw)
1011{
1012 struct rtl_priv *rtlpriv = rtl_priv(hw);
1013 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
Larry Finger5c99f042014-09-26 16:40:25 -05001014
Larry Fingera619d1a2014-02-28 15:16:50 -06001015 static u64 last_txok_cnt;
1016 static u64 last_rxok_cnt;
1017 u64 cur_txok_cnt = 0;
1018 u64 cur_rxok_cnt = 0;
1019 u32 edca_be_ul = 0x6ea42b;
1020 u32 edca_be_dl = 0x6ea42b;/*not sure*/
1021 u32 edca_be = 0x5ea42b;
1022 u32 iot_peer = 0;
Larry Finger5c99f042014-09-26 16:40:25 -05001023 bool b_is_cur_rdlstate;
1024 bool b_last_is_cur_rdlstate = false;
1025 bool b_bias_on_rx = false;
1026 bool b_edca_turbo_on = false;
Larry Fingera619d1a2014-02-28 15:16:50 -06001027
Larry Finger5c99f042014-09-26 16:40:25 -05001028 b_last_is_cur_rdlstate = rtlpriv->dm.is_cur_rdlstate;
Larry Fingera619d1a2014-02-28 15:16:50 -06001029
1030 cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
1031 cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
1032
1033 iot_peer = rtlpriv->mac80211.vendor;
Larry Finger5c99f042014-09-26 16:40:25 -05001034 b_bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ?
1035 true : false;
1036 b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
1037 (!rtlpriv->dm.disable_framebursting)) ?
1038 true : false;
Larry Fingera619d1a2014-02-28 15:16:50 -06001039
1040 if ((iot_peer == PEER_CISCO) &&
1041 (mac->mode == WIRELESS_MODE_N_24G)) {
1042 edca_be_dl = edca_setting_dl[iot_peer];
1043 edca_be_ul = edca_setting_ul[iot_peer];
1044 }
1045 if (rtl8723be_dm_is_edca_turbo_disable(hw))
1046 goto exit;
1047
Larry Finger5c99f042014-09-26 16:40:25 -05001048 if (b_edca_turbo_on) {
1049 if (b_bias_on_rx)
1050 b_is_cur_rdlstate = (cur_txok_cnt > cur_rxok_cnt * 4) ?
1051 false : true;
Larry Fingera619d1a2014-02-28 15:16:50 -06001052 else
Larry Finger5c99f042014-09-26 16:40:25 -05001053 b_is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
1054 true : false;
Larry Fingera619d1a2014-02-28 15:16:50 -06001055
Larry Finger5c99f042014-09-26 16:40:25 -05001056 edca_be = (b_is_cur_rdlstate) ? edca_be_dl : edca_be_ul;
Larry Fingera619d1a2014-02-28 15:16:50 -06001057 rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be);
Larry Finger5c99f042014-09-26 16:40:25 -05001058 rtlpriv->dm.is_cur_rdlstate = b_is_cur_rdlstate;
Larry Fingera619d1a2014-02-28 15:16:50 -06001059 rtlpriv->dm.current_turbo_edca = true;
1060 } else {
1061 if (rtlpriv->dm.current_turbo_edca) {
1062 u8 tmp = AC0_BE;
1063 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
Larry Finger5c99f042014-09-26 16:40:25 -05001064 (u8 *)(&tmp));
Larry Fingera619d1a2014-02-28 15:16:50 -06001065 }
1066 rtlpriv->dm.current_turbo_edca = false;
1067 }
1068
1069exit:
1070 rtlpriv->dm.is_any_nonbepkts = false;
1071 last_txok_cnt = rtlpriv->stats.txbytesunicast;
1072 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
1073}
1074
1075static void rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
1076{
1077 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Finger5c99f042014-09-26 16:40:25 -05001078 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
Larry Fingera619d1a2014-02-28 15:16:50 -06001079 u8 cur_cck_cca_thresh;
1080
1081 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
Larry Finger5c99f042014-09-26 16:40:25 -05001082 if (dm_digtable->rssi_val_min > 25) {
Larry Fingera619d1a2014-02-28 15:16:50 -06001083 cur_cck_cca_thresh = 0xcd;
Larry Finger5c99f042014-09-26 16:40:25 -05001084 } else if ((dm_digtable->rssi_val_min <= 25) &&
1085 (dm_digtable->rssi_val_min > 10)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06001086 cur_cck_cca_thresh = 0x83;
1087 } else {
1088 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1089 cur_cck_cca_thresh = 0x83;
1090 else
1091 cur_cck_cca_thresh = 0x40;
1092 }
1093 } else {
1094 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
1095 cur_cck_cca_thresh = 0x83;
1096 else
1097 cur_cck_cca_thresh = 0x40;
1098 }
1099
Larry Finger5c99f042014-09-26 16:40:25 -05001100 if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh)
Larry Fingera619d1a2014-02-28 15:16:50 -06001101 rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
1102
Larry Finger5c99f042014-09-26 16:40:25 -05001103 dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
1104 dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh;
Larry Fingera619d1a2014-02-28 15:16:50 -06001105 RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
Larry Finger5c99f042014-09-26 16:40:25 -05001106 "CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres);
Larry Fingera619d1a2014-02-28 15:16:50 -06001107}
1108
1109static void rtl8723be_dm_dynamic_edcca(struct ieee80211_hw *hw)
1110{
1111 struct rtl_priv *rtlpriv = rtl_priv(hw);
1112 u8 reg_c50, reg_c58;
1113 bool fw_current_in_ps_mode = false;
1114
1115 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1116 (u8 *)(&fw_current_in_ps_mode));
1117 if (fw_current_in_ps_mode)
1118 return;
1119
1120 reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
1121 reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
1122
1123 if (reg_c50 > 0x28 && reg_c58 > 0x28) {
1124 if (!rtlpriv->rtlhal.pre_edcca_enable) {
1125 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03);
1126 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00);
1127 }
1128 } else if (reg_c50 < 0x25 && reg_c58 < 0x25) {
1129 if (rtlpriv->rtlhal.pre_edcca_enable) {
1130 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f);
1131 rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f);
1132 }
1133 }
1134}
1135
1136static void rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
1137{
1138 struct rtl_priv *rtlpriv = rtl_priv(hw);
1139 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
1140 u8 crystal_cap;
1141 u32 packet_count;
1142 int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
1143 int cfo_ave_diff;
1144
1145 if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1146 if (rtldm->atc_status == ATC_STATUS_OFF) {
1147 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1148 ATC_STATUS_ON);
1149 rtldm->atc_status = ATC_STATUS_ON;
1150 }
1151 if (rtlpriv->cfg->ops->get_btc_status()) {
1152 if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) {
1153 RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
Larry Finger5c99f042014-09-26 16:40:25 -05001154 "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n");
Larry Fingera619d1a2014-02-28 15:16:50 -06001155 return;
1156 }
1157 }
1158
1159 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
1160 rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
1161 crystal_cap = rtldm->crystal_cap & 0x3f;
1162 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1163 (crystal_cap | (crystal_cap << 6)));
1164 }
1165 } else {
1166 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
1167 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
1168 packet_count = rtldm->packet_count;
1169
1170 if (packet_count == rtldm->packet_count_pre)
1171 return;
1172
1173 rtldm->packet_count_pre = packet_count;
1174
1175 if (rtlpriv->phy.rf_type == RF_1T1R)
1176 cfo_ave = cfo_khz_a;
1177 else
1178 cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
1179
1180 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
1181 (rtldm->cfo_ave_pre - cfo_ave) :
1182 (cfo_ave - rtldm->cfo_ave_pre);
1183
1184 if (cfo_ave_diff > 20 && rtldm->large_cfo_hit == 0) {
1185 rtldm->large_cfo_hit = 1;
1186 return;
Larry Finger5c99f042014-09-26 16:40:25 -05001187 } else
Larry Fingera619d1a2014-02-28 15:16:50 -06001188 rtldm->large_cfo_hit = 0;
Larry Fingera619d1a2014-02-28 15:16:50 -06001189
1190 rtldm->cfo_ave_pre = cfo_ave;
1191
1192 if (cfo_ave >= -rtldm->cfo_threshold &&
1193 cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) {
1194 if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
1195 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
1196 rtldm->is_freeze = 1;
1197 } else {
1198 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
1199 }
1200 }
1201
1202 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
1203 adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 1) + 1;
1204 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
1205 rtlpriv->dm.crystal_cap > 0)
1206 adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 1) - 1;
1207
1208 if (adjust_xtal != 0) {
1209 rtldm->is_freeze = 0;
1210 rtldm->crystal_cap += adjust_xtal;
1211
1212 if (rtldm->crystal_cap > 0x3f)
1213 rtldm->crystal_cap = 0x3f;
1214 else if (rtldm->crystal_cap < 0)
1215 rtldm->crystal_cap = 0;
1216
1217 crystal_cap = rtldm->crystal_cap & 0x3f;
1218 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
1219 (crystal_cap | (crystal_cap << 6)));
1220 }
1221
1222 if (cfo_ave < CFO_THRESHOLD_ATC &&
1223 cfo_ave > -CFO_THRESHOLD_ATC) {
1224 if (rtldm->atc_status == ATC_STATUS_ON) {
1225 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1226 ATC_STATUS_OFF);
1227 rtldm->atc_status = ATC_STATUS_OFF;
1228 }
1229 } else {
1230 if (rtldm->atc_status == ATC_STATUS_OFF) {
1231 rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
1232 ATC_STATUS_ON);
1233 rtldm->atc_status = ATC_STATUS_ON;
1234 }
1235 }
1236 }
1237}
1238
1239static void rtl8723be_dm_common_info_self_update(struct ieee80211_hw *hw)
1240{
1241 struct rtl_priv *rtlpriv = rtl_priv(hw);
Larry Fingera619d1a2014-02-28 15:16:50 -06001242 u8 cnt = 0;
Larry Finger5c99f042014-09-26 16:40:25 -05001243 struct rtl_sta_info *drv_priv;
Larry Fingera619d1a2014-02-28 15:16:50 -06001244
1245 rtlpriv->dm.one_entry_only = false;
1246
1247 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
Larry Finger5c99f042014-09-26 16:40:25 -05001248 rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
Larry Fingera619d1a2014-02-28 15:16:50 -06001249 rtlpriv->dm.one_entry_only = true;
1250 return;
1251 }
1252
1253 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
Larry Finger5c99f042014-09-26 16:40:25 -05001254 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
1255 rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
Larry Fingera619d1a2014-02-28 15:16:50 -06001256 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
1257 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
1258 cnt++;
1259 }
1260 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
1261
1262 if (cnt == 1)
1263 rtlpriv->dm.one_entry_only = true;
1264 }
1265}
1266
1267void rtl8723be_dm_watchdog(struct ieee80211_hw *hw)
1268{
1269 struct rtl_priv *rtlpriv = rtl_priv(hw);
1270 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1271 bool fw_current_inpsmode = false;
1272 bool fw_ps_awake = true;
1273
1274 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1275 (u8 *)(&fw_current_inpsmode));
1276
1277 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1278 (u8 *)(&fw_ps_awake));
1279
1280 if (ppsc->p2p_ps_info.p2p_ps_mode)
1281 fw_ps_awake = false;
1282
1283 if ((ppsc->rfpwr_state == ERFON) &&
Larry Finger5c99f042014-09-26 16:40:25 -05001284 ((!fw_current_inpsmode) && fw_ps_awake) &&
1285 (!ppsc->rfchange_inprogress)) {
Larry Fingera619d1a2014-02-28 15:16:50 -06001286 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);
Larry Fingera619d1a2014-02-28 15:16:50 -06001297 }
1298 rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
1299}