162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2013 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 1462306a36Sopenharmony_cistatic u32 _rtl88e_phy_rf_serial_read(struct ieee80211_hw *hw, 1562306a36Sopenharmony_ci enum radio_path rfpath, u32 offset); 1662306a36Sopenharmony_cistatic void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw, 1762306a36Sopenharmony_ci enum radio_path rfpath, u32 offset, 1862306a36Sopenharmony_ci u32 data); 1962306a36Sopenharmony_cistatic bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw); 2062306a36Sopenharmony_cistatic bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); 2162306a36Sopenharmony_cistatic bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw, 2262306a36Sopenharmony_ci u8 configtype); 2362306a36Sopenharmony_cistatic bool phy_config_bb_with_pghdr(struct ieee80211_hw *hw, 2462306a36Sopenharmony_ci u8 configtype); 2562306a36Sopenharmony_cistatic void _rtl88e_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); 2662306a36Sopenharmony_cistatic bool _rtl88e_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, 2762306a36Sopenharmony_ci u32 cmdtableidx, u32 cmdtablesz, 2862306a36Sopenharmony_ci enum swchnlcmd_id cmdid, u32 para1, 2962306a36Sopenharmony_ci u32 para2, u32 msdelay); 3062306a36Sopenharmony_cistatic bool _rtl88e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 3162306a36Sopenharmony_ci u8 channel, u8 *stage, u8 *step, 3262306a36Sopenharmony_ci u32 *delay); 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_cistatic long _rtl88e_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, 3562306a36Sopenharmony_ci enum wireless_mode wirelessmode, 3662306a36Sopenharmony_ci u8 txpwridx); 3762306a36Sopenharmony_cistatic void rtl88ee_phy_set_rf_on(struct ieee80211_hw *hw); 3862306a36Sopenharmony_cistatic void rtl88e_phy_set_io(struct ieee80211_hw *hw); 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ciu32 rtl88e_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) 4162306a36Sopenharmony_ci{ 4262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4362306a36Sopenharmony_ci u32 returnvalue, originalvalue, bitshift; 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 4662306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); 4762306a36Sopenharmony_ci originalvalue = rtl_read_dword(rtlpriv, regaddr); 4862306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 4962306a36Sopenharmony_ci returnvalue = (originalvalue & bitmask) >> bitshift; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 5262306a36Sopenharmony_ci "BBR MASK=0x%x Addr[0x%x]=0x%x\n", bitmask, 5362306a36Sopenharmony_ci regaddr, originalvalue); 5462306a36Sopenharmony_ci 5562306a36Sopenharmony_ci return returnvalue; 5662306a36Sopenharmony_ci 5762306a36Sopenharmony_ci} 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_civoid rtl88e_phy_set_bb_reg(struct ieee80211_hw *hw, 6062306a36Sopenharmony_ci u32 regaddr, u32 bitmask, u32 data) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6362306a36Sopenharmony_ci u32 originalvalue, bitshift; 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 6662306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x)\n", 6762306a36Sopenharmony_ci regaddr, bitmask, data); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_ci if (bitmask != MASKDWORD) { 7062306a36Sopenharmony_ci originalvalue = rtl_read_dword(rtlpriv, regaddr); 7162306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 7262306a36Sopenharmony_ci data = ((originalvalue & (~bitmask)) | (data << bitshift)); 7362306a36Sopenharmony_ci } 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, regaddr, data); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 7862306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x)\n", 7962306a36Sopenharmony_ci regaddr, bitmask, data); 8062306a36Sopenharmony_ci} 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ciu32 rtl88e_phy_query_rf_reg(struct ieee80211_hw *hw, 8362306a36Sopenharmony_ci enum radio_path rfpath, u32 regaddr, u32 bitmask) 8462306a36Sopenharmony_ci{ 8562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8662306a36Sopenharmony_ci u32 original_value, readback_value, bitshift; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 8962306a36Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", 9062306a36Sopenharmony_ci regaddr, rfpath, bitmask); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 9362306a36Sopenharmony_ci 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci original_value = _rtl88e_phy_rf_serial_read(hw, rfpath, regaddr); 9662306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 9762306a36Sopenharmony_ci readback_value = (original_value & bitmask) >> bitshift; 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 10262306a36Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", 10362306a36Sopenharmony_ci regaddr, rfpath, bitmask, original_value); 10462306a36Sopenharmony_ci return readback_value; 10562306a36Sopenharmony_ci} 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_civoid rtl88e_phy_set_rf_reg(struct ieee80211_hw *hw, 10862306a36Sopenharmony_ci enum radio_path rfpath, 10962306a36Sopenharmony_ci u32 regaddr, u32 bitmask, u32 data) 11062306a36Sopenharmony_ci{ 11162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11262306a36Sopenharmony_ci u32 original_value, bitshift; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 11562306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 11662306a36Sopenharmony_ci regaddr, bitmask, data, rfpath); 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci if (bitmask != RFREG_OFFSET_MASK) { 12162306a36Sopenharmony_ci original_value = _rtl88e_phy_rf_serial_read(hw, 12262306a36Sopenharmony_ci rfpath, 12362306a36Sopenharmony_ci regaddr); 12462306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 12562306a36Sopenharmony_ci data = 12662306a36Sopenharmony_ci ((original_value & (~bitmask)) | 12762306a36Sopenharmony_ci (data << bitshift)); 12862306a36Sopenharmony_ci } 12962306a36Sopenharmony_ci 13062306a36Sopenharmony_ci _rtl88e_phy_rf_serial_write(hw, rfpath, regaddr, data); 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 13462306a36Sopenharmony_ci 13562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 13662306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 13762306a36Sopenharmony_ci regaddr, bitmask, data, rfpath); 13862306a36Sopenharmony_ci} 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_cistatic u32 _rtl88e_phy_rf_serial_read(struct ieee80211_hw *hw, 14162306a36Sopenharmony_ci enum radio_path rfpath, u32 offset) 14262306a36Sopenharmony_ci{ 14362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 14562306a36Sopenharmony_ci struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 14662306a36Sopenharmony_ci u32 newoffset; 14762306a36Sopenharmony_ci u32 tmplong, tmplong2; 14862306a36Sopenharmony_ci u8 rfpi_enable = 0; 14962306a36Sopenharmony_ci u32 retvalue; 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci offset &= 0xff; 15262306a36Sopenharmony_ci newoffset = offset; 15362306a36Sopenharmony_ci if (RT_CANNOT_IO(hw)) { 15462306a36Sopenharmony_ci pr_err("return all one\n"); 15562306a36Sopenharmony_ci return 0xFFFFFFFF; 15662306a36Sopenharmony_ci } 15762306a36Sopenharmony_ci tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); 15862306a36Sopenharmony_ci if (rfpath == RF90_PATH_A) 15962306a36Sopenharmony_ci tmplong2 = tmplong; 16062306a36Sopenharmony_ci else 16162306a36Sopenharmony_ci tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); 16262306a36Sopenharmony_ci tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | 16362306a36Sopenharmony_ci (newoffset << 23) | BLSSIREADEDGE; 16462306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, 16562306a36Sopenharmony_ci tmplong & (~BLSSIREADEDGE)); 16662306a36Sopenharmony_ci udelay(10); 16762306a36Sopenharmony_ci rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); 16862306a36Sopenharmony_ci udelay(120); 16962306a36Sopenharmony_ci if (rfpath == RF90_PATH_A) 17062306a36Sopenharmony_ci rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, 17162306a36Sopenharmony_ci BIT(8)); 17262306a36Sopenharmony_ci else if (rfpath == RF90_PATH_B) 17362306a36Sopenharmony_ci rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, 17462306a36Sopenharmony_ci BIT(8)); 17562306a36Sopenharmony_ci if (rfpi_enable) 17662306a36Sopenharmony_ci retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, 17762306a36Sopenharmony_ci BLSSIREADBACKDATA); 17862306a36Sopenharmony_ci else 17962306a36Sopenharmony_ci retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, 18062306a36Sopenharmony_ci BLSSIREADBACKDATA); 18162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 18262306a36Sopenharmony_ci "RFR-%d Addr[0x%x]=0x%x\n", 18362306a36Sopenharmony_ci rfpath, pphyreg->rf_rb, retvalue); 18462306a36Sopenharmony_ci return retvalue; 18562306a36Sopenharmony_ci} 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_cistatic void _rtl88e_phy_rf_serial_write(struct ieee80211_hw *hw, 18862306a36Sopenharmony_ci enum radio_path rfpath, u32 offset, 18962306a36Sopenharmony_ci u32 data) 19062306a36Sopenharmony_ci{ 19162306a36Sopenharmony_ci u32 data_and_addr; 19262306a36Sopenharmony_ci u32 newoffset; 19362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 19462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 19562306a36Sopenharmony_ci struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci if (RT_CANNOT_IO(hw)) { 19862306a36Sopenharmony_ci pr_err("stop\n"); 19962306a36Sopenharmony_ci return; 20062306a36Sopenharmony_ci } 20162306a36Sopenharmony_ci offset &= 0xff; 20262306a36Sopenharmony_ci newoffset = offset; 20362306a36Sopenharmony_ci data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; 20462306a36Sopenharmony_ci rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); 20562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 20662306a36Sopenharmony_ci "RFW-%d Addr[0x%x]=0x%x\n", 20762306a36Sopenharmony_ci rfpath, pphyreg->rf3wire_offset, data_and_addr); 20862306a36Sopenharmony_ci} 20962306a36Sopenharmony_ci 21062306a36Sopenharmony_cibool rtl88e_phy_mac_config(struct ieee80211_hw *hw) 21162306a36Sopenharmony_ci{ 21262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 21362306a36Sopenharmony_ci bool rtstatus = _rtl88e_phy_config_mac_with_headerfile(hw); 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x04CA, 0x0B); 21662306a36Sopenharmony_ci return rtstatus; 21762306a36Sopenharmony_ci} 21862306a36Sopenharmony_ci 21962306a36Sopenharmony_cibool rtl88e_phy_bb_config(struct ieee80211_hw *hw) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci bool rtstatus = true; 22262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 22362306a36Sopenharmony_ci u16 regval; 22462306a36Sopenharmony_ci u8 b_reg_hwparafile = 1; 22562306a36Sopenharmony_ci u32 tmp; 22662306a36Sopenharmony_ci _rtl88e_phy_init_bb_rf_register_definition(hw); 22762306a36Sopenharmony_ci regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 22862306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, 22962306a36Sopenharmony_ci regval | BIT(13) | BIT(0) | BIT(1)); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); 23262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 23362306a36Sopenharmony_ci FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | 23462306a36Sopenharmony_ci FEN_BB_GLB_RSTN | FEN_BBRSTB); 23562306a36Sopenharmony_ci tmp = rtl_read_dword(rtlpriv, 0x4c); 23662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23)); 23762306a36Sopenharmony_ci if (b_reg_hwparafile == 1) 23862306a36Sopenharmony_ci rtstatus = _rtl88e_phy_bb8188e_config_parafile(hw); 23962306a36Sopenharmony_ci return rtstatus; 24062306a36Sopenharmony_ci} 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_cibool rtl88e_phy_rf_config(struct ieee80211_hw *hw) 24362306a36Sopenharmony_ci{ 24462306a36Sopenharmony_ci return rtl88e_phy_rf6052_config(hw); 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cistatic bool _rtl88e_check_condition(struct ieee80211_hw *hw, 24862306a36Sopenharmony_ci const u32 condition) 24962306a36Sopenharmony_ci{ 25062306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 25162306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 25262306a36Sopenharmony_ci u32 _board = rtlefuse->board_type; /*need efuse define*/ 25362306a36Sopenharmony_ci u32 _interface = rtlhal->interface; 25462306a36Sopenharmony_ci u32 _platform = 0x08;/*SupportPlatform */ 25562306a36Sopenharmony_ci u32 cond; 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci if (condition == 0xCDCDCDCD) 25862306a36Sopenharmony_ci return true; 25962306a36Sopenharmony_ci 26062306a36Sopenharmony_ci cond = condition & 0xFF; 26162306a36Sopenharmony_ci if ((_board & cond) == 0 && cond != 0x1F) 26262306a36Sopenharmony_ci return false; 26362306a36Sopenharmony_ci 26462306a36Sopenharmony_ci cond = condition & 0xFF00; 26562306a36Sopenharmony_ci cond = cond >> 8; 26662306a36Sopenharmony_ci if ((_interface & cond) == 0 && cond != 0x07) 26762306a36Sopenharmony_ci return false; 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci cond = condition & 0xFF0000; 27062306a36Sopenharmony_ci cond = cond >> 16; 27162306a36Sopenharmony_ci if ((_platform & cond) == 0 && cond != 0x0F) 27262306a36Sopenharmony_ci return false; 27362306a36Sopenharmony_ci return true; 27462306a36Sopenharmony_ci} 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_cistatic void _rtl8188e_config_rf_reg(struct ieee80211_hw *hw, u32 addr, 27762306a36Sopenharmony_ci u32 data, enum radio_path rfpath, 27862306a36Sopenharmony_ci u32 regaddr) 27962306a36Sopenharmony_ci{ 28062306a36Sopenharmony_ci if (addr == 0xffe) { 28162306a36Sopenharmony_ci mdelay(50); 28262306a36Sopenharmony_ci } else if (addr == 0xfd) { 28362306a36Sopenharmony_ci mdelay(5); 28462306a36Sopenharmony_ci } else if (addr == 0xfc) { 28562306a36Sopenharmony_ci mdelay(1); 28662306a36Sopenharmony_ci } else if (addr == 0xfb) { 28762306a36Sopenharmony_ci udelay(50); 28862306a36Sopenharmony_ci } else if (addr == 0xfa) { 28962306a36Sopenharmony_ci udelay(5); 29062306a36Sopenharmony_ci } else if (addr == 0xf9) { 29162306a36Sopenharmony_ci udelay(1); 29262306a36Sopenharmony_ci } else { 29362306a36Sopenharmony_ci rtl_set_rfreg(hw, rfpath, regaddr, 29462306a36Sopenharmony_ci RFREG_OFFSET_MASK, 29562306a36Sopenharmony_ci data); 29662306a36Sopenharmony_ci udelay(1); 29762306a36Sopenharmony_ci } 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_cistatic void _rtl8188e_config_rf_radio_a(struct ieee80211_hw *hw, 30162306a36Sopenharmony_ci u32 addr, u32 data) 30262306a36Sopenharmony_ci{ 30362306a36Sopenharmony_ci u32 content = 0x1000; /*RF Content: radio_a_txt*/ 30462306a36Sopenharmony_ci u32 maskforphyset = (u32)(content & 0xE000); 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci _rtl8188e_config_rf_reg(hw, addr, data, RF90_PATH_A, 30762306a36Sopenharmony_ci addr | maskforphyset); 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistatic void _rtl8188e_config_bb_reg(struct ieee80211_hw *hw, 31162306a36Sopenharmony_ci u32 addr, u32 data) 31262306a36Sopenharmony_ci{ 31362306a36Sopenharmony_ci if (addr == 0xfe) { 31462306a36Sopenharmony_ci mdelay(50); 31562306a36Sopenharmony_ci } else if (addr == 0xfd) { 31662306a36Sopenharmony_ci mdelay(5); 31762306a36Sopenharmony_ci } else if (addr == 0xfc) { 31862306a36Sopenharmony_ci mdelay(1); 31962306a36Sopenharmony_ci } else if (addr == 0xfb) { 32062306a36Sopenharmony_ci udelay(50); 32162306a36Sopenharmony_ci } else if (addr == 0xfa) { 32262306a36Sopenharmony_ci udelay(5); 32362306a36Sopenharmony_ci } else if (addr == 0xf9) { 32462306a36Sopenharmony_ci udelay(1); 32562306a36Sopenharmony_ci } else { 32662306a36Sopenharmony_ci rtl_set_bbreg(hw, addr, MASKDWORD, data); 32762306a36Sopenharmony_ci udelay(1); 32862306a36Sopenharmony_ci } 32962306a36Sopenharmony_ci} 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_cistatic bool _rtl88e_phy_bb8188e_config_parafile(struct ieee80211_hw *hw) 33262306a36Sopenharmony_ci{ 33362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 33462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 33562306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 33662306a36Sopenharmony_ci bool rtstatus; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci rtstatus = phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_PHY_REG); 33962306a36Sopenharmony_ci if (!rtstatus) { 34062306a36Sopenharmony_ci pr_err("Write BB Reg Fail!!\n"); 34162306a36Sopenharmony_ci return false; 34262306a36Sopenharmony_ci } 34362306a36Sopenharmony_ci 34462306a36Sopenharmony_ci if (!rtlefuse->autoload_failflag) { 34562306a36Sopenharmony_ci rtlphy->pwrgroup_cnt = 0; 34662306a36Sopenharmony_ci rtstatus = 34762306a36Sopenharmony_ci phy_config_bb_with_pghdr(hw, BASEBAND_CONFIG_PHY_REG); 34862306a36Sopenharmony_ci } 34962306a36Sopenharmony_ci if (!rtstatus) { 35062306a36Sopenharmony_ci pr_err("BB_PG Reg Fail!!\n"); 35162306a36Sopenharmony_ci return false; 35262306a36Sopenharmony_ci } 35362306a36Sopenharmony_ci rtstatus = 35462306a36Sopenharmony_ci phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB); 35562306a36Sopenharmony_ci if (!rtstatus) { 35662306a36Sopenharmony_ci pr_err("AGC Table Fail\n"); 35762306a36Sopenharmony_ci return false; 35862306a36Sopenharmony_ci } 35962306a36Sopenharmony_ci rtlphy->cck_high_power = 36062306a36Sopenharmony_ci (bool)(rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, 0x200)); 36162306a36Sopenharmony_ci 36262306a36Sopenharmony_ci return true; 36362306a36Sopenharmony_ci} 36462306a36Sopenharmony_ci 36562306a36Sopenharmony_cistatic bool _rtl88e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) 36662306a36Sopenharmony_ci{ 36762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 36862306a36Sopenharmony_ci u32 i; 36962306a36Sopenharmony_ci u32 arraylength; 37062306a36Sopenharmony_ci u32 *ptrarray; 37162306a36Sopenharmony_ci 37262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8188EMACPHY_Array\n"); 37362306a36Sopenharmony_ci arraylength = RTL8188EEMAC_1T_ARRAYLEN; 37462306a36Sopenharmony_ci ptrarray = RTL8188EEMAC_1T_ARRAY; 37562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 37662306a36Sopenharmony_ci "Img:RTL8188EEMAC_1T_ARRAY LEN %d\n", arraylength); 37762306a36Sopenharmony_ci for (i = 0; i < arraylength; i = i + 2) 37862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]); 37962306a36Sopenharmony_ci return true; 38062306a36Sopenharmony_ci} 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci#define READ_NEXT_PAIR(v1, v2, i) \ 38362306a36Sopenharmony_ci do { \ 38462306a36Sopenharmony_ci i += 2; v1 = array_table[i]; \ 38562306a36Sopenharmony_ci v2 = array_table[i+1]; \ 38662306a36Sopenharmony_ci } while (0) 38762306a36Sopenharmony_ci 38862306a36Sopenharmony_cistatic void handle_branch1(struct ieee80211_hw *hw, u16 arraylen, 38962306a36Sopenharmony_ci u32 *array_table) 39062306a36Sopenharmony_ci{ 39162306a36Sopenharmony_ci u32 v1; 39262306a36Sopenharmony_ci u32 v2; 39362306a36Sopenharmony_ci int i; 39462306a36Sopenharmony_ci 39562306a36Sopenharmony_ci for (i = 0; i < arraylen; i = i + 2) { 39662306a36Sopenharmony_ci v1 = array_table[i]; 39762306a36Sopenharmony_ci v2 = array_table[i+1]; 39862306a36Sopenharmony_ci if (v1 < 0xcdcdcdcd) { 39962306a36Sopenharmony_ci _rtl8188e_config_bb_reg(hw, v1, v2); 40062306a36Sopenharmony_ci } else { /*This line is the start line of branch.*/ 40162306a36Sopenharmony_ci /* to protect READ_NEXT_PAIR not overrun */ 40262306a36Sopenharmony_ci if (i >= arraylen - 2) 40362306a36Sopenharmony_ci break; 40462306a36Sopenharmony_ci 40562306a36Sopenharmony_ci if (!_rtl88e_check_condition(hw, array_table[i])) { 40662306a36Sopenharmony_ci /*Discard the following (offset, data) pairs*/ 40762306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 40862306a36Sopenharmony_ci while (v2 != 0xDEAD && 40962306a36Sopenharmony_ci v2 != 0xCDEF && 41062306a36Sopenharmony_ci v2 != 0xCDCD && i < arraylen - 2) 41162306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 41262306a36Sopenharmony_ci i -= 2; /* prevent from for-loop += 2*/ 41362306a36Sopenharmony_ci } else { /* Configure matched pairs and skip 41462306a36Sopenharmony_ci * to end of if-else. 41562306a36Sopenharmony_ci */ 41662306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 41762306a36Sopenharmony_ci while (v2 != 0xDEAD && 41862306a36Sopenharmony_ci v2 != 0xCDEF && 41962306a36Sopenharmony_ci v2 != 0xCDCD && i < arraylen - 2) { 42062306a36Sopenharmony_ci _rtl8188e_config_bb_reg(hw, v1, v2); 42162306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 42262306a36Sopenharmony_ci } 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci while (v2 != 0xDEAD && i < arraylen - 2) 42562306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 42662306a36Sopenharmony_ci } 42762306a36Sopenharmony_ci } 42862306a36Sopenharmony_ci } 42962306a36Sopenharmony_ci} 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_cistatic void handle_branch2(struct ieee80211_hw *hw, u16 arraylen, 43262306a36Sopenharmony_ci u32 *array_table) 43362306a36Sopenharmony_ci{ 43462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 43562306a36Sopenharmony_ci u32 v1; 43662306a36Sopenharmony_ci u32 v2; 43762306a36Sopenharmony_ci int i; 43862306a36Sopenharmony_ci 43962306a36Sopenharmony_ci for (i = 0; i < arraylen; i = i + 2) { 44062306a36Sopenharmony_ci v1 = array_table[i]; 44162306a36Sopenharmony_ci v2 = array_table[i+1]; 44262306a36Sopenharmony_ci if (v1 < 0xCDCDCDCD) { 44362306a36Sopenharmony_ci rtl_set_bbreg(hw, array_table[i], MASKDWORD, 44462306a36Sopenharmony_ci array_table[i + 1]); 44562306a36Sopenharmony_ci udelay(1); 44662306a36Sopenharmony_ci continue; 44762306a36Sopenharmony_ci } else { /*This line is the start line of branch.*/ 44862306a36Sopenharmony_ci /* to protect READ_NEXT_PAIR not overrun */ 44962306a36Sopenharmony_ci if (i >= arraylen - 2) 45062306a36Sopenharmony_ci break; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci if (!_rtl88e_check_condition(hw, array_table[i])) { 45362306a36Sopenharmony_ci /*Discard the following (offset, data) pairs*/ 45462306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 45562306a36Sopenharmony_ci while (v2 != 0xDEAD && 45662306a36Sopenharmony_ci v2 != 0xCDEF && 45762306a36Sopenharmony_ci v2 != 0xCDCD && i < arraylen - 2) 45862306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 45962306a36Sopenharmony_ci i -= 2; /* prevent from for-loop += 2*/ 46062306a36Sopenharmony_ci } else { /* Configure matched pairs and skip 46162306a36Sopenharmony_ci * to end of if-else. 46262306a36Sopenharmony_ci */ 46362306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 46462306a36Sopenharmony_ci while (v2 != 0xDEAD && 46562306a36Sopenharmony_ci v2 != 0xCDEF && 46662306a36Sopenharmony_ci v2 != 0xCDCD && i < arraylen - 2) { 46762306a36Sopenharmony_ci rtl_set_bbreg(hw, array_table[i], 46862306a36Sopenharmony_ci MASKDWORD, 46962306a36Sopenharmony_ci array_table[i + 1]); 47062306a36Sopenharmony_ci udelay(1); 47162306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 47262306a36Sopenharmony_ci } 47362306a36Sopenharmony_ci 47462306a36Sopenharmony_ci while (v2 != 0xDEAD && i < arraylen - 2) 47562306a36Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 47662306a36Sopenharmony_ci } 47762306a36Sopenharmony_ci } 47862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 47962306a36Sopenharmony_ci "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n", 48062306a36Sopenharmony_ci array_table[i], array_table[i + 1]); 48162306a36Sopenharmony_ci } 48262306a36Sopenharmony_ci} 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_cistatic bool phy_config_bb_with_headerfile(struct ieee80211_hw *hw, 48562306a36Sopenharmony_ci u8 configtype) 48662306a36Sopenharmony_ci{ 48762306a36Sopenharmony_ci u32 *array_table; 48862306a36Sopenharmony_ci u16 arraylen; 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 49162306a36Sopenharmony_ci arraylen = RTL8188EEPHY_REG_1TARRAYLEN; 49262306a36Sopenharmony_ci array_table = RTL8188EEPHY_REG_1TARRAY; 49362306a36Sopenharmony_ci handle_branch1(hw, arraylen, array_table); 49462306a36Sopenharmony_ci } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { 49562306a36Sopenharmony_ci arraylen = RTL8188EEAGCTAB_1TARRAYLEN; 49662306a36Sopenharmony_ci array_table = RTL8188EEAGCTAB_1TARRAY; 49762306a36Sopenharmony_ci handle_branch2(hw, arraylen, array_table); 49862306a36Sopenharmony_ci } 49962306a36Sopenharmony_ci return true; 50062306a36Sopenharmony_ci} 50162306a36Sopenharmony_ci 50262306a36Sopenharmony_cistatic void store_pwrindex_rate_offset(struct ieee80211_hw *hw, 50362306a36Sopenharmony_ci u32 regaddr, u32 bitmask, 50462306a36Sopenharmony_ci u32 data) 50562306a36Sopenharmony_ci{ 50662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 50762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 50862306a36Sopenharmony_ci int count = rtlphy->pwrgroup_cnt; 50962306a36Sopenharmony_ci 51062306a36Sopenharmony_ci if (regaddr == RTXAGC_A_RATE18_06) { 51162306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][0] = data; 51262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 51362306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n", 51462306a36Sopenharmony_ci count, 51562306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][0]); 51662306a36Sopenharmony_ci } 51762306a36Sopenharmony_ci if (regaddr == RTXAGC_A_RATE54_24) { 51862306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][1] = data; 51962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 52062306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n", 52162306a36Sopenharmony_ci count, 52262306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][1]); 52362306a36Sopenharmony_ci } 52462306a36Sopenharmony_ci if (regaddr == RTXAGC_A_CCK1_MCS32) { 52562306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][6] = data; 52662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 52762306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n", 52862306a36Sopenharmony_ci count, 52962306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][6]); 53062306a36Sopenharmony_ci } 53162306a36Sopenharmony_ci if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) { 53262306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][7] = data; 53362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 53462306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n", 53562306a36Sopenharmony_ci count, 53662306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][7]); 53762306a36Sopenharmony_ci } 53862306a36Sopenharmony_ci if (regaddr == RTXAGC_A_MCS03_MCS00) { 53962306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][2] = data; 54062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 54162306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n", 54262306a36Sopenharmony_ci count, 54362306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][2]); 54462306a36Sopenharmony_ci } 54562306a36Sopenharmony_ci if (regaddr == RTXAGC_A_MCS07_MCS04) { 54662306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][3] = data; 54762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 54862306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n", 54962306a36Sopenharmony_ci count, 55062306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][3]); 55162306a36Sopenharmony_ci } 55262306a36Sopenharmony_ci if (regaddr == RTXAGC_A_MCS11_MCS08) { 55362306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][4] = data; 55462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 55562306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n", 55662306a36Sopenharmony_ci count, 55762306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][4]); 55862306a36Sopenharmony_ci } 55962306a36Sopenharmony_ci if (regaddr == RTXAGC_A_MCS15_MCS12) { 56062306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][5] = data; 56162306a36Sopenharmony_ci if (get_rf_type(rtlphy) == RF_1T1R) { 56262306a36Sopenharmony_ci count++; 56362306a36Sopenharmony_ci rtlphy->pwrgroup_cnt = count; 56462306a36Sopenharmony_ci } 56562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 56662306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n", 56762306a36Sopenharmony_ci count, 56862306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][5]); 56962306a36Sopenharmony_ci } 57062306a36Sopenharmony_ci if (regaddr == RTXAGC_B_RATE18_06) { 57162306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][8] = data; 57262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 57362306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n", 57462306a36Sopenharmony_ci count, 57562306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][8]); 57662306a36Sopenharmony_ci } 57762306a36Sopenharmony_ci if (regaddr == RTXAGC_B_RATE54_24) { 57862306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][9] = data; 57962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 58062306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n", 58162306a36Sopenharmony_ci count, 58262306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][9]); 58362306a36Sopenharmony_ci } 58462306a36Sopenharmony_ci if (regaddr == RTXAGC_B_CCK1_55_MCS32) { 58562306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][14] = data; 58662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 58762306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n", 58862306a36Sopenharmony_ci count, 58962306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][14]); 59062306a36Sopenharmony_ci } 59162306a36Sopenharmony_ci if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) { 59262306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][15] = data; 59362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 59462306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n", 59562306a36Sopenharmony_ci count, 59662306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][15]); 59762306a36Sopenharmony_ci } 59862306a36Sopenharmony_ci if (regaddr == RTXAGC_B_MCS03_MCS00) { 59962306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][10] = data; 60062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 60162306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n", 60262306a36Sopenharmony_ci count, 60362306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][10]); 60462306a36Sopenharmony_ci } 60562306a36Sopenharmony_ci if (regaddr == RTXAGC_B_MCS07_MCS04) { 60662306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][11] = data; 60762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 60862306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n", 60962306a36Sopenharmony_ci count, 61062306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][11]); 61162306a36Sopenharmony_ci } 61262306a36Sopenharmony_ci if (regaddr == RTXAGC_B_MCS11_MCS08) { 61362306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][12] = data; 61462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 61562306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n", 61662306a36Sopenharmony_ci count, 61762306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][12]); 61862306a36Sopenharmony_ci } 61962306a36Sopenharmony_ci if (regaddr == RTXAGC_B_MCS15_MCS12) { 62062306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][13] = data; 62162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 62262306a36Sopenharmony_ci "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n", 62362306a36Sopenharmony_ci count, 62462306a36Sopenharmony_ci rtlphy->mcs_txpwrlevel_origoffset[count][13]); 62562306a36Sopenharmony_ci if (get_rf_type(rtlphy) != RF_1T1R) { 62662306a36Sopenharmony_ci count++; 62762306a36Sopenharmony_ci rtlphy->pwrgroup_cnt = count; 62862306a36Sopenharmony_ci } 62962306a36Sopenharmony_ci } 63062306a36Sopenharmony_ci} 63162306a36Sopenharmony_ci 63262306a36Sopenharmony_cistatic bool phy_config_bb_with_pghdr(struct ieee80211_hw *hw, u8 configtype) 63362306a36Sopenharmony_ci{ 63462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 63562306a36Sopenharmony_ci int i; 63662306a36Sopenharmony_ci u32 *phy_reg_page; 63762306a36Sopenharmony_ci u16 phy_reg_page_len; 63862306a36Sopenharmony_ci u32 v1 = 0, v2 = 0; 63962306a36Sopenharmony_ci 64062306a36Sopenharmony_ci phy_reg_page_len = RTL8188EEPHY_REG_ARRAY_PGLEN; 64162306a36Sopenharmony_ci phy_reg_page = RTL8188EEPHY_REG_ARRAY_PG; 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 64462306a36Sopenharmony_ci for (i = 0; i < phy_reg_page_len; i = i + 3) { 64562306a36Sopenharmony_ci v1 = phy_reg_page[i]; 64662306a36Sopenharmony_ci v2 = phy_reg_page[i+1]; 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci if (v1 < 0xcdcdcdcd) { 64962306a36Sopenharmony_ci if (phy_reg_page[i] == 0xfe) 65062306a36Sopenharmony_ci mdelay(50); 65162306a36Sopenharmony_ci else if (phy_reg_page[i] == 0xfd) 65262306a36Sopenharmony_ci mdelay(5); 65362306a36Sopenharmony_ci else if (phy_reg_page[i] == 0xfc) 65462306a36Sopenharmony_ci mdelay(1); 65562306a36Sopenharmony_ci else if (phy_reg_page[i] == 0xfb) 65662306a36Sopenharmony_ci udelay(50); 65762306a36Sopenharmony_ci else if (phy_reg_page[i] == 0xfa) 65862306a36Sopenharmony_ci udelay(5); 65962306a36Sopenharmony_ci else if (phy_reg_page[i] == 0xf9) 66062306a36Sopenharmony_ci udelay(1); 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci store_pwrindex_rate_offset(hw, phy_reg_page[i], 66362306a36Sopenharmony_ci phy_reg_page[i + 1], 66462306a36Sopenharmony_ci phy_reg_page[i + 2]); 66562306a36Sopenharmony_ci continue; 66662306a36Sopenharmony_ci } else { 66762306a36Sopenharmony_ci if (!_rtl88e_check_condition(hw, 66862306a36Sopenharmony_ci phy_reg_page[i])) { 66962306a36Sopenharmony_ci /*don't need the hw_body*/ 67062306a36Sopenharmony_ci i += 2; /* skip the pair of expression*/ 67162306a36Sopenharmony_ci /* to protect 'i+1' 'i+2' not overrun */ 67262306a36Sopenharmony_ci if (i >= phy_reg_page_len - 2) 67362306a36Sopenharmony_ci break; 67462306a36Sopenharmony_ci 67562306a36Sopenharmony_ci v1 = phy_reg_page[i]; 67662306a36Sopenharmony_ci v2 = phy_reg_page[i+1]; 67762306a36Sopenharmony_ci while (v2 != 0xDEAD && 67862306a36Sopenharmony_ci i < phy_reg_page_len - 5) { 67962306a36Sopenharmony_ci i += 3; 68062306a36Sopenharmony_ci v1 = phy_reg_page[i]; 68162306a36Sopenharmony_ci v2 = phy_reg_page[i+1]; 68262306a36Sopenharmony_ci } 68362306a36Sopenharmony_ci } 68462306a36Sopenharmony_ci } 68562306a36Sopenharmony_ci } 68662306a36Sopenharmony_ci } else { 68762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, 68862306a36Sopenharmony_ci "configtype != BaseBand_Config_PHY_REG\n"); 68962306a36Sopenharmony_ci } 69062306a36Sopenharmony_ci return true; 69162306a36Sopenharmony_ci} 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci#define READ_NEXT_RF_PAIR(v1, v2, i) \ 69462306a36Sopenharmony_cido { \ 69562306a36Sopenharmony_ci i += 2; \ 69662306a36Sopenharmony_ci v1 = radioa_array_table[i]; \ 69762306a36Sopenharmony_ci v2 = radioa_array_table[i+1]; \ 69862306a36Sopenharmony_ci} while (0) 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_cistatic void process_path_a(struct ieee80211_hw *hw, 70162306a36Sopenharmony_ci u16 radioa_arraylen, 70262306a36Sopenharmony_ci u32 *radioa_array_table) 70362306a36Sopenharmony_ci{ 70462306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 70562306a36Sopenharmony_ci u32 v1, v2; 70662306a36Sopenharmony_ci int i; 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci for (i = 0; i < radioa_arraylen; i = i + 2) { 70962306a36Sopenharmony_ci v1 = radioa_array_table[i]; 71062306a36Sopenharmony_ci v2 = radioa_array_table[i+1]; 71162306a36Sopenharmony_ci if (v1 < 0xcdcdcdcd) { 71262306a36Sopenharmony_ci _rtl8188e_config_rf_radio_a(hw, v1, v2); 71362306a36Sopenharmony_ci } else { /*This line is the start line of branch.*/ 71462306a36Sopenharmony_ci /* to protect READ_NEXT_PAIR not overrun */ 71562306a36Sopenharmony_ci if (i >= radioa_arraylen - 2) 71662306a36Sopenharmony_ci break; 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci if (!_rtl88e_check_condition(hw, radioa_array_table[i])) { 71962306a36Sopenharmony_ci /*Discard the following (offset, data) pairs*/ 72062306a36Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 72162306a36Sopenharmony_ci while (v2 != 0xDEAD && 72262306a36Sopenharmony_ci v2 != 0xCDEF && 72362306a36Sopenharmony_ci v2 != 0xCDCD && 72462306a36Sopenharmony_ci i < radioa_arraylen - 2) { 72562306a36Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 72662306a36Sopenharmony_ci } 72762306a36Sopenharmony_ci i -= 2; /* prevent from for-loop += 2*/ 72862306a36Sopenharmony_ci } else { /* Configure matched pairs and 72962306a36Sopenharmony_ci * skip to end of if-else. 73062306a36Sopenharmony_ci */ 73162306a36Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 73262306a36Sopenharmony_ci while (v2 != 0xDEAD && 73362306a36Sopenharmony_ci v2 != 0xCDEF && 73462306a36Sopenharmony_ci v2 != 0xCDCD && 73562306a36Sopenharmony_ci i < radioa_arraylen - 2) { 73662306a36Sopenharmony_ci _rtl8188e_config_rf_radio_a(hw, v1, v2); 73762306a36Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 73862306a36Sopenharmony_ci } 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci while (v2 != 0xDEAD && 74162306a36Sopenharmony_ci i < radioa_arraylen - 2) 74262306a36Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 74362306a36Sopenharmony_ci } 74462306a36Sopenharmony_ci } 74562306a36Sopenharmony_ci } 74662306a36Sopenharmony_ci 74762306a36Sopenharmony_ci if (rtlhal->oem_id == RT_CID_819X_HP) 74862306a36Sopenharmony_ci _rtl8188e_config_rf_radio_a(hw, 0x52, 0x7E4BD); 74962306a36Sopenharmony_ci} 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_cibool rtl88e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, 75262306a36Sopenharmony_ci enum radio_path rfpath) 75362306a36Sopenharmony_ci{ 75462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 75562306a36Sopenharmony_ci u32 *radioa_array_table; 75662306a36Sopenharmony_ci u16 radioa_arraylen; 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci radioa_arraylen = RTL8188EE_RADIOA_1TARRAYLEN; 75962306a36Sopenharmony_ci radioa_array_table = RTL8188EE_RADIOA_1TARRAY; 76062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 76162306a36Sopenharmony_ci "Radio_A:RTL8188EE_RADIOA_1TARRAY %d\n", radioa_arraylen); 76262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); 76362306a36Sopenharmony_ci switch (rfpath) { 76462306a36Sopenharmony_ci case RF90_PATH_A: 76562306a36Sopenharmony_ci process_path_a(hw, radioa_arraylen, radioa_array_table); 76662306a36Sopenharmony_ci break; 76762306a36Sopenharmony_ci case RF90_PATH_B: 76862306a36Sopenharmony_ci case RF90_PATH_C: 76962306a36Sopenharmony_ci case RF90_PATH_D: 77062306a36Sopenharmony_ci break; 77162306a36Sopenharmony_ci } 77262306a36Sopenharmony_ci return true; 77362306a36Sopenharmony_ci} 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_civoid rtl88e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) 77662306a36Sopenharmony_ci{ 77762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 77862306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_ci rtlphy->default_initialgain[0] = 78162306a36Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); 78262306a36Sopenharmony_ci rtlphy->default_initialgain[1] = 78362306a36Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); 78462306a36Sopenharmony_ci rtlphy->default_initialgain[2] = 78562306a36Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); 78662306a36Sopenharmony_ci rtlphy->default_initialgain[3] = 78762306a36Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 79062306a36Sopenharmony_ci "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", 79162306a36Sopenharmony_ci rtlphy->default_initialgain[0], 79262306a36Sopenharmony_ci rtlphy->default_initialgain[1], 79362306a36Sopenharmony_ci rtlphy->default_initialgain[2], 79462306a36Sopenharmony_ci rtlphy->default_initialgain[3]); 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_ci rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, 79762306a36Sopenharmony_ci MASKBYTE0); 79862306a36Sopenharmony_ci rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, 79962306a36Sopenharmony_ci MASKDWORD); 80062306a36Sopenharmony_ci 80162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 80262306a36Sopenharmony_ci "Default framesync (0x%x) = 0x%x\n", 80362306a36Sopenharmony_ci ROFDM0_RXDETECTOR3, rtlphy->framesync); 80462306a36Sopenharmony_ci} 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_cistatic void _rtl88e_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) 80762306a36Sopenharmony_ci{ 80862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 80962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; 81262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; 81362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; 81462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; 81762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; 81862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; 81962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; 82262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; 82362306a36Sopenharmony_ci 82462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; 82562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = 82862306a36Sopenharmony_ci RFPGA0_XA_LSSIPARAMETER; 82962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = 83062306a36Sopenharmony_ci RFPGA0_XB_LSSIPARAMETER; 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; 83362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; 83462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; 83562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; 83662306a36Sopenharmony_ci 83762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; 83862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; 83962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; 84062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; 84162306a36Sopenharmony_ci 84262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; 84362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; 84662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = 84962306a36Sopenharmony_ci RFPGA0_XAB_SWITCHCONTROL; 85062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = 85162306a36Sopenharmony_ci RFPGA0_XAB_SWITCHCONTROL; 85262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = 85362306a36Sopenharmony_ci RFPGA0_XCD_SWITCHCONTROL; 85462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = 85562306a36Sopenharmony_ci RFPGA0_XCD_SWITCHCONTROL; 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; 85862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; 85962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; 86062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; 86362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; 86462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; 86562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; 86862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; 86962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBANLANCE; 87062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; 87362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; 87462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; 87562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; 87862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; 87962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; 88062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; 88362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; 88662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; 88962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; 89062306a36Sopenharmony_ci} 89162306a36Sopenharmony_ci 89262306a36Sopenharmony_civoid rtl88e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) 89362306a36Sopenharmony_ci{ 89462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 89562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 89662306a36Sopenharmony_ci u8 txpwr_level; 89762306a36Sopenharmony_ci long txpwr_dbm; 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci txpwr_level = rtlphy->cur_cck_txpwridx; 90062306a36Sopenharmony_ci txpwr_dbm = _rtl88e_phy_txpwr_idx_to_dbm(hw, 90162306a36Sopenharmony_ci WIRELESS_MODE_B, txpwr_level); 90262306a36Sopenharmony_ci txpwr_level = rtlphy->cur_ofdm24g_txpwridx; 90362306a36Sopenharmony_ci if (_rtl88e_phy_txpwr_idx_to_dbm(hw, 90462306a36Sopenharmony_ci WIRELESS_MODE_G, 90562306a36Sopenharmony_ci txpwr_level) > txpwr_dbm) 90662306a36Sopenharmony_ci txpwr_dbm = 90762306a36Sopenharmony_ci _rtl88e_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, 90862306a36Sopenharmony_ci txpwr_level); 90962306a36Sopenharmony_ci txpwr_level = rtlphy->cur_ofdm24g_txpwridx; 91062306a36Sopenharmony_ci if (_rtl88e_phy_txpwr_idx_to_dbm(hw, 91162306a36Sopenharmony_ci WIRELESS_MODE_N_24G, 91262306a36Sopenharmony_ci txpwr_level) > txpwr_dbm) 91362306a36Sopenharmony_ci txpwr_dbm = 91462306a36Sopenharmony_ci _rtl88e_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, 91562306a36Sopenharmony_ci txpwr_level); 91662306a36Sopenharmony_ci *powerlevel = txpwr_dbm; 91762306a36Sopenharmony_ci} 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_cistatic void handle_path_a(struct rtl_efuse *rtlefuse, u8 index, 92062306a36Sopenharmony_ci u8 *cckpowerlevel, u8 *ofdmpowerlevel, 92162306a36Sopenharmony_ci u8 *bw20powerlevel, u8 *bw40powerlevel) 92262306a36Sopenharmony_ci{ 92362306a36Sopenharmony_ci cckpowerlevel[RF90_PATH_A] = 92462306a36Sopenharmony_ci rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; 92562306a36Sopenharmony_ci /*-8~7 */ 92662306a36Sopenharmony_ci if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][index] > 0x0f) 92762306a36Sopenharmony_ci bw20powerlevel[RF90_PATH_A] = 92862306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] - 92962306a36Sopenharmony_ci (~(rtlefuse->txpwr_ht20diff[RF90_PATH_A][index]) + 1); 93062306a36Sopenharmony_ci else 93162306a36Sopenharmony_ci bw20powerlevel[RF90_PATH_A] = 93262306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] + 93362306a36Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_A][index]; 93462306a36Sopenharmony_ci if (rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][index] > 0xf) 93562306a36Sopenharmony_ci ofdmpowerlevel[RF90_PATH_A] = 93662306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] - 93762306a36Sopenharmony_ci (~(rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][index])+1); 93862306a36Sopenharmony_ci else 93962306a36Sopenharmony_ci ofdmpowerlevel[RF90_PATH_A] = 94062306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index] + 94162306a36Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][index]; 94262306a36Sopenharmony_ci bw40powerlevel[RF90_PATH_A] = 94362306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; 94462306a36Sopenharmony_ci} 94562306a36Sopenharmony_ci 94662306a36Sopenharmony_cistatic void _rtl88e_get_txpower_index(struct ieee80211_hw *hw, u8 channel, 94762306a36Sopenharmony_ci u8 *cckpowerlevel, u8 *ofdmpowerlevel, 94862306a36Sopenharmony_ci u8 *bw20powerlevel, u8 *bw40powerlevel) 94962306a36Sopenharmony_ci{ 95062306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 95162306a36Sopenharmony_ci u8 index = (channel - 1); 95262306a36Sopenharmony_ci u8 rf_path = 0; 95362306a36Sopenharmony_ci 95462306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 95562306a36Sopenharmony_ci if (rf_path == RF90_PATH_A) { 95662306a36Sopenharmony_ci handle_path_a(rtlefuse, index, cckpowerlevel, 95762306a36Sopenharmony_ci ofdmpowerlevel, bw20powerlevel, 95862306a36Sopenharmony_ci bw40powerlevel); 95962306a36Sopenharmony_ci } else if (rf_path == RF90_PATH_B) { 96062306a36Sopenharmony_ci cckpowerlevel[RF90_PATH_B] = 96162306a36Sopenharmony_ci rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; 96262306a36Sopenharmony_ci bw20powerlevel[RF90_PATH_B] = 96362306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index] + 96462306a36Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_B][index]; 96562306a36Sopenharmony_ci ofdmpowerlevel[RF90_PATH_B] = 96662306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index] + 96762306a36Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][index]; 96862306a36Sopenharmony_ci bw40powerlevel[RF90_PATH_B] = 96962306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; 97062306a36Sopenharmony_ci } 97162306a36Sopenharmony_ci } 97262306a36Sopenharmony_ci 97362306a36Sopenharmony_ci} 97462306a36Sopenharmony_ci 97562306a36Sopenharmony_cistatic void _rtl88e_ccxpower_index_check(struct ieee80211_hw *hw, 97662306a36Sopenharmony_ci u8 channel, u8 *cckpowerlevel, 97762306a36Sopenharmony_ci u8 *ofdmpowerlevel, u8 *bw20powerlevel, 97862306a36Sopenharmony_ci u8 *bw40powerlevel) 97962306a36Sopenharmony_ci{ 98062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 98162306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; 98462306a36Sopenharmony_ci rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; 98562306a36Sopenharmony_ci rtlphy->cur_bw20_txpwridx = bw20powerlevel[0]; 98662306a36Sopenharmony_ci rtlphy->cur_bw40_txpwridx = bw40powerlevel[0]; 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci} 98962306a36Sopenharmony_ci 99062306a36Sopenharmony_civoid rtl88e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) 99162306a36Sopenharmony_ci{ 99262306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 99362306a36Sopenharmony_ci u8 cckpowerlevel[MAX_TX_COUNT] = {0}; 99462306a36Sopenharmony_ci u8 ofdmpowerlevel[MAX_TX_COUNT] = {0}; 99562306a36Sopenharmony_ci u8 bw20powerlevel[MAX_TX_COUNT] = {0}; 99662306a36Sopenharmony_ci u8 bw40powerlevel[MAX_TX_COUNT] = {0}; 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_ci if (!rtlefuse->txpwr_fromeprom) 99962306a36Sopenharmony_ci return; 100062306a36Sopenharmony_ci _rtl88e_get_txpower_index(hw, channel, 100162306a36Sopenharmony_ci &cckpowerlevel[0], &ofdmpowerlevel[0], 100262306a36Sopenharmony_ci &bw20powerlevel[0], &bw40powerlevel[0]); 100362306a36Sopenharmony_ci _rtl88e_ccxpower_index_check(hw, channel, 100462306a36Sopenharmony_ci &cckpowerlevel[0], &ofdmpowerlevel[0], 100562306a36Sopenharmony_ci &bw20powerlevel[0], &bw40powerlevel[0]); 100662306a36Sopenharmony_ci rtl88e_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); 100762306a36Sopenharmony_ci rtl88e_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], 100862306a36Sopenharmony_ci &bw20powerlevel[0], 100962306a36Sopenharmony_ci &bw40powerlevel[0], channel); 101062306a36Sopenharmony_ci} 101162306a36Sopenharmony_ci 101262306a36Sopenharmony_cistatic long _rtl88e_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, 101362306a36Sopenharmony_ci enum wireless_mode wirelessmode, 101462306a36Sopenharmony_ci u8 txpwridx) 101562306a36Sopenharmony_ci{ 101662306a36Sopenharmony_ci long offset; 101762306a36Sopenharmony_ci long pwrout_dbm; 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci switch (wirelessmode) { 102062306a36Sopenharmony_ci case WIRELESS_MODE_B: 102162306a36Sopenharmony_ci offset = -7; 102262306a36Sopenharmony_ci break; 102362306a36Sopenharmony_ci case WIRELESS_MODE_G: 102462306a36Sopenharmony_ci case WIRELESS_MODE_N_24G: 102562306a36Sopenharmony_ci offset = -8; 102662306a36Sopenharmony_ci break; 102762306a36Sopenharmony_ci default: 102862306a36Sopenharmony_ci offset = -8; 102962306a36Sopenharmony_ci break; 103062306a36Sopenharmony_ci } 103162306a36Sopenharmony_ci pwrout_dbm = txpwridx / 2 + offset; 103262306a36Sopenharmony_ci return pwrout_dbm; 103362306a36Sopenharmony_ci} 103462306a36Sopenharmony_ci 103562306a36Sopenharmony_civoid rtl88e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) 103662306a36Sopenharmony_ci{ 103762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 103862306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 103962306a36Sopenharmony_ci enum io_type iotype; 104062306a36Sopenharmony_ci 104162306a36Sopenharmony_ci if (!is_hal_stop(rtlhal)) { 104262306a36Sopenharmony_ci switch (operation) { 104362306a36Sopenharmony_ci case SCAN_OPT_BACKUP_BAND0: 104462306a36Sopenharmony_ci iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; 104562306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 104662306a36Sopenharmony_ci HW_VAR_IO_CMD, 104762306a36Sopenharmony_ci (u8 *)&iotype); 104862306a36Sopenharmony_ci 104962306a36Sopenharmony_ci break; 105062306a36Sopenharmony_ci case SCAN_OPT_RESTORE: 105162306a36Sopenharmony_ci iotype = IO_CMD_RESUME_DM_BY_SCAN; 105262306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 105362306a36Sopenharmony_ci HW_VAR_IO_CMD, 105462306a36Sopenharmony_ci (u8 *)&iotype); 105562306a36Sopenharmony_ci break; 105662306a36Sopenharmony_ci default: 105762306a36Sopenharmony_ci pr_err("Unknown Scan Backup operation.\n"); 105862306a36Sopenharmony_ci break; 105962306a36Sopenharmony_ci } 106062306a36Sopenharmony_ci } 106162306a36Sopenharmony_ci} 106262306a36Sopenharmony_ci 106362306a36Sopenharmony_civoid rtl88e_phy_set_bw_mode_callback(struct ieee80211_hw *hw) 106462306a36Sopenharmony_ci{ 106562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 106662306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 106762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 106862306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 106962306a36Sopenharmony_ci u8 reg_bw_opmode; 107062306a36Sopenharmony_ci u8 reg_prsr_rsc; 107162306a36Sopenharmony_ci 107262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, 107362306a36Sopenharmony_ci "Switch to %s bandwidth\n", 107462306a36Sopenharmony_ci rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? 107562306a36Sopenharmony_ci "20MHz" : "40MHz"); 107662306a36Sopenharmony_ci 107762306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) { 107862306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 107962306a36Sopenharmony_ci return; 108062306a36Sopenharmony_ci } 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); 108362306a36Sopenharmony_ci reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); 108462306a36Sopenharmony_ci 108562306a36Sopenharmony_ci switch (rtlphy->current_chan_bw) { 108662306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 108762306a36Sopenharmony_ci reg_bw_opmode |= BW_OPMODE_20MHZ; 108862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 108962306a36Sopenharmony_ci break; 109062306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 109162306a36Sopenharmony_ci reg_bw_opmode &= ~BW_OPMODE_20MHZ; 109262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 109362306a36Sopenharmony_ci reg_prsr_rsc = 109462306a36Sopenharmony_ci (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); 109562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); 109662306a36Sopenharmony_ci break; 109762306a36Sopenharmony_ci default: 109862306a36Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 109962306a36Sopenharmony_ci rtlphy->current_chan_bw); 110062306a36Sopenharmony_ci break; 110162306a36Sopenharmony_ci } 110262306a36Sopenharmony_ci 110362306a36Sopenharmony_ci switch (rtlphy->current_chan_bw) { 110462306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 110562306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); 110662306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); 110762306a36Sopenharmony_ci /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/ 110862306a36Sopenharmony_ci break; 110962306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 111062306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); 111162306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, 111462306a36Sopenharmony_ci (mac->cur_40_prime_sc >> 1)); 111562306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); 111662306a36Sopenharmony_ci /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/ 111762306a36Sopenharmony_ci 111862306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), 111962306a36Sopenharmony_ci (mac->cur_40_prime_sc == 112062306a36Sopenharmony_ci HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); 112162306a36Sopenharmony_ci break; 112262306a36Sopenharmony_ci default: 112362306a36Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 112462306a36Sopenharmony_ci rtlphy->current_chan_bw); 112562306a36Sopenharmony_ci break; 112662306a36Sopenharmony_ci } 112762306a36Sopenharmony_ci rtl88e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); 112862306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 112962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "\n"); 113062306a36Sopenharmony_ci} 113162306a36Sopenharmony_ci 113262306a36Sopenharmony_civoid rtl88e_phy_set_bw_mode(struct ieee80211_hw *hw, 113362306a36Sopenharmony_ci enum nl80211_channel_type ch_type) 113462306a36Sopenharmony_ci{ 113562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 113662306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 113762306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 113862306a36Sopenharmony_ci u8 tmp_bw = rtlphy->current_chan_bw; 113962306a36Sopenharmony_ci 114062306a36Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 114162306a36Sopenharmony_ci return; 114262306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = true; 114362306a36Sopenharmony_ci if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 114462306a36Sopenharmony_ci rtl88e_phy_set_bw_mode_callback(hw); 114562306a36Sopenharmony_ci } else { 114662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 114762306a36Sopenharmony_ci "false driver sleep or unload\n"); 114862306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 114962306a36Sopenharmony_ci rtlphy->current_chan_bw = tmp_bw; 115062306a36Sopenharmony_ci } 115162306a36Sopenharmony_ci} 115262306a36Sopenharmony_ci 115362306a36Sopenharmony_civoid rtl88e_phy_sw_chnl_callback(struct ieee80211_hw *hw) 115462306a36Sopenharmony_ci{ 115562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 115662306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 115762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 115862306a36Sopenharmony_ci u32 delay; 115962306a36Sopenharmony_ci 116062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, 116162306a36Sopenharmony_ci "switch to channel%d\n", rtlphy->current_channel); 116262306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) 116362306a36Sopenharmony_ci return; 116462306a36Sopenharmony_ci do { 116562306a36Sopenharmony_ci if (!rtlphy->sw_chnl_inprogress) 116662306a36Sopenharmony_ci break; 116762306a36Sopenharmony_ci if (!_rtl88e_phy_sw_chnl_step_by_step 116862306a36Sopenharmony_ci (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, 116962306a36Sopenharmony_ci &rtlphy->sw_chnl_step, &delay)) { 117062306a36Sopenharmony_ci if (delay > 0) 117162306a36Sopenharmony_ci mdelay(delay); 117262306a36Sopenharmony_ci else 117362306a36Sopenharmony_ci continue; 117462306a36Sopenharmony_ci } else { 117562306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 117662306a36Sopenharmony_ci } 117762306a36Sopenharmony_ci break; 117862306a36Sopenharmony_ci } while (true); 117962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); 118062306a36Sopenharmony_ci} 118162306a36Sopenharmony_ci 118262306a36Sopenharmony_ciu8 rtl88e_phy_sw_chnl(struct ieee80211_hw *hw) 118362306a36Sopenharmony_ci{ 118462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 118562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 118662306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_ci if (rtlphy->sw_chnl_inprogress) 118962306a36Sopenharmony_ci return 0; 119062306a36Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 119162306a36Sopenharmony_ci return 0; 119262306a36Sopenharmony_ci WARN_ONCE((rtlphy->current_channel > 14), 119362306a36Sopenharmony_ci "rtl8188ee: WIRELESS_MODE_G but channel>14"); 119462306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = true; 119562306a36Sopenharmony_ci rtlphy->sw_chnl_stage = 0; 119662306a36Sopenharmony_ci rtlphy->sw_chnl_step = 0; 119762306a36Sopenharmony_ci if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 119862306a36Sopenharmony_ci rtl88e_phy_sw_chnl_callback(hw); 119962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, 120062306a36Sopenharmony_ci "sw_chnl_inprogress false schedule workitem current channel %d\n", 120162306a36Sopenharmony_ci rtlphy->current_channel); 120262306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 120362306a36Sopenharmony_ci } else { 120462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, 120562306a36Sopenharmony_ci "sw_chnl_inprogress false driver sleep or unload\n"); 120662306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 120762306a36Sopenharmony_ci } 120862306a36Sopenharmony_ci return 1; 120962306a36Sopenharmony_ci} 121062306a36Sopenharmony_ci 121162306a36Sopenharmony_cistatic bool _rtl88e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 121262306a36Sopenharmony_ci u8 channel, u8 *stage, u8 *step, 121362306a36Sopenharmony_ci u32 *delay) 121462306a36Sopenharmony_ci{ 121562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 121662306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 121762306a36Sopenharmony_ci struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; 121862306a36Sopenharmony_ci u32 precommoncmdcnt; 121962306a36Sopenharmony_ci struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; 122062306a36Sopenharmony_ci u32 postcommoncmdcnt; 122162306a36Sopenharmony_ci struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; 122262306a36Sopenharmony_ci u32 rfdependcmdcnt; 122362306a36Sopenharmony_ci struct swchnlcmd *currentcmd = NULL; 122462306a36Sopenharmony_ci u8 rfpath; 122562306a36Sopenharmony_ci u8 num_total_rfpath = rtlphy->num_total_rfpath; 122662306a36Sopenharmony_ci 122762306a36Sopenharmony_ci precommoncmdcnt = 0; 122862306a36Sopenharmony_ci _rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 122962306a36Sopenharmony_ci MAX_PRECMD_CNT, 123062306a36Sopenharmony_ci CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); 123162306a36Sopenharmony_ci _rtl88e_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 123262306a36Sopenharmony_ci MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ci postcommoncmdcnt = 0; 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci _rtl88e_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, 123762306a36Sopenharmony_ci MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); 123862306a36Sopenharmony_ci 123962306a36Sopenharmony_ci rfdependcmdcnt = 0; 124062306a36Sopenharmony_ci 124162306a36Sopenharmony_ci WARN_ONCE((channel < 1 || channel > 14), 124262306a36Sopenharmony_ci "rtl8188ee: illegal channel for Zebra: %d\n", channel); 124362306a36Sopenharmony_ci 124462306a36Sopenharmony_ci _rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 124562306a36Sopenharmony_ci MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, 124662306a36Sopenharmony_ci RF_CHNLBW, channel, 10); 124762306a36Sopenharmony_ci 124862306a36Sopenharmony_ci _rtl88e_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 124962306a36Sopenharmony_ci MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 125062306a36Sopenharmony_ci 0); 125162306a36Sopenharmony_ci 125262306a36Sopenharmony_ci do { 125362306a36Sopenharmony_ci switch (*stage) { 125462306a36Sopenharmony_ci case 0: 125562306a36Sopenharmony_ci currentcmd = &precommoncmd[*step]; 125662306a36Sopenharmony_ci break; 125762306a36Sopenharmony_ci case 1: 125862306a36Sopenharmony_ci currentcmd = &rfdependcmd[*step]; 125962306a36Sopenharmony_ci break; 126062306a36Sopenharmony_ci case 2: 126162306a36Sopenharmony_ci currentcmd = &postcommoncmd[*step]; 126262306a36Sopenharmony_ci break; 126362306a36Sopenharmony_ci default: 126462306a36Sopenharmony_ci pr_err("Invalid 'stage' = %d, Check it!\n", 126562306a36Sopenharmony_ci *stage); 126662306a36Sopenharmony_ci return true; 126762306a36Sopenharmony_ci } 126862306a36Sopenharmony_ci 126962306a36Sopenharmony_ci if (currentcmd->cmdid == CMDID_END) { 127062306a36Sopenharmony_ci if ((*stage) == 2) 127162306a36Sopenharmony_ci return true; 127262306a36Sopenharmony_ci (*stage)++; 127362306a36Sopenharmony_ci (*step) = 0; 127462306a36Sopenharmony_ci continue; 127562306a36Sopenharmony_ci } 127662306a36Sopenharmony_ci 127762306a36Sopenharmony_ci switch (currentcmd->cmdid) { 127862306a36Sopenharmony_ci case CMDID_SET_TXPOWEROWER_LEVEL: 127962306a36Sopenharmony_ci rtl88e_phy_set_txpower_level(hw, channel); 128062306a36Sopenharmony_ci break; 128162306a36Sopenharmony_ci case CMDID_WRITEPORT_ULONG: 128262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, currentcmd->para1, 128362306a36Sopenharmony_ci currentcmd->para2); 128462306a36Sopenharmony_ci break; 128562306a36Sopenharmony_ci case CMDID_WRITEPORT_USHORT: 128662306a36Sopenharmony_ci rtl_write_word(rtlpriv, currentcmd->para1, 128762306a36Sopenharmony_ci (u16)currentcmd->para2); 128862306a36Sopenharmony_ci break; 128962306a36Sopenharmony_ci case CMDID_WRITEPORT_UCHAR: 129062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, currentcmd->para1, 129162306a36Sopenharmony_ci (u8)currentcmd->para2); 129262306a36Sopenharmony_ci break; 129362306a36Sopenharmony_ci case CMDID_RF_WRITEREG: 129462306a36Sopenharmony_ci for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { 129562306a36Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath] = 129662306a36Sopenharmony_ci ((rtlphy->rfreg_chnlval[rfpath] & 129762306a36Sopenharmony_ci 0xfffffc00) | currentcmd->para2); 129862306a36Sopenharmony_ci 129962306a36Sopenharmony_ci rtl_set_rfreg(hw, (enum radio_path)rfpath, 130062306a36Sopenharmony_ci currentcmd->para1, 130162306a36Sopenharmony_ci RFREG_OFFSET_MASK, 130262306a36Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath]); 130362306a36Sopenharmony_ci } 130462306a36Sopenharmony_ci break; 130562306a36Sopenharmony_ci default: 130662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 130762306a36Sopenharmony_ci "switch case %#x not processed\n", 130862306a36Sopenharmony_ci currentcmd->cmdid); 130962306a36Sopenharmony_ci break; 131062306a36Sopenharmony_ci } 131162306a36Sopenharmony_ci 131262306a36Sopenharmony_ci break; 131362306a36Sopenharmony_ci } while (true); 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_ci (*delay) = currentcmd->msdelay; 131662306a36Sopenharmony_ci (*step)++; 131762306a36Sopenharmony_ci return false; 131862306a36Sopenharmony_ci} 131962306a36Sopenharmony_ci 132062306a36Sopenharmony_cistatic bool _rtl88e_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, 132162306a36Sopenharmony_ci u32 cmdtableidx, u32 cmdtablesz, 132262306a36Sopenharmony_ci enum swchnlcmd_id cmdid, 132362306a36Sopenharmony_ci u32 para1, u32 para2, u32 msdelay) 132462306a36Sopenharmony_ci{ 132562306a36Sopenharmony_ci struct swchnlcmd *pcmd; 132662306a36Sopenharmony_ci 132762306a36Sopenharmony_ci if (cmdtable == NULL) { 132862306a36Sopenharmony_ci WARN_ONCE(true, "rtl8188ee: cmdtable cannot be NULL.\n"); 132962306a36Sopenharmony_ci return false; 133062306a36Sopenharmony_ci } 133162306a36Sopenharmony_ci 133262306a36Sopenharmony_ci if (cmdtableidx >= cmdtablesz) 133362306a36Sopenharmony_ci return false; 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci pcmd = cmdtable + cmdtableidx; 133662306a36Sopenharmony_ci pcmd->cmdid = cmdid; 133762306a36Sopenharmony_ci pcmd->para1 = para1; 133862306a36Sopenharmony_ci pcmd->para2 = para2; 133962306a36Sopenharmony_ci pcmd->msdelay = msdelay; 134062306a36Sopenharmony_ci return true; 134162306a36Sopenharmony_ci} 134262306a36Sopenharmony_ci 134362306a36Sopenharmony_cistatic u8 _rtl88e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) 134462306a36Sopenharmony_ci{ 134562306a36Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c; 134662306a36Sopenharmony_ci u8 result = 0x00; 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c); 134962306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c); 135062306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a); 135162306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000); 135262306a36Sopenharmony_ci 135362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911); 135462306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); 135562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); 136062306a36Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); 136162306a36Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); 136262306a36Sopenharmony_ci rtl_get_bbreg(hw, 0xea4, MASKDWORD); 136362306a36Sopenharmony_ci 136462306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 136562306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 136662306a36Sopenharmony_ci (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) 136762306a36Sopenharmony_ci result |= 0x01; 136862306a36Sopenharmony_ci return result; 136962306a36Sopenharmony_ci} 137062306a36Sopenharmony_ci 137162306a36Sopenharmony_cistatic u8 _rtl88e_phy_path_b_iqk(struct ieee80211_hw *hw) 137262306a36Sopenharmony_ci{ 137362306a36Sopenharmony_ci u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; 137462306a36Sopenharmony_ci u8 result = 0x00; 137562306a36Sopenharmony_ci 137662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); 137762306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); 137862306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 137962306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); 138062306a36Sopenharmony_ci reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); 138162306a36Sopenharmony_ci reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); 138262306a36Sopenharmony_ci reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); 138362306a36Sopenharmony_ci reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); 138462306a36Sopenharmony_ci 138562306a36Sopenharmony_ci if (!(reg_eac & BIT(31)) && 138662306a36Sopenharmony_ci (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && 138762306a36Sopenharmony_ci (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) 138862306a36Sopenharmony_ci result |= 0x01; 138962306a36Sopenharmony_ci else 139062306a36Sopenharmony_ci return result; 139162306a36Sopenharmony_ci if (!(reg_eac & BIT(30)) && 139262306a36Sopenharmony_ci (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && 139362306a36Sopenharmony_ci (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) 139462306a36Sopenharmony_ci result |= 0x02; 139562306a36Sopenharmony_ci return result; 139662306a36Sopenharmony_ci} 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_cistatic u8 _rtl88e_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb) 139962306a36Sopenharmony_ci{ 140062306a36Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32temp; 140162306a36Sopenharmony_ci u8 result = 0x00; 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci /*Get TXIMR Setting*/ 140462306a36Sopenharmony_ci /*Modify RX IQK mode table*/ 140562306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 140662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); 140762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 140862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); 140962306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b); 141062306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci /*IQK Setting*/ 141362306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); 141462306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x81004800); 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_ci /*path a IQK setting*/ 141762306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x10008c1c); 141862306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x30008c1c); 141962306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160804); 142062306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000); 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_ci /*LO calibration Setting*/ 142362306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); 142462306a36Sopenharmony_ci /*one shot,path A LOK & iqk*/ 142562306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); 142662306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 142762306a36Sopenharmony_ci 142862306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 143162306a36Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); 143262306a36Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_ci 143562306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 143662306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 143762306a36Sopenharmony_ci (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) 143862306a36Sopenharmony_ci result |= 0x01; 143962306a36Sopenharmony_ci else 144062306a36Sopenharmony_ci return result; 144162306a36Sopenharmony_ci 144262306a36Sopenharmony_ci u32temp = 0x80007C00 | (reg_e94&0x3FF0000) | 144362306a36Sopenharmony_ci ((reg_e9c&0x3FF0000) >> 16); 144462306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp); 144562306a36Sopenharmony_ci /*RX IQK*/ 144662306a36Sopenharmony_ci /*Modify RX IQK mode table*/ 144762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 144862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); 144962306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 145062306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); 145162306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa); 145262306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 145362306a36Sopenharmony_ci 145462306a36Sopenharmony_ci /*IQK Setting*/ 145562306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 145662306a36Sopenharmony_ci 145762306a36Sopenharmony_ci /*path a IQK setting*/ 145862306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x30008c1c); 145962306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x10008c1c); 146062306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c05); 146162306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c05); 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci /*LO calibration Setting*/ 146462306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); 146562306a36Sopenharmony_ci /*one shot,path A LOK & iqk*/ 146662306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); 146762306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 146862306a36Sopenharmony_ci 146962306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 147262306a36Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); 147362306a36Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); 147462306a36Sopenharmony_ci reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); 147562306a36Sopenharmony_ci 147662306a36Sopenharmony_ci if (!(reg_eac & BIT(27)) && 147762306a36Sopenharmony_ci (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && 147862306a36Sopenharmony_ci (((reg_eac & 0x03FF0000) >> 16) != 0x36)) 147962306a36Sopenharmony_ci result |= 0x02; 148062306a36Sopenharmony_ci return result; 148162306a36Sopenharmony_ci} 148262306a36Sopenharmony_ci 148362306a36Sopenharmony_cistatic void _rtl88e_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, 148462306a36Sopenharmony_ci bool iqk_ok, long result[][8], 148562306a36Sopenharmony_ci u8 final_candidate, bool btxonly) 148662306a36Sopenharmony_ci{ 148762306a36Sopenharmony_ci u32 oldval_0, x, tx0_a, reg; 148862306a36Sopenharmony_ci long y, tx0_c; 148962306a36Sopenharmony_ci 149062306a36Sopenharmony_ci if (final_candidate == 0xFF) { 149162306a36Sopenharmony_ci return; 149262306a36Sopenharmony_ci } else if (iqk_ok) { 149362306a36Sopenharmony_ci oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 149462306a36Sopenharmony_ci MASKDWORD) >> 22) & 0x3FF; 149562306a36Sopenharmony_ci x = result[final_candidate][0]; 149662306a36Sopenharmony_ci if ((x & 0x00000200) != 0) 149762306a36Sopenharmony_ci x = x | 0xFFFFFC00; 149862306a36Sopenharmony_ci tx0_a = (x * oldval_0) >> 8; 149962306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); 150062306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), 150162306a36Sopenharmony_ci ((x * oldval_0 >> 7) & 0x1)); 150262306a36Sopenharmony_ci y = result[final_candidate][1]; 150362306a36Sopenharmony_ci if ((y & 0x00000200) != 0) 150462306a36Sopenharmony_ci y = y | 0xFFFFFC00; 150562306a36Sopenharmony_ci tx0_c = (y * oldval_0) >> 8; 150662306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, 150762306a36Sopenharmony_ci ((tx0_c & 0x3C0) >> 6)); 150862306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, 150962306a36Sopenharmony_ci (tx0_c & 0x3F)); 151062306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), 151162306a36Sopenharmony_ci ((y * oldval_0 >> 7) & 0x1)); 151262306a36Sopenharmony_ci if (btxonly) 151362306a36Sopenharmony_ci return; 151462306a36Sopenharmony_ci reg = result[final_candidate][2]; 151562306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); 151662306a36Sopenharmony_ci reg = result[final_candidate][3] & 0x3F; 151762306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); 151862306a36Sopenharmony_ci reg = (result[final_candidate][3] >> 6) & 0xF; 151962306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); 152062306a36Sopenharmony_ci } 152162306a36Sopenharmony_ci} 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_cistatic void _rtl88e_phy_save_adda_registers(struct ieee80211_hw *hw, 152462306a36Sopenharmony_ci u32 *addareg, u32 *addabackup, 152562306a36Sopenharmony_ci u32 registernum) 152662306a36Sopenharmony_ci{ 152762306a36Sopenharmony_ci u32 i; 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci for (i = 0; i < registernum; i++) 153062306a36Sopenharmony_ci addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); 153162306a36Sopenharmony_ci} 153262306a36Sopenharmony_ci 153362306a36Sopenharmony_cistatic void _rtl88e_phy_save_mac_registers(struct ieee80211_hw *hw, 153462306a36Sopenharmony_ci u32 *macreg, u32 *macbackup) 153562306a36Sopenharmony_ci{ 153662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 153762306a36Sopenharmony_ci u32 i; 153862306a36Sopenharmony_ci 153962306a36Sopenharmony_ci for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) 154062306a36Sopenharmony_ci macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); 154162306a36Sopenharmony_ci macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); 154262306a36Sopenharmony_ci} 154362306a36Sopenharmony_ci 154462306a36Sopenharmony_cistatic void _rtl88e_phy_reload_adda_registers(struct ieee80211_hw *hw, 154562306a36Sopenharmony_ci u32 *addareg, u32 *addabackup, 154662306a36Sopenharmony_ci u32 regiesternum) 154762306a36Sopenharmony_ci{ 154862306a36Sopenharmony_ci u32 i; 154962306a36Sopenharmony_ci 155062306a36Sopenharmony_ci for (i = 0; i < regiesternum; i++) 155162306a36Sopenharmony_ci rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); 155262306a36Sopenharmony_ci} 155362306a36Sopenharmony_ci 155462306a36Sopenharmony_cistatic void _rtl88e_phy_reload_mac_registers(struct ieee80211_hw *hw, 155562306a36Sopenharmony_ci u32 *macreg, u32 *macbackup) 155662306a36Sopenharmony_ci{ 155762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 155862306a36Sopenharmony_ci u32 i; 155962306a36Sopenharmony_ci 156062306a36Sopenharmony_ci for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) 156162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); 156262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); 156362306a36Sopenharmony_ci} 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_cistatic void _rtl88e_phy_path_adda_on(struct ieee80211_hw *hw, 156662306a36Sopenharmony_ci u32 *addareg, bool is_patha_on, bool is2t) 156762306a36Sopenharmony_ci{ 156862306a36Sopenharmony_ci u32 pathon; 156962306a36Sopenharmony_ci u32 i; 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci pathon = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; 157262306a36Sopenharmony_ci if (!is2t) { 157362306a36Sopenharmony_ci pathon = 0x0bdb25a0; 157462306a36Sopenharmony_ci rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); 157562306a36Sopenharmony_ci } else { 157662306a36Sopenharmony_ci rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathon); 157762306a36Sopenharmony_ci } 157862306a36Sopenharmony_ci 157962306a36Sopenharmony_ci for (i = 1; i < IQK_ADDA_REG_NUM; i++) 158062306a36Sopenharmony_ci rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathon); 158162306a36Sopenharmony_ci} 158262306a36Sopenharmony_ci 158362306a36Sopenharmony_cistatic void _rtl88e_phy_mac_setting_calibration(struct ieee80211_hw *hw, 158462306a36Sopenharmony_ci u32 *macreg, u32 *macbackup) 158562306a36Sopenharmony_ci{ 158662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 158762306a36Sopenharmony_ci u32 i = 0; 158862306a36Sopenharmony_ci 158962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, macreg[i], 0x3F); 159062306a36Sopenharmony_ci 159162306a36Sopenharmony_ci for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) 159262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, macreg[i], 159362306a36Sopenharmony_ci (u8) (macbackup[i] & (~BIT(3)))); 159462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); 159562306a36Sopenharmony_ci} 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_cistatic void _rtl88e_phy_path_a_standby(struct ieee80211_hw *hw) 159862306a36Sopenharmony_ci{ 159962306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); 160062306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); 160162306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); 160262306a36Sopenharmony_ci} 160362306a36Sopenharmony_ci 160462306a36Sopenharmony_cistatic void _rtl88e_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) 160562306a36Sopenharmony_ci{ 160662306a36Sopenharmony_ci u32 mode; 160762306a36Sopenharmony_ci 160862306a36Sopenharmony_ci mode = pi_mode ? 0x01000100 : 0x01000000; 160962306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); 161062306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); 161162306a36Sopenharmony_ci} 161262306a36Sopenharmony_ci 161362306a36Sopenharmony_cistatic bool _rtl88e_phy_simularity_compare(struct ieee80211_hw *hw, 161462306a36Sopenharmony_ci long result[][8], u8 c1, u8 c2) 161562306a36Sopenharmony_ci{ 161662306a36Sopenharmony_ci u32 i, j, diff, simularity_bitmap, bound; 161762306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 161862306a36Sopenharmony_ci 161962306a36Sopenharmony_ci u8 final_candidate[2] = { 0xFF, 0xFF }; 162062306a36Sopenharmony_ci bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci if (is2t) 162362306a36Sopenharmony_ci bound = 8; 162462306a36Sopenharmony_ci else 162562306a36Sopenharmony_ci bound = 4; 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci simularity_bitmap = 0; 162862306a36Sopenharmony_ci 162962306a36Sopenharmony_ci for (i = 0; i < bound; i++) { 163062306a36Sopenharmony_ci diff = (result[c1][i] > result[c2][i]) ? 163162306a36Sopenharmony_ci (result[c1][i] - result[c2][i]) : 163262306a36Sopenharmony_ci (result[c2][i] - result[c1][i]); 163362306a36Sopenharmony_ci 163462306a36Sopenharmony_ci if (diff > MAX_TOLERANCE) { 163562306a36Sopenharmony_ci if ((i == 2 || i == 6) && !simularity_bitmap) { 163662306a36Sopenharmony_ci if (result[c1][i] + result[c1][i + 1] == 0) 163762306a36Sopenharmony_ci final_candidate[(i / 4)] = c2; 163862306a36Sopenharmony_ci else if (result[c2][i] + result[c2][i + 1] == 0) 163962306a36Sopenharmony_ci final_candidate[(i / 4)] = c1; 164062306a36Sopenharmony_ci else 164162306a36Sopenharmony_ci simularity_bitmap = simularity_bitmap | 164262306a36Sopenharmony_ci (1 << i); 164362306a36Sopenharmony_ci } else 164462306a36Sopenharmony_ci simularity_bitmap = 164562306a36Sopenharmony_ci simularity_bitmap | (1 << i); 164662306a36Sopenharmony_ci } 164762306a36Sopenharmony_ci } 164862306a36Sopenharmony_ci 164962306a36Sopenharmony_ci if (simularity_bitmap == 0) { 165062306a36Sopenharmony_ci for (i = 0; i < (bound / 4); i++) { 165162306a36Sopenharmony_ci if (final_candidate[i] != 0xFF) { 165262306a36Sopenharmony_ci for (j = i * 4; j < (i + 1) * 4 - 2; j++) 165362306a36Sopenharmony_ci result[3][j] = 165462306a36Sopenharmony_ci result[final_candidate[i]][j]; 165562306a36Sopenharmony_ci bresult = false; 165662306a36Sopenharmony_ci } 165762306a36Sopenharmony_ci } 165862306a36Sopenharmony_ci return bresult; 165962306a36Sopenharmony_ci } else if (!(simularity_bitmap & 0x0F)) { 166062306a36Sopenharmony_ci for (i = 0; i < 4; i++) 166162306a36Sopenharmony_ci result[3][i] = result[c1][i]; 166262306a36Sopenharmony_ci return false; 166362306a36Sopenharmony_ci } else if (!(simularity_bitmap & 0xF0) && is2t) { 166462306a36Sopenharmony_ci for (i = 4; i < 8; i++) 166562306a36Sopenharmony_ci result[3][i] = result[c1][i]; 166662306a36Sopenharmony_ci return false; 166762306a36Sopenharmony_ci } else { 166862306a36Sopenharmony_ci return false; 166962306a36Sopenharmony_ci } 167062306a36Sopenharmony_ci 167162306a36Sopenharmony_ci} 167262306a36Sopenharmony_ci 167362306a36Sopenharmony_cistatic void _rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, 167462306a36Sopenharmony_ci long result[][8], u8 t, bool is2t) 167562306a36Sopenharmony_ci{ 167662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 167762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 167862306a36Sopenharmony_ci u32 i; 167962306a36Sopenharmony_ci u8 patha_ok, pathb_ok; 168062306a36Sopenharmony_ci u32 adda_reg[IQK_ADDA_REG_NUM] = { 168162306a36Sopenharmony_ci 0x85c, 0xe6c, 0xe70, 0xe74, 168262306a36Sopenharmony_ci 0xe78, 0xe7c, 0xe80, 0xe84, 168362306a36Sopenharmony_ci 0xe88, 0xe8c, 0xed0, 0xed4, 168462306a36Sopenharmony_ci 0xed8, 0xedc, 0xee0, 0xeec 168562306a36Sopenharmony_ci }; 168662306a36Sopenharmony_ci u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { 168762306a36Sopenharmony_ci 0x522, 0x550, 0x551, 0x040 168862306a36Sopenharmony_ci }; 168962306a36Sopenharmony_ci u32 iqk_bb_reg[IQK_BB_REG_NUM] = { 169062306a36Sopenharmony_ci ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, 169162306a36Sopenharmony_ci RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c, 169262306a36Sopenharmony_ci 0x870, 0x860, 0x864, 0x800 169362306a36Sopenharmony_ci }; 169462306a36Sopenharmony_ci const u32 retrycount = 2; 169562306a36Sopenharmony_ci 169662306a36Sopenharmony_ci if (t == 0) { 169762306a36Sopenharmony_ci _rtl88e_phy_save_adda_registers(hw, adda_reg, 169862306a36Sopenharmony_ci rtlphy->adda_backup, 16); 169962306a36Sopenharmony_ci _rtl88e_phy_save_mac_registers(hw, iqk_mac_reg, 170062306a36Sopenharmony_ci rtlphy->iqk_mac_backup); 170162306a36Sopenharmony_ci _rtl88e_phy_save_adda_registers(hw, iqk_bb_reg, 170262306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 170362306a36Sopenharmony_ci IQK_BB_REG_NUM); 170462306a36Sopenharmony_ci } 170562306a36Sopenharmony_ci _rtl88e_phy_path_adda_on(hw, adda_reg, true, is2t); 170662306a36Sopenharmony_ci if (t == 0) { 170762306a36Sopenharmony_ci rtlphy->rfpi_enable = 170862306a36Sopenharmony_ci (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, BIT(8)); 170962306a36Sopenharmony_ci } 171062306a36Sopenharmony_ci 171162306a36Sopenharmony_ci if (!rtlphy->rfpi_enable) 171262306a36Sopenharmony_ci _rtl88e_phy_pi_mode_switch(hw, true); 171362306a36Sopenharmony_ci /*BB Setting*/ 171462306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x800, BIT(24), 0x00); 171562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); 171662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); 171762306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x870, BIT(10), 0x01); 172062306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x870, BIT(26), 0x01); 172162306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x860, BIT(10), 0x00); 172262306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x864, BIT(10), 0x00); 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci if (is2t) { 172562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); 172662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); 172762306a36Sopenharmony_ci } 172862306a36Sopenharmony_ci _rtl88e_phy_mac_setting_calibration(hw, iqk_mac_reg, 172962306a36Sopenharmony_ci rtlphy->iqk_mac_backup); 173062306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000); 173162306a36Sopenharmony_ci if (is2t) 173262306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x0f600000); 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); 173562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); 173662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800); 173762306a36Sopenharmony_ci for (i = 0; i < retrycount; i++) { 173862306a36Sopenharmony_ci patha_ok = _rtl88e_phy_path_a_iqk(hw, is2t); 173962306a36Sopenharmony_ci if (patha_ok == 0x01) { 174062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 174162306a36Sopenharmony_ci "Path A Tx IQK Success!!\n"); 174262306a36Sopenharmony_ci result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & 174362306a36Sopenharmony_ci 0x3FF0000) >> 16; 174462306a36Sopenharmony_ci result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 174562306a36Sopenharmony_ci 0x3FF0000) >> 16; 174662306a36Sopenharmony_ci break; 174762306a36Sopenharmony_ci } 174862306a36Sopenharmony_ci } 174962306a36Sopenharmony_ci 175062306a36Sopenharmony_ci for (i = 0; i < retrycount; i++) { 175162306a36Sopenharmony_ci patha_ok = _rtl88e_phy_path_a_rx_iqk(hw, is2t); 175262306a36Sopenharmony_ci if (patha_ok == 0x03) { 175362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 175462306a36Sopenharmony_ci "Path A Rx IQK Success!!\n"); 175562306a36Sopenharmony_ci result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & 175662306a36Sopenharmony_ci 0x3FF0000) >> 16; 175762306a36Sopenharmony_ci result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & 175862306a36Sopenharmony_ci 0x3FF0000) >> 16; 175962306a36Sopenharmony_ci break; 176062306a36Sopenharmony_ci } else { 176162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 176262306a36Sopenharmony_ci "Path a RX iqk fail!!!\n"); 176362306a36Sopenharmony_ci } 176462306a36Sopenharmony_ci } 176562306a36Sopenharmony_ci 176662306a36Sopenharmony_ci if (0 == patha_ok) 176762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 176862306a36Sopenharmony_ci "Path A IQK Success!!\n"); 176962306a36Sopenharmony_ci if (is2t) { 177062306a36Sopenharmony_ci _rtl88e_phy_path_a_standby(hw); 177162306a36Sopenharmony_ci _rtl88e_phy_path_adda_on(hw, adda_reg, false, is2t); 177262306a36Sopenharmony_ci for (i = 0; i < retrycount; i++) { 177362306a36Sopenharmony_ci pathb_ok = _rtl88e_phy_path_b_iqk(hw); 177462306a36Sopenharmony_ci if (pathb_ok == 0x03) { 177562306a36Sopenharmony_ci result[t][4] = (rtl_get_bbreg(hw, 177662306a36Sopenharmony_ci 0xeb4, 177762306a36Sopenharmony_ci MASKDWORD) & 177862306a36Sopenharmony_ci 0x3FF0000) >> 16; 177962306a36Sopenharmony_ci result[t][5] = 178062306a36Sopenharmony_ci (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & 178162306a36Sopenharmony_ci 0x3FF0000) >> 16; 178262306a36Sopenharmony_ci result[t][6] = 178362306a36Sopenharmony_ci (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & 178462306a36Sopenharmony_ci 0x3FF0000) >> 16; 178562306a36Sopenharmony_ci result[t][7] = 178662306a36Sopenharmony_ci (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & 178762306a36Sopenharmony_ci 0x3FF0000) >> 16; 178862306a36Sopenharmony_ci break; 178962306a36Sopenharmony_ci } else if (i == (retrycount - 1) && pathb_ok == 0x01) { 179062306a36Sopenharmony_ci result[t][4] = (rtl_get_bbreg(hw, 179162306a36Sopenharmony_ci 0xeb4, 179262306a36Sopenharmony_ci MASKDWORD) & 179362306a36Sopenharmony_ci 0x3FF0000) >> 16; 179462306a36Sopenharmony_ci } 179562306a36Sopenharmony_ci result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & 179662306a36Sopenharmony_ci 0x3FF0000) >> 16; 179762306a36Sopenharmony_ci } 179862306a36Sopenharmony_ci } 179962306a36Sopenharmony_ci 180062306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); 180162306a36Sopenharmony_ci 180262306a36Sopenharmony_ci if (t != 0) { 180362306a36Sopenharmony_ci if (!rtlphy->rfpi_enable) 180462306a36Sopenharmony_ci _rtl88e_phy_pi_mode_switch(hw, false); 180562306a36Sopenharmony_ci _rtl88e_phy_reload_adda_registers(hw, adda_reg, 180662306a36Sopenharmony_ci rtlphy->adda_backup, 16); 180762306a36Sopenharmony_ci _rtl88e_phy_reload_mac_registers(hw, iqk_mac_reg, 180862306a36Sopenharmony_ci rtlphy->iqk_mac_backup); 180962306a36Sopenharmony_ci _rtl88e_phy_reload_adda_registers(hw, iqk_bb_reg, 181062306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 181162306a36Sopenharmony_ci IQK_BB_REG_NUM); 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); 181462306a36Sopenharmony_ci if (is2t) 181562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); 181662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00); 181762306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00); 181862306a36Sopenharmony_ci } 181962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "88ee IQK Finish!!\n"); 182062306a36Sopenharmony_ci} 182162306a36Sopenharmony_ci 182262306a36Sopenharmony_cistatic void _rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) 182362306a36Sopenharmony_ci{ 182462306a36Sopenharmony_ci u8 tmpreg; 182562306a36Sopenharmony_ci u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; 182662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 182762306a36Sopenharmony_ci 182862306a36Sopenharmony_ci tmpreg = rtl_read_byte(rtlpriv, 0xd03); 182962306a36Sopenharmony_ci 183062306a36Sopenharmony_ci if ((tmpreg & 0x70) != 0) 183162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); 183262306a36Sopenharmony_ci else 183362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 183462306a36Sopenharmony_ci 183562306a36Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 183662306a36Sopenharmony_ci rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); 183762306a36Sopenharmony_ci 183862306a36Sopenharmony_ci if (is2t) 183962306a36Sopenharmony_ci rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, 184062306a36Sopenharmony_ci MASK12BITS); 184162306a36Sopenharmony_ci 184262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, 184362306a36Sopenharmony_ci (rf_a_mode & 0x8FFFF) | 0x10000); 184462306a36Sopenharmony_ci 184562306a36Sopenharmony_ci if (is2t) 184662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, 184762306a36Sopenharmony_ci (rf_b_mode & 0x8FFFF) | 0x10000); 184862306a36Sopenharmony_ci } 184962306a36Sopenharmony_ci lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); 185062306a36Sopenharmony_ci 185162306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); 185262306a36Sopenharmony_ci 185362306a36Sopenharmony_ci mdelay(100); 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 185662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg); 185762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); 185862306a36Sopenharmony_ci 185962306a36Sopenharmony_ci if (is2t) 186062306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, 186162306a36Sopenharmony_ci rf_b_mode); 186262306a36Sopenharmony_ci } else { 186362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 186462306a36Sopenharmony_ci } 186562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); 186662306a36Sopenharmony_ci} 186762306a36Sopenharmony_ci 186862306a36Sopenharmony_cistatic void _rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, 186962306a36Sopenharmony_ci bool bmain, bool is2t) 187062306a36Sopenharmony_ci{ 187162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 187262306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 187362306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 187462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); 187562306a36Sopenharmony_ci 187662306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) { 187762306a36Sopenharmony_ci u8 u1btmp; 187862306a36Sopenharmony_ci u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0); 187962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7)); 188062306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); 188162306a36Sopenharmony_ci } 188262306a36Sopenharmony_ci if (is2t) { 188362306a36Sopenharmony_ci if (bmain) 188462306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 188562306a36Sopenharmony_ci BIT(5) | BIT(6), 0x1); 188662306a36Sopenharmony_ci else 188762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 188862306a36Sopenharmony_ci BIT(5) | BIT(6), 0x2); 188962306a36Sopenharmony_ci } else { 189062306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0); 189162306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201); 189262306a36Sopenharmony_ci 189362306a36Sopenharmony_ci /* We use the RF definition of MAIN and AUX, 189462306a36Sopenharmony_ci * left antenna and right antenna repectively. 189562306a36Sopenharmony_ci * Default output at AUX. 189662306a36Sopenharmony_ci */ 189762306a36Sopenharmony_ci if (bmain) { 189862306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 189962306a36Sopenharmony_ci BIT(14) | BIT(13) | BIT(12), 0); 190062306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 190162306a36Sopenharmony_ci BIT(5) | BIT(4) | BIT(3), 0); 190262306a36Sopenharmony_ci if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) 190362306a36Sopenharmony_ci rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 0); 190462306a36Sopenharmony_ci } else { 190562306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 190662306a36Sopenharmony_ci BIT(14) | BIT(13) | BIT(12), 1); 190762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 190862306a36Sopenharmony_ci BIT(5) | BIT(4) | BIT(3), 1); 190962306a36Sopenharmony_ci if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) 191062306a36Sopenharmony_ci rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 1); 191162306a36Sopenharmony_ci } 191262306a36Sopenharmony_ci } 191362306a36Sopenharmony_ci} 191462306a36Sopenharmony_ci 191562306a36Sopenharmony_ci#undef IQK_ADDA_REG_NUM 191662306a36Sopenharmony_ci#undef IQK_DELAY_TIME 191762306a36Sopenharmony_ci 191862306a36Sopenharmony_civoid rtl88e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) 191962306a36Sopenharmony_ci{ 192062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 192162306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 192262306a36Sopenharmony_ci long result[4][8]; 192362306a36Sopenharmony_ci u8 i, final_candidate; 192462306a36Sopenharmony_ci bool b_patha_ok; 192562306a36Sopenharmony_ci long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, 192662306a36Sopenharmony_ci reg_tmp = 0; 192762306a36Sopenharmony_ci bool is12simular, is13simular, is23simular; 192862306a36Sopenharmony_ci u32 iqk_bb_reg[9] = { 192962306a36Sopenharmony_ci ROFDM0_XARXIQIMBALANCE, 193062306a36Sopenharmony_ci ROFDM0_XBRXIQIMBALANCE, 193162306a36Sopenharmony_ci ROFDM0_ECCATHRESHOLD, 193262306a36Sopenharmony_ci ROFDM0_AGCRSSITABLE, 193362306a36Sopenharmony_ci ROFDM0_XATXIQIMBALANCE, 193462306a36Sopenharmony_ci ROFDM0_XBTXIQIMBALANCE, 193562306a36Sopenharmony_ci ROFDM0_XCTXAFE, 193662306a36Sopenharmony_ci ROFDM0_XDTXAFE, 193762306a36Sopenharmony_ci ROFDM0_RXIQEXTANTA 193862306a36Sopenharmony_ci }; 193962306a36Sopenharmony_ci 194062306a36Sopenharmony_ci if (b_recovery) { 194162306a36Sopenharmony_ci _rtl88e_phy_reload_adda_registers(hw, 194262306a36Sopenharmony_ci iqk_bb_reg, 194362306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 9); 194462306a36Sopenharmony_ci return; 194562306a36Sopenharmony_ci } 194662306a36Sopenharmony_ci 194762306a36Sopenharmony_ci for (i = 0; i < 8; i++) { 194862306a36Sopenharmony_ci result[0][i] = 0; 194962306a36Sopenharmony_ci result[1][i] = 0; 195062306a36Sopenharmony_ci result[2][i] = 0; 195162306a36Sopenharmony_ci result[3][i] = 0; 195262306a36Sopenharmony_ci } 195362306a36Sopenharmony_ci final_candidate = 0xff; 195462306a36Sopenharmony_ci b_patha_ok = false; 195562306a36Sopenharmony_ci is12simular = false; 195662306a36Sopenharmony_ci is23simular = false; 195762306a36Sopenharmony_ci is13simular = false; 195862306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 195962306a36Sopenharmony_ci if (get_rf_type(rtlphy) == RF_2T2R) 196062306a36Sopenharmony_ci _rtl88e_phy_iq_calibrate(hw, result, i, true); 196162306a36Sopenharmony_ci else 196262306a36Sopenharmony_ci _rtl88e_phy_iq_calibrate(hw, result, i, false); 196362306a36Sopenharmony_ci if (i == 1) { 196462306a36Sopenharmony_ci is12simular = 196562306a36Sopenharmony_ci _rtl88e_phy_simularity_compare(hw, result, 0, 1); 196662306a36Sopenharmony_ci if (is12simular) { 196762306a36Sopenharmony_ci final_candidate = 0; 196862306a36Sopenharmony_ci break; 196962306a36Sopenharmony_ci } 197062306a36Sopenharmony_ci } 197162306a36Sopenharmony_ci if (i == 2) { 197262306a36Sopenharmony_ci is13simular = 197362306a36Sopenharmony_ci _rtl88e_phy_simularity_compare(hw, result, 0, 2); 197462306a36Sopenharmony_ci if (is13simular) { 197562306a36Sopenharmony_ci final_candidate = 0; 197662306a36Sopenharmony_ci break; 197762306a36Sopenharmony_ci } 197862306a36Sopenharmony_ci is23simular = 197962306a36Sopenharmony_ci _rtl88e_phy_simularity_compare(hw, result, 1, 2); 198062306a36Sopenharmony_ci if (is23simular) { 198162306a36Sopenharmony_ci final_candidate = 1; 198262306a36Sopenharmony_ci } else { 198362306a36Sopenharmony_ci for (i = 0; i < 8; i++) 198462306a36Sopenharmony_ci reg_tmp += result[3][i]; 198562306a36Sopenharmony_ci 198662306a36Sopenharmony_ci if (reg_tmp != 0) 198762306a36Sopenharmony_ci final_candidate = 3; 198862306a36Sopenharmony_ci else 198962306a36Sopenharmony_ci final_candidate = 0xFF; 199062306a36Sopenharmony_ci } 199162306a36Sopenharmony_ci } 199262306a36Sopenharmony_ci } 199362306a36Sopenharmony_ci for (i = 0; i < 4; i++) { 199462306a36Sopenharmony_ci reg_e94 = result[i][0]; 199562306a36Sopenharmony_ci reg_e9c = result[i][1]; 199662306a36Sopenharmony_ci reg_ea4 = result[i][2]; 199762306a36Sopenharmony_ci reg_eb4 = result[i][4]; 199862306a36Sopenharmony_ci reg_ebc = result[i][5]; 199962306a36Sopenharmony_ci } 200062306a36Sopenharmony_ci if (final_candidate != 0xff) { 200162306a36Sopenharmony_ci reg_e94 = result[final_candidate][0]; 200262306a36Sopenharmony_ci reg_e9c = result[final_candidate][1]; 200362306a36Sopenharmony_ci reg_ea4 = result[final_candidate][2]; 200462306a36Sopenharmony_ci reg_eb4 = result[final_candidate][4]; 200562306a36Sopenharmony_ci reg_ebc = result[final_candidate][5]; 200662306a36Sopenharmony_ci rtlphy->reg_eb4 = reg_eb4; 200762306a36Sopenharmony_ci rtlphy->reg_ebc = reg_ebc; 200862306a36Sopenharmony_ci rtlphy->reg_e94 = reg_e94; 200962306a36Sopenharmony_ci rtlphy->reg_e9c = reg_e9c; 201062306a36Sopenharmony_ci b_patha_ok = true; 201162306a36Sopenharmony_ci } else { 201262306a36Sopenharmony_ci rtlphy->reg_e94 = 0x100; 201362306a36Sopenharmony_ci rtlphy->reg_eb4 = 0x100; 201462306a36Sopenharmony_ci rtlphy->reg_e9c = 0x0; 201562306a36Sopenharmony_ci rtlphy->reg_ebc = 0x0; 201662306a36Sopenharmony_ci } 201762306a36Sopenharmony_ci if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ 201862306a36Sopenharmony_ci _rtl88e_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, 201962306a36Sopenharmony_ci final_candidate, 202062306a36Sopenharmony_ci (reg_ea4 == 0)); 202162306a36Sopenharmony_ci if (final_candidate != 0xFF) { 202262306a36Sopenharmony_ci for (i = 0; i < IQK_MATRIX_REG_NUM; i++) 202362306a36Sopenharmony_ci rtlphy->iqk_matrix[0].value[0][i] = 202462306a36Sopenharmony_ci result[final_candidate][i]; 202562306a36Sopenharmony_ci rtlphy->iqk_matrix[0].iqk_done = true; 202662306a36Sopenharmony_ci 202762306a36Sopenharmony_ci } 202862306a36Sopenharmony_ci _rtl88e_phy_save_adda_registers(hw, iqk_bb_reg, 202962306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 9); 203062306a36Sopenharmony_ci} 203162306a36Sopenharmony_ci 203262306a36Sopenharmony_civoid rtl88e_phy_lc_calibrate(struct ieee80211_hw *hw) 203362306a36Sopenharmony_ci{ 203462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 203562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 203662306a36Sopenharmony_ci struct rtl_hal *rtlhal = &rtlpriv->rtlhal; 203762306a36Sopenharmony_ci u32 timeout = 2000, timecount = 0; 203862306a36Sopenharmony_ci 203962306a36Sopenharmony_ci while (rtlpriv->mac80211.act_scanning && timecount < timeout) { 204062306a36Sopenharmony_ci udelay(50); 204162306a36Sopenharmony_ci timecount += 50; 204262306a36Sopenharmony_ci } 204362306a36Sopenharmony_ci 204462306a36Sopenharmony_ci rtlphy->lck_inprogress = true; 204562306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_IQK, 204662306a36Sopenharmony_ci "LCK:Start!!! currentband %x delay %d ms\n", 204762306a36Sopenharmony_ci rtlhal->current_bandtype, timecount); 204862306a36Sopenharmony_ci 204962306a36Sopenharmony_ci _rtl88e_phy_lc_calibrate(hw, false); 205062306a36Sopenharmony_ci 205162306a36Sopenharmony_ci rtlphy->lck_inprogress = false; 205262306a36Sopenharmony_ci} 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_civoid rtl88e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) 205562306a36Sopenharmony_ci{ 205662306a36Sopenharmony_ci _rtl88e_phy_set_rfpath_switch(hw, bmain, false); 205762306a36Sopenharmony_ci} 205862306a36Sopenharmony_ci 205962306a36Sopenharmony_cibool rtl88e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) 206062306a36Sopenharmony_ci{ 206162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 206262306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 206362306a36Sopenharmony_ci bool postprocessing = false; 206462306a36Sopenharmony_ci 206562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 206662306a36Sopenharmony_ci "-->IO Cmd(%#x), set_io_inprogress(%d)\n", 206762306a36Sopenharmony_ci iotype, rtlphy->set_io_inprogress); 206862306a36Sopenharmony_ci do { 206962306a36Sopenharmony_ci switch (iotype) { 207062306a36Sopenharmony_ci case IO_CMD_RESUME_DM_BY_SCAN: 207162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 207262306a36Sopenharmony_ci "[IO CMD] Resume DM after scan.\n"); 207362306a36Sopenharmony_ci postprocessing = true; 207462306a36Sopenharmony_ci break; 207562306a36Sopenharmony_ci case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 207662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 207762306a36Sopenharmony_ci "[IO CMD] Pause DM before scan.\n"); 207862306a36Sopenharmony_ci postprocessing = true; 207962306a36Sopenharmony_ci break; 208062306a36Sopenharmony_ci default: 208162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 208262306a36Sopenharmony_ci "switch case %#x not processed\n", iotype); 208362306a36Sopenharmony_ci break; 208462306a36Sopenharmony_ci } 208562306a36Sopenharmony_ci } while (false); 208662306a36Sopenharmony_ci if (postprocessing && !rtlphy->set_io_inprogress) { 208762306a36Sopenharmony_ci rtlphy->set_io_inprogress = true; 208862306a36Sopenharmony_ci rtlphy->current_io_type = iotype; 208962306a36Sopenharmony_ci } else { 209062306a36Sopenharmony_ci return false; 209162306a36Sopenharmony_ci } 209262306a36Sopenharmony_ci rtl88e_phy_set_io(hw); 209362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); 209462306a36Sopenharmony_ci return true; 209562306a36Sopenharmony_ci} 209662306a36Sopenharmony_ci 209762306a36Sopenharmony_cistatic void rtl88e_phy_set_io(struct ieee80211_hw *hw) 209862306a36Sopenharmony_ci{ 209962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 210062306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 210162306a36Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 210262306a36Sopenharmony_ci 210362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 210462306a36Sopenharmony_ci "--->Cmd(%#x), set_io_inprogress(%d)\n", 210562306a36Sopenharmony_ci rtlphy->current_io_type, rtlphy->set_io_inprogress); 210662306a36Sopenharmony_ci switch (rtlphy->current_io_type) { 210762306a36Sopenharmony_ci case IO_CMD_RESUME_DM_BY_SCAN: 210862306a36Sopenharmony_ci dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; 210962306a36Sopenharmony_ci /*rtl92c_dm_write_dig(hw);*/ 211062306a36Sopenharmony_ci rtl88e_phy_set_txpower_level(hw, rtlphy->current_channel); 211162306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83); 211262306a36Sopenharmony_ci break; 211362306a36Sopenharmony_ci case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 211462306a36Sopenharmony_ci rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; 211562306a36Sopenharmony_ci dm_digtable->cur_igvalue = 0x17; 211662306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40); 211762306a36Sopenharmony_ci break; 211862306a36Sopenharmony_ci default: 211962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 212062306a36Sopenharmony_ci "switch case %#x not processed\n", 212162306a36Sopenharmony_ci rtlphy->current_io_type); 212262306a36Sopenharmony_ci break; 212362306a36Sopenharmony_ci } 212462306a36Sopenharmony_ci rtlphy->set_io_inprogress = false; 212562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 212662306a36Sopenharmony_ci "(%#x)\n", rtlphy->current_io_type); 212762306a36Sopenharmony_ci} 212862306a36Sopenharmony_ci 212962306a36Sopenharmony_cistatic void rtl88ee_phy_set_rf_on(struct ieee80211_hw *hw) 213062306a36Sopenharmony_ci{ 213162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 213262306a36Sopenharmony_ci 213362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); 213462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 213562306a36Sopenharmony_ci /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/ 213662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 213762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 213862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 213962306a36Sopenharmony_ci} 214062306a36Sopenharmony_ci 214162306a36Sopenharmony_cistatic void _rtl88ee_phy_set_rf_sleep(struct ieee80211_hw *hw) 214262306a36Sopenharmony_ci{ 214362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 214462306a36Sopenharmony_ci 214562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 214662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 214762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 214862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); 214962306a36Sopenharmony_ci} 215062306a36Sopenharmony_ci 215162306a36Sopenharmony_cistatic bool _rtl88ee_phy_set_rf_power_state(struct ieee80211_hw *hw, 215262306a36Sopenharmony_ci enum rf_pwrstate rfpwr_state) 215362306a36Sopenharmony_ci{ 215462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 215562306a36Sopenharmony_ci struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 215662306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 215762306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 215862306a36Sopenharmony_ci bool bresult = true; 215962306a36Sopenharmony_ci u8 i, queue_id; 216062306a36Sopenharmony_ci struct rtl8192_tx_ring *ring = NULL; 216162306a36Sopenharmony_ci 216262306a36Sopenharmony_ci switch (rfpwr_state) { 216362306a36Sopenharmony_ci case ERFON: 216462306a36Sopenharmony_ci if ((ppsc->rfpwr_state == ERFOFF) && 216562306a36Sopenharmony_ci RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { 216662306a36Sopenharmony_ci bool rtstatus; 216762306a36Sopenharmony_ci u32 initializecount = 0; 216862306a36Sopenharmony_ci 216962306a36Sopenharmony_ci do { 217062306a36Sopenharmony_ci initializecount++; 217162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 217262306a36Sopenharmony_ci "IPS Set eRf nic enable\n"); 217362306a36Sopenharmony_ci rtstatus = rtl_ps_enable_nic(hw); 217462306a36Sopenharmony_ci } while (!rtstatus && 217562306a36Sopenharmony_ci (initializecount < 10)); 217662306a36Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, 217762306a36Sopenharmony_ci RT_RF_OFF_LEVL_HALT_NIC); 217862306a36Sopenharmony_ci } else { 217962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 218062306a36Sopenharmony_ci "Set ERFON slept:%d ms\n", 218162306a36Sopenharmony_ci jiffies_to_msecs(jiffies - 218262306a36Sopenharmony_ci ppsc->last_sleep_jiffies)); 218362306a36Sopenharmony_ci ppsc->last_awake_jiffies = jiffies; 218462306a36Sopenharmony_ci rtl88ee_phy_set_rf_on(hw); 218562306a36Sopenharmony_ci } 218662306a36Sopenharmony_ci if (mac->link_state == MAC80211_LINKED) { 218762306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 218862306a36Sopenharmony_ci LED_CTL_LINK); 218962306a36Sopenharmony_ci } else { 219062306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 219162306a36Sopenharmony_ci LED_CTL_NO_LINK); 219262306a36Sopenharmony_ci } 219362306a36Sopenharmony_ci break; 219462306a36Sopenharmony_ci case ERFOFF: 219562306a36Sopenharmony_ci for (queue_id = 0, i = 0; 219662306a36Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 219762306a36Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 219862306a36Sopenharmony_ci if (queue_id == BEACON_QUEUE || 219962306a36Sopenharmony_ci skb_queue_len(&ring->queue) == 0) { 220062306a36Sopenharmony_ci queue_id++; 220162306a36Sopenharmony_ci continue; 220262306a36Sopenharmony_ci } else { 220362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 220462306a36Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", 220562306a36Sopenharmony_ci (i + 1), queue_id, 220662306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 220762306a36Sopenharmony_ci 220862306a36Sopenharmony_ci udelay(10); 220962306a36Sopenharmony_ci i++; 221062306a36Sopenharmony_ci } 221162306a36Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 221262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 221362306a36Sopenharmony_ci "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", 221462306a36Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 221562306a36Sopenharmony_ci queue_id, 221662306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 221762306a36Sopenharmony_ci break; 221862306a36Sopenharmony_ci } 221962306a36Sopenharmony_ci } 222062306a36Sopenharmony_ci 222162306a36Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { 222262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 222362306a36Sopenharmony_ci "IPS Set eRf nic disable\n"); 222462306a36Sopenharmony_ci rtl_ps_disable_nic(hw); 222562306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 222662306a36Sopenharmony_ci } else { 222762306a36Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { 222862306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 222962306a36Sopenharmony_ci LED_CTL_NO_LINK); 223062306a36Sopenharmony_ci } else { 223162306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 223262306a36Sopenharmony_ci LED_CTL_POWER_OFF); 223362306a36Sopenharmony_ci } 223462306a36Sopenharmony_ci } 223562306a36Sopenharmony_ci break; 223662306a36Sopenharmony_ci case ERFSLEEP:{ 223762306a36Sopenharmony_ci if (ppsc->rfpwr_state == ERFOFF) 223862306a36Sopenharmony_ci break; 223962306a36Sopenharmony_ci for (queue_id = 0, i = 0; 224062306a36Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 224162306a36Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 224262306a36Sopenharmony_ci if (skb_queue_len(&ring->queue) == 0) { 224362306a36Sopenharmony_ci queue_id++; 224462306a36Sopenharmony_ci continue; 224562306a36Sopenharmony_ci } else { 224662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 224762306a36Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", 224862306a36Sopenharmony_ci (i + 1), queue_id, 224962306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 225062306a36Sopenharmony_ci 225162306a36Sopenharmony_ci udelay(10); 225262306a36Sopenharmony_ci i++; 225362306a36Sopenharmony_ci } 225462306a36Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 225562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 225662306a36Sopenharmony_ci "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", 225762306a36Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 225862306a36Sopenharmony_ci queue_id, 225962306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 226062306a36Sopenharmony_ci break; 226162306a36Sopenharmony_ci } 226262306a36Sopenharmony_ci } 226362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 226462306a36Sopenharmony_ci "Set ERFSLEEP awaked:%d ms\n", 226562306a36Sopenharmony_ci jiffies_to_msecs(jiffies - 226662306a36Sopenharmony_ci ppsc->last_awake_jiffies)); 226762306a36Sopenharmony_ci ppsc->last_sleep_jiffies = jiffies; 226862306a36Sopenharmony_ci _rtl88ee_phy_set_rf_sleep(hw); 226962306a36Sopenharmony_ci break; 227062306a36Sopenharmony_ci } 227162306a36Sopenharmony_ci default: 227262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 227362306a36Sopenharmony_ci "switch case %#x not processed\n", rfpwr_state); 227462306a36Sopenharmony_ci bresult = false; 227562306a36Sopenharmony_ci break; 227662306a36Sopenharmony_ci } 227762306a36Sopenharmony_ci if (bresult) 227862306a36Sopenharmony_ci ppsc->rfpwr_state = rfpwr_state; 227962306a36Sopenharmony_ci return bresult; 228062306a36Sopenharmony_ci} 228162306a36Sopenharmony_ci 228262306a36Sopenharmony_cibool rtl88e_phy_set_rf_power_state(struct ieee80211_hw *hw, 228362306a36Sopenharmony_ci enum rf_pwrstate rfpwr_state) 228462306a36Sopenharmony_ci{ 228562306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 228662306a36Sopenharmony_ci 228762306a36Sopenharmony_ci bool bresult = false; 228862306a36Sopenharmony_ci 228962306a36Sopenharmony_ci if (rfpwr_state == ppsc->rfpwr_state) 229062306a36Sopenharmony_ci return bresult; 229162306a36Sopenharmony_ci bresult = _rtl88ee_phy_set_rf_power_state(hw, rfpwr_state); 229262306a36Sopenharmony_ci return bresult; 229362306a36Sopenharmony_ci} 2294