Linux Audio

Check our new training course

Linux kernel drivers training

Mar 31-Apr 9, 2025, special US time zones
Register
Loading...
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright(c) 2009-2012  Realtek Corporation.*/
   3
   4#include "../wifi.h"
   5#include "../pci.h"
   6#include "../ps.h"
   7#include "reg.h"
   8#include "def.h"
   9#include "phy.h"
  10#include "rf.h"
  11#include "dm.h"
  12#include "table.h"
  13#include "../rtl8723com/phy_common.h"
  14
  15static void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
  16					     enum radio_path rfpath, u32 offset,
  17					     u32 data);
  18static bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);
  19static bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
  20static bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
  21						    u8 configtype);
  22static bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
  23						      u8 configtype);
  24static bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
  25					       u8 channel, u8 *stage, u8 *step,
  26					       u32 *delay);
  27static u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw,
  28					 enum wireless_mode wirelessmode,
  29					 long power_indbm);
  30static void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw);
  31static void rtl8723e_phy_set_io(struct ieee80211_hw *hw);
  32
  33u32 rtl8723e_phy_query_rf_reg(struct ieee80211_hw *hw,
  34			      enum radio_path rfpath,
  35			      u32 regaddr, u32 bitmask)
  36{
  37	struct rtl_priv *rtlpriv = rtl_priv(hw);
  38	u32 original_value = 0, readback_value, bitshift;
  39	struct rtl_phy *rtlphy = &rtlpriv->phy;
  40
  41	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  42		"regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
  43		regaddr, rfpath, bitmask);
  44
  45	spin_lock(&rtlpriv->locks.rf_lock);
  46
  47	if (rtlphy->rf_mode != RF_OP_BY_FW) {
  48		original_value = rtl8723_phy_rf_serial_read(hw,
  49							    rfpath, regaddr);
  50	}
  51
  52	bitshift = calculate_bit_shift(bitmask);
  53	readback_value = (original_value & bitmask) >> bitshift;
  54
  55	spin_unlock(&rtlpriv->locks.rf_lock);
  56
  57	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  58		"regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
  59		regaddr, rfpath, bitmask, original_value);
  60
  61	return readback_value;
  62}
  63
  64void rtl8723e_phy_set_rf_reg(struct ieee80211_hw *hw,
  65			     enum radio_path rfpath,
  66			   u32 regaddr, u32 bitmask, u32 data)
  67{
  68	struct rtl_priv *rtlpriv = rtl_priv(hw);
  69	struct rtl_phy *rtlphy = &rtlpriv->phy;
  70	u32 original_value = 0, bitshift;
  71
  72	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
  73		"regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
  74		regaddr, bitmask, data, rfpath);
  75
  76	spin_lock(&rtlpriv->locks.rf_lock);
  77
  78	if (rtlphy->rf_mode != RF_OP_BY_FW) {
  79		if (bitmask != RFREG_OFFSET_MASK) {
  80			original_value = rtl8723_phy_rf_serial_read(hw,
  81								    rfpath,
  82								    regaddr);
  83			bitshift = calculate_bit_shift(bitmask);
  84			data =
  85			    ((original_value & (~bitmask)) |
  86			     (data << bitshift));
  87		}
  88
  89		rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data);
  90	} else {
  91		if (bitmask != RFREG_OFFSET_MASK) {
  92			bitshift = calculate_bit_shift(bitmask);
  93			data =
  94			    ((original_value & (~bitmask)) |
  95			     (data << bitshift));
  96		}
  97		_rtl8723e_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);
  98	}
  99
 100	spin_unlock(&rtlpriv->locks.rf_lock);
 101
 102	rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,
 103		"regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
 104		regaddr, bitmask, data, rfpath);
 105
 106}
 107
 108static void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw,
 109					     enum radio_path rfpath, u32 offset,
 110					     u32 data)
 111{
 112	WARN_ONCE(true, "rtl8723ae: _rtl8723e_phy_fw_rf_serial_write deprecated!\n");
 113}
 114
 115static void _rtl8723e_phy_bb_config_1t(struct ieee80211_hw *hw)
 116{
 117	rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);
 118	rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);
 119	rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);
 120	rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);
 121	rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);
 122	rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);
 123	rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);
 124	rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);
 125	rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);
 126	rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);
 127}
 128
 129bool rtl8723e_phy_mac_config(struct ieee80211_hw *hw)
 130{
 131	struct rtl_priv *rtlpriv = rtl_priv(hw);
 132	bool rtstatus = _rtl8723e_phy_config_mac_with_headerfile(hw);
 133	rtl_write_byte(rtlpriv, 0x04CA, 0x0A);
 134	return rtstatus;
 135}
 136
 137bool rtl8723e_phy_bb_config(struct ieee80211_hw *hw)
 138{
 139	bool rtstatus = true;
 140	struct rtl_priv *rtlpriv = rtl_priv(hw);
 141	u8 tmpu1b;
 142	u8 b_reg_hwparafile = 1;
 143
 144	rtl8723_phy_init_bb_rf_reg_def(hw);
 145
 146	/* 1. 0x28[1] = 1 */
 147	tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);
 148	udelay(2);
 149	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1)));
 150	udelay(2);
 151	/* 2. 0x29[7:0] = 0xFF */
 152	rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff);
 153	udelay(2);
 154
 155	/* 3. 0x02[1:0] = 2b'11 */
 156	tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);
 157	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
 158		       (tmpu1b | FEN_BB_GLB_RSTN | FEN_BBRSTB));
 159
 160	/* 4. 0x25[6] = 0 */
 161	tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1);
 162	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b & (~BIT(6))));
 163
 164	/* 5. 0x24[20] = 0	//Advised by SD3 Alex Wang. 2011.02.09. */
 165	tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2);
 166	rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b & (~BIT(4))));
 167
 168	/* 6. 0x1f[7:0] = 0x07 */
 169	rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07);
 170
 171	if (b_reg_hwparafile == 1)
 172		rtstatus = _rtl8723e_phy_bb8192c_config_parafile(hw);
 173	return rtstatus;
 174}
 175
 176bool rtl8723e_phy_rf_config(struct ieee80211_hw *hw)
 177{
 178	return rtl8723e_phy_rf6052_config(hw);
 179}
 180
 181static bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)
 182{
 183	struct rtl_priv *rtlpriv = rtl_priv(hw);
 184	struct rtl_phy *rtlphy = &rtlpriv->phy;
 185	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 186	bool rtstatus;
 187
 188	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n");
 189	rtstatus = _rtl8723e_phy_config_bb_with_headerfile(hw,
 190						BASEBAND_CONFIG_PHY_REG);
 191	if (!rtstatus) {
 192		pr_err("Write BB Reg Fail!!\n");
 193		return false;
 194	}
 195
 196	if (rtlphy->rf_type == RF_1T2R) {
 197		_rtl8723e_phy_bb_config_1t(hw);
 198		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");
 199	}
 200	if (rtlefuse->autoload_failflag == false) {
 201		rtlphy->pwrgroup_cnt = 0;
 202		rtstatus = _rtl8723e_phy_config_bb_with_pgheaderfile(hw,
 203					BASEBAND_CONFIG_PHY_REG);
 204	}
 205	if (!rtstatus) {
 206		pr_err("BB_PG Reg Fail!!\n");
 207		return false;
 208	}
 209	rtstatus =
 210	  _rtl8723e_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB);
 211	if (!rtstatus) {
 212		pr_err("AGC Table Fail\n");
 213		return false;
 214	}
 215	rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,
 216					RFPGA0_XA_HSSIPARAMETER2,
 217					0x200));
 218
 219	return true;
 220}
 221
 222static bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
 223{
 224	struct rtl_priv *rtlpriv = rtl_priv(hw);
 225	u32 i;
 226	u32 arraylength;
 227	u32 *ptrarray;
 228
 229	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n");
 230	arraylength = RTL8723E_MACARRAYLENGTH;
 231	ptrarray = RTL8723EMAC_ARRAY;
 232
 233	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 234		"Img:RTL8192CEMAC_2T_ARRAY\n");
 235	for (i = 0; i < arraylength; i = i + 2)
 236		rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);
 237	return true;
 238}
 239
 240static bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
 241						    u8 configtype)
 242{
 243	int i;
 244	u32 *phy_regarray_table;
 245	u32 *agctab_array_table;
 246	u16 phy_reg_arraylen, agctab_arraylen;
 247	struct rtl_priv *rtlpriv = rtl_priv(hw);
 248
 249	agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH;
 250	agctab_array_table = RTL8723EAGCTAB_1TARRAY;
 251	phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH;
 252	phy_regarray_table = RTL8723EPHY_REG_1TARRAY;
 253	if (configtype == BASEBAND_CONFIG_PHY_REG) {
 254		for (i = 0; i < phy_reg_arraylen; i = i + 2) {
 255			if (phy_regarray_table[i] == 0xfe)
 256				mdelay(50);
 257			else if (phy_regarray_table[i] == 0xfd)
 258				mdelay(5);
 259			else if (phy_regarray_table[i] == 0xfc)
 260				mdelay(1);
 261			else if (phy_regarray_table[i] == 0xfb)
 262				udelay(50);
 263			else if (phy_regarray_table[i] == 0xfa)
 264				udelay(5);
 265			else if (phy_regarray_table[i] == 0xf9)
 266				udelay(1);
 267			rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,
 268				      phy_regarray_table[i + 1]);
 269			udelay(1);
 270			rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 271				"The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
 272				phy_regarray_table[i],
 273				phy_regarray_table[i + 1]);
 274		}
 275	} else if (configtype == BASEBAND_CONFIG_AGC_TAB) {
 276		for (i = 0; i < agctab_arraylen; i = i + 2) {
 277			rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,
 278				      agctab_array_table[i + 1]);
 279			udelay(1);
 280			rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 281				"The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",
 282				agctab_array_table[i],
 283				agctab_array_table[i + 1]);
 284		}
 285	}
 286	return true;
 287}
 288
 289static void store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,
 290					   u32 regaddr, u32 bitmask,
 291					   u32 data)
 292{
 293	struct rtl_priv *rtlpriv = rtl_priv(hw);
 294	struct rtl_phy *rtlphy = &rtlpriv->phy;
 295
 296	if (regaddr == RTXAGC_A_RATE18_06) {
 297		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =
 298		    data;
 299		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 300			"MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",
 301			rtlphy->pwrgroup_cnt,
 302			rtlphy->mcs_txpwrlevel_origoffset
 303			[rtlphy->pwrgroup_cnt][0]);
 304	}
 305	if (regaddr == RTXAGC_A_RATE54_24) {
 306		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =
 307		    data;
 308		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 309			"MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",
 310			rtlphy->pwrgroup_cnt,
 311			rtlphy->mcs_txpwrlevel_origoffset[rtlphy->
 312							    pwrgroup_cnt][1]);
 313	}
 314	if (regaddr == RTXAGC_A_CCK1_MCS32) {
 315		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =
 316		    data;
 317		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 318			"MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",
 319			rtlphy->pwrgroup_cnt,
 320			rtlphy->mcs_txpwrlevel_origoffset
 321			[rtlphy->pwrgroup_cnt][6]);
 322	}
 323	if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {
 324		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =
 325		    data;
 326		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 327			"MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",
 328			rtlphy->pwrgroup_cnt,
 329			rtlphy->mcs_txpwrlevel_origoffset
 330			[rtlphy->pwrgroup_cnt][7]);
 331	}
 332	if (regaddr == RTXAGC_A_MCS03_MCS00) {
 333		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =
 334		    data;
 335		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 336			"MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",
 337			rtlphy->pwrgroup_cnt,
 338			rtlphy->mcs_txpwrlevel_origoffset
 339			[rtlphy->pwrgroup_cnt][2]);
 340	}
 341	if (regaddr == RTXAGC_A_MCS07_MCS04) {
 342		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =
 343		    data;
 344		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 345			"MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",
 346			rtlphy->pwrgroup_cnt,
 347			rtlphy->mcs_txpwrlevel_origoffset
 348			[rtlphy->pwrgroup_cnt][3]);
 349	}
 350	if (regaddr == RTXAGC_A_MCS11_MCS08) {
 351		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =
 352		    data;
 353		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 354			"MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",
 355			rtlphy->pwrgroup_cnt,
 356			rtlphy->mcs_txpwrlevel_origoffset
 357			[rtlphy->pwrgroup_cnt][4]);
 358	}
 359	if (regaddr == RTXAGC_A_MCS15_MCS12) {
 360		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =
 361		    data;
 362		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 363			"MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",
 364			rtlphy->pwrgroup_cnt,
 365			rtlphy->mcs_txpwrlevel_origoffset
 366			[rtlphy->pwrgroup_cnt][5]);
 367	}
 368	if (regaddr == RTXAGC_B_RATE18_06) {
 369		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =
 370		    data;
 371		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 372			"MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",
 373			rtlphy->pwrgroup_cnt,
 374			rtlphy->mcs_txpwrlevel_origoffset
 375			[rtlphy->pwrgroup_cnt][8]);
 376	}
 377	if (regaddr == RTXAGC_B_RATE54_24) {
 378		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =
 379		    data;
 380		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 381			"MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",
 382			rtlphy->pwrgroup_cnt,
 383			rtlphy->mcs_txpwrlevel_origoffset
 384			[rtlphy->pwrgroup_cnt][9]);
 385	}
 386	if (regaddr == RTXAGC_B_CCK1_55_MCS32) {
 387		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =
 388		    data;
 389		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 390			"MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",
 391			rtlphy->pwrgroup_cnt,
 392			rtlphy->mcs_txpwrlevel_origoffset
 393			[rtlphy->pwrgroup_cnt][14]);
 394	}
 395	if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {
 396		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =
 397		    data;
 398		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 399			"MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",
 400			rtlphy->pwrgroup_cnt,
 401			rtlphy->mcs_txpwrlevel_origoffset
 402			[rtlphy->pwrgroup_cnt][15]);
 403	}
 404	if (regaddr == RTXAGC_B_MCS03_MCS00) {
 405		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =
 406		    data;
 407		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 408			"MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",
 409			rtlphy->pwrgroup_cnt,
 410			rtlphy->mcs_txpwrlevel_origoffset
 411			[rtlphy->pwrgroup_cnt][10]);
 412	}
 413	if (regaddr == RTXAGC_B_MCS07_MCS04) {
 414		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =
 415		    data;
 416		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 417			"MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",
 418			rtlphy->pwrgroup_cnt,
 419			rtlphy->mcs_txpwrlevel_origoffset
 420			[rtlphy->pwrgroup_cnt][11]);
 421	}
 422	if (regaddr == RTXAGC_B_MCS11_MCS08) {
 423		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =
 424		    data;
 425		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 426			"MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",
 427			rtlphy->pwrgroup_cnt,
 428			rtlphy->mcs_txpwrlevel_origoffset
 429			[rtlphy->pwrgroup_cnt][12]);
 430	}
 431	if (regaddr == RTXAGC_B_MCS15_MCS12) {
 432		rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =
 433		    data;
 434		rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 435			"MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",
 436			rtlphy->pwrgroup_cnt,
 437			rtlphy->mcs_txpwrlevel_origoffset
 438			[rtlphy->pwrgroup_cnt][13]);
 439
 440		rtlphy->pwrgroup_cnt++;
 441	}
 442}
 443
 444static bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
 445						      u8 configtype)
 446{
 447	struct rtl_priv *rtlpriv = rtl_priv(hw);
 448	int i;
 449	u32 *phy_regarray_table_pg;
 450	u16 phy_regarray_pg_len;
 451
 452	phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH;
 453	phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG;
 454
 455	if (configtype == BASEBAND_CONFIG_PHY_REG) {
 456		for (i = 0; i < phy_regarray_pg_len; i = i + 3) {
 457			if (phy_regarray_table_pg[i] == 0xfe)
 458				mdelay(50);
 459			else if (phy_regarray_table_pg[i] == 0xfd)
 460				mdelay(5);
 461			else if (phy_regarray_table_pg[i] == 0xfc)
 462				mdelay(1);
 463			else if (phy_regarray_table_pg[i] == 0xfb)
 464				udelay(50);
 465			else if (phy_regarray_table_pg[i] == 0xfa)
 466				udelay(5);
 467			else if (phy_regarray_table_pg[i] == 0xf9)
 468				udelay(1);
 469
 470			store_pwrindex_diffrate_offset(hw,
 471						phy_regarray_table_pg[i],
 472						phy_regarray_table_pg[i + 1],
 473						phy_regarray_table_pg[i + 2]);
 474		}
 475	} else {
 476		rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,
 477			"configtype != BaseBand_Config_PHY_REG\n");
 478	}
 479	return true;
 480}
 481
 482bool rtl8723e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
 483					    enum radio_path rfpath)
 484{
 485	int i;
 486	u32 *radioa_array_table;
 487	u16 radioa_arraylen;
 488
 489	radioa_arraylen = RTL8723ERADIOA_1TARRAYLENGTH;
 490	radioa_array_table = RTL8723E_RADIOA_1TARRAY;
 491
 492	switch (rfpath) {
 493	case RF90_PATH_A:
 494		for (i = 0; i < radioa_arraylen; i = i + 2) {
 495			if (radioa_array_table[i] == 0xfe) {
 496				mdelay(50);
 497			} else if (radioa_array_table[i] == 0xfd) {
 498				mdelay(5);
 499			} else if (radioa_array_table[i] == 0xfc) {
 500				mdelay(1);
 501			} else if (radioa_array_table[i] == 0xfb) {
 502				udelay(50);
 503			} else if (radioa_array_table[i] == 0xfa) {
 504				udelay(5);
 505			} else if (radioa_array_table[i] == 0xf9) {
 506				udelay(1);
 507			} else {
 508				rtl_set_rfreg(hw, rfpath, radioa_array_table[i],
 509					      RFREG_OFFSET_MASK,
 510					      radioa_array_table[i + 1]);
 511				udelay(1);
 512			}
 513		}
 514		break;
 515	case RF90_PATH_B:
 516	case RF90_PATH_C:
 517	case RF90_PATH_D:
 518		break;
 519	}
 520	return true;
 521}
 522
 523void rtl8723e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
 524{
 525	struct rtl_priv *rtlpriv = rtl_priv(hw);
 526	struct rtl_phy *rtlphy = &rtlpriv->phy;
 527
 528	rtlphy->default_initialgain[0] =
 529	    (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
 530	rtlphy->default_initialgain[1] =
 531	    (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
 532	rtlphy->default_initialgain[2] =
 533	    (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
 534	rtlphy->default_initialgain[3] =
 535	    (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
 536
 537	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 538		"Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
 539		rtlphy->default_initialgain[0],
 540		rtlphy->default_initialgain[1],
 541		rtlphy->default_initialgain[2],
 542		rtlphy->default_initialgain[3]);
 543
 544	rtlphy->framesync = (u8) rtl_get_bbreg(hw,
 545					       ROFDM0_RXDETECTOR3, MASKBYTE0);
 546	rtlphy->framesync_c34 = rtl_get_bbreg(hw,
 547					      ROFDM0_RXDETECTOR2, MASKDWORD);
 548
 549	rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,
 550		"Default framesync (0x%x) = 0x%x\n",
 551		ROFDM0_RXDETECTOR3, rtlphy->framesync);
 552}
 553
 554void rtl8723e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)
 555{
 556	struct rtl_priv *rtlpriv = rtl_priv(hw);
 557	struct rtl_phy *rtlphy = &rtlpriv->phy;
 558	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 559	u8 txpwr_level;
 560	long txpwr_dbm;
 561
 562	txpwr_level = rtlphy->cur_cck_txpwridx;
 563	txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw,
 564						 WIRELESS_MODE_B, txpwr_level);
 565	txpwr_level = rtlphy->cur_ofdm24g_txpwridx +
 566	    rtlefuse->legacy_ht_txpowerdiff;
 567	if (rtl8723_phy_txpwr_idx_to_dbm(hw,
 568					 WIRELESS_MODE_G,
 569					 txpwr_level) > txpwr_dbm)
 570		txpwr_dbm =
 571		    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,
 572						 txpwr_level);
 573	txpwr_level = rtlphy->cur_ofdm24g_txpwridx;
 574	if (rtl8723_phy_txpwr_idx_to_dbm(hw,
 575					 WIRELESS_MODE_N_24G,
 576					 txpwr_level) > txpwr_dbm)
 577		txpwr_dbm =
 578		    rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,
 579						 txpwr_level);
 580	*powerlevel = txpwr_dbm;
 581}
 582
 583static void _rtl8723e_get_txpower_index(struct ieee80211_hw *hw, u8 channel,
 584					u8 *cckpowerlevel, u8 *ofdmpowerlevel)
 585{
 586	struct rtl_priv *rtlpriv = rtl_priv(hw);
 587	struct rtl_phy *rtlphy = &rtlpriv->phy;
 588	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 589	u8 index = (channel - 1);
 590
 591	cckpowerlevel[RF90_PATH_A] =
 592	    rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];
 593	cckpowerlevel[RF90_PATH_B] =
 594	    rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];
 595	if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {
 596		ofdmpowerlevel[RF90_PATH_A] =
 597		    rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];
 598		ofdmpowerlevel[RF90_PATH_B] =
 599		    rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];
 600	} else if (get_rf_type(rtlphy) == RF_2T2R) {
 601		ofdmpowerlevel[RF90_PATH_A] =
 602		    rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];
 603		ofdmpowerlevel[RF90_PATH_B] =
 604		    rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];
 605	}
 606}
 607
 608static void _rtl8723e_ccxpower_index_check(struct ieee80211_hw *hw,
 609					   u8 channel, u8 *cckpowerlevel,
 610					   u8 *ofdmpowerlevel)
 611{
 612	struct rtl_priv *rtlpriv = rtl_priv(hw);
 613	struct rtl_phy *rtlphy = &rtlpriv->phy;
 614
 615	rtlphy->cur_cck_txpwridx = cckpowerlevel[0];
 616	rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];
 617
 618}
 619
 620void rtl8723e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
 621{
 622	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 623	u8 cckpowerlevel[2], ofdmpowerlevel[2];
 624
 625	if (!rtlefuse->txpwr_fromeprom)
 626		return;
 627	_rtl8723e_get_txpower_index(hw, channel,
 628				    &cckpowerlevel[0], &ofdmpowerlevel[0]);
 629	_rtl8723e_ccxpower_index_check(hw,
 630				       channel, &cckpowerlevel[0],
 631				       &ofdmpowerlevel[0]);
 632	rtl8723e_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);
 633	rtl8723e_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);
 634}
 635
 636bool rtl8723e_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)
 637{
 638	struct rtl_priv *rtlpriv = rtl_priv(hw);
 639	struct rtl_phy *rtlphy = &rtlpriv->phy;
 640	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
 641	u8 idx;
 642	u8 rf_path;
 643	u8 ccktxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw,
 644						      WIRELESS_MODE_B,
 645						      power_indbm);
 646	u8 ofdmtxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw,
 647						       WIRELESS_MODE_N_24G,
 648						       power_indbm);
 649	if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)
 650		ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;
 651	else
 652		ofdmtxpwridx = 0;
 653	rtl_dbg(rtlpriv, COMP_TXAGC, DBG_TRACE,
 654		"%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",
 655		power_indbm, ccktxpwridx, ofdmtxpwridx);
 656	for (idx = 0; idx < 14; idx++) {
 657		for (rf_path = 0; rf_path < 2; rf_path++) {
 658			rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;
 659			rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =
 660			    ofdmtxpwridx;
 661			rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =
 662			    ofdmtxpwridx;
 663		}
 664	}
 665	rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel);
 666	return true;
 667}
 668
 669static u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw,
 670					 enum wireless_mode wirelessmode,
 671					 long power_indbm)
 672{
 673	u8 txpwridx;
 674	long offset;
 675
 676	switch (wirelessmode) {
 677	case WIRELESS_MODE_B:
 678		offset = -7;
 679		break;
 680	case WIRELESS_MODE_G:
 681	case WIRELESS_MODE_N_24G:
 682		offset = -8;
 683		break;
 684	default:
 685		offset = -8;
 686		break;
 687	}
 688
 689	if ((power_indbm - offset) > 0)
 690		txpwridx = (u8)((power_indbm - offset) * 2);
 691	else
 692		txpwridx = 0;
 693
 694	if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)
 695		txpwridx = MAX_TXPWR_IDX_NMODE_92S;
 696
 697	return txpwridx;
 698}
 699
 700void rtl8723e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
 701{
 702	struct rtl_priv *rtlpriv = rtl_priv(hw);
 703	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 704	enum io_type iotype;
 705
 706	if (!is_hal_stop(rtlhal)) {
 707		switch (operation) {
 708		case SCAN_OPT_BACKUP_BAND0:
 709			iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
 710			rtlpriv->cfg->ops->set_hw_reg(hw,
 711						      HW_VAR_IO_CMD,
 712						      (u8 *)&iotype);
 713
 714			break;
 715		case SCAN_OPT_RESTORE:
 716			iotype = IO_CMD_RESUME_DM_BY_SCAN;
 717			rtlpriv->cfg->ops->set_hw_reg(hw,
 718						      HW_VAR_IO_CMD,
 719						      (u8 *)&iotype);
 720			break;
 721		default:
 722			pr_err("Unknown Scan Backup operation.\n");
 723			break;
 724		}
 725	}
 726}
 727
 728void rtl8723e_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
 729{
 730	struct rtl_priv *rtlpriv = rtl_priv(hw);
 731	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 732	struct rtl_phy *rtlphy = &rtlpriv->phy;
 733	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
 734	u8 reg_bw_opmode;
 735	u8 reg_prsr_rsc;
 736
 737	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
 738		"Switch to %s bandwidth\n",
 739		rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
 740		"20MHz" : "40MHz");
 741
 742	if (is_hal_stop(rtlhal)) {
 743		rtlphy->set_bwmode_inprogress = false;
 744		return;
 745	}
 746
 747	reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
 748	reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
 749
 750	switch (rtlphy->current_chan_bw) {
 751	case HT_CHANNEL_WIDTH_20:
 752		reg_bw_opmode |= BW_OPMODE_20MHZ;
 753		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
 754		break;
 755	case HT_CHANNEL_WIDTH_20_40:
 756		reg_bw_opmode &= ~BW_OPMODE_20MHZ;
 757		rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
 758		reg_prsr_rsc =
 759		    (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);
 760		rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
 761		break;
 762	default:
 763		pr_err("unknown bandwidth: %#X\n",
 764		       rtlphy->current_chan_bw);
 765		break;
 766	}
 767
 768	switch (rtlphy->current_chan_bw) {
 769	case HT_CHANNEL_WIDTH_20:
 770		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
 771		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
 772		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);
 773		break;
 774	case HT_CHANNEL_WIDTH_20_40:
 775		rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
 776		rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
 777
 778		rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
 779			      (mac->cur_40_prime_sc >> 1));
 780		rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
 781		rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);
 782
 783		rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
 784			      (mac->cur_40_prime_sc ==
 785			       HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
 786		break;
 787	default:
 788		pr_err("unknown bandwidth: %#X\n",
 789		       rtlphy->current_chan_bw);
 790		break;
 791	}
 792	rtl8723e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
 793	rtlphy->set_bwmode_inprogress = false;
 794	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
 795}
 796
 797void rtl8723e_phy_set_bw_mode(struct ieee80211_hw *hw,
 798			      enum nl80211_channel_type ch_type)
 799{
 800	struct rtl_priv *rtlpriv = rtl_priv(hw);
 801	struct rtl_phy *rtlphy = &rtlpriv->phy;
 802	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 803	u8 tmp_bw = rtlphy->current_chan_bw;
 804
 805	if (rtlphy->set_bwmode_inprogress)
 806		return;
 807	rtlphy->set_bwmode_inprogress = true;
 808	if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
 809		rtl8723e_phy_set_bw_mode_callback(hw);
 810	} else {
 811		rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
 812			"false driver sleep or unload\n");
 813		rtlphy->set_bwmode_inprogress = false;
 814		rtlphy->current_chan_bw = tmp_bw;
 815	}
 816}
 817
 818void rtl8723e_phy_sw_chnl_callback(struct ieee80211_hw *hw)
 819{
 820	struct rtl_priv *rtlpriv = rtl_priv(hw);
 821	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 822	struct rtl_phy *rtlphy = &rtlpriv->phy;
 823	u32 delay;
 824
 825	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,
 826		"switch to channel%d\n", rtlphy->current_channel);
 827	if (is_hal_stop(rtlhal))
 828		return;
 829	do {
 830		if (!rtlphy->sw_chnl_inprogress)
 831			break;
 832		if (!_rtl8723e_phy_sw_chnl_step_by_step
 833		    (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,
 834		     &rtlphy->sw_chnl_step, &delay)) {
 835			if (delay > 0)
 836				mdelay(delay);
 837			else
 838				continue;
 839		} else {
 840			rtlphy->sw_chnl_inprogress = false;
 841		}
 842		break;
 843	} while (true);
 844	rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
 845}
 846
 847u8 rtl8723e_phy_sw_chnl(struct ieee80211_hw *hw)
 848{
 849	struct rtl_priv *rtlpriv = rtl_priv(hw);
 850	struct rtl_phy *rtlphy = &rtlpriv->phy;
 851	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 852
 853	if (rtlphy->sw_chnl_inprogress)
 854		return 0;
 855	if (rtlphy->set_bwmode_inprogress)
 856		return 0;
 857	WARN_ONCE((rtlphy->current_channel > 14),
 858		  "rtl8723ae: WIRELESS_MODE_G but channel>14");
 859	rtlphy->sw_chnl_inprogress = true;
 860	rtlphy->sw_chnl_stage = 0;
 861	rtlphy->sw_chnl_step = 0;
 862	if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
 863		rtl8723e_phy_sw_chnl_callback(hw);
 864		rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,
 865			"sw_chnl_inprogress false schedule workitem\n");
 866		rtlphy->sw_chnl_inprogress = false;
 867	} else {
 868		rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,
 869			"sw_chnl_inprogress false driver sleep or unload\n");
 870		rtlphy->sw_chnl_inprogress = false;
 871	}
 872	return 1;
 873}
 874
 875static void _rtl8723e_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)
 876{
 877	struct rtl_priv *rtlpriv = rtl_priv(hw);
 878	struct rtl_phy *rtlphy = &rtlpriv->phy;
 879	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
 880
 881	if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) {
 882		if (channel == 6 && rtlphy->current_chan_bw ==
 883				HT_CHANNEL_WIDTH_20)
 884			rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1,
 885				      MASKDWORD, 0x00255);
 886		else{
 887			u32 backuprf0x1a = (u32)rtl_get_rfreg(hw,
 888					RF90_PATH_A, RF_RX_G1,
 889					RFREG_OFFSET_MASK);
 890			rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1,
 891				      MASKDWORD, backuprf0x1a);
 892		}
 893	}
 894}
 895
 896static bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
 897					       u8 channel, u8 *stage, u8 *step,
 898					       u32 *delay)
 899{
 900	struct rtl_priv *rtlpriv = rtl_priv(hw);
 901	struct rtl_phy *rtlphy = &rtlpriv->phy;
 902	struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
 903	u32 precommoncmdcnt;
 904	struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
 905	u32 postcommoncmdcnt;
 906	struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
 907	u32 rfdependcmdcnt;
 908	struct swchnlcmd *currentcmd = NULL;
 909	u8 rfpath;
 910	u8 num_total_rfpath = rtlphy->num_total_rfpath;
 911
 912	precommoncmdcnt = 0;
 913	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
 914					 MAX_PRECMD_CNT,
 915					 CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);
 916	rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
 917					 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
 918
 919	postcommoncmdcnt = 0;
 920
 921	rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
 922					 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);
 923
 924	rfdependcmdcnt = 0;
 925
 926	WARN_ONCE((channel < 1 || channel > 14),
 927		  "rtl8723ae: illegal channel for Zebra: %d\n", channel);
 928
 929	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 930					 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,
 931					 RF_CHNLBW, channel, 10);
 932
 933	rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
 934					 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,
 935					 0);
 936
 937	do {
 938		switch (*stage) {
 939		case 0:
 940			currentcmd = &precommoncmd[*step];
 941			break;
 942		case 1:
 943			currentcmd = &rfdependcmd[*step];
 944			break;
 945		case 2:
 946			currentcmd = &postcommoncmd[*step];
 947			break;
 948		default:
 949			pr_err("Invalid 'stage' = %d, Check it!\n",
 950			       *stage);
 951			return true;
 952		}
 953
 954		if (currentcmd->cmdid == CMDID_END) {
 955			if ((*stage) == 2) {
 956				return true;
 957			} else {
 958				(*stage)++;
 959				(*step) = 0;
 960				continue;
 961			}
 962		}
 963
 964		switch (currentcmd->cmdid) {
 965		case CMDID_SET_TXPOWEROWER_LEVEL:
 966			rtl8723e_phy_set_txpower_level(hw, channel);
 967			break;
 968		case CMDID_WRITEPORT_ULONG:
 969			rtl_write_dword(rtlpriv, currentcmd->para1,
 970					currentcmd->para2);
 971			break;
 972		case CMDID_WRITEPORT_USHORT:
 973			rtl_write_word(rtlpriv, currentcmd->para1,
 974				       (u16) currentcmd->para2);
 975			break;
 976		case CMDID_WRITEPORT_UCHAR:
 977			rtl_write_byte(rtlpriv, currentcmd->para1,
 978				       (u8) currentcmd->para2);
 979			break;
 980		case CMDID_RF_WRITEREG:
 981			for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
 982				rtlphy->rfreg_chnlval[rfpath] =
 983				    ((rtlphy->rfreg_chnlval[rfpath] &
 984				      0xfffffc00) | currentcmd->para2);
 985
 986				rtl_set_rfreg(hw, (enum radio_path)rfpath,
 987					      currentcmd->para1,
 988					      RFREG_OFFSET_MASK,
 989					      rtlphy->rfreg_chnlval[rfpath]);
 990			}
 991			_rtl8723e_phy_sw_rf_seting(hw, channel);
 992			break;
 993		default:
 994			rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
 995				"switch case %#x not processed\n",
 996				currentcmd->cmdid);
 997			break;
 998		}
 999
