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