xref: /linux/drivers/net/wireless/realtek/rtlwifi/rtl8723be/phy.c (revision 1f2367a39f17bd553a75e179a747f9b257bc9478)
1 // SPDX-License-Identifier: GPL-2.0
2 /* Copyright(c) 2009-2014  Realtek Corporation.*/
3 
4 #include "../wifi.h"
5 #include "../pci.h"
6 #include "../ps.h"
7 #include "reg.h"
8 #include "def.h"
9 #include "phy.h"
10 #include "../rtl8723com/phy_common.h"
11 #include "rf.h"
12 #include "dm.h"
13 #include "../rtl8723com/dm_common.h"
14 #include "table.h"
15 #include "trx.h"
16 #include <linux/kernel.h>
17 
18 static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
19 static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
20 static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
21 						     u8 configtype);
22 static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
23 						       u8 configtype);
24 static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
25 						u8 channel, u8 *stage,
26 						u8 *step, u32 *delay);
27 
28 static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw);
29 static void rtl8723be_phy_set_io(struct ieee80211_hw *hw);
30 
31 u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
32 			       u32 regaddr, u32 bitmask)
33 {
34 	struct rtl_priv *rtlpriv = rtl_priv(hw);
35 	u32 original_value, readback_value, bitshift;
36 	unsigned long flags;
37 
38 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
39 		 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
40 		  regaddr, rfpath, bitmask);
41 
42 	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
43 
44 	original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
45 	bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
46 	readback_value = (original_value & bitmask) >> bitshift;
47 
48 	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
49 
50 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
51 		 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
52 		 regaddr, rfpath, bitmask, original_value);
53 
54 	return readback_value;
55 }
56 
57 void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
58 			      u32 regaddr, u32 bitmask, u32 data)
59 {
60 	struct rtl_priv *rtlpriv = rtl_priv(hw);
61 	u32 original_value, bitshift;
62 	unsigned long flags;
63 
64 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
65 		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
66 		  regaddr, bitmask, data, path);
67 
68 	spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
69 
70 	if (bitmask != RFREG_OFFSET_MASK) {
71 			original_value = rtl8723_phy_rf_serial_read(hw, path,
72 								    regaddr);
73 			bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
74 			data = ((original_value & (~bitmask)) |
75 				(data << bitshift));
76 		}
77 
78 	rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
79 
80 	spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
81 
82 	RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
83 		 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
84 		  regaddr, bitmask, data, path);
85 
86 }
87 
88 bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
89 {
90 	struct rtl_priv *rtlpriv = rtl_priv(hw);
91 	bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
92 
93 	rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
94 	return rtstatus;
95 }
96 
97 bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
98 {
99 	bool rtstatus = true;
100 	struct rtl_priv *rtlpriv = rtl_priv(hw);
101 	u16 regval;
102 	u8 b_reg_hwparafile = 1;
103 	u32 tmp;
104 	u8 crystalcap = rtlpriv->efuse.crystalcap;
105 	rtl8723_phy_init_bb_rf_reg_def(hw);
106 	regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
107 	rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
108 		       regval | BIT(13) | BIT(0) | BIT(1));
109 
110 	rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
111 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
112 		       FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
113 		       FEN_BB_GLB_RSTN | FEN_BBRSTB);
114 	tmp = rtl_read_dword(rtlpriv, 0x4c);
115 	rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
116 
117 	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
118 
119 	if (b_reg_hwparafile == 1)
120 		rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
121 
122 	crystalcap = crystalcap & 0x3F;
123 	rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
124 		      (crystalcap | crystalcap << 6));
125 
126 	return rtstatus;
127 }
128 
129 bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
130 {
131 	return rtl8723be_phy_rf6052_config(hw);
132 }
133 
134 static bool _rtl8723be_check_positive(struct ieee80211_hw *hw,
135 				      const u32 condition1,
136 				      const u32 condition2)
137 {
138 	struct rtl_priv *rtlpriv = rtl_priv(hw);
139 	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
140 	u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK)
141 					>> CHIP_VER_RTL_SHIFT);
142 	u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0));
143 
144 	u8  board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */
145 			 ((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA  */
146 			 ((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */
147 			 ((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA  */
148 			 ((rtlhal->board_type & BIT(2)) >> 2) << 4;  /* _BT   */
149 
150 	u32 cond1 = condition1, cond2 = condition2;
151 	u32 driver1 = cut_ver << 24 |	/* CUT ver */
152 		      0 << 20 |			/* interface 2/2 */
153 		      0x04 << 16 |		/* platform */
154 		      rtlhal->package_type << 12 |
155 		      intf << 8 |			/* interface 1/2 */
156 		      board_type;
157 
158 	u32 driver2 = rtlhal->type_glna <<  0 |
159 		      rtlhal->type_gpa  <<  8 |
160 		      rtlhal->type_alna << 16 |
161 		      rtlhal->type_apa  << 24;
162 
163 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
164 		 "===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n",
165 		 cond1, cond2);
166 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
167 		 "===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n",
168 		 driver1, driver2);
169 
170 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
171 		 "	(Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf);
172 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
173 		 "	(Board, Package) = (0x%X, 0x%X)\n",
174 		 rtlhal->board_type, rtlhal->package_type);
175 
176 	/*============== Value Defined Check ===============*/
177 	/*QFN Type [15:12] and Cut Version [27:24] need to do value check*/
178 
179 	if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) !=
180 		(driver1 & 0x0000F000)))
181 		return false;
182 	if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) !=
183 		(driver1 & 0x0F000000)))
184 		return false;
185 
186 	/*=============== Bit Defined Check ================*/
187 	/* We don't care [31:28] */
188 
189 	cond1   &= 0x00FF0FFF;
190 	driver1 &= 0x00FF0FFF;
191 
192 	if ((cond1 & driver1) == cond1) {
193 		u32 mask = 0;
194 
195 		if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/
196 			return true;
197 
198 		if ((cond1 & BIT(0)) != 0) /*GLNA*/
199 			mask |= 0x000000FF;
200 		if ((cond1 & BIT(1)) != 0) /*GPA*/
201 			mask |= 0x0000FF00;
202 		if ((cond1 & BIT(2)) != 0) /*ALNA*/
203 			mask |= 0x00FF0000;
204 		if ((cond1 & BIT(3)) != 0) /*APA*/
205 			mask |= 0xFF000000;
206 
207 		/* BoardType of each RF path is matched*/
208 		if ((cond2 & mask) == (driver2 & mask))
209 			return true;
210 		else
211 			return false;
212 	}
213 	return false;
214 }
215 
216 static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
217 				     u32 data, enum radio_path rfpath,
218 				     u32 regaddr)
219 {
220 	if (addr == 0xfe || addr == 0xffe) {
221 		/* In order not to disturb BT music
222 		 *	when wifi init.(1ant NIC only)
223 		 */
224 		mdelay(50);
225 	} else {
226 		rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
227 		udelay(1);
228 	}
229 }
230 static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
231 					 u32 addr, u32 data)
232 {
233 	u32 content = 0x1000; /*RF Content: radio_a_txt*/
234 	u32 maskforphyset = (u32)(content & 0xE000);
235 
236 	_rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
237 				 addr | maskforphyset);
238 
239 }
240 
241 static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
242 {
243 	struct rtl_priv *rtlpriv = rtl_priv(hw);
244 	struct rtl_phy *rtlphy = &rtlpriv->phy;
245 
246 	u8 band, path, txnum, section;
247 
248 	for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
249 		for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
250 			for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
251 				for (section = 0;
252 				     section < TX_PWR_BY_RATE_NUM_SECTION;
253 				     ++section)
254 					rtlphy->tx_power_by_rate_offset
255 					  [band][path][txnum][section] = 0;
256 }
257 
258 static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
259 				     u32 addr, u32 data)
260 {
261 	if (addr == 0xfe) {
262 		mdelay(50);
263 	} else if (addr == 0xfd) {
264 		mdelay(5);
265 	} else if (addr == 0xfc) {
266 		mdelay(1);
267 	} else if (addr == 0xfb) {
268 		udelay(50);
269 	} else if (addr == 0xfa) {
270 		udelay(5);
271 	} else if (addr == 0xf9) {
272 		udelay(1);
273 	} else {
274 		rtl_set_bbreg(hw, addr, MASKDWORD, data);
275 		udelay(1);
276 	}
277 }
278 
279 static void _rtl8723be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
280 						    u8 band,
281 						    u8 path, u8 rate_section,
282 						    u8 txnum, u8 value)
283 {
284 	struct rtl_priv *rtlpriv = rtl_priv(hw);
285 	struct rtl_phy *rtlphy = &rtlpriv->phy;
286 
287 	if (path > RF90_PATH_D) {
288 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
289 			 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
290 			  path);
291 		return;
292 	}
293 
294 	if (band == BAND_ON_2_4G) {
295 		switch (rate_section) {
296 		case CCK:
297 			rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
298 			break;
299 		case OFDM:
300 			rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
301 			break;
302 		case HT_MCS0_MCS7:
303 			rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
304 			break;
305 		case HT_MCS8_MCS15:
306 			rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
307 			break;
308 		default:
309 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
310 				 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
311 				 rate_section, path, txnum);
312 			break;
313 		}
314 	} else {
315 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
316 			 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
317 			 band);
318 	}
319 
320 }
321 
322 static u8 _rtl8723be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
323 						  u8 band, u8 path, u8 txnum,
324 						  u8 rate_section)
325 {
326 	struct rtl_priv *rtlpriv = rtl_priv(hw);
327 	struct rtl_phy *rtlphy = &rtlpriv->phy;
328 	u8 value = 0;
329 	if (path > RF90_PATH_D) {
330 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
331 			 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
332 			  path);
333 		return 0;
334 	}
335 
336 	if (band == BAND_ON_2_4G) {
337 		switch (rate_section) {
338 		case CCK:
339 			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
340 			break;
341 		case OFDM:
342 			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
343 			break;
344 		case HT_MCS0_MCS7:
345 			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
346 			break;
347 		case HT_MCS8_MCS15:
348 			value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
349 			break;
350 		default:
351 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
352 				 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
353 				 rate_section, path, txnum);
354 			break;
355 		}
356 	} else {
357 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
358 			 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
359 			 band);
360 	}
361 
362 	return value;
363 }
364 
365 static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
366 {
367 	struct rtl_priv *rtlpriv = rtl_priv(hw);
368 	struct rtl_phy *rtlphy = &rtlpriv->phy;
369 	u16 rawvalue = 0;
370 	u8 base = 0, path = 0;
371 
372 	for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
373 		if (path == RF90_PATH_A) {
374 			rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
375 				[BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
376 			base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
377 			_rtl8723be_phy_set_txpower_by_rate_base(hw,
378 				BAND_ON_2_4G, path, CCK, RF_1TX, base);
379 		} else if (path == RF90_PATH_B) {
380 			rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
381 				[BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
382 			base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
383 			_rtl8723be_phy_set_txpower_by_rate_base(hw,
384 								BAND_ON_2_4G,
385 								path, CCK,
386 								RF_1TX, base);
387 		}
388 		rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
389 				[BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
390 		base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
391 		_rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
392 							path, OFDM, RF_1TX,
393 							base);
394 
395 		rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
396 				[BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
397 		base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
398 		_rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
399 							path, HT_MCS0_MCS7,
400 							RF_1TX, base);
401 
402 		rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
403 				[BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
404 		base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
405 		_rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
406 							path, HT_MCS8_MCS15,
407 							RF_2TX, base);
408 	}
409 }
410 
411 static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
412 						u8 end, u8 base_val)
413 {
414 	s8 i = 0;
415 	u8 temp_value = 0;
416 	u32 temp_data = 0;
417 
418 	for (i = 3; i >= 0; --i) {
419 		if (i >= start && i <= end) {
420 			/* Get the exact value */
421 			temp_value = (u8)(*data >> (i * 8)) & 0xF;
422 			temp_value += ((u8)((*data >> (i*8 + 4)) & 0xF)) * 10;
423 
424 			/* Change the value to a relative value */
425 			temp_value = (temp_value > base_val) ?
426 				     temp_value - base_val :
427 				     base_val - temp_value;
428 		} else {
429 			temp_value = (u8)(*data >> (i * 8)) & 0xFF;
430 		}
431 		temp_data <<= 8;
432 		temp_data |= temp_value;
433 	}
434 	*data = temp_data;
435 }
436 
437 static void _rtl8723be_phy_convert_txpower_dbm_to_relative_value(
438 							struct ieee80211_hw *hw)
439 {
440 	struct rtl_priv *rtlpriv = rtl_priv(hw);
441 	struct rtl_phy *rtlphy = &rtlpriv->phy;
442 	u8 base = 0, rfpath = RF90_PATH_A;
443 
444 	base = _rtl8723be_phy_get_txpower_by_rate_base(hw,
445 			BAND_ON_2_4G, rfpath, RF_1TX, CCK);
446 	_phy_convert_txpower_dbm_to_relative_value(
447 	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2],
448 	    1, 1, base);
449 	_phy_convert_txpower_dbm_to_relative_value(
450 	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3],
451 	    1, 3, base);
452 
453 	base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath,
454 						       RF_1TX, OFDM);
455 	_phy_convert_txpower_dbm_to_relative_value(
456 	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0],
457 	    0, 3, base);
458 	_phy_convert_txpower_dbm_to_relative_value(
459 	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1],
460 	    0, 3, base);
461 
462 	base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
463 						rfpath, RF_1TX, HT_MCS0_MCS7);
464 	_phy_convert_txpower_dbm_to_relative_value(
465 	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4],
466 	    0, 3, base);
467 	_phy_convert_txpower_dbm_to_relative_value(
468 	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][5],
469 	    0, 3, base);
470 
471 	base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
472 						       rfpath, RF_2TX,
473 						       HT_MCS8_MCS15);
474 	_phy_convert_txpower_dbm_to_relative_value(
475 	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6],
476 	    0, 3, base);
477 
478 	_phy_convert_txpower_dbm_to_relative_value(
479 	    &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][7],
480 	    0, 3, base);
481 
482 	RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
483 	    "<===_rtl8723be_phy_convert_txpower_dbm_to_relative_value()\n");
484 }
485 
486 static void phy_txpower_by_rate_config(struct ieee80211_hw *hw)
487 {
488 	_rtl8723be_phy_store_txpower_by_rate_base(hw);
489 	_rtl8723be_phy_convert_txpower_dbm_to_relative_value(hw);
490 }
491 
492 static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
493 {
494 	struct rtl_priv *rtlpriv = rtl_priv(hw);
495 	struct rtl_phy *rtlphy = &rtlpriv->phy;
496 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
497 	bool rtstatus;
498 
499 	/* switch ant to BT */
500 	if (rtlpriv->rtlhal.interface == INTF_USB) {
501 		rtl_write_dword(rtlpriv, 0x948, 0x0);
502 	} else {
503 		if (rtlpriv->btcoexist.btc_info.single_ant_path == 0)
504 			rtl_write_dword(rtlpriv, 0x948, 0x280);
505 		else
506 			rtl_write_dword(rtlpriv, 0x948, 0x0);
507 	}
508 
509 	rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
510 						BASEBAND_CONFIG_PHY_REG);
511 	if (!rtstatus) {
512 		pr_err("Write BB Reg Fail!!\n");
513 		return false;
514 	}
515 	_rtl8723be_phy_init_tx_power_by_rate(hw);
516 	if (!rtlefuse->autoload_failflag) {
517 		rtlphy->pwrgroup_cnt = 0;
518 		rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
519 						BASEBAND_CONFIG_PHY_REG);
520 	}
521 	phy_txpower_by_rate_config(hw);
522 	if (!rtstatus) {
523 		pr_err("BB_PG Reg Fail!!\n");
524 		return false;
525 	}
526 	rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
527 						BASEBAND_CONFIG_AGC_TAB);
528 	if (!rtstatus) {
529 		pr_err("AGC Table Fail\n");
530 		return false;
531 	}
532 	rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
533 						      RFPGA0_XA_HSSIPARAMETER2,
534 						      0x200));
535 	return true;
536 }
537 
538 static bool rtl8723be_phy_config_with_headerfile(struct ieee80211_hw *hw,
539 						 u32 *array_table,
540 						 u16 arraylen,
541 		void (*set_reg)(struct ieee80211_hw *hw, u32 regaddr, u32 data))
542 {
543 	#define COND_ELSE  2
544 	#define COND_ENDIF 3
545 
546 	int i = 0;
547 	u8 cond;
548 	bool matched = true, skipped = false;
549 
550 	while ((i + 1) < arraylen) {
551 		u32 v1 = array_table[i];
552 		u32 v2 = array_table[i + 1];
553 
554 		if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/
555 			if (v1 & BIT(31)) {/* positive condition*/
556 				cond  = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
557 				if (cond == COND_ENDIF) { /*end*/
558 					matched = true;
559 					skipped = false;
560 				} else if (cond == COND_ELSE) { /*else*/
561 					matched = skipped ? false : true;
562 				} else {/*if , else if*/
563 					if (skipped) {
564 						matched = false;
565 					} else {
566 						if (_rtl8723be_check_positive(
567 								hw, v1, v2)) {
568 							matched = true;
569 							skipped = true;
570 						} else {
571 							matched = false;
572 							skipped = false;
573 						}
574 					}
575 				}
576 			} else if (v1 & BIT(30)) { /*negative condition*/
577 			/*do nothing*/
578 			}
579 		} else {
580 			if (matched)
581 				set_reg(hw, v1, v2);
582 		}
583 		i = i + 2;
584 	}
585 
586 	return true;
587 }
588 
589 static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
590 {
591 	struct rtl_priv *rtlpriv = rtl_priv(hw);
592 
593 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
594 
595 	return rtl8723be_phy_config_with_headerfile(hw,
596 			RTL8723BEMAC_1T_ARRAY, RTL8723BEMAC_1T_ARRAYLEN,
597 			rtl_write_byte_with_val32);
598 }
599 
600 static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
601 						     u8 configtype)
602 {
603 
604 	if (configtype == BASEBAND_CONFIG_PHY_REG)
605 		return rtl8723be_phy_config_with_headerfile(hw,
606 				RTL8723BEPHY_REG_1TARRAY,
607 				RTL8723BEPHY_REG_1TARRAYLEN,
608 				_rtl8723be_config_bb_reg);
609 	else if (configtype == BASEBAND_CONFIG_AGC_TAB)
610 		return rtl8723be_phy_config_with_headerfile(hw,
611 				RTL8723BEAGCTAB_1TARRAY,
612 				RTL8723BEAGCTAB_1TARRAYLEN,
613 				rtl_set_bbreg_with_dwmask);
614 
615 	return false;
616 }
617 
618 static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
619 {
620 	u8 index = 0;
621 
622 	switch (regaddr) {
623 	case RTXAGC_A_RATE18_06:
624 		index = 0;
625 	break;
626 	case RTXAGC_A_RATE54_24:
627 		index = 1;
628 	break;
629 	case RTXAGC_A_CCK1_MCS32:
630 		index = 2;
631 	break;
632 	case RTXAGC_B_CCK11_A_CCK2_11:
633 		index = 3;
634 	break;
635 	case RTXAGC_A_MCS03_MCS00:
636 		index = 4;
637 	break;
638 	case RTXAGC_A_MCS07_MCS04:
639 		index = 5;
640 	break;
641 	case RTXAGC_A_MCS11_MCS08:
642 		index = 6;
643 	break;
644 	case RTXAGC_A_MCS15_MCS12:
645 		index = 7;
646 	break;
647 	case RTXAGC_B_RATE18_06:
648 		index = 0;
649 	break;
650 	case RTXAGC_B_RATE54_24:
651 		index = 1;
652 	break;
653 	case RTXAGC_B_CCK1_55_MCS32:
654 		index = 2;
655 	break;
656 	case RTXAGC_B_MCS03_MCS00:
657 		index = 4;
658 	break;
659 	case RTXAGC_B_MCS07_MCS04:
660 		index = 5;
661 	break;
662 	case RTXAGC_B_MCS11_MCS08:
663 		index = 6;
664 	break;
665 	case RTXAGC_B_MCS15_MCS12:
666 		index = 7;
667 	break;
668 	default:
669 		regaddr &= 0xFFF;
670 		if (regaddr >= 0xC20 && regaddr <= 0xC4C)
671 			index = (u8)((regaddr - 0xC20) / 4);
672 		else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
673 			index = (u8)((regaddr - 0xE20) / 4);
674 		break;
675 	}
676 	return index;
677 }
678 
679 static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
680 					      u32 band, u32 rfpath,
681 					      u32 txnum, u32 regaddr,
682 					      u32 bitmask, u32 data)
683 {
684 	struct rtl_priv *rtlpriv = rtl_priv(hw);
685 	struct rtl_phy *rtlphy = &rtlpriv->phy;
686 	u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
687 
688 	if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
689 		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
690 		return;
691 	}
692 	if (rfpath > MAX_RF_PATH - 1) {
693 		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
694 			 "Invalid RfPath %d\n", rfpath);
695 		return;
696 	}
697 	if (txnum > MAX_RF_PATH - 1) {
698 		RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
699 		return;
700 	}
701 
702 	rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
703 									data;
704 
705 }
706 
707 static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
708 						       u8 configtype)
709 {
710 	struct rtl_priv *rtlpriv = rtl_priv(hw);
711 	int i;
712 	u32 *phy_regarray_table_pg;
713 	u16 phy_regarray_pg_len;
714 	u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
715 
716 	phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
717 	phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
718 
719 	if (configtype == BASEBAND_CONFIG_PHY_REG) {
720 		for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
721 			v1 = phy_regarray_table_pg[i];
722 			v2 = phy_regarray_table_pg[i+1];
723 			v3 = phy_regarray_table_pg[i+2];
724 			v4 = phy_regarray_table_pg[i+3];
725 			v5 = phy_regarray_table_pg[i+4];
726 			v6 = phy_regarray_table_pg[i+5];
727 
728 			if (v1 < 0xcdcdcdcd) {
729 				if (phy_regarray_table_pg[i] == 0xfe ||
730 				    phy_regarray_table_pg[i] == 0xffe)
731 					mdelay(50);
732 				else
733 					_rtl8723be_store_tx_power_by_rate(hw,
734 							v1, v2, v3, v4, v5, v6);
735 				continue;
736 			}
737 		}
738 	} else {
739 		RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
740 			 "configtype != BaseBand_Config_PHY_REG\n");
741 	}
742 	return true;
743 }
744 
745 bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
746 					     enum radio_path rfpath)
747 {
748 	struct rtl_priv *rtlpriv = rtl_priv(hw);
749 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
750 	bool ret = true;
751 
752 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
753 	switch (rfpath) {
754 	case RF90_PATH_A:
755 		ret =  rtl8723be_phy_config_with_headerfile(hw,
756 				RTL8723BE_RADIOA_1TARRAY,
757 				RTL8723BE_RADIOA_1TARRAYLEN,
758 				_rtl8723be_config_rf_radio_a);
759 
760 		if (rtlhal->oem_id == RT_CID_819X_HP)
761 			_rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
762 		break;
763 	case RF90_PATH_B:
764 	case RF90_PATH_C:
765 		break;
766 	case RF90_PATH_D:
767 		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
768 			 "switch case %#x not processed\n", rfpath);
769 		break;
770 	}
771 	return ret;
772 }
773 
774 void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
775 {
776 	struct rtl_priv *rtlpriv = rtl_priv(hw);
777 	struct rtl_phy *rtlphy = &rtlpriv->phy;
778 
779 	rtlphy->default_initialgain[0] =
780 	    (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
781 	rtlphy->default_initialgain[1] =
782 	    (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
783 	rtlphy->default_initialgain[2] =
784 	    (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
785 	rtlphy->default_initialgain[3] =
786 	    (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
787 
788 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
789 		 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
790 		 rtlphy->default_initialgain[0],
791 		 rtlphy->default_initialgain[1],
792 		 rtlphy->default_initialgain[2],
793 		 rtlphy->default_initialgain[3]);
794 
795 	rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
796 					       MASKBYTE0);
797 	rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
798 					      MASKDWORD);
799 
800 	RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
801 		 "Default framesync (0x%x) = 0x%x\n",
802 		  ROFDM0_RXDETECTOR3, rtlphy->framesync);
803 }
804 
805 static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
806 							  u8 rate)
807 {
808 	u8 rate_section = 0;
809 
810 	switch (rate) {
811 	case DESC92C_RATE1M:
812 		rate_section = 2;
813 		break;
814 
815 	case DESC92C_RATE2M:
816 	case DESC92C_RATE5_5M:
817 		if (path == RF90_PATH_A)
818 			rate_section = 3;
819 		else if (path == RF90_PATH_B)
820 			rate_section = 2;
821 		break;
822 
823 	case DESC92C_RATE11M:
824 		rate_section = 3;
825 		break;
826 
827 	case DESC92C_RATE6M:
828 	case DESC92C_RATE9M:
829 	case DESC92C_RATE12M:
830 	case DESC92C_RATE18M:
831 		rate_section = 0;
832 		break;
833 
834 	case DESC92C_RATE24M:
835 	case DESC92C_RATE36M:
836 	case DESC92C_RATE48M:
837 	case DESC92C_RATE54M:
838 		rate_section = 1;
839 		break;
840 
841 	case DESC92C_RATEMCS0:
842 	case DESC92C_RATEMCS1:
843 	case DESC92C_RATEMCS2:
844 	case DESC92C_RATEMCS3:
845 		rate_section = 4;
846 		break;
847 
848 	case DESC92C_RATEMCS4:
849 	case DESC92C_RATEMCS5:
850 	case DESC92C_RATEMCS6:
851 	case DESC92C_RATEMCS7:
852 		rate_section = 5;
853 		break;
854 
855 	case DESC92C_RATEMCS8:
856 	case DESC92C_RATEMCS9:
857 	case DESC92C_RATEMCS10:
858 	case DESC92C_RATEMCS11:
859 		rate_section = 6;
860 		break;
861 
862 	case DESC92C_RATEMCS12:
863 	case DESC92C_RATEMCS13:
864 	case DESC92C_RATEMCS14:
865 	case DESC92C_RATEMCS15:
866 		rate_section = 7;
867 		break;
868 
869 	default:
870 		WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n");
871 		break;
872 	}
873 
874 	return rate_section;
875 }
876 
877 static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
878 					 enum band_type band,
879 					 enum radio_path rfpath, u8 rate)
880 {
881 	struct rtl_priv *rtlpriv = rtl_priv(hw);
882 	struct rtl_phy *rtlphy = &rtlpriv->phy;
883 	u8 shift = 0, rate_section, tx_num;
884 	s8 tx_pwr_diff = 0;
885 
886 	rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
887 								       rate);
888 	tx_num = RF_TX_NUM_NONIMPLEMENT;
889 
890 	if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
891 		if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
892 			tx_num = RF_2TX;
893 		else
894 			tx_num = RF_1TX;
895 	}
896 
897 	switch (rate) {
898 	case DESC92C_RATE6M:
899 	case DESC92C_RATE24M:
900 	case DESC92C_RATEMCS0:
901 	case DESC92C_RATEMCS4:
902 	case DESC92C_RATEMCS8:
903 	case DESC92C_RATEMCS12:
904 		shift = 0;
905 		break;
906 	case DESC92C_RATE1M:
907 	case DESC92C_RATE2M:
908 	case DESC92C_RATE9M:
909 	case DESC92C_RATE36M:
910 	case DESC92C_RATEMCS1:
911 	case DESC92C_RATEMCS5:
912 	case DESC92C_RATEMCS9:
913 	case DESC92C_RATEMCS13:
914 		shift = 8;
915 		break;
916 	case DESC92C_RATE5_5M:
917 	case DESC92C_RATE12M:
918 	case DESC92C_RATE48M:
919 	case DESC92C_RATEMCS2:
920 	case DESC92C_RATEMCS6:
921 	case DESC92C_RATEMCS10:
922 	case DESC92C_RATEMCS14:
923 		shift = 16;
924 		break;
925 	case DESC92C_RATE11M:
926 	case DESC92C_RATE18M:
927 	case DESC92C_RATE54M:
928 	case DESC92C_RATEMCS3:
929 	case DESC92C_RATEMCS7:
930 	case DESC92C_RATEMCS11:
931 	case DESC92C_RATEMCS15:
932 		shift = 24;
933 		break;
934 	default:
935 		WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n");
936 		break;
937 	}
938 	tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
939 					  [rate_section] >> shift) & 0xff;
940 
941 	return	tx_pwr_diff;
942 }
943 
944 static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
945 				       u8 rate, u8 bandwidth, u8 channel)
946 {
947 	struct rtl_priv *rtlpriv = rtl_priv(hw);
948 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
949 	u8 index = (channel - 1);
950 	u8 txpower = 0;
951 	u8 power_diff_byrate = 0;
952 
953 	if (channel > 14 || channel < 1) {
954 		index = 0;
955 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
956 			 "Illegal channel!\n");
957 	}
958 	if (RX_HAL_IS_CCK_RATE(rate))
959 		txpower = rtlefuse->txpwrlevel_cck[path][index];
960 	else if (DESC92C_RATE6M <= rate)
961 		txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
962 	else
963 		RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
964 			 "invalid rate\n");
965 
966 	if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
967 	    !RX_HAL_IS_CCK_RATE(rate))
968 		txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
969 
970 	if (bandwidth == HT_CHANNEL_WIDTH_20) {
971 		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
972 			txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
973 		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
974 			txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
975 	} else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
976 		if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
977 			txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
978 		if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
979 			txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
980 	}
981 
982 	if (rtlefuse->eeprom_regulatory != 2)
983 		power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
984 								   BAND_ON_2_4G,
985 								   path, rate);
986 
987 	txpower += power_diff_byrate;
988 
989 	if (txpower > MAX_POWER_INDEX)
990 		txpower = MAX_POWER_INDEX;
991 
992 	return txpower;
993 }
994 
995 static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
996 					     u8 power_index, u8 path, u8 rate)
997 {
998 	struct rtl_priv *rtlpriv = rtl_priv(hw);
999 	if (path == RF90_PATH_A) {
1000 		switch (rate) {
1001 		case DESC92C_RATE1M:
1002 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1003 					       MASKBYTE1, power_index);
1004 			break;
1005 		case DESC92C_RATE2M:
1006 			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1007 					       MASKBYTE1, power_index);
1008 			break;
1009 		case DESC92C_RATE5_5M:
1010 			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1011 					       MASKBYTE2, power_index);
1012 			break;
1013 		case DESC92C_RATE11M:
1014 			rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1015 					       MASKBYTE3, power_index);
1016 			break;
1017 
1018 		case DESC92C_RATE6M:
1019 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1020 					       MASKBYTE0, power_index);
1021 			break;
1022 		case DESC92C_RATE9M:
1023 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1024 					       MASKBYTE1, power_index);
1025 			break;
1026 		case DESC92C_RATE12M:
1027 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1028 					       MASKBYTE2, power_index);
1029 			break;
1030 		case DESC92C_RATE18M:
1031 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1032 					       MASKBYTE3, power_index);
1033 			break;
1034 
1035 		case DESC92C_RATE24M:
1036 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1037 					       MASKBYTE0, power_index);
1038 			break;
1039 		case DESC92C_RATE36M:
1040 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1041 					       MASKBYTE1, power_index);
1042 			break;
1043 		case DESC92C_RATE48M:
1044 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1045 					       MASKBYTE2, power_index);
1046 			break;
1047 		case DESC92C_RATE54M:
1048 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1049 					       MASKBYTE3, power_index);
1050 			break;
1051 
1052 		case DESC92C_RATEMCS0:
1053 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1054 					       MASKBYTE0, power_index);
1055 			break;
1056 		case DESC92C_RATEMCS1:
1057 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1058 					       MASKBYTE1, power_index);
1059 			break;
1060 		case DESC92C_RATEMCS2:
1061 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1062 					       MASKBYTE2, power_index);
1063 			break;
1064 		case DESC92C_RATEMCS3:
1065 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1066 					       MASKBYTE3, power_index);
1067 			break;
1068 
1069 		case DESC92C_RATEMCS4:
1070 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1071 					       MASKBYTE0, power_index);
1072 			break;
1073 		case DESC92C_RATEMCS5:
1074 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1075 					       MASKBYTE1, power_index);
1076 			break;
1077 		case DESC92C_RATEMCS6:
1078 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1079 					       MASKBYTE2, power_index);
1080 			break;
1081 		case DESC92C_RATEMCS7:
1082 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1083 					       MASKBYTE3, power_index);
1084 			break;
1085 
1086 		case DESC92C_RATEMCS8:
1087 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1088 					       MASKBYTE0, power_index);
1089 			break;
1090 		case DESC92C_RATEMCS9:
1091 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1092 					       MASKBYTE1, power_index);
1093 			break;
1094 		case DESC92C_RATEMCS10:
1095 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1096 					       MASKBYTE2, power_index);
1097 			break;
1098 		case DESC92C_RATEMCS11:
1099 			rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1100 					       MASKBYTE3, power_index);
1101 			break;
1102 
1103 		default:
1104 			RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n");
1105 			break;
1106 		}
1107 	} else {
1108 		RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1109 	}
1110 }
1111 
1112 void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1113 {
1114 	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1115 	u8 cck_rates[]  = {DESC92C_RATE1M, DESC92C_RATE2M,
1116 			   DESC92C_RATE5_5M, DESC92C_RATE11M};
1117 	u8 ofdm_rates[]  = {DESC92C_RATE6M, DESC92C_RATE9M,
1118 			    DESC92C_RATE12M, DESC92C_RATE18M,
1119 			    DESC92C_RATE24M, DESC92C_RATE36M,
1120 			    DESC92C_RATE48M, DESC92C_RATE54M};
1121 	u8 ht_rates_1t[]  = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1122 			     DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1123 			     DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1124 			     DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1125 	u8 i;
1126 	u8 power_index;
1127 
1128 	if (!rtlefuse->txpwr_fromeprom)
1129 		return;
1130 
1131 	for (i = 0; i < ARRAY_SIZE(cck_rates); i++) {
1132 		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1133 					cck_rates[i],
1134 					rtl_priv(hw)->phy.current_chan_bw,
1135 					channel);
1136 		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1137 						 cck_rates[i]);
1138 	}
1139 	for (i = 0; i < ARRAY_SIZE(ofdm_rates); i++) {
1140 		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1141 					ofdm_rates[i],
1142 					rtl_priv(hw)->phy.current_chan_bw,
1143 					channel);
1144 		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1145 						 ofdm_rates[i]);
1146 	}
1147 	for (i = 0; i < ARRAY_SIZE(ht_rates_1t); i++) {
1148 		power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1149 					ht_rates_1t[i],
1150 					rtl_priv(hw)->phy.current_chan_bw,
1151 					channel);
1152 		_rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1153 						 ht_rates_1t[i]);
1154 	}
1155 }
1156 
1157 void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1158 {
1159 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1160 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1161 	enum io_type iotype;
1162 
1163 	if (!is_hal_stop(rtlhal)) {
1164 		switch (operation) {
1165 		case SCAN_OPT_BACKUP_BAND0:
1166 			iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1167 			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1168 						      (u8 *)&iotype);
1169 
1170 			break;
1171 		case SCAN_OPT_RESTORE:
1172 			iotype = IO_CMD_RESUME_DM_BY_SCAN;
1173 			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1174 						      (u8 *)&iotype);
1175 			break;
1176 		default:
1177 			pr_err("Unknown Scan Backup operation.\n");
1178 			break;
1179 		}
1180 	}
1181 }
1182 
1183 void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1184 {
1185 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1186 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1187 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1188 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1189 	u8 reg_bw_opmode;
1190 	u8 reg_prsr_rsc;
1191 
1192 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1193 		 "Switch to %s bandwidth\n",
1194 		  rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1195 		  "20MHz" : "40MHz");
1196 
1197 	if (is_hal_stop(rtlhal)) {
1198 		rtlphy->set_bwmode_inprogress = false;
1199 		return;
1200 	}
1201 
1202 	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1203 	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1204 
1205 	switch (rtlphy->current_chan_bw) {
1206 	case HT_CHANNEL_WIDTH_20:
1207 		reg_bw_opmode |= BW_OPMODE_20MHZ;
1208 		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1209 		break;
1210 	case HT_CHANNEL_WIDTH_20_40:
1211 		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1212 		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1213 		reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1214 			       (mac->cur_40_prime_sc << 5);
1215 		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1216 		break;
1217 	default:
1218 		pr_err("unknown bandwidth: %#X\n",
1219 		       rtlphy->current_chan_bw);
1220 		break;
1221 	}
1222 
1223 	switch (rtlphy->current_chan_bw) {
1224 	case HT_CHANNEL_WIDTH_20:
1225 		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1226 		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1227 	/*	rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
1228 		break;
1229 	case HT_CHANNEL_WIDTH_20_40:
1230 		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1231 		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1232 
1233 		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1234 			      (mac->cur_40_prime_sc >> 1));
1235 		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1236 		/*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1237 
1238 		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1239 			      (mac->cur_40_prime_sc ==
1240 			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1241 		break;
1242 	default:
1243 		pr_err("unknown bandwidth: %#X\n",
1244 		       rtlphy->current_chan_bw);
1245 		break;
1246 	}
1247 	rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1248 	rtlphy->set_bwmode_inprogress = false;
1249 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1250 }
1251 
1252 void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1253 			    enum nl80211_channel_type ch_type)
1254 {
1255 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1256 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1257 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1258 	u8 tmp_bw = rtlphy->current_chan_bw;
1259 
1260 	if (rtlphy->set_bwmode_inprogress)
1261 		return;
1262 	rtlphy->set_bwmode_inprogress = true;
1263 	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1264 		rtl8723be_phy_set_bw_mode_callback(hw);
1265 	} else {
1266 		RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1267 			 "false driver sleep or unload\n");
1268 		rtlphy->set_bwmode_inprogress = false;
1269 		rtlphy->current_chan_bw = tmp_bw;
1270 	}
1271 }
1272 
1273 void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1274 {
1275 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1276 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1277 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1278 	u32 delay = 0;
1279 
1280 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1281 		 "switch to channel%d\n", rtlphy->current_channel);
1282 	if (is_hal_stop(rtlhal))
1283 		return;
1284 	do {
1285 		if (!rtlphy->sw_chnl_inprogress)
1286 			break;
1287 		if (!_rtl8723be_phy_sw_chnl_step_by_step(hw,
1288 							 rtlphy->current_channel,
1289 							 &rtlphy->sw_chnl_stage,
1290 							 &rtlphy->sw_chnl_step,
1291 							 &delay)) {
1292 			if (delay > 0)
1293 				mdelay(delay);
1294 			else
1295 				continue;
1296 		} else {
1297 			rtlphy->sw_chnl_inprogress = false;
1298 		}
1299 		break;
1300 	} while (true);
1301 	RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1302 }
1303 
1304 u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1305 {
1306 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1307 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1308 	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1309 
1310 	if (rtlphy->sw_chnl_inprogress)
1311 		return 0;
1312 	if (rtlphy->set_bwmode_inprogress)
1313 		return 0;
1314 	WARN_ONCE((rtlphy->current_channel > 14),
1315 		  "rtl8723be: WIRELESS_MODE_G but channel>14");
1316 	rtlphy->sw_chnl_inprogress = true;
1317 	rtlphy->sw_chnl_stage = 0;
1318 	rtlphy->sw_chnl_step = 0;
1319 	if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1320 		rtl8723be_phy_sw_chnl_callback(hw);
1321 		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1322 			 "sw_chnl_inprogress false schedule workitem current channel %d\n",
1323 			 rtlphy->current_channel);
1324 		rtlphy->sw_chnl_inprogress = false;
1325 	} else {
1326 		RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1327 			 "sw_chnl_inprogress false driver sleep or unload\n");
1328 		rtlphy->sw_chnl_inprogress = false;
1329 	}
1330 	return 1;
1331 }
1332 
1333 static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1334 						u8 channel, u8 *stage,
1335 						u8 *step, u32 *delay)
1336 {
1337 	struct rtl_priv *rtlpriv = rtl_priv(hw);
1338 	struct rtl_phy *rtlphy = &rtlpriv->phy;
1339 	struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1340 	u32 precommoncmdcnt;
1341 	struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1342 	u32 postcommoncmdcnt;
1343 	struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1344 	u32 rfdependcmdcnt;
1345 	struct swchnlcmd *currentcmd = NULL;
1346 	u8 rfpath;
1347 	u8 num_total_rfpath = rtlphy->num_total_rfpath;
1348 
1349 	precommoncmdcnt = 0;
1350 	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1351 					 MAX_PRECMD_CNT,
1352 					 CMDID_SET_TXPOWEROWER_LEVEL,
1353 					 0, 0, 0);
1354 	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1355 					 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1356 
1357 	postcommoncmdcnt = 0;
1358 
1359 	rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1360 					 MAX_POSTCMD_CNT, CMDID_END,
1361 					    0, 0, 0);
1362 
1363 	rfdependcmdcnt = 0;
1364 
1365 	WARN_ONCE((channel < 1 || channel > 14),
1366 		  "rtl8723be: illegal channel for Zebra: %d\n", channel);
1367 
1368 	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1369 					 MAX_RFDEPENDCMD_CNT,
1370 					 CMDID_RF_WRITEREG,
1371 					 RF_CHNLBW, channel, 10);
1372 
1373 	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1374 					 MAX_RFDEPENDCMD_CNT,
1375 					    CMDID_END, 0, 0, 0);
1376 
1377 	do {
1378 		switch (*stage) {
1379 		case 0:
1380 			currentcmd = &precommoncmd[*step];
1381 			break;
1382 		case 1:
1383 			currentcmd = &rfdependcmd[*step];
1384 			break;
1385 		case 2:
1386 			currentcmd = &postcommoncmd[*step];
1387 			break;
1388 		default:
1389 			pr_err("Invalid 'stage' = %d, Check it!\n",
1390 			       *stage);
1391 			return true;
1392 		}
1393 
1394 		if (currentcmd->cmdid == CMDID_END) {
1395 			if ((*stage) == 2) {
1396 				return true;
1397 			} else {
1398 				(*stage)++;
1399 				(*step) = 0;
1400 				continue;
1401 			}
1402 		}
1403 
1404 		switch (currentcmd->cmdid) {
1405 		case CMDID_SET_TXPOWEROWER_LEVEL:
1406 			rtl8723be_phy_set_txpower_level(hw, channel);
1407 			break;
1408 		case CMDID_WRITEPORT_ULONG:
1409 			rtl_write_dword(rtlpriv, currentcmd->para1,
1410 					currentcmd->para2);
1411 			break;
1412 		case CMDID_WRITEPORT_USHORT:
1413 			rtl_write_word(rtlpriv, currentcmd->para1,
1414 				       (u16)currentcmd->para2);
1415 			break;
1416 		case CMDID_WRITEPORT_UCHAR:
1417 			rtl_write_byte(rtlpriv, currentcmd->para1,
1418 				       (u8)currentcmd->para2);
1419 			break;
1420 		case CMDID_RF_WRITEREG:
1421 			for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1422 				rtlphy->rfreg_chnlval[rfpath] =
1423 				    ((rtlphy->rfreg_chnlval[rfpath] &
1424 				      0xfffffc00) | currentcmd->para2);
1425 
1426 				rtl_set_rfreg(hw, (enum radio_path)rfpath,
1427 					      currentcmd->para1,
1428 					      RFREG_OFFSET_MASK,
1429 					      rtlphy->rfreg_chnlval[rfpath]);
1430 			}
1431 			break;
1432 		default:
1433 			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1434 				 "switch case %#x not processed\n",
1435 				 currentcmd->cmdid);
1436 			break;
1437 		}
1438 
1439 		break;
1440 	} while (true);
1441 
1442 	(*delay) = currentcmd->msdelay;
1443 	(*step)++;
1444 	return false;
1445 }
1446 
1447 static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw)
1448 {
1449 	u32 reg_eac, reg_e94, reg_e9c, tmp;
1450 	u8 result = 0x00;
1451 
1452 	/* leave IQK mode */
1453 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1454 	/* switch to path A */
1455 	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1456 	/* enable path A PA in TXIQK mode */
1457 	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1458 	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000);
1459 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f);
1460 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87);
1461 
1462 	/* 1. TX IQK */
1463 	/* path-A IQK setting */
1464 	/* IQK setting */
1465 	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1466 	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1467 	/* path-A IQK setting */
1468 	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1469 	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1470 	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1471 	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1472 
1473 	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1474 	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1475 	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1476 	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1477 	/* LO calibration setting */
1478 	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1479 	/* enter IQK mode */
1480 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1481 
1482 	/* One shot, path A LOK & IQK */
1483 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1484 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1485 
1486 	mdelay(IQK_DELAY_TIME);
1487 
1488 	/* leave IQK mode */
1489 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1490 
1491 	/* Check failed */
1492 	reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1493 	reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1494 	reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1495 
1496 	if (!(reg_eac & BIT(28)) &&
1497 	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1498 	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1499 		result |= 0x01;
1500 	else /* if Tx not OK, ignore Rx */
1501 		return result;
1502 
1503 	/* Allen 20131125 */
1504 	tmp = (reg_e9c & 0x03FF0000) >> 16;
1505 	if ((tmp & 0x200) > 0)
1506 		tmp = 0x400 - tmp;
1507 
1508 	if (!(reg_eac & BIT(28)) &&
1509 	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1510 	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1511 	    (tmp < 0xf))
1512 		result |= 0x01;
1513 	else /* if Tx not OK, ignore Rx */
1514 		return result;
1515 
1516 	return result;
1517 }
1518 
1519 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1520 static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw)
1521 {
1522 	u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp;
1523 	u8 result = 0x00;
1524 
1525 	/* leave IQK mode */
1526 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1527 
1528 	/* switch to path A */
1529 	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1530 
1531 	/* 1 Get TXIMR setting */
1532 	/* modify RXIQK mode table */
1533 	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1534 	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1535 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1536 	/* LNA2 off, PA on for Dcut */
1537 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7);
1538 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1539 
1540 	/* IQK setting */
1541 	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1542 	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1543 
1544 	/* path-A IQK setting */
1545 	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1546 	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1547 	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1548 	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1549 
1550 	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1551 	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1552 	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1553 	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1554 
1555 	/* LO calibration setting */
1556 	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1557 
1558 	/* enter IQK mode */
1559 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1560 
1561 	/* One shot, path A LOK & IQK */
1562 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1563 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1564 
1565 	mdelay(IQK_DELAY_TIME);
1566 
1567 	/* leave IQK mode */
1568 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1569 
1570 	/* Check failed */
1571 	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1572 	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1573 	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1574 
1575 	if (!(reg_eac & BIT(28)) &&
1576 	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1577 	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1578 		result |= 0x01;
1579 	else /* if Tx not OK, ignore Rx */
1580 		return result;
1581 
1582 	/* Allen 20131125 */
1583 	tmp = (reg_e9c & 0x03FF0000) >> 16;
1584 	if ((tmp & 0x200) > 0)
1585 		tmp = 0x400 - tmp;
1586 
1587 	if (!(reg_eac & BIT(28)) &&
1588 	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1589 	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1590 	    (tmp < 0xf))
1591 		result |= 0x01;
1592 	else /* if Tx not OK, ignore Rx */
1593 		return result;
1594 
1595 	u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1596 		 ((reg_e9c & 0x3FF0000) >> 16);
1597 	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1598 
1599 	/* 1 RX IQK */
1600 	/* modify RXIQK mode table */
1601 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1602 	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1603 	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1604 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1605 	/* LAN2 on, PA off for Dcut */
1606 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1607 
1608 	/* PA, PAD setting */
1609 	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80);
1610 	rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f);
1611 
1612 	/* IQK setting */
1613 	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1614 
1615 	/* path-A IQK setting */
1616 	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1617 	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1618 	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1619 	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1620 
1621 	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1622 	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1623 	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1624 	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1625 
1626 	/* LO calibration setting */
1627 	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1628 
1629 	/* enter IQK mode */
1630 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1631 
1632 	/* One shot, path A LOK & IQK */
1633 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1634 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1635 
1636 	mdelay(IQK_DELAY_TIME);
1637 
1638 	/* leave IQK mode */
1639 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1640 
1641 	/* Check failed */
1642 	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1643 	reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1644 
1645 	/* leave IQK mode */
1646 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1647 	rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780);
1648 
1649 	/* Allen 20131125 */
1650 	tmp = (reg_eac & 0x03FF0000) >> 16;
1651 	if ((tmp & 0x200) > 0)
1652 		tmp = 0x400 - tmp;
1653 	/* if Tx is OK, check whether Rx is OK */
1654 	if (!(reg_eac & BIT(27)) &&
1655 	    (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1656 	    (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1657 		result |= 0x02;
1658 	else if (!(reg_eac & BIT(27)) &&
1659 		 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1660 		 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1661 		 (tmp < 0xf))
1662 		result |= 0x02;
1663 
1664 	return result;
1665 }
1666 
1667 static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw)
1668 {
1669 	u32 reg_eac, reg_e94, reg_e9c, tmp;
1670 	u8 result = 0x00;
1671 
1672 	/* leave IQK mode */
1673 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1674 	/* switch to path B */
1675 	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1676 
1677 	/* enable path B PA in TXIQK mode */
1678 	rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1679 	rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1);
1680 
1681 	/* 1 Tx IQK */
1682 	/* IQK setting */
1683 	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1684 	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1685 	/* path-A IQK setting */
1686 	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1687 	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1688 	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1689 	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1690 
1691 	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1692 	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1693 	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1694 	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1695 
1696 	/* LO calibration setting */
1697 	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1698 
1699 	/* enter IQK mode */
1700 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1701 
1702 	/* One shot, path B LOK & IQK */
1703 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1704 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1705 
1706 	mdelay(IQK_DELAY_TIME);
1707 
1708 	/* leave IQK mode */
1709 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1710 
1711 	/* Check failed */
1712 	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1713 	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1714 	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1715 
1716 	if (!(reg_eac & BIT(28)) &&
1717 	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1718 	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1719 		result |= 0x01;
1720 	else
1721 		return result;
1722 
1723 	/* Allen 20131125 */
1724 	tmp = (reg_e9c & 0x03FF0000) >> 16;
1725 	if ((tmp & 0x200) > 0)
1726 		tmp = 0x400 - tmp;
1727 
1728 	if (!(reg_eac & BIT(28)) &&
1729 	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1730 	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1731 	    (tmp < 0xf))
1732 		result |= 0x01;
1733 	else
1734 		return result;
1735 
1736 	return result;
1737 }
1738 
1739 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1740 static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw)
1741 {
1742 	u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp;
1743 	u8 result = 0x00;
1744 
1745 	/* leave IQK mode */
1746 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1747 	/* switch to path B */
1748 	rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1749 
1750 	/* 1 Get TXIMR setting */
1751 	/* modify RXIQK mode table */
1752 	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1753 	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1754 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1755 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7);
1756 
1757 	/* open PA S1 & SMIXER */
1758 	rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1759 	rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed);
1760 
1761 	/* IQK setting */
1762 	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1763 	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1764 
1765 	/* path-B IQK setting */
1766 	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1767 	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1768 	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1769 	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1770 
1771 	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1772 	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1773 	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1774 	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1775 
1776 	/* LO calibration setting */
1777 	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1778 	/* enter IQK mode */
1779 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1780 
1781 	/* One shot, path B TXIQK @ RXIQK */
1782 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1783 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1784 
1785 	mdelay(IQK_DELAY_TIME);
1786 
1787 	/* leave IQK mode */
1788 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1789 	/* Check failed */
1790 	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1791 	reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1792 	reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1793 
1794 	if (!(reg_eac & BIT(28)) &&
1795 	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1796 	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1797 		result |= 0x01;
1798 	else	/* if Tx not OK, ignore Rx */
1799 		return result;
1800 
1801 	/* Allen 20131125 */
1802 	tmp = (reg_e9c & 0x03FF0000) >> 16;
1803 	if ((tmp & 0x200) > 0)
1804 		tmp = 0x400 - tmp;
1805 
1806 	if (!(reg_eac & BIT(28)) &&
1807 	    (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1808 	    (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1809 	    (tmp < 0xf))
1810 		result |= 0x01;
1811 	else
1812 		return result;
1813 
1814 	u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000)  |
1815 		 ((reg_e9c & 0x3FF0000) >> 16);
1816 	rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1817 
1818 	/* 1 RX IQK */
1819 
1820 	/* <20121009, Kordan> RF Mode = 3 */
1821 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1822 	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1823 	rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1824 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1825 	rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1826 	rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0);
1827 
1828 	/* open PA S1 & close SMIXER */
1829 	rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1830 	rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd);
1831 
1832 	/* IQK setting */
1833 	rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1834 
1835 	/* path-B IQK setting */
1836 	rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1837 	rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1838 	rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1839 	rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1840 
1841 	rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1842 	rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1843 	rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1844 	rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1845 
1846 	/* LO calibration setting */
1847 	rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1848 	/* enter IQK mode */
1849 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1850 
1851 	/* One shot, path B LOK & IQK */
1852 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1853 	rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1854 
1855 	mdelay(IQK_DELAY_TIME);
1856 
1857 	/* leave IQK mode */
1858 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1859 	/* Check failed */
1860 	reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1861 	reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1862 
1863 	/* Allen 20131125 */
1864 	tmp = (reg_eac & 0x03FF0000) >> 16;
1865 	if ((tmp & 0x200) > 0)
1866 		tmp = 0x400 - tmp;
1867 
1868 	/* if Tx is OK, check whether Rx is OK */
1869 	if (!(reg_eac & BIT(27)) &&
1870 	    (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1871 	    (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1872 		result |= 0x02;
1873 	else if (!(reg_eac & BIT(27)) &&
1874 		 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1875 		 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1876 		 (tmp < 0xf))
1877 		result |= 0x02;
1878 	else
1879 		return result;
1880 
1881 	return result;
1882 }
1883 
1884 static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1885 						  bool b_iqk_ok,
1886 						  long result[][8],
1887 						  u8 final_candidate,
1888 						  bool btxonly)
1889 {
1890 	u32 oldval_1, x, tx1_a, reg;
1891 	long y, tx1_c;
1892 
1893 	if (final_candidate == 0xFF) {
1894 		return;
1895 	} else if (b_iqk_ok) {
1896 		oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1897 					  MASKDWORD) >> 22) & 0x3FF;
1898 		x = result[final_candidate][4];
1899 		if ((x & 0x00000200) != 0)
1900 			x = x | 0xFFFFFC00;
1901 		tx1_a = (x * oldval_1) >> 8;
1902 		rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1903 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1904 			      ((x * oldval_1 >> 7) & 0x1));
1905 		y = result[final_candidate][5];
1906 		if ((y & 0x00000200) != 0)
1907 			y = y | 0xFFFFFC00;
1908 		tx1_c = (y * oldval_1) >> 8;
1909 		rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1910 			      ((tx1_c & 0x3C0) >> 6));
1911 		rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1912 			      (tx1_c & 0x3F));
1913 		rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1914 			      ((y * oldval_1 >> 7) & 0x1));
1915 		if (btxonly)
1916 			return;
1917 		reg = result[final_candidate][6];
1918 		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1919 		reg = result[final_candidate][7] & 0x3F;
1920 		rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1921 		reg = (result[final_candidate][7] >> 6) & 0xF;
1922 		/* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */
1923 	}
1924 }
1925 
1926 static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw,
1927 					      long result[][8], u8 c1, u8 c2)
1928 {
1929 	u32 i, j, diff, simularity_bitmap, bound = 0;
1930 
1931 	u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
1932 	bool bresult = true; /* is2t = true*/
1933 	s32 tmp1 = 0, tmp2 = 0;
1934 
1935 	bound = 8;
1936 
1937 	simularity_bitmap = 0;
1938 
1939 	for (i = 0; i < bound; i++) {
1940 		if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1941 			if ((result[c1][i] & 0x00000200) != 0)
1942 				tmp1 = result[c1][i] | 0xFFFFFC00;
1943 			else
1944 				tmp1 = result[c1][i];
1945 
1946 			if ((result[c2][i] & 0x00000200) != 0)
1947 				tmp2 = result[c2][i] | 0xFFFFFC00;
1948 			else
1949 				tmp2 = result[c2][i];
1950 		} else {
1951 			tmp1 = result[c1][i];
1952 			tmp2 = result[c2][i];
1953 		}
1954 
1955 		diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
1956 
1957 		if (diff > MAX_TOLERANCE) {
1958 			if ((i == 2 || i == 6) && !simularity_bitmap) {
1959 				if (result[c1][i] + result[c1][i + 1] == 0)
1960 					final_candidate[(i / 4)] = c2;
1961 				else if (result[c2][i] + result[c2][i + 1] == 0)
1962 					final_candidate[(i / 4)] = c1;
1963 				else
1964 					simularity_bitmap |= (1 << i);
1965 			} else
1966 				simularity_bitmap |= (1 << i);
1967 		}
1968 	}
1969 
1970 	if (simularity_bitmap == 0) {
1971 		for (i = 0; i < (bound / 4); i++) {
1972 			if (final_candidate[i] != 0xFF) {
1973 				for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1974 					result[3][j] =
1975 						result[final_candidate[i]][j];
1976 				bresult = false;
1977 			}
1978 		}
1979 		return bresult;
1980 	} else {
1981 		if (!(simularity_bitmap & 0x03)) { /* path A TX OK */
1982 			for (i = 0; i < 2; i++)
1983 				result[3][i] = result[c1][i];
1984 		}
1985 		if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */
1986 			for (i = 2; i < 4; i++)
1987 				result[3][i] = result[c1][i];
1988 		}
1989 		if (!(simularity_bitmap & 0x30)) { /* path B TX OK */
1990 			for (i = 4; i < 6; i++)
1991 				result[3][i] = result[c1][i];
1992 		}
1993 		if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */
1994 			for (i = 6; i < 8; i++)
1995 				result[3][i] = result[c1][i];
1996 		}
1997 		return false;
1998 	}
1999 }
2000 
2001 static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
2002 					long result[][8], u8 t, bool is2t)
2003 {
2004 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2005 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2006 	u32 i;
2007 	u8 patha_ok, pathb_ok;
2008 	u32 adda_reg[IQK_ADDA_REG_NUM] = {
2009 		0x85c, 0xe6c, 0xe70, 0xe74,
2010 		0xe78, 0xe7c, 0xe80, 0xe84,
2011 		0xe88, 0xe8c, 0xed0, 0xed4,
2012 		0xed8, 0xedc, 0xee0, 0xeec
2013 	};
2014 
2015 	u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2016 		0x522, 0x550, 0x551, 0x040
2017 	};
2018 	u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2019 		ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2020 		RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2021 		0x870, 0x860,
2022 		0x864, 0xa04
2023 	};
2024 	const u32 retrycount = 2;
2025 
2026 	u32 path_sel_bb;/* path_sel_rf */
2027 
2028 	u8 tmp_reg_c50, tmp_reg_c58;
2029 
2030 	tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2031 	tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2032 
2033 	if (t == 0) {
2034 		rtl8723_save_adda_registers(hw, adda_reg,
2035 					    rtlphy->adda_backup, 16);
2036 		rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
2037 					       rtlphy->iqk_mac_backup);
2038 		rtl8723_save_adda_registers(hw, iqk_bb_reg,
2039 					    rtlphy->iqk_bb_backup,
2040 					    IQK_BB_REG_NUM);
2041 	}
2042 	rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
2043 	if (t == 0) {
2044 		rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
2045 						RFPGA0_XA_HSSIPARAMETER1,
2046 						BIT(8));
2047 	}
2048 
2049 	path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2050 
2051 	rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
2052 					    rtlphy->iqk_mac_backup);
2053 	/*BB Setting*/
2054 	rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf);
2055 	rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
2056 	rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
2057 	rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
2058 
2059 	/* path A TX IQK */
2060 	for (i = 0; i < retrycount; i++) {
2061 		patha_ok = _rtl8723be_phy_path_a_iqk(hw);
2062 		if (patha_ok == 0x01) {
2063 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2064 				"Path A Tx IQK Success!!\n");
2065 			result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2066 					0x3FF0000) >> 16;
2067 			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2068 					0x3FF0000) >> 16;
2069 			break;
2070 		} else {
2071 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2072 				 "Path A Tx IQK Fail!!\n");
2073 		}
2074 	}
2075 	/* path A RX IQK */
2076 	for (i = 0; i < retrycount; i++) {
2077 		patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw);
2078 		if (patha_ok == 0x03) {
2079 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2080 				 "Path A Rx IQK Success!!\n");
2081 			result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2082 					0x3FF0000) >> 16;
2083 			result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2084 					0x3FF0000) >> 16;
2085 			break;
2086 		}
2087 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2088 			 "Path A Rx IQK Fail!!\n");
2089 	}
2090 
2091 	if (0x00 == patha_ok)
2092 		RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n");
2093 
2094 	if (is2t) {
2095 		/* path B TX IQK */
2096 		for (i = 0; i < retrycount; i++) {
2097 			pathb_ok = _rtl8723be_phy_path_b_iqk(hw);
2098 			if (pathb_ok == 0x01) {
2099 				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2100 					 "Path B Tx IQK Success!!\n");
2101 				result[t][4] = (rtl_get_bbreg(hw, 0xe94,
2102 							      MASKDWORD) &
2103 							      0x3FF0000) >> 16;
2104 				result[t][5] = (rtl_get_bbreg(hw, 0xe9c,
2105 							      MASKDWORD) &
2106 							      0x3FF0000) >> 16;
2107 				break;
2108 			}
2109 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2110 				 "Path B Tx IQK Fail!!\n");
2111 		}
2112 		/* path B RX IQK */
2113 		for (i = 0; i < retrycount; i++) {
2114 			pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw);
2115 			if (pathb_ok == 0x03) {
2116 				RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2117 					 "Path B Rx IQK Success!!\n");
2118 				result[t][6] = (rtl_get_bbreg(hw, 0xea4,
2119 							      MASKDWORD) &
2120 							      0x3FF0000) >> 16;
2121 				result[t][7] = (rtl_get_bbreg(hw, 0xeac,
2122 							      MASKDWORD) &
2123 							      0x3FF0000) >> 16;
2124 				break;
2125 			}
2126 			RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2127 				 "Path B Rx IQK Fail!!\n");
2128 		}
2129 	}
2130 
2131 	/* Back to BB mode, load original value */
2132 	rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2133 
2134 	if (t != 0) {
2135 		rtl8723_phy_reload_adda_registers(hw, adda_reg,
2136 						  rtlphy->adda_backup, 16);
2137 		rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
2138 						 rtlphy->iqk_mac_backup);
2139 		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2140 						  rtlphy->iqk_bb_backup,
2141 						  IQK_BB_REG_NUM);
2142 
2143 		rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2144 		/*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/
2145 
2146 		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2147 		rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
2148 		if (is2t) {
2149 			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
2150 			rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
2151 		}
2152 		rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2153 		rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2154 	}
2155 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
2156 }
2157 
2158 static u8 _get_right_chnl_place_for_iqk(u8 chnl)
2159 {
2160 	u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
2161 			1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2162 			13, 14, 36, 38, 40, 42, 44, 46,
2163 			48, 50, 52, 54, 56, 58, 60, 62, 64,
2164 			100, 102, 104, 106, 108, 110,
2165 			112, 114, 116, 118, 120, 122,
2166 			124, 126, 128, 130, 132, 134, 136,
2167 			138, 140, 149, 151, 153, 155, 157,
2168 			159, 161, 163, 165};
2169 	u8 place = chnl;
2170 
2171 	if (chnl > 14) {
2172 		for (place = 14; place < sizeof(channel_all); place++) {
2173 			if (channel_all[place] == chnl)
2174 				return place - 13;
2175 		}
2176 	}
2177 	return 0;
2178 }
2179 
2180 static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2181 {
2182 	u8 tmpreg;
2183 	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2184 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2185 
2186 	tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2187 
2188 	if ((tmpreg & 0x70) != 0)
2189 		rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2190 	else
2191 		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2192 
2193 	if ((tmpreg & 0x70) != 0) {
2194 		rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2195 
2196 		if (is2t)
2197 			rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2198 						  MASK12BITS);
2199 
2200 		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2201 			      (rf_a_mode & 0x8FFFF) | 0x10000);
2202 
2203 		if (is2t)
2204 			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2205 				      (rf_b_mode & 0x8FFFF) | 0x10000);
2206 	}
2207 	lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2208 
2209 	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
2210 	rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
2211 
2212 	/* In order not to disturb BT music when wifi init.(1ant NIC only) */
2213 	/*mdelay(100);*/
2214 	/* In order not to disturb BT music when wifi init.(1ant NIC only) */
2215 	mdelay(50);
2216 
2217 	rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
2218 
2219 	if ((tmpreg & 0x70) != 0) {
2220 		rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2221 		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2222 
2223 		if (is2t)
2224 			rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
2225 				      MASK12BITS, rf_b_mode);
2226 	} else {
2227 		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2228 	}
2229 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2230 }
2231 
2232 static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2233 					     bool bmain, bool is2t)
2234 {
2235 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2236 	RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2237 
2238 	if (bmain) /* left antenna */
2239 		rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1);
2240 	else
2241 		rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2);
2242 }
2243 
2244 #undef IQK_ADDA_REG_NUM
2245 #undef IQK_DELAY_TIME
2246 /* IQK is merge from Merge Temp */
2247 void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2248 {
2249 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2250 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2251 	long result[4][8];
2252 	u8 i, final_candidate, idx;
2253 	bool b_patha_ok, b_pathb_ok;
2254 	long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4;
2255 	long reg_ecc, reg_tmp = 0;
2256 	bool is12simular, is13simular, is23simular;
2257 	u32 iqk_bb_reg[9] = {
2258 		ROFDM0_XARXIQIMBALANCE,
2259 		ROFDM0_XBRXIQIMBALANCE,
2260 		ROFDM0_ECCATHRESHOLD,
2261 		ROFDM0_AGCRSSITABLE,
2262 		ROFDM0_XATXIQIMBALANCE,
2263 		ROFDM0_XBTXIQIMBALANCE,
2264 		ROFDM0_XCTXAFE,
2265 		ROFDM0_XDTXAFE,
2266 		ROFDM0_RXIQEXTANTA
2267 	};
2268 	u32 path_sel_bb = 0; /* path_sel_rf = 0 */
2269 
2270 	if (rtlphy->lck_inprogress)
2271 		return;
2272 
2273 	spin_lock(&rtlpriv->locks.iqk_lock);
2274 	rtlphy->lck_inprogress = true;
2275 	spin_unlock(&rtlpriv->locks.iqk_lock);
2276 
2277 	if (b_recovery) {
2278 		rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2279 						  rtlphy->iqk_bb_backup, 9);
2280 		goto label_done;
2281 	}
2282 	/* Save RF Path */
2283 	path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2284 	/* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */
2285 
2286 	for (i = 0; i < 8; i++) {
2287 		result[0][i] = 0;
2288 		result[1][i] = 0;
2289 		result[2][i] = 0;
2290 		result[3][i] = 0;
2291 	}
2292 	final_candidate = 0xff;
2293 	b_patha_ok = false;
2294 	b_pathb_ok = false;
2295 	is12simular = false;
2296 	is23simular = false;
2297 	is13simular = false;
2298 	for (i = 0; i < 3; i++) {
2299 		_rtl8723be_phy_iq_calibrate(hw, result, i, true);
2300 		if (i == 1) {
2301 			is12simular = _rtl8723be_phy_simularity_compare(hw,
2302 									result,
2303 									0, 1);
2304 			if (is12simular) {
2305 				final_candidate = 0;
2306 				break;
2307 			}
2308 		}
2309 		if (i == 2) {
2310 			is13simular = _rtl8723be_phy_simularity_compare(hw,
2311 									result,
2312 									0, 2);
2313 			if (is13simular) {
2314 				final_candidate = 0;
2315 				break;
2316 			}
2317 			is23simular = _rtl8723be_phy_simularity_compare(hw,
2318 									result,
2319 									1, 2);
2320 			if (is23simular) {
2321 				final_candidate = 1;
2322 			} else {
2323 				for (i = 0; i < 8; i++)
2324 					reg_tmp += result[3][i];
2325 
2326 				if (reg_tmp != 0)
2327 					final_candidate = 3;
2328 				else
2329 					final_candidate = 0xFF;
2330 			}
2331 		}
2332 	}
2333 	for (i = 0; i < 4; i++) {
2334 		reg_e94 = result[i][0];
2335 		reg_e9c = result[i][1];
2336 		reg_ea4 = result[i][2];
2337 		reg_eac = result[i][3];
2338 		reg_eb4 = result[i][4];
2339 		reg_ebc = result[i][5];
2340 		reg_ec4 = result[i][6];
2341 		reg_ecc = result[i][7];
2342 	}
2343 	if (final_candidate != 0xff) {
2344 		reg_e94 = result[final_candidate][0];
2345 		rtlphy->reg_e94 = reg_e94;
2346 		reg_e9c = result[final_candidate][1];
2347 		rtlphy->reg_e9c = reg_e9c;
2348 		reg_ea4 = result[final_candidate][2];
2349 		reg_eac = result[final_candidate][3];
2350 		reg_eb4 = result[final_candidate][4];
2351 		rtlphy->reg_eb4 = reg_eb4;
2352 		reg_ebc = result[final_candidate][5];
2353 		rtlphy->reg_ebc = reg_ebc;
2354 		reg_ec4 = result[final_candidate][6];
2355 		reg_ecc = result[final_candidate][7];
2356 		b_patha_ok = true;
2357 		b_pathb_ok = true;
2358 	} else {
2359 		rtlphy->reg_e94 = 0x100;
2360 		rtlphy->reg_eb4 = 0x100;
2361 		rtlphy->reg_e9c = 0x0;
2362 		rtlphy->reg_ebc = 0x0;
2363 	}
2364 	if (reg_e94 != 0)
2365 		rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2366 						   final_candidate,
2367 						   (reg_ea4 == 0));
2368 	if (reg_eb4 != 0)
2369 		_rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2370 						      final_candidate,
2371 						      (reg_ec4 == 0));
2372 
2373 	idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel);
2374 
2375 	if (final_candidate < 4) {
2376 		for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2377 			rtlphy->iqk_matrix[idx].value[0][i] =
2378 						result[final_candidate][i];
2379 		rtlphy->iqk_matrix[idx].iqk_done = true;
2380 
2381 	}
2382 	rtl8723_save_adda_registers(hw, iqk_bb_reg,
2383 				    rtlphy->iqk_bb_backup, 9);
2384 
2385 	rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2386 	/* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */
2387 
2388 label_done:
2389 	spin_lock(&rtlpriv->locks.iqk_lock);
2390 	rtlphy->lck_inprogress = false;
2391 	spin_unlock(&rtlpriv->locks.iqk_lock);
2392 }
2393 
2394 void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
2395 {
2396 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2397 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2398 	struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2399 	u32 timeout = 2000, timecount = 0;
2400 
2401 	while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2402 		udelay(50);
2403 		timecount += 50;
2404 	}
2405 
2406 	rtlphy->lck_inprogress = true;
2407 	RTPRINT(rtlpriv, FINIT, INIT_IQK,
2408 		"LCK:Start!!! currentband %x delay %d ms\n",
2409 		 rtlhal->current_bandtype, timecount);
2410 
2411 	_rtl8723be_phy_lc_calibrate(hw, false);
2412 
2413 	rtlphy->lck_inprogress = false;
2414 }
2415 
2416 void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2417 {
2418 	_rtl8723be_phy_set_rfpath_switch(hw, bmain, true);
2419 }
2420 
2421 bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2422 {
2423 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2424 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2425 	bool b_postprocessing = false;
2426 
2427 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2428 		 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2429 		  iotype, rtlphy->set_io_inprogress);
2430 	do {
2431 		switch (iotype) {
2432 		case IO_CMD_RESUME_DM_BY_SCAN:
2433 			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2434 				 "[IO CMD] Resume DM after scan.\n");
2435 			b_postprocessing = true;
2436 			break;
2437 		case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2438 			RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2439 				 "[IO CMD] Pause DM before scan.\n");
2440 			b_postprocessing = true;
2441 			break;
2442 		default:
2443 			RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2444 				 "switch case %#x not processed\n", iotype);
2445 			break;
2446 		}
2447 	} while (false);
2448 	if (b_postprocessing && !rtlphy->set_io_inprogress) {
2449 		rtlphy->set_io_inprogress = true;
2450 		rtlphy->current_io_type = iotype;
2451 	} else {
2452 		return false;
2453 	}
2454 	rtl8723be_phy_set_io(hw);
2455 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2456 	return true;
2457 }
2458 
2459 static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
2460 {
2461 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2462 	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2463 	struct rtl_phy *rtlphy = &rtlpriv->phy;
2464 
2465 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2466 		 "--->Cmd(%#x), set_io_inprogress(%d)\n",
2467 		  rtlphy->current_io_type, rtlphy->set_io_inprogress);
2468 	switch (rtlphy->current_io_type) {
2469 	case IO_CMD_RESUME_DM_BY_SCAN:
2470 		dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2471 		/*rtl92c_dm_write_dig(hw);*/
2472 		rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
2473 		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
2474 		break;
2475 	case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2476 		rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
2477 		dm_digtable->cur_igvalue = 0x17;
2478 		rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
2479 		break;
2480 	default:
2481 		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2482 			 "switch case %#x not processed\n",
2483 			 rtlphy->current_io_type);
2484 		break;
2485 	}
2486 	rtlphy->set_io_inprogress = false;
2487 	RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2488 		 "(%#x)\n", rtlphy->current_io_type);
2489 }
2490 
2491 static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2492 {
2493 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2494 
2495 	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2496 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2497 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2498 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2499 	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2500 }
2501 
2502 static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2503 {
2504 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2505 
2506 	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2507 	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2508 	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2509 	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2510 }
2511 
2512 static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2513 					      enum rf_pwrstate rfpwr_state)
2514 {
2515 	struct rtl_priv *rtlpriv = rtl_priv(hw);
2516 	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2517 	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2518 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2519 	bool bresult = true;
2520 	u8 i, queue_id;
2521 	struct rtl8192_tx_ring *ring = NULL;
2522 
2523 	switch (rfpwr_state) {
2524 	case ERFON:
2525 		if ((ppsc->rfpwr_state == ERFOFF) &&
2526 		     RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2527 			bool rtstatus;
2528 			u32 initializecount = 0;
2529 			do {
2530 				initializecount++;
2531 				RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2532 					 "IPS Set eRf nic enable\n");
2533 				rtstatus = rtl_ps_enable_nic(hw);
2534 			} while (!rtstatus && (initializecount < 10));
2535 			RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2536 		} else {
2537 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2538 				 "Set ERFON sleeped:%d ms\n",
2539 				  jiffies_to_msecs(jiffies -
2540 						   ppsc->last_sleep_jiffies));
2541 			ppsc->last_awake_jiffies = jiffies;
2542 			rtl8723be_phy_set_rf_on(hw);
2543 		}
2544 		if (mac->link_state == MAC80211_LINKED)
2545 			rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2546 		else
2547 			rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2548 
2549 		break;
2550 
2551 	case ERFOFF:
2552 		for (queue_id = 0, i = 0;
2553 		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2554 			ring = &pcipriv->dev.tx_ring[queue_id];
2555 			/* Don't check BEACON Q.
2556 			 * BEACON Q is always not empty,
2557 			 * because '_rtl8723be_cmd_send_packet'
2558 			 */
2559 			if (queue_id == BEACON_QUEUE ||
2560 			    skb_queue_len(&ring->queue) == 0) {
2561 				queue_id++;
2562 				continue;
2563 			} else {
2564 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2565 					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2566 					 (i + 1), queue_id,
2567 					 skb_queue_len(&ring->queue));
2568 
2569 				udelay(10);
2570 				i++;
2571 			}
2572 			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2573 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2574 					 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2575 					  MAX_DOZE_WAITING_TIMES_9x,
2576 					  queue_id,
2577 					  skb_queue_len(&ring->queue));
2578 				break;
2579 			}
2580 		}
2581 
2582 		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2583 			RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2584 				 "IPS Set eRf nic disable\n");
2585 			rtl_ps_disable_nic(hw);
2586 			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2587 		} else {
2588 			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2589 				rtlpriv->cfg->ops->led_control(hw,
2590 							       LED_CTL_NO_LINK);
2591 			} else {
2592 				rtlpriv->cfg->ops->led_control(hw,
2593 							     LED_CTL_POWER_OFF);
2594 			}
2595 		}
2596 		break;
2597 
2598 	case ERFSLEEP:
2599 		if (ppsc->rfpwr_state == ERFOFF)
2600 			break;
2601 		for (queue_id = 0, i = 0;
2602 		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2603 			ring = &pcipriv->dev.tx_ring[queue_id];
2604 			if (skb_queue_len(&ring->queue) == 0) {
2605 				queue_id++;
2606 				continue;
2607 			} else {
2608 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2609 					 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2610 					 (i + 1), queue_id,
2611 					 skb_queue_len(&ring->queue));
2612 
2613 				udelay(10);
2614 				i++;
2615 			}
2616 			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2617 				RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2618 					 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2619 					 MAX_DOZE_WAITING_TIMES_9x,
2620 					 queue_id,
2621 					 skb_queue_len(&ring->queue));
2622 				break;
2623 			}
2624 		}
2625 		RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2626 			 "Set ERFSLEEP awaked:%d ms\n",
2627 			  jiffies_to_msecs(jiffies -
2628 					   ppsc->last_awake_jiffies));
2629 		ppsc->last_sleep_jiffies = jiffies;
2630 		_rtl8723be_phy_set_rf_sleep(hw);
2631 		break;
2632 
2633 	default:
2634 		RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2635 			 "switch case %#x not processed\n", rfpwr_state);
2636 		bresult = false;
2637 		break;
2638 	}
2639 	if (bresult)
2640 		ppsc->rfpwr_state = rfpwr_state;
2641 	return bresult;
2642 }
2643 
2644 bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2645 				      enum rf_pwrstate rfpwr_state)
2646 {
2647 	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2648 
2649 	bool bresult = false;
2650 
2651 	if (rfpwr_state == ppsc->rfpwr_state)
2652 		return bresult;
2653 	bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);
2654 	return bresult;
2655 }
2656