1000		break;
1001	} while (true);
1002
1003	(*delay) = currentcmd->msdelay;
1004	(*step)++;
1005	return false;
1006}
1007
1008static u8 _rtl8723e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)
1009{
1010	u32 reg_eac, reg_e94, reg_e9c, reg_ea4;
1011	u8 result = 0x00;
1012
1013	rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);
1014	rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);
1015	rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);
1016	rtl_set_bbreg(hw, 0xe3c, MASKDWORD,
1017		      config_pathb ? 0x28160202 : 0x28160502);
1018
1019	if (config_pathb) {
1020		rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);
1021		rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);
1022		rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);
1023		rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);
1024	}
1025
1026	rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);
1027	rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);
1028	rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);
1029
1030	mdelay(IQK_DELAY_TIME);
1031
1032	reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1033	reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1034	reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1035	reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);
1036
1037	if (!(reg_eac & BIT(28)) &&
1038	    (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1039	    (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1040		result |= 0x01;
1041	else
1042		return result;
1043
1044	if (!(reg_eac & BIT(27)) &&
1045	    (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1046	    (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1047		result |= 0x02;
1048	return result;
1049}
1050
1051static u8 _rtl8723e_phy_path_b_iqk(struct ieee80211_hw *hw)
1052{
1053	u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;
1054	u8 result = 0x00;
1055
1056	rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);
1057	rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);
1058	mdelay(IQK_DELAY_TIME);
1059	reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1060	reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);
1061	reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);
1062	reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);
1063	reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);
1064
1065	if (!(reg_eac & BIT(31)) &&
1066	    (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&
1067	    (((reg_ebc & 0x03FF0000) >> 16) != 0x42))
1068		result |= 0x01;
1069	else
1070		return result;
1071	if (!(reg_eac & BIT(30)) &&
1072	    (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&
1073	    (((reg_ecc & 0x03FF0000) >> 16) != 0x36))
1074		result |= 0x02;
1075	return result;
1076}
1077
1078static bool _rtl8723e_phy_simularity_compare(struct ieee80211_hw *hw,
1079					     long result[][8], u8 c1, u8 c2)
1080{
1081	u32 i, j, diff, simularity_bitmap, bound;
1082
1083	u8 final_candidate[2] = { 0xFF, 0xFF };
1084	bool bresult = true;
1085
1086	bound = 4;
1087
1088	simularity_bitmap = 0;
1089
1090	for (i = 0; i < bound; i++) {
1091		diff = (result[c1][i] > result[c2][i]) ?
1092		    (result[c1][i] - result[c2][i]) :
1093		    (result[c2][i] - result[c1][i]);
1094
1095		if (diff > MAX_TOLERANCE) {
1096			if ((i == 2 || i == 6) && !simularity_bitmap) {
1097				if (result[c1][i] + result[c1][i + 1] == 0)
1098					final_candidate[(i / 4)] = c2;
1099				else if (result[c2][i] + result[c2][i + 1] == 0)
1100					final_candidate[(i / 4)] = c1;
1101				else
1102					simularity_bitmap = simularity_bitmap |
1103					    (1 << i);
1104			} else
1105				simularity_bitmap =
1106				    simularity_bitmap | (1 << i);
1107		}
1108	}
1109
1110	if (simularity_bitmap == 0) {
1111		for (i = 0; i < (bound / 4); i++) {
1112			if (final_candidate[i] != 0xFF) {
1113				for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1114					result[3][j] =
1115					    result[final_candidate[i]][j];
1116				bresult = false;
1117			}
1118		}
1119		return bresult;
1120	} else if (!(simularity_bitmap & 0x0F)) {
1121		for (i = 0; i < 4; i++)
1122			result[3][i] = result[c1][i];
1123		return false;
1124	} else {
1125		return false;
1126	}
1127
1128}
1129
1130static void _rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw,
1131				       long result[][8], u8 t, bool is2t)
1132{
1133	struct rtl_priv *rtlpriv = rtl_priv(hw);
1134	struct rtl_phy *rtlphy = &rtlpriv->phy;
1135	u32 i;
1136	u8 patha_ok, pathb_ok;
1137	u32 adda_reg[IQK_ADDA_REG_NUM] = {
1138		0x85c, 0xe6c, 0xe70, 0xe74,
1139		0xe78, 0xe7c, 0xe80, 0xe84,
1140		0xe88, 0xe8c, 0xed0, 0xed4,
1141		0xed8, 0xedc, 0xee0, 0xeec
1142	};
1143
1144	u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
1145		0x522, 0x550, 0x551, 0x040
1146	};
1147
1148	const u32 retrycount = 2;
1149
1150	if (t == 0) {
1151		rtl_get_bbreg(hw, 0x800, MASKDWORD);
1152
1153		rtl8723_save_adda_registers(hw, adda_reg,
1154					    rtlphy->adda_backup, 16);
1155		rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
1156					       rtlphy->iqk_mac_backup);
1157	}
1158	rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
1159	if (t == 0) {
1160		rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,
1161					RFPGA0_XA_HSSIPARAMETER1,
1162					BIT(8));
1163	}
1164
1165	if (!rtlphy->rfpi_enable)
1166		rtl8723_phy_pi_mode_switch(hw, true);
1167	if (t == 0) {
1168		rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);
1169		rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);
1170		rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);
1171	}
1172	rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
1173	rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
1174	rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
1175	if (is2t) {
1176		rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);
1177		rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);
1178	}
1179	rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
1180					    rtlphy->iqk_mac_backup);
1181	rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);
1182	if (is2t)
1183		rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);
1184	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);
1185	rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);
1186	rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);
1187	for (i = 0; i < retrycount; i++) {
1188		patha_ok = _rtl8723e_phy_path_a_iqk(hw, is2t);
1189		if (patha_ok == 0x03) {
1190			result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
1191					0x3FF0000) >> 16;
1192			result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
1193					0x3FF0000) >> 16;
1194			result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
1195					0x3FF0000) >> 16;
1196			result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
1197					0x3FF0000) >> 16;
1198			break;
1199		} else if (i == (retrycount - 1) && patha_ok == 0x01)
1200
1201			result[t][0] = (rtl_get_bbreg(hw, 0xe94,
1202						      MASKDWORD) & 0x3FF0000) >>
1203			    16;
1204		result[t][1] =
1205		    (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;
1206
1207	}
1208
1209	if (is2t) {
1210		rtl8723_phy_path_a_standby(hw);
1211		rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);
1212		for (i = 0; i < retrycount; i++) {
1213			pathb_ok = _rtl8723e_phy_path_b_iqk(hw);
1214			if (pathb_ok == 0x03) {
1215				result[t][4] = (rtl_get_bbreg(hw,
1216							      0xeb4,
1217							      MASKDWORD) &
1218						0x3FF0000) >> 16;
1219				result[t][5] =
1220				    (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1221				     0x3FF0000) >> 16;
1222				result[t][6] =
1223				    (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &
1224				     0x3FF0000) >> 16;
1225				result[t][7] =
1226				    (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &
1227				     0x3FF0000) >> 16;
1228				break;
1229			} else if (i == (retrycount - 1) && pathb_ok == 0x01) {
1230				result[t][4] = (rtl_get_bbreg(hw,
1231							      0xeb4,
1232							      MASKDWORD) &
1233						0x3FF0000) >> 16;
1234			}
1235			result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &
1236					0x3FF0000) >> 16;
1237		}
1238	}
1239	rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);
1240	rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);
1241	rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);
1242	rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);
1243	rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);
1244	if (is2t)
1245		rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);
1246	if (t != 0) {
1247		if (!rtlphy->rfpi_enable)
1248			rtl8723_phy_pi_mode_switch(hw, false);
1249		rtl8723_phy_reload_adda_registers(hw, adda_reg,
1250						  rtlphy->adda_backup, 16);
1251		rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
1252						 rtlphy->iqk_mac_backup);
1253	}
1254}
1255
1256static void _rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
1257{
1258	u8 tmpreg;
1259	u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
1260	struct rtl_priv *rtlpriv = rtl_priv(hw);
1261
1262	tmpreg = rtl_read_byte(rtlpriv, 0xd03);
1263
1264	if ((tmpreg & 0x70) != 0)
1265		rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
1266	else
1267		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1268
1269	if ((tmpreg & 0x70) != 0) {
1270		rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
1271
1272		if (is2t)
1273			rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
1274						  MASK12BITS);
1275
1276		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
1277			      (rf_a_mode & 0x8FFFF) | 0x10000);
1278
1279		if (is2t)
1280			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1281				      (rf_b_mode & 0x8FFFF) | 0x10000);
1282	}
1283	lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
1284
1285	rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);
1286
1287	mdelay(100);
1288
1289	if ((tmpreg & 0x70) != 0) {
1290		rtl_write_byte(rtlpriv, 0xd03, tmpreg);
1291		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
1292
1293		if (is2t)
1294			rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
1295				      rf_b_mode);
1296	} else {
1297		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1298	}
1299}
1300
1301static void _rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw,
1302					    bool bmain, bool is2t)
1303{
1304	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1305
1306	if (is_hal_stop(rtlhal)) {
1307		rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);
1308		rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);
1309	}
1310	if (is2t) {
1311		if (bmain)
1312			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1313				      BIT(5) | BIT(6), 0x1);
1314		else
1315			rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,
1316				      BIT(5) | BIT(6), 0x2);
1317	} else {
1318		if (bmain)
1319			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);
1320		else
1321			rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);
1322
1323	}
1324
1325}
1326
1327#undef IQK_ADDA_REG_NUM
1328#undef IQK_DELAY_TIME
1329
1330void rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
1331{
1332	struct rtl_priv *rtlpriv = rtl_priv(hw);
1333	struct rtl_phy *rtlphy = &rtlpriv->phy;
1334
1335	long result[4][8];
1336	u8 i, final_candidate;
1337	bool b_patha_ok;
1338	long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc,
1339	   reg_tmp = 0;
1340	bool is12simular, is13simular, is23simular;
1341	u32 iqk_bb_reg[10] = {
1342		ROFDM0_XARXIQIMBALANCE,
1343		ROFDM0_XBRXIQIMBALANCE,
1344		ROFDM0_ECCATHRESHOLD,
1345		ROFDM0_AGCRSSITABLE,
1346		ROFDM0_XATXIQIMBALANCE,
1347		ROFDM0_XBTXIQIMBALANCE,
1348		ROFDM0_XCTXIQIMBALANCE,
1349		ROFDM0_XCTXAFE,
1350		ROFDM0_XDTXAFE,
1351		ROFDM0_RXIQEXTANTA
1352	};
1353
1354	if (b_recovery) {
1355		rtl8723_phy_reload_adda_registers(hw,
1356						  iqk_bb_reg,
1357						  rtlphy->iqk_bb_backup, 10);
1358		return;
1359	}
1360	for (i = 0; i < 8; i++) {
1361		result[0][i] = 0;
1362		result[1][i] = 0;
1363		result[2][i] = 0;
1364		result[3][i] = 0;
1365	}
1366	final_candidate = 0xff;
1367	b_patha_ok = false;
1368	is12simular = false;
1369	is23simular = false;
1370	is13simular = false;
1371	for (i = 0; i < 3; i++) {
1372		_rtl8723e_phy_iq_calibrate(hw, result, i, false);
1373		if (i == 1) {
1374			is12simular =
1375			  _rtl8723e_phy_simularity_compare(hw, result, 0, 1);
1376			if (is12simular) {
1377				final_candidate = 0;
1378				break;
1379			}
1380		}
1381		if (i == 2) {
1382			is13simular =
1383			  _rtl8723e_phy_simularity_compare(hw, result, 0, 2);
1384			if (is13simular) {
1385				final_candidate = 0;
1386				break;
1387			}
1388			is23simular =
1389			  _rtl8723e_phy_simularity_compare(hw, result, 1, 2);
1390			if (is23simular)
1391				final_candidate = 1;
1392			else {
1393				for (i = 0; i < 8; i++)
1394					reg_tmp += result[3][i];
1395
1396				if (reg_tmp != 0)
1397					final_candidate = 3;
1398				else
1399					final_candidate = 0xFF;
1400			}
1401		}
1402	}
1403	for (i = 0; i < 4; i++) {
1404		reg_e94 = result[i][0];
1405		reg_e9c = result[i][1];
1406		reg_ea4 = result[i][2];
1407		reg_eb4 = result[i][4];
1408		reg_ebc = result[i][5];
1409	}
1410	if (final_candidate != 0xff) {
1411		rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];
1412		rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];
1413		reg_ea4 = result[final_candidate][2];
1414		rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];
1415		rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];
1416		b_patha_ok = true;
1417	} else {
1418		rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;
1419		rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;
1420	}
1421	if (reg_e94 != 0)
1422		rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
1423						   final_candidate,
1424						   (reg_ea4 == 0));
1425	rtl8723_save_adda_registers(hw, iqk_bb_reg,
1426				    rtlphy->iqk_bb_backup, 10);
1427}
1428
1429void rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw)
1430{
1431	_rtl8723e_phy_lc_calibrate(hw, false);
1432}
1433
1434void rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
1435{
1436	_rtl8723e_phy_set_rfpath_switch(hw, bmain, false);
1437}
1438
1439bool rtl8723e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
1440{
1441	struct rtl_priv *rtlpriv = rtl_priv(hw);
1442	struct rtl_phy *rtlphy = &rtlpriv->phy;
1443	bool postprocessing = false;
1444
1445	rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1446		"-->IO Cmd(%#x), set_io_inprogress(%d)\n",
1447		iotype, rtlphy->set_io_inprogress);
1448	do {
1449		switch (iotype) {
1450		case IO_CMD_RESUME_DM_BY_SCAN:
1451			rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1452				"[IO CMD] Resume DM after scan.\n");
1453			postprocessing = true;
1454			break;
1455		case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
1456			rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1457				"[IO CMD] Pause DM before scan.\n");
1458			postprocessing = true;
1459			break;
1460		default:
1461			rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
1462				"switch case %#x not processed\n", iotype);
1463			break;
1464		}
1465	} while (false);
1466	if (postprocessing && !rtlphy->set_io_inprogress) {
1467		rtlphy->set_io_inprogress = true;
1468		rtlphy->current_io_type = iotype;
1469	} else {
1470		return false;
1471	}
1472	rtl8723e_phy_set_io(hw);
1473	rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
1474	return true;
1475}
1476
1477static void rtl8723e_phy_set_io(struct ieee80211_hw *hw)
1478{
1479	struct rtl_priv *rtlpriv = rtl_priv(hw);
1480	struct rtl_phy *rtlphy = &rtlpriv->phy;
1481	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
1482
1483	rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1484		"--->Cmd(%#x), set_io_inprogress(%d)\n",
1485		rtlphy->current_io_type, rtlphy->set_io_inprogress);
1486	switch (rtlphy->current_io_type) {
1487	case IO_CMD_RESUME_DM_BY_SCAN:
1488		dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
1489		rtl8723e_dm_write_dig(hw);
1490		rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel);
1491		break;
1492	case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
1493		rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
1494		dm_digtable->cur_igvalue = 0x17;
1495		rtl8723e_dm_write_dig(hw);
1496		break;
1497	default:
1498		rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
1499			"switch case %#x not processed\n",
1500			rtlphy->current_io_type);
1501		break;
1502	}
1503	rtlphy->set_io_inprogress = false;
1504	rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,
1505		"(%#x)\n", rtlphy->current_io_type);
1506}
1507
1508static void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw)
1509{
1510	struct rtl_priv *rtlpriv = rtl_priv(hw);
1511
1512	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
1513	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1514	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1515	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1516	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1517	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1518}
1519
1520static void _rtl8723e_phy_set_rf_sleep(struct ieee80211_hw *hw)
1521{
1522	u32 u4b_tmp;
1523	u8 delay = 5;
1524	struct rtl_priv *rtlpriv = rtl_priv(hw);
1525
1526	rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
1527	rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1528	rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1529	u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1530	while (u4b_tmp != 0 && delay > 0) {
1531		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);
1532		rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
1533		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);
1534		u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);
1535		delay--;
1536	}
1537	if (delay == 0) {
1538		rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);
1539		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1540		rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
1541		rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
1542		rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
1543			"Switch RF timeout !!!.\n");
1544		return;
1545	}
1546	rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
1547	rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
1548}
1549
1550static bool _rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw,
1551					     enum rf_pwrstate rfpwr_state)
1552{
1553	struct rtl_priv *rtlpriv = rtl_priv(hw);
1554	struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
1555	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1556	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1557	bool bresult = true;
1558	u8 i, queue_id;
1559	struct rtl8192_tx_ring *ring = NULL;
1560
1561	switch (rfpwr_state) {
1562	case ERFON:
1563		if ((ppsc->rfpwr_state == ERFOFF) &&
1564		    RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
1565			bool rtstatus;
1566			u32 initializecount = 0;
1567
1568			do {
1569				initializecount++;
1570				rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
1571					"IPS Set eRf nic enable\n");
1572				rtstatus = rtl_ps_enable_nic(hw);
1573			} while (!rtstatus && (initializecount < 10));
1574			RT_CLEAR_PS_LEVEL(ppsc,
1575					  RT_RF_OFF_LEVL_HALT_NIC);
1576		} else {
1577			rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
1578				"Set ERFON slept:%d ms\n",
1579				jiffies_to_msecs(jiffies -
1580					   ppsc->last_sleep_jiffies));
1581			ppsc->last_awake_jiffies = jiffies;
1582			rtl8723e_phy_set_rf_on(hw);
1583		}
1584		if (mac->link_state == MAC80211_LINKED) {
1585			rtlpriv->cfg->ops->led_control(hw,
1586						       LED_CTL_LINK);
1587		} else {
1588			rtlpriv->cfg->ops->led_control(hw,
1589						       LED_CTL_NO_LINK);
1590		}
1591		break;
1592	case ERFOFF:
1593		if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
1594			rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
1595				"IPS Set eRf nic disable\n");
1596			rtl_ps_disable_nic(hw);
1597			RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
1598		} else {
1599			if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
1600				rtlpriv->cfg->ops->led_control(hw,
1601						LED_CTL_NO_LINK);
1602			} else {
1603				rtlpriv->cfg->ops->led_control(hw,
1604						LED_CTL_POWER_OFF);
1605			}
1606		}
1607		break;
1608	case ERFSLEEP:
1609		if (ppsc->rfpwr_state == ERFOFF)
1610			break;
1611		for (queue_id = 0, i = 0;
1612		     queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
1613			ring = &pcipriv->dev.tx_ring[queue_id];
1614			if (queue_id == BEACON_QUEUE ||
1615			    skb_queue_len(&ring->queue) == 0) {
1616				queue_id++;
1617				continue;
1618			} else {
1619				rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
1620					"eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
1621					(i + 1), queue_id,
1622					skb_queue_len(&ring->queue));
1623
1624				udelay(10);
1625				i++;
1626			}
1627			if (i >= MAX_DOZE_WAITING_TIMES_9x) {
1628				rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,
1629					"ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
1630					MAX_DOZE_WAITING_TIMES_9x,
1631					queue_id,
1632					skb_queue_len(&ring->queue));
1633				break;
1634			}
1635		}
1636		rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,
1637			"Set ERFSLEEP awaked:%d ms\n",
1638			jiffies_to_msecs(jiffies -
1639			   ppsc->last_awake_jiffies));
1640		ppsc->last_sleep_jiffies = jiffies;
1641		_rtl8723e_phy_set_rf_sleep(hw);
1642		break;
1643	default:
1644		rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,
1645			"switch case %#x not processed\n", rfpwr_state);
1646		bresult = false;
1647		break;
1648	}
1649	if (bresult)
1650		ppsc->rfpwr_state = rfpwr_state;
1651	return bresult;
1652}
1653
1654bool rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw,
1655				     enum rf_pwrstate rfpwr_state)
1656{
1657	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
1658
1659	bool bresult = false;
1660
1661	if (rfpwr_state == ppsc->rfpwr_state)
1662		return bresult;
1663	bresult = _rtl8723e_phy_set_rf_power_state(hw, rfpwr_state);
1664	return bresult;
1665}
1