cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

phy.c (48063B)


      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 = rtl8723_phy_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 = rtl8723_phy_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 = rtl8723_phy_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}