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