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