1 /******************************************************************************
2  *
3  * Copyright(c) 2009-2010  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  * You should have received a copy of the GNU General Public License along with
15  * this program; if not, write to the Free Software Foundation, Inc.,
16  * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
17  *
18  * The full GNU General Public License is included in this distribution in the
19  * file called LICENSE.
20  *
21  * Contact Information:
22  * wlanfae <wlanfae@realtek.com>
23  * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
24  * Hsinchu 300, Taiwan.
25  *
26  * Larry Finger <Larry.Finger@lwfinger.net>
27  *
28  *****************************************************************************/
29 
30 #include <linux/export.h>
31 #include "dm_common.h"
32 #include "phy_common.h"
33 #include "../pci.h"
34 #include "../base.h"
35 
36 struct dig_t dm_digtable;
37 static struct ps_t dm_pstable;
38 
39 #define BT_RSSI_STATE_NORMAL_POWER	BIT_OFFSET_LEN_MASK_32(0, 1)
40 #define BT_RSSI_STATE_AMDPU_OFF		BIT_OFFSET_LEN_MASK_32(1, 1)
41 #define BT_RSSI_STATE_SPECIAL_LOW	BIT_OFFSET_LEN_MASK_32(2, 1)
42 #define BT_RSSI_STATE_BG_EDCA_LOW	BIT_OFFSET_LEN_MASK_32(3, 1)
43 #define BT_RSSI_STATE_TXPOWER_LOW	BIT_OFFSET_LEN_MASK_32(4, 1)
44 
45 #define RTLPRIV			(struct rtl_priv *)
46 #define GET_UNDECORATED_AVERAGE_RSSI(_priv)	\
47 	((RTLPRIV(_priv))->mac80211.opmode == \
48 			     NL80211_IFTYPE_ADHOC) ?	\
49 	((RTLPRIV(_priv))->dm.entry_min_undecoratedsmoothed_pwdb) : \
50 	((RTLPRIV(_priv))->dm.undecorated_smoothed_pwdb)
51 
52 static const u32 ofdmswing_table[OFDM_TABLE_SIZE] = {
53 	0x7f8001fe,
54 	0x788001e2,
55 	0x71c001c7,
56 	0x6b8001ae,
57 	0x65400195,
58 	0x5fc0017f,
59 	0x5a400169,
60 	0x55400155,
61 	0x50800142,
62 	0x4c000130,
63 	0x47c0011f,
64 	0x43c0010f,
65 	0x40000100,
66 	0x3c8000f2,
67 	0x390000e4,
68 	0x35c000d7,
69 	0x32c000cb,
70 	0x300000c0,
71 	0x2d4000b5,
72 	0x2ac000ab,
73 	0x288000a2,
74 	0x26000098,
75 	0x24000090,
76 	0x22000088,
77 	0x20000080,
78 	0x1e400079,
79 	0x1c800072,
80 	0x1b00006c,
81 	0x19800066,
82 	0x18000060,
83 	0x16c0005b,
84 	0x15800056,
85 	0x14400051,
86 	0x1300004c,
87 	0x12000048,
88 	0x11000044,
89 	0x10000040,
90 };
91 
92 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
93 	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04},
94 	{0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
95 	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
96 	{0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
97 	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
98 	{0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
99 	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
100 	{0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
101 	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
102 	{0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
103 	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
104 	{0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
105 	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
106 	{0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
107 	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
108 	{0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
109 	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
110 	{0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
111 	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
112 	{0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
113 	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
114 	{0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
115 	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
116 	{0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
117 	{0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
118 	{0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
119 	{0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
120 	{0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
121 	{0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
122 	{0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
123 	{0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
124 	{0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
125 	{0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}
126 };
127 
128 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
129 	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00},
130 	{0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
131 	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
132 	{0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
133 	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
134 	{0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
135 	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
136 	{0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
137 	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
138 	{0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
139 	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
140 	{0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
141 	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
142 	{0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
143 	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
144 	{0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
145 	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
146 	{0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
147 	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
148 	{0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
149 	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
150 	{0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
151 	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
152 	{0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
153 	{0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
154 	{0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
155 	{0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
156 	{0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
157 	{0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
158 	{0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
159 	{0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
160 	{0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
161 	{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}
162 };
163 
rtl92c_dm_diginit(struct ieee80211_hw * hw)164 static void rtl92c_dm_diginit(struct ieee80211_hw *hw)
165 {
166 	dm_digtable.dig_enable_flag = true;
167 	dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
168 	dm_digtable.cur_igvalue = 0x20;
169 	dm_digtable.pre_igvalue = 0x0;
170 	dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
171 	dm_digtable.presta_connectstate = DIG_STA_DISCONNECT;
172 	dm_digtable.curmultista_connectstate = DIG_MULTISTA_DISCONNECT;
173 	dm_digtable.rssi_lowthresh = DM_DIG_THRESH_LOW;
174 	dm_digtable.rssi_highthresh = DM_DIG_THRESH_HIGH;
175 	dm_digtable.fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
176 	dm_digtable.fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
177 	dm_digtable.rx_gain_range_max = DM_DIG_MAX;
178 	dm_digtable.rx_gain_range_min = DM_DIG_MIN;
179 	dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
180 	dm_digtable.backoff_val_range_max = DM_DIG_BACKOFF_MAX;
181 	dm_digtable.backoff_val_range_min = DM_DIG_BACKOFF_MIN;
182 	dm_digtable.pre_cck_pd_state = CCK_PD_STAGE_MAX;
183 	dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX;
184 }
185 
rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw * hw)186 static u8 rtl92c_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
187 {
188 	struct rtl_priv *rtlpriv = rtl_priv(hw);
189 	long rssi_val_min = 0;
190 
191 	if ((dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) &&
192 	    (dm_digtable.cursta_connectctate == DIG_STA_CONNECT)) {
193 		if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb != 0)
194 			rssi_val_min =
195 			    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb >
196 			     rtlpriv->dm.undecorated_smoothed_pwdb) ?
197 			    rtlpriv->dm.undecorated_smoothed_pwdb :
198 			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
199 		else
200 			rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb;
201 	} else if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT ||
202 		   dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT) {
203 		rssi_val_min = rtlpriv->dm.undecorated_smoothed_pwdb;
204 	} else if (dm_digtable.curmultista_connectstate ==
205 		   DIG_MULTISTA_CONNECT) {
206 		rssi_val_min = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
207 	}
208 
209 	return (u8) rssi_val_min;
210 }
211 
rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw * hw)212 static void rtl92c_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
213 {
214 	u32 ret_value;
215 	struct rtl_priv *rtlpriv = rtl_priv(hw);
216 	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
217 
218 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
219 	falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
220 
221 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
222 	falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
223 	falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
224 
225 	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
226 	falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
227 	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
228 	    falsealm_cnt->cnt_rate_illegal +
229 	    falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
230 
231 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
232 	ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
233 	falsealm_cnt->cnt_cck_fail = ret_value;
234 
235 	ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
236 	falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
237 	falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
238 				 falsealm_cnt->cnt_rate_illegal +
239 				 falsealm_cnt->cnt_crc8_fail +
240 				 falsealm_cnt->cnt_mcs_fail +
241 				 falsealm_cnt->cnt_cck_fail);
242 
243 	rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
244 	rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
245 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
246 	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
247 
248 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
249 		 ("cnt_parity_fail = %d, cnt_rate_illegal = %d, "
250 		  "cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
251 		  falsealm_cnt->cnt_parity_fail,
252 		  falsealm_cnt->cnt_rate_illegal,
253 		  falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail));
254 
255 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
256 		 ("cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
257 		  falsealm_cnt->cnt_ofdm_fail,
258 		  falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all));
259 }
260 
rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw * hw)261 static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
262 {
263 	struct rtl_priv *rtlpriv = rtl_priv(hw);
264 	u8 value_igi = dm_digtable.cur_igvalue;
265 
266 	if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
267 		value_igi--;
268 	else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
269 		value_igi += 0;
270 	else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
271 		value_igi++;
272 	else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
273 		value_igi += 2;
274 	if (value_igi > DM_DIG_FA_UPPER)
275 		value_igi = DM_DIG_FA_UPPER;
276 	else if (value_igi < DM_DIG_FA_LOWER)
277 		value_igi = DM_DIG_FA_LOWER;
278 	if (rtlpriv->falsealm_cnt.cnt_all > 10000)
279 		value_igi = 0x32;
280 
281 	dm_digtable.cur_igvalue = value_igi;
282 	rtl92c_dm_write_dig(hw);
283 }
284 
rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw * hw)285 static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
286 {
287 	struct rtl_priv *rtlpriv = rtl_priv(hw);
288 
289 	if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable.fa_highthresh) {
290 		if ((dm_digtable.backoff_val - 2) <
291 		    dm_digtable.backoff_val_range_min)
292 			dm_digtable.backoff_val =
293 			    dm_digtable.backoff_val_range_min;
294 		else
295 			dm_digtable.backoff_val -= 2;
296 	} else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable.fa_lowthresh) {
297 		if ((dm_digtable.backoff_val + 2) >
298 		    dm_digtable.backoff_val_range_max)
299 			dm_digtable.backoff_val =
300 			    dm_digtable.backoff_val_range_max;
301 		else
302 			dm_digtable.backoff_val += 2;
303 	}
304 
305 	if ((dm_digtable.rssi_val_min + 10 - dm_digtable.backoff_val) >
306 	    dm_digtable.rx_gain_range_max)
307 		dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_max;
308 	else if ((dm_digtable.rssi_val_min + 10 -
309 		  dm_digtable.backoff_val) < dm_digtable.rx_gain_range_min)
310 		dm_digtable.cur_igvalue = dm_digtable.rx_gain_range_min;
311 	else
312 		dm_digtable.cur_igvalue = dm_digtable.rssi_val_min + 10 -
313 		    dm_digtable.backoff_val;
314 
315 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
316 		 ("rssi_val_min = %x backoff_val %x\n",
317 		  dm_digtable.rssi_val_min, dm_digtable.backoff_val));
318 
319 	rtl92c_dm_write_dig(hw);
320 }
321 
rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw * hw)322 static void rtl92c_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
323 {
324 	static u8 initialized; /* initialized to false */
325 	struct rtl_priv *rtlpriv = rtl_priv(hw);
326 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
327 	long rssi_strength = rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
328 	bool multi_sta = false;
329 
330 	if (mac->opmode == NL80211_IFTYPE_ADHOC)
331 		multi_sta = true;
332 
333 	if ((multi_sta == false) || (dm_digtable.cursta_connectctate !=
334 				     DIG_STA_DISCONNECT)) {
335 		initialized = false;
336 		dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
337 		return;
338 	} else if (initialized == false) {
339 		initialized = true;
340 		dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
341 		dm_digtable.cur_igvalue = 0x20;
342 		rtl92c_dm_write_dig(hw);
343 	}
344 
345 	if (dm_digtable.curmultista_connectstate == DIG_MULTISTA_CONNECT) {
346 		if ((rssi_strength < dm_digtable.rssi_lowthresh) &&
347 		    (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
348 
349 			if (dm_digtable.dig_ext_port_stage ==
350 			    DIG_EXT_PORT_STAGE_2) {
351 				dm_digtable.cur_igvalue = 0x20;
352 				rtl92c_dm_write_dig(hw);
353 			}
354 
355 			dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
356 		} else if (rssi_strength > dm_digtable.rssi_highthresh) {
357 			dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
358 			rtl92c_dm_ctrl_initgain_by_fa(hw);
359 		}
360 	} else if (dm_digtable.dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
361 		dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
362 		dm_digtable.cur_igvalue = 0x20;
363 		rtl92c_dm_write_dig(hw);
364 	}
365 
366 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
367 		 ("curmultista_connectstate = "
368 		  "%x dig_ext_port_stage %x\n",
369 		  dm_digtable.curmultista_connectstate,
370 		  dm_digtable.dig_ext_port_stage));
371 }
372 
rtl92c_dm_initial_gain_sta(struct ieee80211_hw * hw)373 static void rtl92c_dm_initial_gain_sta(struct ieee80211_hw *hw)
374 {
375 	struct rtl_priv *rtlpriv = rtl_priv(hw);
376 
377 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
378 		 ("presta_connectstate = %x,"
379 		  " cursta_connectctate = %x\n",
380 		  dm_digtable.presta_connectstate,
381 		  dm_digtable.cursta_connectctate));
382 
383 	if (dm_digtable.presta_connectstate == dm_digtable.cursta_connectctate
384 	    || dm_digtable.cursta_connectctate == DIG_STA_BEFORE_CONNECT
385 	    || dm_digtable.cursta_connectctate == DIG_STA_CONNECT) {
386 
387 		if (dm_digtable.cursta_connectctate != DIG_STA_DISCONNECT) {
388 			dm_digtable.rssi_val_min =
389 			    rtl92c_dm_initial_gain_min_pwdb(hw);
390 			rtl92c_dm_ctrl_initgain_by_rssi(hw);
391 		}
392 	} else {
393 		dm_digtable.rssi_val_min = 0;
394 		dm_digtable.dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
395 		dm_digtable.backoff_val = DM_DIG_BACKOFF_DEFAULT;
396 		dm_digtable.cur_igvalue = 0x20;
397 		dm_digtable.pre_igvalue = 0;
398 		rtl92c_dm_write_dig(hw);
399 	}
400 }
401 
rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw * hw)402 static void rtl92c_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
403 {
404 	struct rtl_priv *rtlpriv = rtl_priv(hw);
405 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
406 
407 	if (dm_digtable.cursta_connectctate == DIG_STA_CONNECT) {
408 		dm_digtable.rssi_val_min = rtl92c_dm_initial_gain_min_pwdb(hw);
409 
410 		if (dm_digtable.pre_cck_pd_state == CCK_PD_STAGE_LowRssi) {
411 			if (dm_digtable.rssi_val_min <= 25)
412 				dm_digtable.cur_cck_pd_state =
413 				    CCK_PD_STAGE_LowRssi;
414 			else
415 				dm_digtable.cur_cck_pd_state =
416 				    CCK_PD_STAGE_HighRssi;
417 		} else {
418 			if (dm_digtable.rssi_val_min <= 20)
419 				dm_digtable.cur_cck_pd_state =
420 				    CCK_PD_STAGE_LowRssi;
421 			else
422 				dm_digtable.cur_cck_pd_state =
423 				    CCK_PD_STAGE_HighRssi;
424 		}
425 	} else {
426 		dm_digtable.cur_cck_pd_state = CCK_PD_STAGE_MAX;
427 	}
428 
429 	if (dm_digtable.pre_cck_pd_state != dm_digtable.cur_cck_pd_state) {
430 		if (dm_digtable.cur_cck_pd_state == CCK_PD_STAGE_LowRssi) {
431 			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
432 				dm_digtable.cur_cck_fa_state =
433 				    CCK_FA_STAGE_High;
434 			else
435 				dm_digtable.cur_cck_fa_state = CCK_FA_STAGE_Low;
436 
437 			if (dm_digtable.pre_cck_fa_state !=
438 			    dm_digtable.cur_cck_fa_state) {
439 				if (dm_digtable.cur_cck_fa_state ==
440 				    CCK_FA_STAGE_Low)
441 					rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
442 						      0x83);
443 				else
444 					rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
445 						      0xcd);
446 
447 				dm_digtable.pre_cck_fa_state =
448 				    dm_digtable.cur_cck_fa_state;
449 			}
450 
451 			rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
452 
453 			if (IS_92C_SERIAL(rtlhal->version))
454 				rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
455 					      MASKBYTE2, 0xd7);
456 		} else {
457 			rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
458 			rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
459 
460 			if (IS_92C_SERIAL(rtlhal->version))
461 				rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT,
462 					      MASKBYTE2, 0xd3);
463 		}
464 		dm_digtable.pre_cck_pd_state = dm_digtable.cur_cck_pd_state;
465 	}
466 
467 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
468 		 ("CCKPDStage=%x\n", dm_digtable.cur_cck_pd_state));
469 
470 	RT_TRACE(rtlpriv, COMP_DIG, DBG_TRACE,
471 		 ("is92C=%x\n", IS_92C_SERIAL(rtlhal->version)));
472 }
473 
rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw * hw)474 static void rtl92c_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
475 {
476 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
477 
478 	if (mac->act_scanning)
479 		return;
480 
481 	if (mac->link_state >= MAC80211_LINKED)
482 		dm_digtable.cursta_connectctate = DIG_STA_CONNECT;
483 	else
484 		dm_digtable.cursta_connectctate = DIG_STA_DISCONNECT;
485 
486 	rtl92c_dm_initial_gain_sta(hw);
487 	rtl92c_dm_initial_gain_multi_sta(hw);
488 	rtl92c_dm_cck_packet_detection_thresh(hw);
489 
490 	dm_digtable.presta_connectstate = dm_digtable.cursta_connectctate;
491 
492 }
493 
rtl92c_dm_dig(struct ieee80211_hw * hw)494 static void rtl92c_dm_dig(struct ieee80211_hw *hw)
495 {
496 	struct rtl_priv *rtlpriv = rtl_priv(hw);
497 
498 	if (rtlpriv->dm.dm_initialgain_enable == false)
499 		return;
500 	if (dm_digtable.dig_enable_flag == false)
501 		return;
502 
503 	rtl92c_dm_ctrl_initgain_by_twoport(hw);
504 
505 }
506 
rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw * hw)507 static void rtl92c_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
508 {
509 	struct rtl_priv *rtlpriv = rtl_priv(hw);
510 
511 	rtlpriv->dm.dynamic_txpower_enable = false;
512 
513 	rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
514 	rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
515 }
516 
rtl92c_dm_write_dig(struct ieee80211_hw * hw)517 void rtl92c_dm_write_dig(struct ieee80211_hw *hw)
518 {
519 	struct rtl_priv *rtlpriv = rtl_priv(hw);
520 
521 	RT_TRACE(rtlpriv, COMP_DIG, DBG_LOUD,
522 		 ("cur_igvalue = 0x%x, "
523 		  "pre_igvalue = 0x%x, backoff_val = %d\n",
524 		  dm_digtable.cur_igvalue, dm_digtable.pre_igvalue,
525 		  dm_digtable.backoff_val));
526 
527 	if (dm_digtable.pre_igvalue != dm_digtable.cur_igvalue) {
528 		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
529 			      dm_digtable.cur_igvalue);
530 		rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
531 			      dm_digtable.cur_igvalue);
532 
533 		dm_digtable.pre_igvalue = dm_digtable.cur_igvalue;
534 	}
535 }
536 EXPORT_SYMBOL(rtl92c_dm_write_dig);
537 
rtl92c_dm_pwdb_monitor(struct ieee80211_hw * hw)538 static void rtl92c_dm_pwdb_monitor(struct ieee80211_hw *hw)
539 {
540 	struct rtl_priv *rtlpriv = rtl_priv(hw);
541 	long tmpentry_max_pwdb = 0, tmpentry_min_pwdb = 0xff;
542 
543 	u8 h2c_parameter[3] = { 0 };
544 
545 	return;
546 
547 	if (tmpentry_max_pwdb != 0) {
548 		rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb =
549 		    tmpentry_max_pwdb;
550 	} else {
551 		rtlpriv->dm.entry_max_undecoratedsmoothed_pwdb = 0;
552 	}
553 
554 	if (tmpentry_min_pwdb != 0xff) {
555 		rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb =
556 		    tmpentry_min_pwdb;
557 	} else {
558 		rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb = 0;
559 	}
560 
561 	h2c_parameter[2] = (u8) (rtlpriv->dm.undecorated_smoothed_pwdb & 0xFF);
562 	h2c_parameter[0] = 0;
563 
564 	rtl92c_fill_h2c_cmd(hw, H2C_RSSI_REPORT, 3, h2c_parameter);
565 }
566 
rtl92c_dm_init_edca_turbo(struct ieee80211_hw * hw)567 void rtl92c_dm_init_edca_turbo(struct ieee80211_hw *hw)
568 {
569 	struct rtl_priv *rtlpriv = rtl_priv(hw);
570 	rtlpriv->dm.current_turbo_edca = false;
571 	rtlpriv->dm.is_any_nonbepkts = false;
572 	rtlpriv->dm.is_cur_rdlstate = false;
573 }
574 EXPORT_SYMBOL(rtl92c_dm_init_edca_turbo);
575 
rtl92c_dm_check_edca_turbo(struct ieee80211_hw * hw)576 static void rtl92c_dm_check_edca_turbo(struct ieee80211_hw *hw)
577 {
578 	struct rtl_priv *rtlpriv = rtl_priv(hw);
579 	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
580 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
581 
582 	static u64 last_txok_cnt;
583 	static u64 last_rxok_cnt;
584 	static u32 last_bt_edca_ul;
585 	static u32 last_bt_edca_dl;
586 	u64 cur_txok_cnt = 0;
587 	u64 cur_rxok_cnt = 0;
588 	u32 edca_be_ul = 0x5ea42b;
589 	u32 edca_be_dl = 0x5ea42b;
590 	bool bt_change_edca = false;
591 
592 	if ((last_bt_edca_ul != rtlpcipriv->bt_coexist.bt_edca_ul) ||
593 	    (last_bt_edca_dl != rtlpcipriv->bt_coexist.bt_edca_dl)) {
594 		rtlpriv->dm.current_turbo_edca = false;
595 		last_bt_edca_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
596 		last_bt_edca_dl = rtlpcipriv->bt_coexist.bt_edca_dl;
597 	}
598 
599 	if (rtlpcipriv->bt_coexist.bt_edca_ul != 0) {
600 		edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_ul;
601 		bt_change_edca = true;
602 	}
603 
604 	if (rtlpcipriv->bt_coexist.bt_edca_dl != 0) {
605 		edca_be_ul = rtlpcipriv->bt_coexist.bt_edca_dl;
606 		bt_change_edca = true;
607 	}
608 
609 	if (mac->link_state != MAC80211_LINKED) {
610 		rtlpriv->dm.current_turbo_edca = false;
611 		return;
612 	}
613 
614 	if ((!mac->ht_enable) && (!rtlpcipriv->bt_coexist.bt_coexistence)) {
615 		if (!(edca_be_ul & 0xffff0000))
616 			edca_be_ul |= 0x005e0000;
617 
618 		if (!(edca_be_dl & 0xffff0000))
619 			edca_be_dl |= 0x005e0000;
620 	}
621 
622 	if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
623 	     (!rtlpriv->dm.disable_framebursting))) {
624 
625 		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
626 		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
627 
628 		if (cur_rxok_cnt > 4 * cur_txok_cnt) {
629 			if (!rtlpriv->dm.is_cur_rdlstate ||
630 			    !rtlpriv->dm.current_turbo_edca) {
631 				rtl_write_dword(rtlpriv,
632 						REG_EDCA_BE_PARAM,
633 						edca_be_dl);
634 				rtlpriv->dm.is_cur_rdlstate = true;
635 			}
636 		} else {
637 			if (rtlpriv->dm.is_cur_rdlstate ||
638 			    !rtlpriv->dm.current_turbo_edca) {
639 				rtl_write_dword(rtlpriv,
640 						REG_EDCA_BE_PARAM,
641 						edca_be_ul);
642 				rtlpriv->dm.is_cur_rdlstate = false;
643 			}
644 		}
645 		rtlpriv->dm.current_turbo_edca = true;
646 	} else {
647 		if (rtlpriv->dm.current_turbo_edca) {
648 			u8 tmp = AC0_BE;
649 			rtlpriv->cfg->ops->set_hw_reg(hw,
650 						      HW_VAR_AC_PARAM,
651 						      (u8 *) (&tmp));
652 			rtlpriv->dm.current_turbo_edca = false;
653 		}
654 	}
655 
656 	rtlpriv->dm.is_any_nonbepkts = false;
657 	last_txok_cnt = rtlpriv->stats.txbytesunicast;
658 	last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
659 }
660 
rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw * hw)661 static void rtl92c_dm_txpower_tracking_callback_thermalmeter(struct ieee80211_hw
662 							     *hw)
663 {
664 	struct rtl_priv *rtlpriv = rtl_priv(hw);
665 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
666 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
667 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
668 	u8 thermalvalue, delta, delta_lck, delta_iqk;
669 	long ele_a, ele_d, temp_cck, val_x, value32;
670 	long val_y, ele_c = 0;
671 	u8 ofdm_index[2], cck_index = 0, ofdm_index_old[2], cck_index_old = 0;
672 	int i;
673 	bool is2t = IS_92C_SERIAL(rtlhal->version);
674 	s8 txpwr_level[2] = {0, 0};
675 	u8 ofdm_min_index = 6, rf;
676 
677 	rtlpriv->dm.txpower_trackinginit = true;
678 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
679 		 ("rtl92c_dm_txpower_tracking_callback_thermalmeter\n"));
680 
681 	thermalvalue = (u8) rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
682 
683 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
684 		 ("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
685 		  "eeprom_thermalmeter 0x%x\n",
686 		  thermalvalue, rtlpriv->dm.thermalvalue,
687 		  rtlefuse->eeprom_thermalmeter));
688 
689 	rtl92c_phy_ap_calibrate(hw, (thermalvalue -
690 				     rtlefuse->eeprom_thermalmeter));
691 	if (is2t)
692 		rf = 2;
693 	else
694 		rf = 1;
695 
696 	if (thermalvalue) {
697 		ele_d = rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
698 				      MASKDWORD) & MASKOFDM_D;
699 
700 		for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
701 			if (ele_d == (ofdmswing_table[i] & MASKOFDM_D)) {
702 				ofdm_index_old[0] = (u8) i;
703 
704 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
705 					("Initial pathA ele_d reg0x%x = 0x%lx, "
706 					 "ofdm_index=0x%x\n",
707 					 ROFDM0_XATXIQIMBALANCE,
708 					 ele_d, ofdm_index_old[0]));
709 				break;
710 			}
711 		}
712 
713 		if (is2t) {
714 			ele_d = rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
715 					      MASKDWORD) & MASKOFDM_D;
716 
717 			for (i = 0; i < OFDM_TABLE_LENGTH; i++) {
718 				if (ele_d == (ofdmswing_table[i] &
719 				    MASKOFDM_D)) {
720 
721 					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
722 					   DBG_LOUD,
723 					   ("Initial pathB ele_d reg0x%x = "
724 					   "0x%lx, ofdm_index=0x%x\n",
725 					   ROFDM0_XBTXIQIMBALANCE, ele_d,
726 					   ofdm_index_old[1]));
727 					break;
728 				}
729 			}
730 		}
731 
732 		temp_cck =
733 		    rtl_get_bbreg(hw, RCCK0_TXFILTER2, MASKDWORD) & MASKCCK;
734 
735 		for (i = 0; i < CCK_TABLE_LENGTH; i++) {
736 			if (rtlpriv->dm.cck_inch14) {
737 				if (memcmp((void *)&temp_cck,
738 					   (void *)&cckswing_table_ch14[i][2],
739 					   4) == 0) {
740 					cck_index_old = (u8) i;
741 
742 					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
743 						 DBG_LOUD,
744 						 ("Initial reg0x%x = 0x%lx, "
745 						  "cck_index=0x%x, ch 14 %d\n",
746 						  RCCK0_TXFILTER2, temp_cck,
747 						  cck_index_old,
748 						  rtlpriv->dm.cck_inch14));
749 					break;
750 				}
751 			} else {
752 				if (memcmp((void *)&temp_cck,
753 					   (void *)
754 					   &cckswing_table_ch1ch13[i][2],
755 					   4) == 0) {
756 					cck_index_old = (u8) i;
757 
758 					RT_TRACE(rtlpriv, COMP_POWER_TRACKING,
759 						 DBG_LOUD,
760 						 ("Initial reg0x%x = 0x%lx, "
761 						  "cck_index=0x%x, ch14 %d\n",
762 						  RCCK0_TXFILTER2, temp_cck,
763 						  cck_index_old,
764 						  rtlpriv->dm.cck_inch14));
765 					break;
766 				}
767 			}
768 		}
769 
770 		if (!rtlpriv->dm.thermalvalue) {
771 			rtlpriv->dm.thermalvalue =
772 			    rtlefuse->eeprom_thermalmeter;
773 			rtlpriv->dm.thermalvalue_lck = thermalvalue;
774 			rtlpriv->dm.thermalvalue_iqk = thermalvalue;
775 			for (i = 0; i < rf; i++)
776 				rtlpriv->dm.ofdm_index[i] = ofdm_index_old[i];
777 			rtlpriv->dm.cck_index = cck_index_old;
778 		}
779 
780 		delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
781 		    (thermalvalue - rtlpriv->dm.thermalvalue) :
782 		    (rtlpriv->dm.thermalvalue - thermalvalue);
783 
784 		delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
785 		    (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
786 		    (rtlpriv->dm.thermalvalue_lck - thermalvalue);
787 
788 		delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
789 		    (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
790 		    (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
791 
792 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
793 			("Readback Thermal Meter = 0x%x pre thermal meter 0x%x "
794 			 "eeprom_thermalmeter 0x%x delta 0x%x "
795 			 "delta_lck 0x%x delta_iqk 0x%x\n",
796 			 thermalvalue, rtlpriv->dm.thermalvalue,
797 			 rtlefuse->eeprom_thermalmeter, delta, delta_lck,
798 			 delta_iqk));
799 
800 		if (delta_lck > 1) {
801 			rtlpriv->dm.thermalvalue_lck = thermalvalue;
802 			rtl92c_phy_lc_calibrate(hw);
803 		}
804 
805 		if (delta > 0 && rtlpriv->dm.txpower_track_control) {
806 			if (thermalvalue > rtlpriv->dm.thermalvalue) {
807 				for (i = 0; i < rf; i++)
808 					rtlpriv->dm.ofdm_index[i] -= delta;
809 				rtlpriv->dm.cck_index -= delta;
810 			} else {
811 				for (i = 0; i < rf; i++)
812 					rtlpriv->dm.ofdm_index[i] += delta;
813 				rtlpriv->dm.cck_index += delta;
814 			}
815 
816 			if (is2t) {
817 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
818 					 ("temp OFDM_A_index=0x%x, "
819 					  "OFDM_B_index=0x%x,"
820 					  "cck_index=0x%x\n",
821 					  rtlpriv->dm.ofdm_index[0],
822 					  rtlpriv->dm.ofdm_index[1],
823 					  rtlpriv->dm.cck_index));
824 			} else {
825 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
826 					 ("temp OFDM_A_index=0x%x,"
827 					  "cck_index=0x%x\n",
828 					  rtlpriv->dm.ofdm_index[0],
829 					  rtlpriv->dm.cck_index));
830 			}
831 
832 			if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
833 				for (i = 0; i < rf; i++)
834 					ofdm_index[i] =
835 					    rtlpriv->dm.ofdm_index[i]
836 					    + 1;
837 				cck_index = rtlpriv->dm.cck_index + 1;
838 			} else {
839 				for (i = 0; i < rf; i++)
840 					ofdm_index[i] =
841 					    rtlpriv->dm.ofdm_index[i];
842 				cck_index = rtlpriv->dm.cck_index;
843 			}
844 
845 			for (i = 0; i < rf; i++) {
846 				if (txpwr_level[i] >= 0 &&
847 				    txpwr_level[i] <= 26) {
848 					if (thermalvalue >
849 					    rtlefuse->eeprom_thermalmeter) {
850 						if (delta < 5)
851 							ofdm_index[i] -= 1;
852 
853 						else
854 							ofdm_index[i] -= 2;
855 					} else if (delta > 5 && thermalvalue <
856 						   rtlefuse->
857 						   eeprom_thermalmeter) {
858 						ofdm_index[i] += 1;
859 					}
860 				} else if (txpwr_level[i] >= 27 &&
861 					   txpwr_level[i] <= 32
862 					   && thermalvalue >
863 					   rtlefuse->eeprom_thermalmeter) {
864 					if (delta < 5)
865 						ofdm_index[i] -= 1;
866 
867 					else
868 						ofdm_index[i] -= 2;
869 				} else if (txpwr_level[i] >= 32 &&
870 					   txpwr_level[i] <= 38 &&
871 					   thermalvalue >
872 					   rtlefuse->eeprom_thermalmeter
873 					   && delta > 5) {
874 					ofdm_index[i] -= 1;
875 				}
876 			}
877 
878 			if (txpwr_level[i] >= 0 && txpwr_level[i] <= 26) {
879 				if (thermalvalue >
880 				    rtlefuse->eeprom_thermalmeter) {
881 					if (delta < 5)
882 						cck_index -= 1;
883 
884 					else
885 						cck_index -= 2;
886 				} else if (delta > 5 && thermalvalue <
887 					   rtlefuse->eeprom_thermalmeter) {
888 					cck_index += 1;
889 				}
890 			} else if (txpwr_level[i] >= 27 &&
891 				   txpwr_level[i] <= 32 &&
892 				   thermalvalue >
893 				   rtlefuse->eeprom_thermalmeter) {
894 				if (delta < 5)
895 					cck_index -= 1;
896 
897 				else
898 					cck_index -= 2;
899 			} else if (txpwr_level[i] >= 32 &&
900 				   txpwr_level[i] <= 38 &&
901 				   thermalvalue > rtlefuse->eeprom_thermalmeter
902 				   && delta > 5) {
903 				cck_index -= 1;
904 			}
905 
906 			for (i = 0; i < rf; i++) {
907 				if (ofdm_index[i] > OFDM_TABLE_SIZE - 1)
908 					ofdm_index[i] = OFDM_TABLE_SIZE - 1;
909 
910 				else if (ofdm_index[i] < ofdm_min_index)
911 					ofdm_index[i] = ofdm_min_index;
912 			}
913 
914 			if (cck_index > CCK_TABLE_SIZE - 1)
915 				cck_index = CCK_TABLE_SIZE - 1;
916 			else if (cck_index < 0)
917 				cck_index = 0;
918 
919 			if (is2t) {
920 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
921 					 ("new OFDM_A_index=0x%x, "
922 					  "OFDM_B_index=0x%x,"
923 					  "cck_index=0x%x\n",
924 					  ofdm_index[0], ofdm_index[1],
925 					  cck_index));
926 			} else {
927 				RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
928 					 ("new OFDM_A_index=0x%x,"
929 					  "cck_index=0x%x\n",
930 					  ofdm_index[0], cck_index));
931 			}
932 		}
933 
934 		if (rtlpriv->dm.txpower_track_control && delta != 0) {
935 			ele_d =
936 			    (ofdmswing_table[ofdm_index[0]] & 0xFFC00000) >> 22;
937 			val_x = rtlphy->reg_e94;
938 			val_y = rtlphy->reg_e9c;
939 
940 			if (val_x != 0) {
941 				if ((val_x & 0x00000200) != 0)
942 					val_x = val_x | 0xFFFFFC00;
943 				ele_a = ((val_x * ele_d) >> 8) & 0x000003FF;
944 
945 				if ((val_y & 0x00000200) != 0)
946 					val_y = val_y | 0xFFFFFC00;
947 				ele_c = ((val_y * ele_d) >> 8) & 0x000003FF;
948 
949 				value32 = (ele_d << 22) |
950 				    ((ele_c & 0x3F) << 16) | ele_a;
951 
952 				rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
953 					      MASKDWORD, value32);
954 
955 				value32 = (ele_c & 0x000003C0) >> 6;
956 				rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
957 					      value32);
958 
959 				value32 = ((val_x * ele_d) >> 7) & 0x01;
960 				rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
961 					      BIT(31), value32);
962 
963 				value32 = ((val_y * ele_d) >> 7) & 0x01;
964 				rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
965 					      BIT(29), value32);
966 			} else {
967 				rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE,
968 					      MASKDWORD,
969 					      ofdmswing_table[ofdm_index[0]]);
970 
971 				rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS,
972 					      0x00);
973 				rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
974 					      BIT(31) | BIT(29), 0x00);
975 			}
976 
977 			if (!rtlpriv->dm.cck_inch14) {
978 				rtl_write_byte(rtlpriv, 0xa22,
979 					       cckswing_table_ch1ch13[cck_index]
980 					       [0]);
981 				rtl_write_byte(rtlpriv, 0xa23,
982 					       cckswing_table_ch1ch13[cck_index]
983 					       [1]);
984 				rtl_write_byte(rtlpriv, 0xa24,
985 					       cckswing_table_ch1ch13[cck_index]
986 					       [2]);
987 				rtl_write_byte(rtlpriv, 0xa25,
988 					       cckswing_table_ch1ch13[cck_index]
989 					       [3]);
990 				rtl_write_byte(rtlpriv, 0xa26,
991 					       cckswing_table_ch1ch13[cck_index]
992 					       [4]);
993 				rtl_write_byte(rtlpriv, 0xa27,
994 					       cckswing_table_ch1ch13[cck_index]
995 					       [5]);
996 				rtl_write_byte(rtlpriv, 0xa28,
997 					       cckswing_table_ch1ch13[cck_index]
998 					       [6]);
999 				rtl_write_byte(rtlpriv, 0xa29,
1000 					       cckswing_table_ch1ch13[cck_index]
1001 					       [7]);
1002 			} else {
1003 				rtl_write_byte(rtlpriv, 0xa22,
1004 					       cckswing_table_ch14[cck_index]
1005 					       [0]);
1006 				rtl_write_byte(rtlpriv, 0xa23,
1007 					       cckswing_table_ch14[cck_index]
1008 					       [1]);
1009 				rtl_write_byte(rtlpriv, 0xa24,
1010 					       cckswing_table_ch14[cck_index]
1011 					       [2]);
1012 				rtl_write_byte(rtlpriv, 0xa25,
1013 					       cckswing_table_ch14[cck_index]
1014 					       [3]);
1015 				rtl_write_byte(rtlpriv, 0xa26,
1016 					       cckswing_table_ch14[cck_index]
1017 					       [4]);
1018 				rtl_write_byte(rtlpriv, 0xa27,
1019 					       cckswing_table_ch14[cck_index]
1020 					       [5]);
1021 				rtl_write_byte(rtlpriv, 0xa28,
1022 					       cckswing_table_ch14[cck_index]
1023 					       [6]);
1024 				rtl_write_byte(rtlpriv, 0xa29,
1025 					       cckswing_table_ch14[cck_index]
1026 					       [7]);
1027 			}
1028 
1029 			if (is2t) {
1030 				ele_d = (ofdmswing_table[ofdm_index[1]] &
1031 					 0xFFC00000) >> 22;
1032 
1033 				val_x = rtlphy->reg_eb4;
1034 				val_y = rtlphy->reg_ebc;
1035 
1036 				if (val_x != 0) {
1037 					if ((val_x & 0x00000200) != 0)
1038 						val_x = val_x | 0xFFFFFC00;
1039 					ele_a = ((val_x * ele_d) >> 8) &
1040 					    0x000003FF;
1041 
1042 					if ((val_y & 0x00000200) != 0)
1043 						val_y = val_y | 0xFFFFFC00;
1044 					ele_c = ((val_y * ele_d) >> 8) &
1045 					    0x00003FF;
1046 
1047 					value32 = (ele_d << 22) |
1048 					    ((ele_c & 0x3F) << 16) | ele_a;
1049 					rtl_set_bbreg(hw,
1050 						      ROFDM0_XBTXIQIMBALANCE,
1051 						      MASKDWORD, value32);
1052 
1053 					value32 = (ele_c & 0x000003C0) >> 6;
1054 					rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1055 						      MASKH4BITS, value32);
1056 
1057 					value32 = ((val_x * ele_d) >> 7) & 0x01;
1058 					rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1059 						      BIT(27), value32);
1060 
1061 					value32 = ((val_y * ele_d) >> 7) & 0x01;
1062 					rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1063 						      BIT(25), value32);
1064 				} else {
1065 					rtl_set_bbreg(hw,
1066 						      ROFDM0_XBTXIQIMBALANCE,
1067 						      MASKDWORD,
1068 						      ofdmswing_table[ofdm_index
1069 								      [1]]);
1070 					rtl_set_bbreg(hw, ROFDM0_XDTXAFE,
1071 						      MASKH4BITS, 0x00);
1072 					rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD,
1073 						      BIT(27) | BIT(25), 0x00);
1074 				}
1075 
1076 			}
1077 		}
1078 
1079 		if (delta_iqk > 3) {
1080 			rtlpriv->dm.thermalvalue_iqk = thermalvalue;
1081 			rtl92c_phy_iq_calibrate(hw, false);
1082 		}
1083 
1084 		if (rtlpriv->dm.txpower_track_control)
1085 			rtlpriv->dm.thermalvalue = thermalvalue;
1086 	}
1087 
1088 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, ("<===\n"));
1089 
1090 }
1091 
rtl92c_dm_initialize_txpower_tracking_thermalmeter(struct ieee80211_hw * hw)1092 static void rtl92c_dm_initialize_txpower_tracking_thermalmeter(
1093 						struct ieee80211_hw *hw)
1094 {
1095 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1096 
1097 	rtlpriv->dm.txpower_tracking = true;
1098 	rtlpriv->dm.txpower_trackinginit = false;
1099 
1100 	RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1101 		 ("pMgntInfo->txpower_tracking = %d\n",
1102 		  rtlpriv->dm.txpower_tracking));
1103 }
1104 
rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw * hw)1105 static void rtl92c_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
1106 {
1107 	rtl92c_dm_initialize_txpower_tracking_thermalmeter(hw);
1108 }
1109 
rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw * hw)1110 static void rtl92c_dm_txpower_tracking_directcall(struct ieee80211_hw *hw)
1111 {
1112 	rtl92c_dm_txpower_tracking_callback_thermalmeter(hw);
1113 }
1114 
rtl92c_dm_check_txpower_tracking_thermal_meter(struct ieee80211_hw * hw)1115 static void rtl92c_dm_check_txpower_tracking_thermal_meter(
1116 						struct ieee80211_hw *hw)
1117 {
1118 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1119 	static u8 tm_trigger;
1120 
1121 	if (!rtlpriv->dm.txpower_tracking)
1122 		return;
1123 
1124 	if (!tm_trigger) {
1125 		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, RFREG_OFFSET_MASK,
1126 			      0x60);
1127 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1128 			 ("Trigger 92S Thermal Meter!!\n"));
1129 		tm_trigger = 1;
1130 		return;
1131 	} else {
1132 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
1133 			 ("Schedule TxPowerTracking direct call!!\n"));
1134 		rtl92c_dm_txpower_tracking_directcall(hw);
1135 		tm_trigger = 0;
1136 	}
1137 }
1138 
rtl92c_dm_check_txpower_tracking(struct ieee80211_hw * hw)1139 void rtl92c_dm_check_txpower_tracking(struct ieee80211_hw *hw)
1140 {
1141 	rtl92c_dm_check_txpower_tracking_thermal_meter(hw);
1142 }
1143 EXPORT_SYMBOL(rtl92c_dm_check_txpower_tracking);
1144 
rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw * hw)1145 void rtl92c_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
1146 {
1147 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1148 	struct rate_adaptive *p_ra = &(rtlpriv->ra);
1149 
1150 	p_ra->ratr_state = DM_RATR_STA_INIT;
1151 	p_ra->pre_ratr_state = DM_RATR_STA_INIT;
1152 
1153 	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
1154 		rtlpriv->dm.useramask = true;
1155 	else
1156 		rtlpriv->dm.useramask = false;
1157 
1158 }
1159 EXPORT_SYMBOL(rtl92c_dm_init_rate_adaptive_mask);
1160 
rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw * hw)1161 static void rtl92c_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
1162 {
1163 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1164 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1165 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1166 	struct rate_adaptive *p_ra = &(rtlpriv->ra);
1167 	u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
1168 	struct ieee80211_sta *sta = NULL;
1169 
1170 	if (is_hal_stop(rtlhal)) {
1171 		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1172 			 ("<---- driver is going to unload\n"));
1173 		return;
1174 	}
1175 
1176 	if (!rtlpriv->dm.useramask) {
1177 		RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1178 			("<---- driver does not control rate adaptive mask\n"));
1179 		return;
1180 	}
1181 
1182 	if (mac->link_state == MAC80211_LINKED &&
1183 	    mac->opmode == NL80211_IFTYPE_STATION) {
1184 		switch (p_ra->pre_ratr_state) {
1185 		case DM_RATR_STA_HIGH:
1186 			high_rssithresh_for_ra = 50;
1187 			low_rssithresh_for_ra = 20;
1188 			break;
1189 		case DM_RATR_STA_MIDDLE:
1190 			high_rssithresh_for_ra = 55;
1191 			low_rssithresh_for_ra = 20;
1192 			break;
1193 		case DM_RATR_STA_LOW:
1194 			high_rssithresh_for_ra = 50;
1195 			low_rssithresh_for_ra = 25;
1196 			break;
1197 		default:
1198 			high_rssithresh_for_ra = 50;
1199 			low_rssithresh_for_ra = 20;
1200 			break;
1201 		}
1202 
1203 		if (rtlpriv->dm.undecorated_smoothed_pwdb >
1204 		    (long)high_rssithresh_for_ra)
1205 			p_ra->ratr_state = DM_RATR_STA_HIGH;
1206 		else if (rtlpriv->dm.undecorated_smoothed_pwdb >
1207 			 (long)low_rssithresh_for_ra)
1208 			p_ra->ratr_state = DM_RATR_STA_MIDDLE;
1209 		else
1210 			p_ra->ratr_state = DM_RATR_STA_LOW;
1211 
1212 		if (p_ra->pre_ratr_state != p_ra->ratr_state) {
1213 			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1214 				 ("RSSI = %ld\n",
1215 				  rtlpriv->dm.undecorated_smoothed_pwdb));
1216 			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1217 				 ("RSSI_LEVEL = %d\n", p_ra->ratr_state));
1218 			RT_TRACE(rtlpriv, COMP_RATE, DBG_LOUD,
1219 				 ("PreState = %d, CurState = %d\n",
1220 				  p_ra->pre_ratr_state, p_ra->ratr_state));
1221 
1222 			rcu_read_lock();
1223 			sta = ieee80211_find_sta(mac->vif, mac->bssid);
1224 			rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
1225 					p_ra->ratr_state);
1226 
1227 			p_ra->pre_ratr_state = p_ra->ratr_state;
1228 			rcu_read_unlock();
1229 		}
1230 	}
1231 }
1232 
rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw * hw)1233 static void rtl92c_dm_init_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1234 {
1235 	dm_pstable.pre_ccastate = CCA_MAX;
1236 	dm_pstable.cur_ccasate = CCA_MAX;
1237 	dm_pstable.pre_rfstate = RF_MAX;
1238 	dm_pstable.cur_rfstate = RF_MAX;
1239 	dm_pstable.rssi_val_min = 0;
1240 }
1241 
rtl92c_dm_rf_saving(struct ieee80211_hw * hw,u8 bforce_in_normal)1242 void rtl92c_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
1243 {
1244 	static u8 initialize;
1245 	static u32 reg_874, reg_c70, reg_85c, reg_a74;
1246 
1247 	if (initialize == 0) {
1248 		reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1249 					 MASKDWORD) & 0x1CC000) >> 14;
1250 
1251 		reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
1252 					 MASKDWORD) & BIT(3)) >> 3;
1253 
1254 		reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1255 					 MASKDWORD) & 0xFF000000) >> 24;
1256 
1257 		reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12;
1258 
1259 		initialize = 1;
1260 	}
1261 
1262 	if (!bforce_in_normal) {
1263 		if (dm_pstable.rssi_val_min != 0) {
1264 			if (dm_pstable.pre_rfstate == RF_NORMAL) {
1265 				if (dm_pstable.rssi_val_min >= 30)
1266 					dm_pstable.cur_rfstate = RF_SAVE;
1267 				else
1268 					dm_pstable.cur_rfstate = RF_NORMAL;
1269 			} else {
1270 				if (dm_pstable.rssi_val_min <= 25)
1271 					dm_pstable.cur_rfstate = RF_NORMAL;
1272 				else
1273 					dm_pstable.cur_rfstate = RF_SAVE;
1274 			}
1275 		} else {
1276 			dm_pstable.cur_rfstate = RF_MAX;
1277 		}
1278 	} else {
1279 		dm_pstable.cur_rfstate = RF_NORMAL;
1280 	}
1281 
1282 	if (dm_pstable.pre_rfstate != dm_pstable.cur_rfstate) {
1283 		if (dm_pstable.cur_rfstate == RF_SAVE) {
1284 			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1285 				      0x1C0000, 0x2);
1286 			rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
1287 			rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
1288 				      0xFF000000, 0x63);
1289 			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1290 				      0xC000, 0x2);
1291 			rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
1292 			rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1293 			rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
1294 		} else {
1295 			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
1296 				      0x1CC000, reg_874);
1297 			rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
1298 				      reg_c70);
1299 			rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
1300 				      reg_85c);
1301 			rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74);
1302 			rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
1303 		}
1304 
1305 		dm_pstable.pre_rfstate = dm_pstable.cur_rfstate;
1306 	}
1307 }
1308 EXPORT_SYMBOL(rtl92c_dm_rf_saving);
1309 
rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw * hw)1310 static void rtl92c_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
1311 {
1312 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1313 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1314 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1315 
1316 	if (((mac->link_state == MAC80211_NOLINK)) &&
1317 	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
1318 		dm_pstable.rssi_val_min = 0;
1319 		RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1320 			 ("Not connected to any\n"));
1321 	}
1322 
1323 	if (mac->link_state == MAC80211_LINKED) {
1324 		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
1325 			dm_pstable.rssi_val_min =
1326 			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
1327 			RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1328 				 ("AP Client PWDB = 0x%lx\n",
1329 				  dm_pstable.rssi_val_min));
1330 		} else {
1331 			dm_pstable.rssi_val_min =
1332 			    rtlpriv->dm.undecorated_smoothed_pwdb;
1333 			RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1334 				 ("STA Default Port PWDB = 0x%lx\n",
1335 				  dm_pstable.rssi_val_min));
1336 		}
1337 	} else {
1338 		dm_pstable.rssi_val_min =
1339 		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
1340 
1341 		RT_TRACE(rtlpriv, DBG_LOUD, DBG_LOUD,
1342 			 ("AP Ext Port PWDB = 0x%lx\n",
1343 			  dm_pstable.rssi_val_min));
1344 	}
1345 
1346 	if (IS_92C_SERIAL(rtlhal->version))
1347 		;/* rtl92c_dm_1r_cca(hw); */
1348 	else
1349 		rtl92c_dm_rf_saving(hw, false);
1350 }
1351 
rtl92c_dm_init(struct ieee80211_hw * hw)1352 void rtl92c_dm_init(struct ieee80211_hw *hw)
1353 {
1354 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1355 
1356 	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
1357 	rtl92c_dm_diginit(hw);
1358 	rtl92c_dm_init_dynamic_txpower(hw);
1359 	rtl92c_dm_init_edca_turbo(hw);
1360 	rtl92c_dm_init_rate_adaptive_mask(hw);
1361 	rtl92c_dm_initialize_txpower_tracking(hw);
1362 	rtl92c_dm_init_dynamic_bb_powersaving(hw);
1363 }
1364 EXPORT_SYMBOL(rtl92c_dm_init);
1365 
rtl92c_dm_dynamic_txpower(struct ieee80211_hw * hw)1366 void rtl92c_dm_dynamic_txpower(struct ieee80211_hw *hw)
1367 {
1368 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1369 	struct rtl_phy *rtlphy = &(rtlpriv->phy);
1370 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1371 	long undecorated_smoothed_pwdb;
1372 
1373 	if (!rtlpriv->dm.dynamic_txpower_enable)
1374 		return;
1375 
1376 	if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
1377 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
1378 		return;
1379 	}
1380 
1381 	if ((mac->link_state < MAC80211_LINKED) &&
1382 	    (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)) {
1383 		RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
1384 			 ("Not connected to any\n"));
1385 
1386 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
1387 
1388 		rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
1389 		return;
1390 	}
1391 
1392 	if (mac->link_state >= MAC80211_LINKED) {
1393 		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
1394 			undecorated_smoothed_pwdb =
1395 			    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
1396 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1397 				 ("AP Client PWDB = 0x%lx\n",
1398 				  undecorated_smoothed_pwdb));
1399 		} else {
1400 			undecorated_smoothed_pwdb =
1401 			    rtlpriv->dm.undecorated_smoothed_pwdb;
1402 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1403 				 ("STA Default Port PWDB = 0x%lx\n",
1404 				  undecorated_smoothed_pwdb));
1405 		}
1406 	} else {
1407 		undecorated_smoothed_pwdb =
1408 		    rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
1409 
1410 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1411 			 ("AP Ext Port PWDB = 0x%lx\n",
1412 			  undecorated_smoothed_pwdb));
1413 	}
1414 
1415 	if (undecorated_smoothed_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
1416 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
1417 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1418 			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"));
1419 	} else if ((undecorated_smoothed_pwdb <
1420 		    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
1421 		   (undecorated_smoothed_pwdb >=
1422 		    TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
1423 
1424 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
1425 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1426 			 ("TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"));
1427 	} else if (undecorated_smoothed_pwdb <
1428 		   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
1429 		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
1430 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1431 			 ("TXHIGHPWRLEVEL_NORMAL\n"));
1432 	}
1433 
1434 	if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl)) {
1435 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD,
1436 			 ("PHY_SetTxPowerLevel8192S() Channel = %d\n",
1437 			  rtlphy->current_channel));
1438 		rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel);
1439 	}
1440 
1441 	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
1442 }
1443 
rtl92c_dm_watchdog(struct ieee80211_hw * hw)1444 void rtl92c_dm_watchdog(struct ieee80211_hw *hw)
1445 {
1446 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1447 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1448 	bool fw_current_inpsmode = false;
1449 	bool fw_ps_awake = true;
1450 
1451 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
1452 				      (u8 *) (&fw_current_inpsmode));
1453 	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
1454 				      (u8 *) (&fw_ps_awake));
1455 
1456 	if ((ppsc->rfpwr_state == ERFON) && ((!fw_current_inpsmode) &&
1457 					     fw_ps_awake)
1458 	    && (!ppsc->rfchange_inprogress)) {
1459 		rtl92c_dm_pwdb_monitor(hw);
1460 		rtl92c_dm_dig(hw);
1461 		rtl92c_dm_false_alarm_counter_statistics(hw);
1462 		rtl92c_dm_dynamic_bb_powersaving(hw);
1463 		rtl92c_dm_dynamic_txpower(hw);
1464 		rtl92c_dm_check_txpower_tracking(hw);
1465 		rtl92c_dm_refresh_rate_adaptive_mask(hw);
1466 		rtl92c_dm_bt_coexist(hw);
1467 		rtl92c_dm_check_edca_turbo(hw);
1468 	}
1469 }
1470 EXPORT_SYMBOL(rtl92c_dm_watchdog);
1471 
rtl92c_bt_rssi_state_change(struct ieee80211_hw * hw)1472 u8 rtl92c_bt_rssi_state_change(struct ieee80211_hw *hw)
1473 {
1474 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1475 	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1476 	long undecorated_smoothed_pwdb;
1477 	u8 curr_bt_rssi_state = 0x00;
1478 
1479 	if (rtlpriv->mac80211.link_state == MAC80211_LINKED) {
1480 		undecorated_smoothed_pwdb =
1481 				 GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
1482 	} else {
1483 		if (rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb == 0)
1484 			undecorated_smoothed_pwdb = 100;
1485 		else
1486 			undecorated_smoothed_pwdb =
1487 				rtlpriv->dm.entry_min_undecoratedsmoothed_pwdb;
1488 	}
1489 
1490 	/* Check RSSI to determine HighPower/NormalPower state for
1491 	 * BT coexistence. */
1492 	if (undecorated_smoothed_pwdb >= 67)
1493 		curr_bt_rssi_state &= (~BT_RSSI_STATE_NORMAL_POWER);
1494 	else if (undecorated_smoothed_pwdb < 62)
1495 		curr_bt_rssi_state |= BT_RSSI_STATE_NORMAL_POWER;
1496 
1497 	/* Check RSSI to determine AMPDU setting for BT coexistence. */
1498 	if (undecorated_smoothed_pwdb >= 40)
1499 		curr_bt_rssi_state &= (~BT_RSSI_STATE_AMDPU_OFF);
1500 	else if (undecorated_smoothed_pwdb <= 32)
1501 		curr_bt_rssi_state |= BT_RSSI_STATE_AMDPU_OFF;
1502 
1503 	/* Marked RSSI state. It will be used to determine BT coexistence
1504 	 * setting later. */
1505 	if (undecorated_smoothed_pwdb < 35)
1506 		curr_bt_rssi_state |=  BT_RSSI_STATE_SPECIAL_LOW;
1507 	else
1508 		curr_bt_rssi_state &= (~BT_RSSI_STATE_SPECIAL_LOW);
1509 
1510 	/* Set Tx Power according to BT status. */
1511 	if (undecorated_smoothed_pwdb >= 30)
1512 		curr_bt_rssi_state |=  BT_RSSI_STATE_TXPOWER_LOW;
1513 	else if (undecorated_smoothed_pwdb < 25)
1514 		curr_bt_rssi_state &= (~BT_RSSI_STATE_TXPOWER_LOW);
1515 
1516 	/* Check BT state related to BT_Idle in B/G mode. */
1517 	if (undecorated_smoothed_pwdb < 15)
1518 		curr_bt_rssi_state |=  BT_RSSI_STATE_BG_EDCA_LOW;
1519 	else
1520 		curr_bt_rssi_state &= (~BT_RSSI_STATE_BG_EDCA_LOW);
1521 
1522 	if (curr_bt_rssi_state != rtlpcipriv->bt_coexist.bt_rssi_state) {
1523 		rtlpcipriv->bt_coexist.bt_rssi_state = curr_bt_rssi_state;
1524 		return true;
1525 	} else {
1526 		return false;
1527 	}
1528 }
1529 EXPORT_SYMBOL(rtl92c_bt_rssi_state_change);
1530 
rtl92c_bt_state_change(struct ieee80211_hw * hw)1531 static bool rtl92c_bt_state_change(struct ieee80211_hw *hw)
1532 {
1533 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1534 	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1535 
1536 	u32 polling, ratio_tx, ratio_pri;
1537 	u32 bt_tx, bt_pri;
1538 	u8 bt_state;
1539 	u8 cur_service_type;
1540 
1541 	if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
1542 		return false;
1543 
1544 	bt_state = rtl_read_byte(rtlpriv, 0x4fd);
1545 	bt_tx = rtl_read_dword(rtlpriv, 0x488);
1546 	bt_tx = bt_tx & 0x00ffffff;
1547 	bt_pri = rtl_read_dword(rtlpriv, 0x48c);
1548 	bt_pri = bt_pri & 0x00ffffff;
1549 	polling = rtl_read_dword(rtlpriv, 0x490);
1550 
1551 	if (bt_tx == 0xffffffff && bt_pri == 0xffffffff &&
1552 	    polling == 0xffffffff && bt_state == 0xff)
1553 		return false;
1554 
1555 	bt_state &= BIT_OFFSET_LEN_MASK_32(0, 1);
1556 	if (bt_state != rtlpcipriv->bt_coexist.bt_cur_state) {
1557 		rtlpcipriv->bt_coexist.bt_cur_state = bt_state;
1558 
1559 		if (rtlpcipriv->bt_coexist.reg_bt_sco == 3) {
1560 			rtlpcipriv->bt_coexist.bt_service = BT_IDLE;
1561 
1562 			bt_state = bt_state |
1563 			  ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
1564 			  0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
1565 			  BIT_OFFSET_LEN_MASK_32(2, 1);
1566 			rtl_write_byte(rtlpriv, 0x4fd, bt_state);
1567 		}
1568 		return true;
1569 	}
1570 
1571 	ratio_tx = bt_tx * 1000 / polling;
1572 	ratio_pri = bt_pri * 1000 / polling;
1573 	rtlpcipriv->bt_coexist.ratio_tx = ratio_tx;
1574 	rtlpcipriv->bt_coexist.ratio_pri = ratio_pri;
1575 
1576 	if (bt_state && rtlpcipriv->bt_coexist.reg_bt_sco == 3) {
1577 
1578 		if ((ratio_tx < 30)  && (ratio_pri < 30))
1579 			cur_service_type = BT_IDLE;
1580 		else if ((ratio_pri > 110) && (ratio_pri < 250))
1581 			cur_service_type = BT_SCO;
1582 		else if ((ratio_tx >= 200) && (ratio_pri >= 200))
1583 			cur_service_type = BT_BUSY;
1584 		else if ((ratio_tx >= 350) && (ratio_tx < 500))
1585 			cur_service_type = BT_OTHERBUSY;
1586 		else if (ratio_tx >= 500)
1587 			cur_service_type = BT_PAN;
1588 		else
1589 			cur_service_type = BT_OTHER_ACTION;
1590 
1591 		if (cur_service_type != rtlpcipriv->bt_coexist.bt_service) {
1592 			rtlpcipriv->bt_coexist.bt_service = cur_service_type;
1593 			bt_state = bt_state |
1594 			   ((rtlpcipriv->bt_coexist.bt_ant_isolation == 1) ?
1595 			   0 : BIT_OFFSET_LEN_MASK_32(1, 1)) |
1596 			   ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) ?
1597 			   0 : BIT_OFFSET_LEN_MASK_32(2, 1));
1598 
1599 			/* Add interrupt migration when bt is not ini
1600 			 * idle state (no traffic). */
1601 			if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
1602 				rtl_write_word(rtlpriv, 0x504, 0x0ccc);
1603 				rtl_write_byte(rtlpriv, 0x506, 0x54);
1604 				rtl_write_byte(rtlpriv, 0x507, 0x54);
1605 			} else {
1606 				rtl_write_byte(rtlpriv, 0x506, 0x00);
1607 				rtl_write_byte(rtlpriv, 0x507, 0x00);
1608 			}
1609 
1610 			rtl_write_byte(rtlpriv, 0x4fd, bt_state);
1611 			return true;
1612 		}
1613 	}
1614 
1615 	return false;
1616 
1617 }
1618 
rtl92c_bt_wifi_connect_change(struct ieee80211_hw * hw)1619 static bool rtl92c_bt_wifi_connect_change(struct ieee80211_hw *hw)
1620 {
1621 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1622 	static bool media_connect;
1623 
1624 	if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
1625 		media_connect = false;
1626 	} else {
1627 		if (!media_connect) {
1628 			media_connect = true;
1629 			return true;
1630 		}
1631 		media_connect = true;
1632 	}
1633 
1634 	return false;
1635 }
1636 
rtl92c_bt_set_normal(struct ieee80211_hw * hw)1637 static void rtl92c_bt_set_normal(struct ieee80211_hw *hw)
1638 {
1639 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1640 	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1641 
1642 
1643 	if (rtlpcipriv->bt_coexist.bt_service == BT_OTHERBUSY) {
1644 		rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72b;
1645 		rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72b;
1646 	} else if (rtlpcipriv->bt_coexist.bt_service == BT_BUSY) {
1647 		rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82f;
1648 		rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82f;
1649 	} else if (rtlpcipriv->bt_coexist.bt_service == BT_SCO) {
1650 		if (rtlpcipriv->bt_coexist.ratio_tx > 160) {
1651 			rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea72f;
1652 			rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea72f;
1653 		} else {
1654 			rtlpcipriv->bt_coexist.bt_edca_ul = 0x5ea32b;
1655 			rtlpcipriv->bt_coexist.bt_edca_dl = 0x5ea42b;
1656 		}
1657 	} else {
1658 		rtlpcipriv->bt_coexist.bt_edca_ul = 0;
1659 		rtlpcipriv->bt_coexist.bt_edca_dl = 0;
1660 	}
1661 
1662 	if ((rtlpcipriv->bt_coexist.bt_service != BT_IDLE) &&
1663 	     (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
1664 	     (rtlpriv->mac80211.mode == (WIRELESS_MODE_G | WIRELESS_MODE_B))) &&
1665 	     (rtlpcipriv->bt_coexist.bt_rssi_state &
1666 	     BT_RSSI_STATE_BG_EDCA_LOW)) {
1667 		rtlpcipriv->bt_coexist.bt_edca_ul = 0x5eb82b;
1668 		rtlpcipriv->bt_coexist.bt_edca_dl = 0x5eb82b;
1669 	}
1670 }
1671 
rtl92c_bt_ant_isolation(struct ieee80211_hw * hw)1672 static void rtl92c_bt_ant_isolation(struct ieee80211_hw *hw)
1673 {
1674 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1675 	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1676 
1677 
1678 	/* Only enable HW BT coexist when BT in "Busy" state. */
1679 	if (rtlpriv->mac80211.vendor == PEER_CISCO &&
1680 	    rtlpcipriv->bt_coexist.bt_service == BT_OTHER_ACTION) {
1681 		rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1682 	} else {
1683 		if ((rtlpcipriv->bt_coexist.bt_service == BT_BUSY) &&
1684 		    (rtlpcipriv->bt_coexist.bt_rssi_state &
1685 		     BT_RSSI_STATE_NORMAL_POWER)) {
1686 			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1687 		} else if ((rtlpcipriv->bt_coexist.bt_service ==
1688 			    BT_OTHER_ACTION) && (rtlpriv->mac80211.mode <
1689 			    WIRELESS_MODE_N_24G) &&
1690 			    (rtlpcipriv->bt_coexist.bt_rssi_state &
1691 			    BT_RSSI_STATE_SPECIAL_LOW)) {
1692 			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0xa0);
1693 		} else if (rtlpcipriv->bt_coexist.bt_service == BT_PAN) {
1694 			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00);
1695 		} else {
1696 			rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00);
1697 		}
1698 	}
1699 
1700 	if (rtlpcipriv->bt_coexist.bt_service == BT_PAN)
1701 		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x10100);
1702 	else
1703 		rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x0);
1704 
1705 	if (rtlpcipriv->bt_coexist.bt_rssi_state &
1706 	    BT_RSSI_STATE_NORMAL_POWER) {
1707 		rtl92c_bt_set_normal(hw);
1708 	} else {
1709 		rtlpcipriv->bt_coexist.bt_edca_ul = 0;
1710 		rtlpcipriv->bt_coexist.bt_edca_dl = 0;
1711 	}
1712 
1713 	if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
1714 		rtlpriv->cfg->ops->set_rfreg(hw,
1715 				 RF90_PATH_A,
1716 				 0x1e,
1717 				 0xf0, 0xf);
1718 	} else {
1719 		rtlpriv->cfg->ops->set_rfreg(hw,
1720 		     RF90_PATH_A, 0x1e, 0xf0,
1721 		     rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
1722 	}
1723 
1724 	if (!rtlpriv->dm.dynamic_txpower_enable) {
1725 		if (rtlpcipriv->bt_coexist.bt_service != BT_IDLE) {
1726 			if (rtlpcipriv->bt_coexist.bt_rssi_state &
1727 				BT_RSSI_STATE_TXPOWER_LOW) {
1728 				rtlpriv->dm.dynamic_txhighpower_lvl =
1729 							TXHIGHPWRLEVEL_BT2;
1730 			} else {
1731 				rtlpriv->dm.dynamic_txhighpower_lvl =
1732 					TXHIGHPWRLEVEL_BT1;
1733 			}
1734 		} else {
1735 			rtlpriv->dm.dynamic_txhighpower_lvl =
1736 				TXHIGHPWRLEVEL_NORMAL;
1737 		}
1738 		rtl92c_phy_set_txpower_level(hw,
1739 			rtlpriv->phy.current_channel);
1740 	}
1741 }
1742 
rtl92c_check_bt_change(struct ieee80211_hw * hw)1743 static void rtl92c_check_bt_change(struct ieee80211_hw *hw)
1744 {
1745 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1746 	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1747 
1748 	if (rtlpcipriv->bt_coexist.bt_cur_state) {
1749 		if (rtlpcipriv->bt_coexist.bt_ant_isolation)
1750 			rtl92c_bt_ant_isolation(hw);
1751 	} else {
1752 		rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG, 0x00);
1753 		rtlpriv->cfg->ops->set_rfreg(hw, RF90_PATH_A, 0x1e, 0xf0,
1754 				rtlpcipriv->bt_coexist.bt_rfreg_origin_1e);
1755 
1756 		rtlpcipriv->bt_coexist.bt_edca_ul = 0;
1757 		rtlpcipriv->bt_coexist.bt_edca_dl = 0;
1758 	}
1759 }
1760 
rtl92c_dm_bt_coexist(struct ieee80211_hw * hw)1761 void rtl92c_dm_bt_coexist(struct ieee80211_hw *hw)
1762 {
1763 	struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
1764 
1765 	bool wifi_connect_change;
1766 	bool bt_state_change;
1767 	bool rssi_state_change;
1768 
1769 	if ((rtlpcipriv->bt_coexist.bt_coexistence) &&
1770 	     (rtlpcipriv->bt_coexist.bt_coexist_type == BT_CSR_BC4)) {
1771 
1772 		wifi_connect_change = rtl92c_bt_wifi_connect_change(hw);
1773 		bt_state_change = rtl92c_bt_state_change(hw);
1774 		rssi_state_change = rtl92c_bt_rssi_state_change(hw);
1775 
1776 		if (wifi_connect_change || bt_state_change || rssi_state_change)
1777 			rtl92c_check_bt_change(hw);
1778 	}
1779 }
1780 EXPORT_SYMBOL(rtl92c_dm_bt_coexist);
1781