162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2012 Realtek Corporation.*/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "../wifi.h" 562306a36Sopenharmony_ci#include "../pci.h" 662306a36Sopenharmony_ci#include "../ps.h" 762306a36Sopenharmony_ci#include "reg.h" 862306a36Sopenharmony_ci#include "def.h" 962306a36Sopenharmony_ci#include "phy.h" 1062306a36Sopenharmony_ci#include "rf.h" 1162306a36Sopenharmony_ci#include "dm.h" 1262306a36Sopenharmony_ci#include "table.h" 1362306a36Sopenharmony_ci#include "../rtl8723com/phy_common.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw, 1662306a36Sopenharmony_ci enum radio_path rfpath, u32 offset, 1762306a36Sopenharmony_ci u32 data); 1862306a36Sopenharmony_cistatic bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw); 1962306a36Sopenharmony_cistatic bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); 2062306a36Sopenharmony_cistatic bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, 2162306a36Sopenharmony_ci u8 configtype); 2262306a36Sopenharmony_cistatic bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, 2362306a36Sopenharmony_ci u8 configtype); 2462306a36Sopenharmony_cistatic bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 2562306a36Sopenharmony_ci u8 channel, u8 *stage, u8 *step, 2662306a36Sopenharmony_ci u32 *delay); 2762306a36Sopenharmony_cistatic u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw, 2862306a36Sopenharmony_ci enum wireless_mode wirelessmode, 2962306a36Sopenharmony_ci long power_indbm); 3062306a36Sopenharmony_cistatic void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw); 3162306a36Sopenharmony_cistatic void rtl8723e_phy_set_io(struct ieee80211_hw *hw); 3262306a36Sopenharmony_ci 3362306a36Sopenharmony_ciu32 rtl8723e_phy_query_rf_reg(struct ieee80211_hw *hw, 3462306a36Sopenharmony_ci enum radio_path rfpath, 3562306a36Sopenharmony_ci u32 regaddr, u32 bitmask) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3862306a36Sopenharmony_ci u32 original_value = 0, readback_value, bitshift; 3962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 4262306a36Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", 4362306a36Sopenharmony_ci regaddr, rfpath, bitmask); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci if (rtlphy->rf_mode != RF_OP_BY_FW) { 4862306a36Sopenharmony_ci original_value = rtl8723_phy_rf_serial_read(hw, 4962306a36Sopenharmony_ci rfpath, regaddr); 5062306a36Sopenharmony_ci } 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 5362306a36Sopenharmony_ci readback_value = (original_value & bitmask) >> bitshift; 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 5862306a36Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", 5962306a36Sopenharmony_ci regaddr, rfpath, bitmask, original_value); 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_ci return readback_value; 6262306a36Sopenharmony_ci} 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_civoid rtl8723e_phy_set_rf_reg(struct ieee80211_hw *hw, 6562306a36Sopenharmony_ci enum radio_path rfpath, 6662306a36Sopenharmony_ci u32 regaddr, u32 bitmask, u32 data) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 7062306a36Sopenharmony_ci u32 original_value = 0, bitshift; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 7362306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 7462306a36Sopenharmony_ci regaddr, bitmask, data, rfpath); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci if (rtlphy->rf_mode != RF_OP_BY_FW) { 7962306a36Sopenharmony_ci if (bitmask != RFREG_OFFSET_MASK) { 8062306a36Sopenharmony_ci original_value = rtl8723_phy_rf_serial_read(hw, 8162306a36Sopenharmony_ci rfpath, 8262306a36Sopenharmony_ci regaddr); 8362306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 8462306a36Sopenharmony_ci data = 8562306a36Sopenharmony_ci ((original_value & (~bitmask)) | 8662306a36Sopenharmony_ci (data << bitshift)); 8762306a36Sopenharmony_ci } 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data); 9062306a36Sopenharmony_ci } else { 9162306a36Sopenharmony_ci if (bitmask != RFREG_OFFSET_MASK) { 9262306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 9362306a36Sopenharmony_ci data = 9462306a36Sopenharmony_ci ((original_value & (~bitmask)) | 9562306a36Sopenharmony_ci (data << bitshift)); 9662306a36Sopenharmony_ci } 9762306a36Sopenharmony_ci _rtl8723e_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci 10062306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 10162306a36Sopenharmony_ci 10262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 10362306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 10462306a36Sopenharmony_ci regaddr, bitmask, data, rfpath); 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci} 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_cistatic void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw, 10962306a36Sopenharmony_ci enum radio_path rfpath, u32 offset, 11062306a36Sopenharmony_ci u32 data) 11162306a36Sopenharmony_ci{ 11262306a36Sopenharmony_ci WARN_ONCE(true, "rtl8723ae: _rtl8723e_phy_fw_rf_serial_write deprecated!\n"); 11362306a36Sopenharmony_ci} 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_cistatic void _rtl8723e_phy_bb_config_1t(struct ieee80211_hw *hw) 11662306a36Sopenharmony_ci{ 11762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); 11862306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); 11962306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); 12062306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); 12162306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); 12262306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); 12362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); 12462306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); 12562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); 12662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); 12762306a36Sopenharmony_ci} 12862306a36Sopenharmony_ci 12962306a36Sopenharmony_cibool rtl8723e_phy_mac_config(struct ieee80211_hw *hw) 13062306a36Sopenharmony_ci{ 13162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13262306a36Sopenharmony_ci bool rtstatus = _rtl8723e_phy_config_mac_with_headerfile(hw); 13362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x04CA, 0x0A); 13462306a36Sopenharmony_ci return rtstatus; 13562306a36Sopenharmony_ci} 13662306a36Sopenharmony_ci 13762306a36Sopenharmony_cibool rtl8723e_phy_bb_config(struct ieee80211_hw *hw) 13862306a36Sopenharmony_ci{ 13962306a36Sopenharmony_ci bool rtstatus = true; 14062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14162306a36Sopenharmony_ci u8 tmpu1b; 14262306a36Sopenharmony_ci u8 b_reg_hwparafile = 1; 14362306a36Sopenharmony_ci 14462306a36Sopenharmony_ci rtl8723_phy_init_bb_rf_reg_def(hw); 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci /* 1. 0x28[1] = 1 */ 14762306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL); 14862306a36Sopenharmony_ci udelay(2); 14962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1))); 15062306a36Sopenharmony_ci udelay(2); 15162306a36Sopenharmony_ci /* 2. 0x29[7:0] = 0xFF */ 15262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff); 15362306a36Sopenharmony_ci udelay(2); 15462306a36Sopenharmony_ci 15562306a36Sopenharmony_ci /* 3. 0x02[1:0] = 2b'11 */ 15662306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); 15762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 15862306a36Sopenharmony_ci (tmpu1b | FEN_BB_GLB_RSTN | FEN_BBRSTB)); 15962306a36Sopenharmony_ci 16062306a36Sopenharmony_ci /* 4. 0x25[6] = 0 */ 16162306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1); 16262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b & (~BIT(6)))); 16362306a36Sopenharmony_ci 16462306a36Sopenharmony_ci /* 5. 0x24[20] = 0 //Advised by SD3 Alex Wang. 2011.02.09. */ 16562306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2); 16662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b & (~BIT(4)))); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci /* 6. 0x1f[7:0] = 0x07 */ 16962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07); 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci if (b_reg_hwparafile == 1) 17262306a36Sopenharmony_ci rtstatus = _rtl8723e_phy_bb8192c_config_parafile(hw); 17362306a36Sopenharmony_ci return rtstatus; 17462306a36Sopenharmony_ci} 17562306a36Sopenharmony_ci 17662306a36Sopenharmony_cibool rtl8723e_phy_rf_config(struct ieee80211_hw *hw) 17762306a36Sopenharmony_ci{ 17862306a36Sopenharmony_ci return rtl8723e_phy_rf6052_config(hw); 17962306a36Sopenharmony_ci} 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_cistatic bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) 18262306a36Sopenharmony_ci{ 18362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 18462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 18562306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 18662306a36Sopenharmony_ci bool rtstatus; 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n"); 18962306a36Sopenharmony_ci rtstatus = _rtl8723e_phy_config_bb_with_headerfile(hw, 19062306a36Sopenharmony_ci BASEBAND_CONFIG_PHY_REG); 19162306a36Sopenharmony_ci if (!rtstatus) { 19262306a36Sopenharmony_ci pr_err("Write BB Reg Fail!!\n"); 19362306a36Sopenharmony_ci return false; 19462306a36Sopenharmony_ci } 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) { 19762306a36Sopenharmony_ci _rtl8723e_phy_bb_config_1t(hw); 19862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); 19962306a36Sopenharmony_ci } 20062306a36Sopenharmony_ci if (rtlefuse->autoload_failflag == false) { 20162306a36Sopenharmony_ci rtlphy->pwrgroup_cnt = 0; 20262306a36Sopenharmony_ci rtstatus = _rtl8723e_phy_config_bb_with_pgheaderfile(hw, 20362306a36Sopenharmony_ci BASEBAND_CONFIG_PHY_REG); 20462306a36Sopenharmony_ci } 20562306a36Sopenharmony_ci if (!rtstatus) { 20662306a36Sopenharmony_ci pr_err("BB_PG Reg Fail!!\n"); 20762306a36Sopenharmony_ci return false; 20862306a36Sopenharmony_ci } 20962306a36Sopenharmony_ci rtstatus = 21062306a36Sopenharmony_ci _rtl8723e_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); 21162306a36Sopenharmony_ci if (!rtstatus) { 21262306a36Sopenharmony_ci pr_err("AGC Table Fail\n"); 21362306a36Sopenharmony_ci return false; 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, 21662306a36Sopenharmony_ci RFPGA0_XA_HSSIPARAMETER2, 21762306a36Sopenharmony_ci 0x200)); 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_ci return true; 22062306a36Sopenharmony_ci} 22162306a36Sopenharmony_ci 22262306a36Sopenharmony_cistatic bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) 22362306a36Sopenharmony_ci{ 22462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 22562306a36Sopenharmony_ci u32 i; 22662306a36Sopenharmony_ci u32 arraylength; 22762306a36Sopenharmony_ci u32 *ptrarray; 22862306a36Sopenharmony_ci 22962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n"); 23062306a36Sopenharmony_ci arraylength = RTL8723E_MACARRAYLENGTH; 23162306a36Sopenharmony_ci ptrarray = RTL8723EMAC_ARRAY; 23262306a36Sopenharmony_ci 23362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 23462306a36Sopenharmony_ci "Img:RTL8192CEMAC_2T_ARRAY\n"); 23562306a36Sopenharmony_ci for (i = 0; i < arraylength; i = i + 2) 23662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); 23762306a36Sopenharmony_ci return true; 23862306a36Sopenharmony_ci} 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_cistatic bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, 24162306a36Sopenharmony_ci u8 configtype) 24262306a36Sopenharmony_ci{ 24362306a36Sopenharmony_ci int i; 24462306a36Sopenharmony_ci u32 *phy_regarray_table; 24562306a36Sopenharmony_ci u32 *agctab_array_table; 24662306a36Sopenharmony_ci u16 phy_reg_arraylen, agctab_arraylen; 24762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 24862306a36Sopenharmony_ci 24962306a36Sopenharmony_ci agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH; 25062306a36Sopenharmony_ci agctab_array_table = RTL8723EAGCTAB_1TARRAY; 25162306a36Sopenharmony_ci phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH; 25262306a36Sopenharmony_ci phy_regarray_table = RTL8723EPHY_REG_1TARRAY; 25362306a36Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 25462306a36Sopenharmony_ci for (i = 0; i < phy_reg_arraylen; i = i + 2) { 25562306a36Sopenharmony_ci if (phy_regarray_table[i] == 0xfe) 25662306a36Sopenharmony_ci mdelay(50); 25762306a36Sopenharmony_ci else if (phy_regarray_table[i] == 0xfd) 25862306a36Sopenharmony_ci mdelay(5); 25962306a36Sopenharmony_ci else if (phy_regarray_table[i] == 0xfc) 26062306a36Sopenharmony_ci mdelay(1); 26162306a36Sopenharmony_ci else if (phy_regarray_table[i] == 0xfb) 26262306a36Sopenharmony_ci udelay(50); 26362306a36Sopenharmony_ci else if (phy_regarray_table[i] == 0xfa) 26462306a36Sopenharmony_ci udelay(5); 26562306a36Sopenharmony_ci else if (phy_regarray_table[i] == 0xf9) 26662306a36Sopenharmony_ci udelay(1); 26762306a36Sopenharmony_ci rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, 26862306a36Sopenharmony_ci phy_regarray_table[i + 1]); 26962306a36Sopenharmony_ci udelay(1); 27062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 27162306a36Sopenharmony_ci "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", 27262306a36Sopenharmony_ci phy_regarray_table[i], 27362306a36Sopenharmony_ci phy_regarray_table[i + 1]); 27462306a36Sopenharmony_ci } 27562306a36Sopenharmony_ci } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { 27662306a36Sopenharmony_ci for (i = 0; i < agctab_arraylen; i = i + 2) { 27762306a36Sopenharmony_ci rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, 27862306a36Sopenharmony_ci agctab_array_table[i + 1]); 27962306a36Sopenharmony_ci udelay(1); 28062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 28162306a36Sopenharmony_ci "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", 28262306a36Sopenharmony_ci agctab_array_table[i], 28362306a36Sopenharmony_ci agctab_array_table[i + 1]); 28462306a36Sopenharmony_ci } 28562306a36Sopenharmony_ci } 28662306a36Sopenharmony_ci return true; 28762306a36Sopenharmony_ci} 28862306a36Sopenharmony_ci 28962306a36Sopenharmony_cistatic void store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, 29062306a36Sopenharmony_ci u32 regaddr, u32 bitmask, 29162306a36Sopenharmony_ci u32 data) 29262306a36Sopenharmony_ci{ 29362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 29462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 29562306a36Sopenharmony_ci 29662306a36Sopenharmony_ci if (regaddr == RTXAGC_A_RATE18_06) { 29762306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] = 29862306a36Sopenharmony_ci data; 29962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 30062306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", 30162306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 30262306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 30362306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][0]); 30462306a36Sopenharmony_ci } 30562306a36Sopenharmony_ci if (regaddr == RTXAGC_A_RATE54_24) { 30662306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] = 30762306a36Sopenharmony_ci data; 30862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 30962306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", 31062306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 31162306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy-> 31262306a36Sopenharmony_ci pwrgroup_cnt][1]); 31362306a36Sopenharmony_ci } 31462306a36Sopenharmony_ci if (regaddr == RTXAGC_A_CCK1_MCS32) { 31562306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] = 31662306a36Sopenharmony_ci data; 31762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 31862306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", 31962306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 32062306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 32162306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][6]); 32262306a36Sopenharmony_ci } 32362306a36Sopenharmony_ci if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { 32462306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] = 32562306a36Sopenharmony_ci data; 32662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 32762306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", 32862306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 32962306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 33062306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][7]); 33162306a36Sopenharmony_ci } 33262306a36Sopenharmony_ci if (regaddr == RTXAGC_A_MCS03_MCS00) { 33362306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] = 33462306a36Sopenharmony_ci data; 33562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 33662306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", 33762306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 33862306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 33962306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][2]); 34062306a36Sopenharmony_ci } 34162306a36Sopenharmony_ci if (regaddr == RTXAGC_A_MCS07_MCS04) { 34262306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] = 34362306a36Sopenharmony_ci data; 34462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 34562306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", 34662306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 34762306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 34862306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][3]); 34962306a36Sopenharmony_ci } 35062306a36Sopenharmony_ci if (regaddr == RTXAGC_A_MCS11_MCS08) { 35162306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] = 35262306a36Sopenharmony_ci data; 35362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 35462306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", 35562306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 35662306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 35762306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][4]); 35862306a36Sopenharmony_ci } 35962306a36Sopenharmony_ci if (regaddr == RTXAGC_A_MCS15_MCS12) { 36062306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] = 36162306a36Sopenharmony_ci data; 36262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 36362306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", 36462306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 36562306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 36662306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][5]); 36762306a36Sopenharmony_ci } 36862306a36Sopenharmony_ci if (regaddr == RTXAGC_B_RATE18_06) { 36962306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] = 37062306a36Sopenharmony_ci data; 37162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 37262306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", 37362306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 37462306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 37562306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][8]); 37662306a36Sopenharmony_ci } 37762306a36Sopenharmony_ci if (regaddr == RTXAGC_B_RATE54_24) { 37862306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] = 37962306a36Sopenharmony_ci data; 38062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 38162306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", 38262306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 38362306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 38462306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][9]); 38562306a36Sopenharmony_ci } 38662306a36Sopenharmony_ci if (regaddr == RTXAGC_B_CCK1_55_MCS32) { 38762306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] = 38862306a36Sopenharmony_ci data; 38962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 39062306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", 39162306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 39262306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 39362306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][14]); 39462306a36Sopenharmony_ci } 39562306a36Sopenharmony_ci if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { 39662306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] = 39762306a36Sopenharmony_ci data; 39862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 39962306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", 40062306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 40162306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 40262306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][15]); 40362306a36Sopenharmony_ci } 40462306a36Sopenharmony_ci if (regaddr == RTXAGC_B_MCS03_MCS00) { 40562306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] = 40662306a36Sopenharmony_ci data; 40762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 40862306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", 40962306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 41062306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 41162306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][10]); 41262306a36Sopenharmony_ci } 41362306a36Sopenharmony_ci if (regaddr == RTXAGC_B_MCS07_MCS04) { 41462306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] = 41562306a36Sopenharmony_ci data; 41662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 41762306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", 41862306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 41962306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 42062306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][11]); 42162306a36Sopenharmony_ci } 42262306a36Sopenharmony_ci if (regaddr == RTXAGC_B_MCS11_MCS08) { 42362306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] = 42462306a36Sopenharmony_ci data; 42562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 42662306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", 42762306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 42862306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 42962306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][12]); 43062306a36Sopenharmony_ci } 43162306a36Sopenharmony_ci if (regaddr == RTXAGC_B_MCS15_MCS12) { 43262306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] = 43362306a36Sopenharmony_ci data; 43462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 43562306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", 43662306a36Sopenharmony_ci rtlphy->pwrgroup_cnt, 43762306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset 43862306a36Sopenharmony_ci [rtlphy->pwrgroup_cnt][13]); 43962306a36Sopenharmony_ci 44062306a36Sopenharmony_ci rtlphy->pwrgroup_cnt++; 44162306a36Sopenharmony_ci } 44262306a36Sopenharmony_ci} 44362306a36Sopenharmony_ci 44462306a36Sopenharmony_cistatic bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, 44562306a36Sopenharmony_ci u8 configtype) 44662306a36Sopenharmony_ci{ 44762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 44862306a36Sopenharmony_ci int i; 44962306a36Sopenharmony_ci u32 *phy_regarray_table_pg; 45062306a36Sopenharmony_ci u16 phy_regarray_pg_len; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH; 45362306a36Sopenharmony_ci phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG; 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 45662306a36Sopenharmony_ci for (i = 0; i < phy_regarray_pg_len; i = i + 3) { 45762306a36Sopenharmony_ci if (phy_regarray_table_pg[i] == 0xfe) 45862306a36Sopenharmony_ci mdelay(50); 45962306a36Sopenharmony_ci else if (phy_regarray_table_pg[i] == 0xfd) 46062306a36Sopenharmony_ci mdelay(5); 46162306a36Sopenharmony_ci else if (phy_regarray_table_pg[i] == 0xfc) 46262306a36Sopenharmony_ci mdelay(1); 46362306a36Sopenharmony_ci else if (phy_regarray_table_pg[i] == 0xfb) 46462306a36Sopenharmony_ci udelay(50); 46562306a36Sopenharmony_ci else if (phy_regarray_table_pg[i] == 0xfa) 46662306a36Sopenharmony_ci udelay(5); 46762306a36Sopenharmony_ci else if (phy_regarray_table_pg[i] == 0xf9) 46862306a36Sopenharmony_ci udelay(1); 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci store_pwrindex_diffrate_offset(hw, 47162306a36Sopenharmony_ci phy_regarray_table_pg[i], 47262306a36Sopenharmony_ci phy_regarray_table_pg[i + 1], 47362306a36Sopenharmony_ci phy_regarray_table_pg[i + 2]); 47462306a36Sopenharmony_ci } 47562306a36Sopenharmony_ci } else { 47662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, 47762306a36Sopenharmony_ci "configtype != BaseBand_Config_PHY_REG\n"); 47862306a36Sopenharmony_ci } 47962306a36Sopenharmony_ci return true; 48062306a36Sopenharmony_ci} 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_cibool rtl8723e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, 48362306a36Sopenharmony_ci enum radio_path rfpath) 48462306a36Sopenharmony_ci{ 48562306a36Sopenharmony_ci int i; 48662306a36Sopenharmony_ci u32 *radioa_array_table; 48762306a36Sopenharmony_ci u16 radioa_arraylen; 48862306a36Sopenharmony_ci 48962306a36Sopenharmony_ci radioa_arraylen = RTL8723ERADIOA_1TARRAYLENGTH; 49062306a36Sopenharmony_ci radioa_array_table = RTL8723E_RADIOA_1TARRAY; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci switch (rfpath) { 49362306a36Sopenharmony_ci case RF90_PATH_A: 49462306a36Sopenharmony_ci for (i = 0; i < radioa_arraylen; i = i + 2) { 49562306a36Sopenharmony_ci if (radioa_array_table[i] == 0xfe) { 49662306a36Sopenharmony_ci mdelay(50); 49762306a36Sopenharmony_ci } else if (radioa_array_table[i] == 0xfd) { 49862306a36Sopenharmony_ci mdelay(5); 49962306a36Sopenharmony_ci } else if (radioa_array_table[i] == 0xfc) { 50062306a36Sopenharmony_ci mdelay(1); 50162306a36Sopenharmony_ci } else if (radioa_array_table[i] == 0xfb) { 50262306a36Sopenharmony_ci udelay(50); 50362306a36Sopenharmony_ci } else if (radioa_array_table[i] == 0xfa) { 50462306a36Sopenharmony_ci udelay(5); 50562306a36Sopenharmony_ci } else if (radioa_array_table[i] == 0xf9) { 50662306a36Sopenharmony_ci udelay(1); 50762306a36Sopenharmony_ci } else { 50862306a36Sopenharmony_ci rtl_set_rfreg(hw, rfpath, radioa_array_table[i], 50962306a36Sopenharmony_ci RFREG_OFFSET_MASK, 51062306a36Sopenharmony_ci radioa_array_table[i + 1]); 51162306a36Sopenharmony_ci udelay(1); 51262306a36Sopenharmony_ci } 51362306a36Sopenharmony_ci } 51462306a36Sopenharmony_ci break; 51562306a36Sopenharmony_ci case RF90_PATH_B: 51662306a36Sopenharmony_ci case RF90_PATH_C: 51762306a36Sopenharmony_ci case RF90_PATH_D: 51862306a36Sopenharmony_ci break; 51962306a36Sopenharmony_ci } 52062306a36Sopenharmony_ci return true; 52162306a36Sopenharmony_ci} 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_civoid rtl8723e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) 52462306a36Sopenharmony_ci{ 52562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 52662306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_ci rtlphy->default_initialgain[0] = 52962306a36Sopenharmony_ci (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); 53062306a36Sopenharmony_ci rtlphy->default_initialgain[1] = 53162306a36Sopenharmony_ci (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); 53262306a36Sopenharmony_ci rtlphy->default_initialgain[2] = 53362306a36Sopenharmony_ci (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); 53462306a36Sopenharmony_ci rtlphy->default_initialgain[3] = 53562306a36Sopenharmony_ci (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 53862306a36Sopenharmony_ci "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", 53962306a36Sopenharmony_ci rtlphy->default_initialgain[0], 54062306a36Sopenharmony_ci rtlphy->default_initialgain[1], 54162306a36Sopenharmony_ci rtlphy->default_initialgain[2], 54262306a36Sopenharmony_ci rtlphy->default_initialgain[3]); 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci rtlphy->framesync = (u8) rtl_get_bbreg(hw, 54562306a36Sopenharmony_ci ROFDM0_RXDETECTOR3, MASKBYTE0); 54662306a36Sopenharmony_ci rtlphy->framesync_c34 = rtl_get_bbreg(hw, 54762306a36Sopenharmony_ci ROFDM0_RXDETECTOR2, MASKDWORD); 54862306a36Sopenharmony_ci 54962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 55062306a36Sopenharmony_ci "Default framesync (0x%x) = 0x%x\n", 55162306a36Sopenharmony_ci ROFDM0_RXDETECTOR3, rtlphy->framesync); 55262306a36Sopenharmony_ci} 55362306a36Sopenharmony_ci 55462306a36Sopenharmony_civoid rtl8723e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) 55562306a36Sopenharmony_ci{ 55662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 55762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 55862306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 55962306a36Sopenharmony_ci u8 txpwr_level; 56062306a36Sopenharmony_ci long txpwr_dbm; 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci txpwr_level = rtlphy->cur_cck_txpwridx; 56362306a36Sopenharmony_ci txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw, 56462306a36Sopenharmony_ci WIRELESS_MODE_B, txpwr_level); 56562306a36Sopenharmony_ci txpwr_level = rtlphy->cur_ofdm24g_txpwridx + 56662306a36Sopenharmony_ci rtlefuse->legacy_ht_txpowerdiff; 56762306a36Sopenharmony_ci if (rtl8723_phy_txpwr_idx_to_dbm(hw, 56862306a36Sopenharmony_ci WIRELESS_MODE_G, 56962306a36Sopenharmony_ci txpwr_level) > txpwr_dbm) 57062306a36Sopenharmony_ci txpwr_dbm = 57162306a36Sopenharmony_ci rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, 57262306a36Sopenharmony_ci txpwr_level); 57362306a36Sopenharmony_ci txpwr_level = rtlphy->cur_ofdm24g_txpwridx; 57462306a36Sopenharmony_ci if (rtl8723_phy_txpwr_idx_to_dbm(hw, 57562306a36Sopenharmony_ci WIRELESS_MODE_N_24G, 57662306a36Sopenharmony_ci txpwr_level) > txpwr_dbm) 57762306a36Sopenharmony_ci txpwr_dbm = 57862306a36Sopenharmony_ci rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, 57962306a36Sopenharmony_ci txpwr_level); 58062306a36Sopenharmony_ci *powerlevel = txpwr_dbm; 58162306a36Sopenharmony_ci} 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_cistatic void _rtl8723e_get_txpower_index(struct ieee80211_hw *hw, u8 channel, 58462306a36Sopenharmony_ci u8 *cckpowerlevel, u8 *ofdmpowerlevel) 58562306a36Sopenharmony_ci{ 58662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 58762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 58862306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 58962306a36Sopenharmony_ci u8 index = (channel - 1); 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci cckpowerlevel[RF90_PATH_A] = 59262306a36Sopenharmony_ci rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; 59362306a36Sopenharmony_ci cckpowerlevel[RF90_PATH_B] = 59462306a36Sopenharmony_ci rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; 59562306a36Sopenharmony_ci if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { 59662306a36Sopenharmony_ci ofdmpowerlevel[RF90_PATH_A] = 59762306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; 59862306a36Sopenharmony_ci ofdmpowerlevel[RF90_PATH_B] = 59962306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; 60062306a36Sopenharmony_ci } else if (get_rf_type(rtlphy) == RF_2T2R) { 60162306a36Sopenharmony_ci ofdmpowerlevel[RF90_PATH_A] = 60262306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; 60362306a36Sopenharmony_ci ofdmpowerlevel[RF90_PATH_B] = 60462306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; 60562306a36Sopenharmony_ci } 60662306a36Sopenharmony_ci} 60762306a36Sopenharmony_ci 60862306a36Sopenharmony_cistatic void _rtl8723e_ccxpower_index_check(struct ieee80211_hw *hw, 60962306a36Sopenharmony_ci u8 channel, u8 *cckpowerlevel, 61062306a36Sopenharmony_ci u8 *ofdmpowerlevel) 61162306a36Sopenharmony_ci{ 61262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 61362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; 61662306a36Sopenharmony_ci rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_ci} 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_civoid rtl8723e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) 62162306a36Sopenharmony_ci{ 62262306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 62362306a36Sopenharmony_ci u8 cckpowerlevel[2], ofdmpowerlevel[2]; 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci if (!rtlefuse->txpwr_fromeprom) 62662306a36Sopenharmony_ci return; 62762306a36Sopenharmony_ci _rtl8723e_get_txpower_index(hw, channel, 62862306a36Sopenharmony_ci &cckpowerlevel[0], &ofdmpowerlevel[0]); 62962306a36Sopenharmony_ci _rtl8723e_ccxpower_index_check(hw, 63062306a36Sopenharmony_ci channel, &cckpowerlevel[0], 63162306a36Sopenharmony_ci &ofdmpowerlevel[0]); 63262306a36Sopenharmony_ci rtl8723e_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); 63362306a36Sopenharmony_ci rtl8723e_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel); 63462306a36Sopenharmony_ci} 63562306a36Sopenharmony_ci 63662306a36Sopenharmony_cibool rtl8723e_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) 63762306a36Sopenharmony_ci{ 63862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 63962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 64062306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 64162306a36Sopenharmony_ci u8 idx; 64262306a36Sopenharmony_ci u8 rf_path; 64362306a36Sopenharmony_ci u8 ccktxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw, 64462306a36Sopenharmony_ci WIRELESS_MODE_B, 64562306a36Sopenharmony_ci power_indbm); 64662306a36Sopenharmony_ci u8 ofdmtxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw, 64762306a36Sopenharmony_ci WIRELESS_MODE_N_24G, 64862306a36Sopenharmony_ci power_indbm); 64962306a36Sopenharmony_ci if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) 65062306a36Sopenharmony_ci ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; 65162306a36Sopenharmony_ci else 65262306a36Sopenharmony_ci ofdmtxpwridx = 0; 65362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TXAGC, DBG_TRACE, 65462306a36Sopenharmony_ci "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", 65562306a36Sopenharmony_ci power_indbm, ccktxpwridx, ofdmtxpwridx); 65662306a36Sopenharmony_ci for (idx = 0; idx < 14; idx++) { 65762306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 65862306a36Sopenharmony_ci rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; 65962306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = 66062306a36Sopenharmony_ci ofdmtxpwridx; 66162306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = 66262306a36Sopenharmony_ci ofdmtxpwridx; 66362306a36Sopenharmony_ci } 66462306a36Sopenharmony_ci } 66562306a36Sopenharmony_ci rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel); 66662306a36Sopenharmony_ci return true; 66762306a36Sopenharmony_ci} 66862306a36Sopenharmony_ci 66962306a36Sopenharmony_cistatic u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw, 67062306a36Sopenharmony_ci enum wireless_mode wirelessmode, 67162306a36Sopenharmony_ci long power_indbm) 67262306a36Sopenharmony_ci{ 67362306a36Sopenharmony_ci u8 txpwridx; 67462306a36Sopenharmony_ci long offset; 67562306a36Sopenharmony_ci 67662306a36Sopenharmony_ci switch (wirelessmode) { 67762306a36Sopenharmony_ci case WIRELESS_MODE_B: 67862306a36Sopenharmony_ci offset = -7; 67962306a36Sopenharmony_ci break; 68062306a36Sopenharmony_ci case WIRELESS_MODE_G: 68162306a36Sopenharmony_ci case WIRELESS_MODE_N_24G: 68262306a36Sopenharmony_ci offset = -8; 68362306a36Sopenharmony_ci break; 68462306a36Sopenharmony_ci default: 68562306a36Sopenharmony_ci offset = -8; 68662306a36Sopenharmony_ci break; 68762306a36Sopenharmony_ci } 68862306a36Sopenharmony_ci 68962306a36Sopenharmony_ci if ((power_indbm - offset) > 0) 69062306a36Sopenharmony_ci txpwridx = (u8)((power_indbm - offset) * 2); 69162306a36Sopenharmony_ci else 69262306a36Sopenharmony_ci txpwridx = 0; 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) 69562306a36Sopenharmony_ci txpwridx = MAX_TXPWR_IDX_NMODE_92S; 69662306a36Sopenharmony_ci 69762306a36Sopenharmony_ci return txpwridx; 69862306a36Sopenharmony_ci} 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_civoid rtl8723e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) 70162306a36Sopenharmony_ci{ 70262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 70362306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 70462306a36Sopenharmony_ci enum io_type iotype; 70562306a36Sopenharmony_ci 70662306a36Sopenharmony_ci if (!is_hal_stop(rtlhal)) { 70762306a36Sopenharmony_ci switch (operation) { 70862306a36Sopenharmony_ci case SCAN_OPT_BACKUP_BAND0: 70962306a36Sopenharmony_ci iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; 71062306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 71162306a36Sopenharmony_ci HW_VAR_IO_CMD, 71262306a36Sopenharmony_ci (u8 *)&iotype); 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci break; 71562306a36Sopenharmony_ci case SCAN_OPT_RESTORE: 71662306a36Sopenharmony_ci iotype = IO_CMD_RESUME_DM_BY_SCAN; 71762306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 71862306a36Sopenharmony_ci HW_VAR_IO_CMD, 71962306a36Sopenharmony_ci (u8 *)&iotype); 72062306a36Sopenharmony_ci break; 72162306a36Sopenharmony_ci default: 72262306a36Sopenharmony_ci pr_err("Unknown Scan Backup operation.\n"); 72362306a36Sopenharmony_ci break; 72462306a36Sopenharmony_ci } 72562306a36Sopenharmony_ci } 72662306a36Sopenharmony_ci} 72762306a36Sopenharmony_ci 72862306a36Sopenharmony_civoid rtl8723e_phy_set_bw_mode_callback(struct ieee80211_hw *hw) 72962306a36Sopenharmony_ci{ 73062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 73162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 73262306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 73362306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 73462306a36Sopenharmony_ci u8 reg_bw_opmode; 73562306a36Sopenharmony_ci u8 reg_prsr_rsc; 73662306a36Sopenharmony_ci 73762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, 73862306a36Sopenharmony_ci "Switch to %s bandwidth\n", 73962306a36Sopenharmony_ci rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? 74062306a36Sopenharmony_ci "20MHz" : "40MHz"); 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) { 74362306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 74462306a36Sopenharmony_ci return; 74562306a36Sopenharmony_ci } 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); 74862306a36Sopenharmony_ci reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci switch (rtlphy->current_chan_bw) { 75162306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 75262306a36Sopenharmony_ci reg_bw_opmode |= BW_OPMODE_20MHZ; 75362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 75462306a36Sopenharmony_ci break; 75562306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 75662306a36Sopenharmony_ci reg_bw_opmode &= ~BW_OPMODE_20MHZ; 75762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 75862306a36Sopenharmony_ci reg_prsr_rsc = 75962306a36Sopenharmony_ci (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); 76062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); 76162306a36Sopenharmony_ci break; 76262306a36Sopenharmony_ci default: 76362306a36Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 76462306a36Sopenharmony_ci rtlphy->current_chan_bw); 76562306a36Sopenharmony_ci break; 76662306a36Sopenharmony_ci } 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci switch (rtlphy->current_chan_bw) { 76962306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 77062306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); 77162306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); 77262306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); 77362306a36Sopenharmony_ci break; 77462306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 77562306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); 77662306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, 77962306a36Sopenharmony_ci (mac->cur_40_prime_sc >> 1)); 78062306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); 78162306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); 78262306a36Sopenharmony_ci 78362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), 78462306a36Sopenharmony_ci (mac->cur_40_prime_sc == 78562306a36Sopenharmony_ci HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); 78662306a36Sopenharmony_ci break; 78762306a36Sopenharmony_ci default: 78862306a36Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 78962306a36Sopenharmony_ci rtlphy->current_chan_bw); 79062306a36Sopenharmony_ci break; 79162306a36Sopenharmony_ci } 79262306a36Sopenharmony_ci rtl8723e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); 79362306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 79462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); 79562306a36Sopenharmony_ci} 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_civoid rtl8723e_phy_set_bw_mode(struct ieee80211_hw *hw, 79862306a36Sopenharmony_ci enum nl80211_channel_type ch_type) 79962306a36Sopenharmony_ci{ 80062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 80162306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 80262306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 80362306a36Sopenharmony_ci u8 tmp_bw = rtlphy->current_chan_bw; 80462306a36Sopenharmony_ci 80562306a36Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 80662306a36Sopenharmony_ci return; 80762306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = true; 80862306a36Sopenharmony_ci if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 80962306a36Sopenharmony_ci rtl8723e_phy_set_bw_mode_callback(hw); 81062306a36Sopenharmony_ci } else { 81162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 81262306a36Sopenharmony_ci "false driver sleep or unload\n"); 81362306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 81462306a36Sopenharmony_ci rtlphy->current_chan_bw = tmp_bw; 81562306a36Sopenharmony_ci } 81662306a36Sopenharmony_ci} 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_civoid rtl8723e_phy_sw_chnl_callback(struct ieee80211_hw *hw) 81962306a36Sopenharmony_ci{ 82062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 82162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 82262306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 82362306a36Sopenharmony_ci u32 delay; 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, 82662306a36Sopenharmony_ci "switch to channel%d\n", rtlphy->current_channel); 82762306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) 82862306a36Sopenharmony_ci return; 82962306a36Sopenharmony_ci do { 83062306a36Sopenharmony_ci if (!rtlphy->sw_chnl_inprogress) 83162306a36Sopenharmony_ci break; 83262306a36Sopenharmony_ci if (!_rtl8723e_phy_sw_chnl_step_by_step 83362306a36Sopenharmony_ci (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, 83462306a36Sopenharmony_ci &rtlphy->sw_chnl_step, &delay)) { 83562306a36Sopenharmony_ci if (delay > 0) 83662306a36Sopenharmony_ci mdelay(delay); 83762306a36Sopenharmony_ci else 83862306a36Sopenharmony_ci continue; 83962306a36Sopenharmony_ci } else { 84062306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 84162306a36Sopenharmony_ci } 84262306a36Sopenharmony_ci break; 84362306a36Sopenharmony_ci } while (true); 84462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); 84562306a36Sopenharmony_ci} 84662306a36Sopenharmony_ci 84762306a36Sopenharmony_ciu8 rtl8723e_phy_sw_chnl(struct ieee80211_hw *hw) 84862306a36Sopenharmony_ci{ 84962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 85062306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 85162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci if (rtlphy->sw_chnl_inprogress) 85462306a36Sopenharmony_ci return 0; 85562306a36Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 85662306a36Sopenharmony_ci return 0; 85762306a36Sopenharmony_ci WARN_ONCE((rtlphy->current_channel > 14), 85862306a36Sopenharmony_ci "rtl8723ae: WIRELESS_MODE_G but channel>14"); 85962306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = true; 86062306a36Sopenharmony_ci rtlphy->sw_chnl_stage = 0; 86162306a36Sopenharmony_ci rtlphy->sw_chnl_step = 0; 86262306a36Sopenharmony_ci if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 86362306a36Sopenharmony_ci rtl8723e_phy_sw_chnl_callback(hw); 86462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, 86562306a36Sopenharmony_ci "sw_chnl_inprogress false schedule workitem\n"); 86662306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 86762306a36Sopenharmony_ci } else { 86862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, 86962306a36Sopenharmony_ci "sw_chnl_inprogress false driver sleep or unload\n"); 87062306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 87162306a36Sopenharmony_ci } 87262306a36Sopenharmony_ci return 1; 87362306a36Sopenharmony_ci} 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_cistatic void _rtl8723e_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel) 87662306a36Sopenharmony_ci{ 87762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 87862306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 87962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 88062306a36Sopenharmony_ci 88162306a36Sopenharmony_ci if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) { 88262306a36Sopenharmony_ci if (channel == 6 && rtlphy->current_chan_bw == 88362306a36Sopenharmony_ci HT_CHANNEL_WIDTH_20) 88462306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, 88562306a36Sopenharmony_ci MASKDWORD, 0x00255); 88662306a36Sopenharmony_ci else{ 88762306a36Sopenharmony_ci u32 backuprf0x1a = (u32)rtl_get_rfreg(hw, 88862306a36Sopenharmony_ci RF90_PATH_A, RF_RX_G1, 88962306a36Sopenharmony_ci RFREG_OFFSET_MASK); 89062306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, 89162306a36Sopenharmony_ci MASKDWORD, backuprf0x1a); 89262306a36Sopenharmony_ci } 89362306a36Sopenharmony_ci } 89462306a36Sopenharmony_ci} 89562306a36Sopenharmony_ci 89662306a36Sopenharmony_cistatic bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 89762306a36Sopenharmony_ci u8 channel, u8 *stage, u8 *step, 89862306a36Sopenharmony_ci u32 *delay) 89962306a36Sopenharmony_ci{ 90062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 90162306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 90262306a36Sopenharmony_ci struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; 90362306a36Sopenharmony_ci u32 precommoncmdcnt; 90462306a36Sopenharmony_ci struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; 90562306a36Sopenharmony_ci u32 postcommoncmdcnt; 90662306a36Sopenharmony_ci struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; 90762306a36Sopenharmony_ci u32 rfdependcmdcnt; 90862306a36Sopenharmony_ci struct swchnlcmd *currentcmd = NULL; 90962306a36Sopenharmony_ci u8 rfpath; 91062306a36Sopenharmony_ci u8 num_total_rfpath = rtlphy->num_total_rfpath; 91162306a36Sopenharmony_ci 91262306a36Sopenharmony_ci precommoncmdcnt = 0; 91362306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 91462306a36Sopenharmony_ci MAX_PRECMD_CNT, 91562306a36Sopenharmony_ci CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); 91662306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 91762306a36Sopenharmony_ci MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ci postcommoncmdcnt = 0; 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, 92262306a36Sopenharmony_ci MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci rfdependcmdcnt = 0; 92562306a36Sopenharmony_ci 92662306a36Sopenharmony_ci WARN_ONCE((channel < 1 || channel > 14), 92762306a36Sopenharmony_ci "rtl8723ae: illegal channel for Zebra: %d\n", channel); 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 93062306a36Sopenharmony_ci MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, 93162306a36Sopenharmony_ci RF_CHNLBW, channel, 10); 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 93462306a36Sopenharmony_ci MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 93562306a36Sopenharmony_ci 0); 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci do { 93862306a36Sopenharmony_ci switch (*stage) { 93962306a36Sopenharmony_ci case 0: 94062306a36Sopenharmony_ci currentcmd = &precommoncmd[*step]; 94162306a36Sopenharmony_ci break; 94262306a36Sopenharmony_ci case 1: 94362306a36Sopenharmony_ci currentcmd = &rfdependcmd[*step]; 94462306a36Sopenharmony_ci break; 94562306a36Sopenharmony_ci case 2: 94662306a36Sopenharmony_ci currentcmd = &postcommoncmd[*step]; 94762306a36Sopenharmony_ci break; 94862306a36Sopenharmony_ci default: 94962306a36Sopenharmony_ci pr_err("Invalid 'stage' = %d, Check it!\n", 95062306a36Sopenharmony_ci *stage); 95162306a36Sopenharmony_ci return true; 95262306a36Sopenharmony_ci } 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci if (currentcmd->cmdid == CMDID_END) { 95562306a36Sopenharmony_ci if ((*stage) == 2) { 95662306a36Sopenharmony_ci return true; 95762306a36Sopenharmony_ci } else { 95862306a36Sopenharmony_ci (*stage)++; 95962306a36Sopenharmony_ci (*step) = 0; 96062306a36Sopenharmony_ci continue; 96162306a36Sopenharmony_ci } 96262306a36Sopenharmony_ci } 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_ci switch (currentcmd->cmdid) { 96562306a36Sopenharmony_ci case CMDID_SET_TXPOWEROWER_LEVEL: 96662306a36Sopenharmony_ci rtl8723e_phy_set_txpower_level(hw, channel); 96762306a36Sopenharmony_ci break; 96862306a36Sopenharmony_ci case CMDID_WRITEPORT_ULONG: 96962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, currentcmd->para1, 97062306a36Sopenharmony_ci currentcmd->para2); 97162306a36Sopenharmony_ci break; 97262306a36Sopenharmony_ci case CMDID_WRITEPORT_USHORT: 97362306a36Sopenharmony_ci rtl_write_word(rtlpriv, currentcmd->para1, 97462306a36Sopenharmony_ci (u16) currentcmd->para2); 97562306a36Sopenharmony_ci break; 97662306a36Sopenharmony_ci case CMDID_WRITEPORT_UCHAR: 97762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, currentcmd->para1, 97862306a36Sopenharmony_ci (u8) currentcmd->para2); 97962306a36Sopenharmony_ci break; 98062306a36Sopenharmony_ci case CMDID_RF_WRITEREG: 98162306a36Sopenharmony_ci for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { 98262306a36Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath] = 98362306a36Sopenharmony_ci ((rtlphy->rfreg_chnlval[rfpath] & 98462306a36Sopenharmony_ci 0xfffffc00) | currentcmd->para2); 98562306a36Sopenharmony_ci 98662306a36Sopenharmony_ci rtl_set_rfreg(hw, (enum radio_path)rfpath, 98762306a36Sopenharmony_ci currentcmd->para1, 98862306a36Sopenharmony_ci RFREG_OFFSET_MASK, 98962306a36Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath]); 99062306a36Sopenharmony_ci } 99162306a36Sopenharmony_ci _rtl8723e_phy_sw_rf_seting(hw, channel); 99262306a36Sopenharmony_ci break; 99362306a36Sopenharmony_ci default: 99462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 99562306a36Sopenharmony_ci "switch case %#x not processed\n", 99662306a36Sopenharmony_ci currentcmd->cmdid); 99762306a36Sopenharmony_ci break; 99862306a36Sopenharmony_ci } 99962306a36Sopenharmony_ci 100062306a36Sopenharmony_ci break; 100162306a36Sopenharmony_ci } while (true); 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_ci (*delay) = currentcmd->msdelay; 100462306a36Sopenharmony_ci (*step)++; 100562306a36Sopenharmony_ci return false; 100662306a36Sopenharmony_ci} 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_cistatic u8 _rtl8723e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) 100962306a36Sopenharmony_ci{ 101062306a36Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c, reg_ea4; 101162306a36Sopenharmony_ci u8 result = 0x00; 101262306a36Sopenharmony_ci 101362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); 101462306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); 101562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); 101662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 101762306a36Sopenharmony_ci config_pathb ? 0x28160202 : 0x28160502); 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci if (config_pathb) { 102062306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); 102162306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); 102262306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); 102362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); 102462306a36Sopenharmony_ci } 102562306a36Sopenharmony_ci 102662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); 102762306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); 102862306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); 102962306a36Sopenharmony_ci 103062306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); 103362306a36Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); 103462306a36Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); 103562306a36Sopenharmony_ci reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 103862306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 103962306a36Sopenharmony_ci (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) 104062306a36Sopenharmony_ci result |= 0x01; 104162306a36Sopenharmony_ci else 104262306a36Sopenharmony_ci return result; 104362306a36Sopenharmony_ci 104462306a36Sopenharmony_ci if (!(reg_eac & BIT(27)) && 104562306a36Sopenharmony_ci (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && 104662306a36Sopenharmony_ci (((reg_eac & 0x03FF0000) >> 16) != 0x36)) 104762306a36Sopenharmony_ci result |= 0x02; 104862306a36Sopenharmony_ci return result; 104962306a36Sopenharmony_ci} 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_cistatic u8 _rtl8723e_phy_path_b_iqk(struct ieee80211_hw *hw) 105262306a36Sopenharmony_ci{ 105362306a36Sopenharmony_ci u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; 105462306a36Sopenharmony_ci u8 result = 0x00; 105562306a36Sopenharmony_ci 105662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); 105762306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); 105862306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 105962306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); 106062306a36Sopenharmony_ci reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); 106162306a36Sopenharmony_ci reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); 106262306a36Sopenharmony_ci reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); 106362306a36Sopenharmony_ci reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); 106462306a36Sopenharmony_ci 106562306a36Sopenharmony_ci if (!(reg_eac & BIT(31)) && 106662306a36Sopenharmony_ci (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && 106762306a36Sopenharmony_ci (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) 106862306a36Sopenharmony_ci result |= 0x01; 106962306a36Sopenharmony_ci else 107062306a36Sopenharmony_ci return result; 107162306a36Sopenharmony_ci if (!(reg_eac & BIT(30)) && 107262306a36Sopenharmony_ci (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && 107362306a36Sopenharmony_ci (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) 107462306a36Sopenharmony_ci result |= 0x02; 107562306a36Sopenharmony_ci return result; 107662306a36Sopenharmony_ci} 107762306a36Sopenharmony_ci 107862306a36Sopenharmony_cistatic bool _rtl8723e_phy_simularity_compare(struct ieee80211_hw *hw, 107962306a36Sopenharmony_ci long result[][8], u8 c1, u8 c2) 108062306a36Sopenharmony_ci{ 108162306a36Sopenharmony_ci u32 i, j, diff, simularity_bitmap, bound; 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci u8 final_candidate[2] = { 0xFF, 0xFF }; 108462306a36Sopenharmony_ci bool bresult = true; 108562306a36Sopenharmony_ci 108662306a36Sopenharmony_ci bound = 4; 108762306a36Sopenharmony_ci 108862306a36Sopenharmony_ci simularity_bitmap = 0; 108962306a36Sopenharmony_ci 109062306a36Sopenharmony_ci for (i = 0; i < bound; i++) { 109162306a36Sopenharmony_ci diff = (result[c1][i] > result[c2][i]) ? 109262306a36Sopenharmony_ci (result[c1][i] - result[c2][i]) : 109362306a36Sopenharmony_ci (result[c2][i] - result[c1][i]); 109462306a36Sopenharmony_ci 109562306a36Sopenharmony_ci if (diff > MAX_TOLERANCE) { 109662306a36Sopenharmony_ci if ((i == 2 || i == 6) && !simularity_bitmap) { 109762306a36Sopenharmony_ci if (result[c1][i] + result[c1][i + 1] == 0) 109862306a36Sopenharmony_ci final_candidate[(i / 4)] = c2; 109962306a36Sopenharmony_ci else if (result[c2][i] + result[c2][i + 1] == 0) 110062306a36Sopenharmony_ci final_candidate[(i / 4)] = c1; 110162306a36Sopenharmony_ci else 110262306a36Sopenharmony_ci simularity_bitmap = simularity_bitmap | 110362306a36Sopenharmony_ci (1 << i); 110462306a36Sopenharmony_ci } else 110562306a36Sopenharmony_ci simularity_bitmap = 110662306a36Sopenharmony_ci simularity_bitmap | (1 << i); 110762306a36Sopenharmony_ci } 110862306a36Sopenharmony_ci } 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_ci if (simularity_bitmap == 0) { 111162306a36Sopenharmony_ci for (i = 0; i < (bound / 4); i++) { 111262306a36Sopenharmony_ci if (final_candidate[i] != 0xFF) { 111362306a36Sopenharmony_ci for (j = i * 4; j < (i + 1) * 4 - 2; j++) 111462306a36Sopenharmony_ci result[3][j] = 111562306a36Sopenharmony_ci result[final_candidate[i]][j]; 111662306a36Sopenharmony_ci bresult = false; 111762306a36Sopenharmony_ci } 111862306a36Sopenharmony_ci } 111962306a36Sopenharmony_ci return bresult; 112062306a36Sopenharmony_ci } else if (!(simularity_bitmap & 0x0F)) { 112162306a36Sopenharmony_ci for (i = 0; i < 4; i++) 112262306a36Sopenharmony_ci result[3][i] = result[c1][i]; 112362306a36Sopenharmony_ci return false; 112462306a36Sopenharmony_ci } else { 112562306a36Sopenharmony_ci return false; 112662306a36Sopenharmony_ci } 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci} 112962306a36Sopenharmony_ci 113062306a36Sopenharmony_cistatic void _rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw, 113162306a36Sopenharmony_ci long result[][8], u8 t, bool is2t) 113262306a36Sopenharmony_ci{ 113362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 113462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 113562306a36Sopenharmony_ci u32 i; 113662306a36Sopenharmony_ci u8 patha_ok, pathb_ok; 113762306a36Sopenharmony_ci u32 adda_reg[IQK_ADDA_REG_NUM] = { 113862306a36Sopenharmony_ci 0x85c, 0xe6c, 0xe70, 0xe74, 113962306a36Sopenharmony_ci 0xe78, 0xe7c, 0xe80, 0xe84, 114062306a36Sopenharmony_ci 0xe88, 0xe8c, 0xed0, 0xed4, 114162306a36Sopenharmony_ci 0xed8, 0xedc, 0xee0, 0xeec 114262306a36Sopenharmony_ci }; 114362306a36Sopenharmony_ci 114462306a36Sopenharmony_ci u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { 114562306a36Sopenharmony_ci 0x522, 0x550, 0x551, 0x040 114662306a36Sopenharmony_ci }; 114762306a36Sopenharmony_ci 114862306a36Sopenharmony_ci const u32 retrycount = 2; 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci if (t == 0) { 115162306a36Sopenharmony_ci rtl_get_bbreg(hw, 0x800, MASKDWORD); 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_ci rtl8723_save_adda_registers(hw, adda_reg, 115462306a36Sopenharmony_ci rtlphy->adda_backup, 16); 115562306a36Sopenharmony_ci rtl8723_phy_save_mac_registers(hw, iqk_mac_reg, 115662306a36Sopenharmony_ci rtlphy->iqk_mac_backup); 115762306a36Sopenharmony_ci } 115862306a36Sopenharmony_ci rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t); 115962306a36Sopenharmony_ci if (t == 0) { 116062306a36Sopenharmony_ci rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, 116162306a36Sopenharmony_ci RFPGA0_XA_HSSIPARAMETER1, 116262306a36Sopenharmony_ci BIT(8)); 116362306a36Sopenharmony_ci } 116462306a36Sopenharmony_ci 116562306a36Sopenharmony_ci if (!rtlphy->rfpi_enable) 116662306a36Sopenharmony_ci rtl8723_phy_pi_mode_switch(hw, true); 116762306a36Sopenharmony_ci if (t == 0) { 116862306a36Sopenharmony_ci rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); 116962306a36Sopenharmony_ci rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); 117062306a36Sopenharmony_ci rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); 117162306a36Sopenharmony_ci } 117262306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); 117362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); 117462306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); 117562306a36Sopenharmony_ci if (is2t) { 117662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); 117762306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); 117862306a36Sopenharmony_ci } 117962306a36Sopenharmony_ci rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg, 118062306a36Sopenharmony_ci rtlphy->iqk_mac_backup); 118162306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); 118262306a36Sopenharmony_ci if (is2t) 118362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); 118462306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); 118562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); 118662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); 118762306a36Sopenharmony_ci for (i = 0; i < retrycount; i++) { 118862306a36Sopenharmony_ci patha_ok = _rtl8723e_phy_path_a_iqk(hw, is2t); 118962306a36Sopenharmony_ci if (patha_ok == 0x03) { 119062306a36Sopenharmony_ci result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & 119162306a36Sopenharmony_ci 0x3FF0000) >> 16; 119262306a36Sopenharmony_ci result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 119362306a36Sopenharmony_ci 0x3FF0000) >> 16; 119462306a36Sopenharmony_ci result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & 119562306a36Sopenharmony_ci 0x3FF0000) >> 16; 119662306a36Sopenharmony_ci result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & 119762306a36Sopenharmony_ci 0x3FF0000) >> 16; 119862306a36Sopenharmony_ci break; 119962306a36Sopenharmony_ci } else if (i == (retrycount - 1) && patha_ok == 0x01) 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_ci result[t][0] = (rtl_get_bbreg(hw, 0xe94, 120262306a36Sopenharmony_ci MASKDWORD) & 0x3FF0000) >> 120362306a36Sopenharmony_ci 16; 120462306a36Sopenharmony_ci result[t][1] = 120562306a36Sopenharmony_ci (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; 120662306a36Sopenharmony_ci 120762306a36Sopenharmony_ci } 120862306a36Sopenharmony_ci 120962306a36Sopenharmony_ci if (is2t) { 121062306a36Sopenharmony_ci rtl8723_phy_path_a_standby(hw); 121162306a36Sopenharmony_ci rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t); 121262306a36Sopenharmony_ci for (i = 0; i < retrycount; i++) { 121362306a36Sopenharmony_ci pathb_ok = _rtl8723e_phy_path_b_iqk(hw); 121462306a36Sopenharmony_ci if (pathb_ok == 0x03) { 121562306a36Sopenharmony_ci result[t][4] = (rtl_get_bbreg(hw, 121662306a36Sopenharmony_ci 0xeb4, 121762306a36Sopenharmony_ci MASKDWORD) & 121862306a36Sopenharmony_ci 0x3FF0000) >> 16; 121962306a36Sopenharmony_ci result[t][5] = 122062306a36Sopenharmony_ci (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & 122162306a36Sopenharmony_ci 0x3FF0000) >> 16; 122262306a36Sopenharmony_ci result[t][6] = 122362306a36Sopenharmony_ci (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & 122462306a36Sopenharmony_ci 0x3FF0000) >> 16; 122562306a36Sopenharmony_ci result[t][7] = 122662306a36Sopenharmony_ci (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & 122762306a36Sopenharmony_ci 0x3FF0000) >> 16; 122862306a36Sopenharmony_ci break; 122962306a36Sopenharmony_ci } else if (i == (retrycount - 1) && pathb_ok == 0x01) { 123062306a36Sopenharmony_ci result[t][4] = (rtl_get_bbreg(hw, 123162306a36Sopenharmony_ci 0xeb4, 123262306a36Sopenharmony_ci MASKDWORD) & 123362306a36Sopenharmony_ci 0x3FF0000) >> 16; 123462306a36Sopenharmony_ci } 123562306a36Sopenharmony_ci result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & 123662306a36Sopenharmony_ci 0x3FF0000) >> 16; 123762306a36Sopenharmony_ci } 123862306a36Sopenharmony_ci } 123962306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); 124062306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); 124162306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); 124262306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); 124362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); 124462306a36Sopenharmony_ci if (is2t) 124562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); 124662306a36Sopenharmony_ci if (t != 0) { 124762306a36Sopenharmony_ci if (!rtlphy->rfpi_enable) 124862306a36Sopenharmony_ci rtl8723_phy_pi_mode_switch(hw, false); 124962306a36Sopenharmony_ci rtl8723_phy_reload_adda_registers(hw, adda_reg, 125062306a36Sopenharmony_ci rtlphy->adda_backup, 16); 125162306a36Sopenharmony_ci rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg, 125262306a36Sopenharmony_ci rtlphy->iqk_mac_backup); 125362306a36Sopenharmony_ci } 125462306a36Sopenharmony_ci} 125562306a36Sopenharmony_ci 125662306a36Sopenharmony_cistatic void _rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) 125762306a36Sopenharmony_ci{ 125862306a36Sopenharmony_ci u8 tmpreg; 125962306a36Sopenharmony_ci u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; 126062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 126162306a36Sopenharmony_ci 126262306a36Sopenharmony_ci tmpreg = rtl_read_byte(rtlpriv, 0xd03); 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_ci if ((tmpreg & 0x70) != 0) 126562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); 126662306a36Sopenharmony_ci else 126762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 126862306a36Sopenharmony_ci 126962306a36Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 127062306a36Sopenharmony_ci rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ci if (is2t) 127362306a36Sopenharmony_ci rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, 127462306a36Sopenharmony_ci MASK12BITS); 127562306a36Sopenharmony_ci 127662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, 127762306a36Sopenharmony_ci (rf_a_mode & 0x8FFFF) | 0x10000); 127862306a36Sopenharmony_ci 127962306a36Sopenharmony_ci if (is2t) 128062306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, 128162306a36Sopenharmony_ci (rf_b_mode & 0x8FFFF) | 0x10000); 128262306a36Sopenharmony_ci } 128362306a36Sopenharmony_ci lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); 128462306a36Sopenharmony_ci 128562306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); 128662306a36Sopenharmony_ci 128762306a36Sopenharmony_ci mdelay(100); 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 129062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg); 129162306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); 129262306a36Sopenharmony_ci 129362306a36Sopenharmony_ci if (is2t) 129462306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, 129562306a36Sopenharmony_ci rf_b_mode); 129662306a36Sopenharmony_ci } else { 129762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 129862306a36Sopenharmony_ci } 129962306a36Sopenharmony_ci} 130062306a36Sopenharmony_ci 130162306a36Sopenharmony_cistatic void _rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw, 130262306a36Sopenharmony_ci bool bmain, bool is2t) 130362306a36Sopenharmony_ci{ 130462306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) { 130762306a36Sopenharmony_ci rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); 130862306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); 130962306a36Sopenharmony_ci } 131062306a36Sopenharmony_ci if (is2t) { 131162306a36Sopenharmony_ci if (bmain) 131262306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 131362306a36Sopenharmony_ci BIT(5) | BIT(6), 0x1); 131462306a36Sopenharmony_ci else 131562306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 131662306a36Sopenharmony_ci BIT(5) | BIT(6), 0x2); 131762306a36Sopenharmony_ci } else { 131862306a36Sopenharmony_ci if (bmain) 131962306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); 132062306a36Sopenharmony_ci else 132162306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); 132262306a36Sopenharmony_ci 132362306a36Sopenharmony_ci } 132462306a36Sopenharmony_ci 132562306a36Sopenharmony_ci} 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci#undef IQK_ADDA_REG_NUM 132862306a36Sopenharmony_ci#undef IQK_DELAY_TIME 132962306a36Sopenharmony_ci 133062306a36Sopenharmony_civoid rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) 133162306a36Sopenharmony_ci{ 133262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 133362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci long result[4][8]; 133662306a36Sopenharmony_ci u8 i, final_candidate; 133762306a36Sopenharmony_ci bool b_patha_ok; 133862306a36Sopenharmony_ci long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, 133962306a36Sopenharmony_ci reg_tmp = 0; 134062306a36Sopenharmony_ci bool is12simular, is13simular, is23simular; 134162306a36Sopenharmony_ci u32 iqk_bb_reg[10] = { 134262306a36Sopenharmony_ci ROFDM0_XARXIQIMBALANCE, 134362306a36Sopenharmony_ci ROFDM0_XBRXIQIMBALANCE, 134462306a36Sopenharmony_ci ROFDM0_ECCATHRESHOLD, 134562306a36Sopenharmony_ci ROFDM0_AGCRSSITABLE, 134662306a36Sopenharmony_ci ROFDM0_XATXIQIMBALANCE, 134762306a36Sopenharmony_ci ROFDM0_XBTXIQIMBALANCE, 134862306a36Sopenharmony_ci ROFDM0_XCTXIQIMBALANCE, 134962306a36Sopenharmony_ci ROFDM0_XCTXAFE, 135062306a36Sopenharmony_ci ROFDM0_XDTXAFE, 135162306a36Sopenharmony_ci ROFDM0_RXIQEXTANTA 135262306a36Sopenharmony_ci }; 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci if (b_recovery) { 135562306a36Sopenharmony_ci rtl8723_phy_reload_adda_registers(hw, 135662306a36Sopenharmony_ci iqk_bb_reg, 135762306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 10); 135862306a36Sopenharmony_ci return; 135962306a36Sopenharmony_ci } 136062306a36Sopenharmony_ci for (i = 0; i < 8; i++) { 136162306a36Sopenharmony_ci result[0][i] = 0; 136262306a36Sopenharmony_ci result[1][i] = 0; 136362306a36Sopenharmony_ci result[2][i] = 0; 136462306a36Sopenharmony_ci result[3][i] = 0; 136562306a36Sopenharmony_ci } 136662306a36Sopenharmony_ci final_candidate = 0xff; 136762306a36Sopenharmony_ci b_patha_ok = false; 136862306a36Sopenharmony_ci is12simular = false; 136962306a36Sopenharmony_ci is23simular = false; 137062306a36Sopenharmony_ci is13simular = false; 137162306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 137262306a36Sopenharmony_ci _rtl8723e_phy_iq_calibrate(hw, result, i, false); 137362306a36Sopenharmony_ci if (i == 1) { 137462306a36Sopenharmony_ci is12simular = 137562306a36Sopenharmony_ci _rtl8723e_phy_simularity_compare(hw, result, 0, 1); 137662306a36Sopenharmony_ci if (is12simular) { 137762306a36Sopenharmony_ci final_candidate = 0; 137862306a36Sopenharmony_ci break; 137962306a36Sopenharmony_ci } 138062306a36Sopenharmony_ci } 138162306a36Sopenharmony_ci if (i == 2) { 138262306a36Sopenharmony_ci is13simular = 138362306a36Sopenharmony_ci _rtl8723e_phy_simularity_compare(hw, result, 0, 2); 138462306a36Sopenharmony_ci if (is13simular) { 138562306a36Sopenharmony_ci final_candidate = 0; 138662306a36Sopenharmony_ci break; 138762306a36Sopenharmony_ci } 138862306a36Sopenharmony_ci is23simular = 138962306a36Sopenharmony_ci _rtl8723e_phy_simularity_compare(hw, result, 1, 2); 139062306a36Sopenharmony_ci if (is23simular) 139162306a36Sopenharmony_ci final_candidate = 1; 139262306a36Sopenharmony_ci else { 139362306a36Sopenharmony_ci for (i = 0; i < 8; i++) 139462306a36Sopenharmony_ci reg_tmp += result[3][i]; 139562306a36Sopenharmony_ci 139662306a36Sopenharmony_ci if (reg_tmp != 0) 139762306a36Sopenharmony_ci final_candidate = 3; 139862306a36Sopenharmony_ci else 139962306a36Sopenharmony_ci final_candidate = 0xFF; 140062306a36Sopenharmony_ci } 140162306a36Sopenharmony_ci } 140262306a36Sopenharmony_ci } 140362306a36Sopenharmony_ci for (i = 0; i < 4; i++) { 140462306a36Sopenharmony_ci reg_e94 = result[i][0]; 140562306a36Sopenharmony_ci reg_e9c = result[i][1]; 140662306a36Sopenharmony_ci reg_ea4 = result[i][2]; 140762306a36Sopenharmony_ci reg_eb4 = result[i][4]; 140862306a36Sopenharmony_ci reg_ebc = result[i][5]; 140962306a36Sopenharmony_ci } 141062306a36Sopenharmony_ci if (final_candidate != 0xff) { 141162306a36Sopenharmony_ci rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; 141262306a36Sopenharmony_ci rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; 141362306a36Sopenharmony_ci reg_ea4 = result[final_candidate][2]; 141462306a36Sopenharmony_ci rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; 141562306a36Sopenharmony_ci rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; 141662306a36Sopenharmony_ci b_patha_ok = true; 141762306a36Sopenharmony_ci } else { 141862306a36Sopenharmony_ci rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; 141962306a36Sopenharmony_ci rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; 142062306a36Sopenharmony_ci } 142162306a36Sopenharmony_ci if (reg_e94 != 0) 142262306a36Sopenharmony_ci rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, 142362306a36Sopenharmony_ci final_candidate, 142462306a36Sopenharmony_ci (reg_ea4 == 0)); 142562306a36Sopenharmony_ci rtl8723_save_adda_registers(hw, iqk_bb_reg, 142662306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 10); 142762306a36Sopenharmony_ci} 142862306a36Sopenharmony_ci 142962306a36Sopenharmony_civoid rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw) 143062306a36Sopenharmony_ci{ 143162306a36Sopenharmony_ci _rtl8723e_phy_lc_calibrate(hw, false); 143262306a36Sopenharmony_ci} 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_civoid rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) 143562306a36Sopenharmony_ci{ 143662306a36Sopenharmony_ci _rtl8723e_phy_set_rfpath_switch(hw, bmain, false); 143762306a36Sopenharmony_ci} 143862306a36Sopenharmony_ci 143962306a36Sopenharmony_cibool rtl8723e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) 144062306a36Sopenharmony_ci{ 144162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 144262306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 144362306a36Sopenharmony_ci bool postprocessing = false; 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 144662306a36Sopenharmony_ci "-->IO Cmd(%#x), set_io_inprogress(%d)\n", 144762306a36Sopenharmony_ci iotype, rtlphy->set_io_inprogress); 144862306a36Sopenharmony_ci do { 144962306a36Sopenharmony_ci switch (iotype) { 145062306a36Sopenharmony_ci case IO_CMD_RESUME_DM_BY_SCAN: 145162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 145262306a36Sopenharmony_ci "[IO CMD] Resume DM after scan.\n"); 145362306a36Sopenharmony_ci postprocessing = true; 145462306a36Sopenharmony_ci break; 145562306a36Sopenharmony_ci case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 145662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 145762306a36Sopenharmony_ci "[IO CMD] Pause DM before scan.\n"); 145862306a36Sopenharmony_ci postprocessing = true; 145962306a36Sopenharmony_ci break; 146062306a36Sopenharmony_ci default: 146162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 146262306a36Sopenharmony_ci "switch case %#x not processed\n", iotype); 146362306a36Sopenharmony_ci break; 146462306a36Sopenharmony_ci } 146562306a36Sopenharmony_ci } while (false); 146662306a36Sopenharmony_ci if (postprocessing && !rtlphy->set_io_inprogress) { 146762306a36Sopenharmony_ci rtlphy->set_io_inprogress = true; 146862306a36Sopenharmony_ci rtlphy->current_io_type = iotype; 146962306a36Sopenharmony_ci } else { 147062306a36Sopenharmony_ci return false; 147162306a36Sopenharmony_ci } 147262306a36Sopenharmony_ci rtl8723e_phy_set_io(hw); 147362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); 147462306a36Sopenharmony_ci return true; 147562306a36Sopenharmony_ci} 147662306a36Sopenharmony_ci 147762306a36Sopenharmony_cistatic void rtl8723e_phy_set_io(struct ieee80211_hw *hw) 147862306a36Sopenharmony_ci{ 147962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 148062306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 148162306a36Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 148262306a36Sopenharmony_ci 148362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 148462306a36Sopenharmony_ci "--->Cmd(%#x), set_io_inprogress(%d)\n", 148562306a36Sopenharmony_ci rtlphy->current_io_type, rtlphy->set_io_inprogress); 148662306a36Sopenharmony_ci switch (rtlphy->current_io_type) { 148762306a36Sopenharmony_ci case IO_CMD_RESUME_DM_BY_SCAN: 148862306a36Sopenharmony_ci dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; 148962306a36Sopenharmony_ci rtl8723e_dm_write_dig(hw); 149062306a36Sopenharmony_ci rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel); 149162306a36Sopenharmony_ci break; 149262306a36Sopenharmony_ci case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 149362306a36Sopenharmony_ci rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; 149462306a36Sopenharmony_ci dm_digtable->cur_igvalue = 0x17; 149562306a36Sopenharmony_ci rtl8723e_dm_write_dig(hw); 149662306a36Sopenharmony_ci break; 149762306a36Sopenharmony_ci default: 149862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 149962306a36Sopenharmony_ci "switch case %#x not processed\n", 150062306a36Sopenharmony_ci rtlphy->current_io_type); 150162306a36Sopenharmony_ci break; 150262306a36Sopenharmony_ci } 150362306a36Sopenharmony_ci rtlphy->set_io_inprogress = false; 150462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 150562306a36Sopenharmony_ci "(%#x)\n", rtlphy->current_io_type); 150662306a36Sopenharmony_ci} 150762306a36Sopenharmony_ci 150862306a36Sopenharmony_cistatic void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw) 150962306a36Sopenharmony_ci{ 151062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); 151362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 151462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); 151562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 151662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 151762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 151862306a36Sopenharmony_ci} 151962306a36Sopenharmony_ci 152062306a36Sopenharmony_cistatic void _rtl8723e_phy_set_rf_sleep(struct ieee80211_hw *hw) 152162306a36Sopenharmony_ci{ 152262306a36Sopenharmony_ci u32 u4b_tmp; 152362306a36Sopenharmony_ci u8 delay = 5; 152462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 152762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 152862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 152962306a36Sopenharmony_ci u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); 153062306a36Sopenharmony_ci while (u4b_tmp != 0 && delay > 0) { 153162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); 153262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 153362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 153462306a36Sopenharmony_ci u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); 153562306a36Sopenharmony_ci delay--; 153662306a36Sopenharmony_ci } 153762306a36Sopenharmony_ci if (delay == 0) { 153862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); 153962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 154062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 154162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 154262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, 154362306a36Sopenharmony_ci "Switch RF timeout !!!.\n"); 154462306a36Sopenharmony_ci return; 154562306a36Sopenharmony_ci } 154662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 154762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); 154862306a36Sopenharmony_ci} 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_cistatic bool _rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw, 155162306a36Sopenharmony_ci enum rf_pwrstate rfpwr_state) 155262306a36Sopenharmony_ci{ 155362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 155462306a36Sopenharmony_ci struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 155562306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 155662306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 155762306a36Sopenharmony_ci bool bresult = true; 155862306a36Sopenharmony_ci u8 i, queue_id; 155962306a36Sopenharmony_ci struct rtl8192_tx_ring *ring = NULL; 156062306a36Sopenharmony_ci 156162306a36Sopenharmony_ci switch (rfpwr_state) { 156262306a36Sopenharmony_ci case ERFON: 156362306a36Sopenharmony_ci if ((ppsc->rfpwr_state == ERFOFF) && 156462306a36Sopenharmony_ci RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { 156562306a36Sopenharmony_ci bool rtstatus; 156662306a36Sopenharmony_ci u32 initializecount = 0; 156762306a36Sopenharmony_ci 156862306a36Sopenharmony_ci do { 156962306a36Sopenharmony_ci initializecount++; 157062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 157162306a36Sopenharmony_ci "IPS Set eRf nic enable\n"); 157262306a36Sopenharmony_ci rtstatus = rtl_ps_enable_nic(hw); 157362306a36Sopenharmony_ci } while (!rtstatus && (initializecount < 10)); 157462306a36Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, 157562306a36Sopenharmony_ci RT_RF_OFF_LEVL_HALT_NIC); 157662306a36Sopenharmony_ci } else { 157762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 157862306a36Sopenharmony_ci "Set ERFON slept:%d ms\n", 157962306a36Sopenharmony_ci jiffies_to_msecs(jiffies - 158062306a36Sopenharmony_ci ppsc->last_sleep_jiffies)); 158162306a36Sopenharmony_ci ppsc->last_awake_jiffies = jiffies; 158262306a36Sopenharmony_ci rtl8723e_phy_set_rf_on(hw); 158362306a36Sopenharmony_ci } 158462306a36Sopenharmony_ci if (mac->link_state == MAC80211_LINKED) { 158562306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 158662306a36Sopenharmony_ci LED_CTL_LINK); 158762306a36Sopenharmony_ci } else { 158862306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 158962306a36Sopenharmony_ci LED_CTL_NO_LINK); 159062306a36Sopenharmony_ci } 159162306a36Sopenharmony_ci break; 159262306a36Sopenharmony_ci case ERFOFF: 159362306a36Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { 159462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 159562306a36Sopenharmony_ci "IPS Set eRf nic disable\n"); 159662306a36Sopenharmony_ci rtl_ps_disable_nic(hw); 159762306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 159862306a36Sopenharmony_ci } else { 159962306a36Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { 160062306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 160162306a36Sopenharmony_ci LED_CTL_NO_LINK); 160262306a36Sopenharmony_ci } else { 160362306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 160462306a36Sopenharmony_ci LED_CTL_POWER_OFF); 160562306a36Sopenharmony_ci } 160662306a36Sopenharmony_ci } 160762306a36Sopenharmony_ci break; 160862306a36Sopenharmony_ci case ERFSLEEP: 160962306a36Sopenharmony_ci if (ppsc->rfpwr_state == ERFOFF) 161062306a36Sopenharmony_ci break; 161162306a36Sopenharmony_ci for (queue_id = 0, i = 0; 161262306a36Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 161362306a36Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 161462306a36Sopenharmony_ci if (queue_id == BEACON_QUEUE || 161562306a36Sopenharmony_ci skb_queue_len(&ring->queue) == 0) { 161662306a36Sopenharmony_ci queue_id++; 161762306a36Sopenharmony_ci continue; 161862306a36Sopenharmony_ci } else { 161962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 162062306a36Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", 162162306a36Sopenharmony_ci (i + 1), queue_id, 162262306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 162362306a36Sopenharmony_ci 162462306a36Sopenharmony_ci udelay(10); 162562306a36Sopenharmony_ci i++; 162662306a36Sopenharmony_ci } 162762306a36Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 162862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 162962306a36Sopenharmony_ci "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", 163062306a36Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 163162306a36Sopenharmony_ci queue_id, 163262306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 163362306a36Sopenharmony_ci break; 163462306a36Sopenharmony_ci } 163562306a36Sopenharmony_ci } 163662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 163762306a36Sopenharmony_ci "Set ERFSLEEP awaked:%d ms\n", 163862306a36Sopenharmony_ci jiffies_to_msecs(jiffies - 163962306a36Sopenharmony_ci ppsc->last_awake_jiffies)); 164062306a36Sopenharmony_ci ppsc->last_sleep_jiffies = jiffies; 164162306a36Sopenharmony_ci _rtl8723e_phy_set_rf_sleep(hw); 164262306a36Sopenharmony_ci break; 164362306a36Sopenharmony_ci default: 164462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 164562306a36Sopenharmony_ci "switch case %#x not processed\n", rfpwr_state); 164662306a36Sopenharmony_ci bresult = false; 164762306a36Sopenharmony_ci break; 164862306a36Sopenharmony_ci } 164962306a36Sopenharmony_ci if (bresult) 165062306a36Sopenharmony_ci ppsc->rfpwr_state = rfpwr_state; 165162306a36Sopenharmony_ci return bresult; 165262306a36Sopenharmony_ci} 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_cibool rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw, 165562306a36Sopenharmony_ci enum rf_pwrstate rfpwr_state) 165662306a36Sopenharmony_ci{ 165762306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 165862306a36Sopenharmony_ci 165962306a36Sopenharmony_ci bool bresult = false; 166062306a36Sopenharmony_ci 166162306a36Sopenharmony_ci if (rfpwr_state == ppsc->rfpwr_state) 166262306a36Sopenharmony_ci return bresult; 166362306a36Sopenharmony_ci bresult = _rtl8723e_phy_set_rf_power_state(hw, rfpwr_state); 166462306a36Sopenharmony_ci return bresult; 166562306a36Sopenharmony_ci} 1666