162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2014 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 "../rtl8723com/phy_common.h" 1162306a36Sopenharmony_ci#include "rf.h" 1262306a36Sopenharmony_ci#include "dm.h" 1362306a36Sopenharmony_ci#include "../rtl8723com/dm_common.h" 1462306a36Sopenharmony_ci#include "table.h" 1562306a36Sopenharmony_ci#include "trx.h" 1662306a36Sopenharmony_ci#include <linux/kernel.h> 1762306a36Sopenharmony_ci 1862306a36Sopenharmony_cistatic bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw); 1962306a36Sopenharmony_cistatic bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); 2062306a36Sopenharmony_cistatic bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, 2162306a36Sopenharmony_ci u8 configtype); 2262306a36Sopenharmony_cistatic bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, 2362306a36Sopenharmony_ci u8 configtype); 2462306a36Sopenharmony_cistatic bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 2562306a36Sopenharmony_ci u8 channel, u8 *stage, 2662306a36Sopenharmony_ci u8 *step, u32 *delay); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_cistatic void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw); 2962306a36Sopenharmony_cistatic void rtl8723be_phy_set_io(struct ieee80211_hw *hw); 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ciu32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, 3262306a36Sopenharmony_ci u32 regaddr, u32 bitmask) 3362306a36Sopenharmony_ci{ 3462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3562306a36Sopenharmony_ci u32 original_value, readback_value, bitshift; 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 3862306a36Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", 3962306a36Sopenharmony_ci regaddr, rfpath, bitmask); 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr); 4462306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 4562306a36Sopenharmony_ci readback_value = (original_value & bitmask) >> bitshift; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 5062306a36Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", 5162306a36Sopenharmony_ci regaddr, rfpath, bitmask, original_value); 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci return readback_value; 5462306a36Sopenharmony_ci} 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_civoid rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path, 5762306a36Sopenharmony_ci u32 regaddr, u32 bitmask, u32 data) 5862306a36Sopenharmony_ci{ 5962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6062306a36Sopenharmony_ci u32 original_value, bitshift; 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 6362306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 6462306a36Sopenharmony_ci regaddr, bitmask, data, path); 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 6762306a36Sopenharmony_ci 6862306a36Sopenharmony_ci if (bitmask != RFREG_OFFSET_MASK) { 6962306a36Sopenharmony_ci original_value = rtl8723_phy_rf_serial_read(hw, path, 7062306a36Sopenharmony_ci regaddr); 7162306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 7262306a36Sopenharmony_ci data = ((original_value & (~bitmask)) | 7362306a36Sopenharmony_ci (data << bitshift)); 7462306a36Sopenharmony_ci } 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci rtl8723_phy_rf_serial_write(hw, path, regaddr, data); 7762306a36Sopenharmony_ci 7862306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 8162306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 8262306a36Sopenharmony_ci regaddr, bitmask, data, path); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci} 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_cibool rtl8723be_phy_mac_config(struct ieee80211_hw *hw) 8762306a36Sopenharmony_ci{ 8862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8962306a36Sopenharmony_ci bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw); 9062306a36Sopenharmony_ci 9162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x04CA, 0x0B); 9262306a36Sopenharmony_ci return rtstatus; 9362306a36Sopenharmony_ci} 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_cibool rtl8723be_phy_bb_config(struct ieee80211_hw *hw) 9662306a36Sopenharmony_ci{ 9762306a36Sopenharmony_ci bool rtstatus = true; 9862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 9962306a36Sopenharmony_ci u16 regval; 10062306a36Sopenharmony_ci u8 b_reg_hwparafile = 1; 10162306a36Sopenharmony_ci u32 tmp; 10262306a36Sopenharmony_ci u8 crystalcap = rtlpriv->efuse.crystalcap; 10362306a36Sopenharmony_ci rtl8723_phy_init_bb_rf_reg_def(hw); 10462306a36Sopenharmony_ci regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 10562306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, 10662306a36Sopenharmony_ci regval | BIT(13) | BIT(0) | BIT(1)); 10762306a36Sopenharmony_ci 10862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); 10962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 11062306a36Sopenharmony_ci FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | 11162306a36Sopenharmony_ci FEN_BB_GLB_RSTN | FEN_BBRSTB); 11262306a36Sopenharmony_ci tmp = rtl_read_dword(rtlpriv, 0x4c); 11362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23)); 11462306a36Sopenharmony_ci 11562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci if (b_reg_hwparafile == 1) 11862306a36Sopenharmony_ci rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw); 11962306a36Sopenharmony_ci 12062306a36Sopenharmony_ci crystalcap = crystalcap & 0x3F; 12162306a36Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, 12262306a36Sopenharmony_ci (crystalcap | crystalcap << 6)); 12362306a36Sopenharmony_ci 12462306a36Sopenharmony_ci return rtstatus; 12562306a36Sopenharmony_ci} 12662306a36Sopenharmony_ci 12762306a36Sopenharmony_cibool rtl8723be_phy_rf_config(struct ieee80211_hw *hw) 12862306a36Sopenharmony_ci{ 12962306a36Sopenharmony_ci return rtl8723be_phy_rf6052_config(hw); 13062306a36Sopenharmony_ci} 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_cistatic bool _rtl8723be_check_positive(struct ieee80211_hw *hw, 13362306a36Sopenharmony_ci const u32 condition1, 13462306a36Sopenharmony_ci const u32 condition2) 13562306a36Sopenharmony_ci{ 13662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13762306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 13862306a36Sopenharmony_ci u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK) 13962306a36Sopenharmony_ci >> CHIP_VER_RTL_SHIFT); 14062306a36Sopenharmony_ci u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0)); 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_ci u8 board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */ 14362306a36Sopenharmony_ci ((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA */ 14462306a36Sopenharmony_ci ((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */ 14562306a36Sopenharmony_ci ((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA */ 14662306a36Sopenharmony_ci ((rtlhal->board_type & BIT(2)) >> 2) << 4; /* _BT */ 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci u32 cond1 = condition1, cond2 = condition2; 14962306a36Sopenharmony_ci u32 driver1 = cut_ver << 24 | /* CUT ver */ 15062306a36Sopenharmony_ci 0 << 20 | /* interface 2/2 */ 15162306a36Sopenharmony_ci 0x04 << 16 | /* platform */ 15262306a36Sopenharmony_ci rtlhal->package_type << 12 | 15362306a36Sopenharmony_ci intf << 8 | /* interface 1/2 */ 15462306a36Sopenharmony_ci board_type; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci u32 driver2 = rtlhal->type_glna << 0 | 15762306a36Sopenharmony_ci rtlhal->type_gpa << 8 | 15862306a36Sopenharmony_ci rtlhal->type_alna << 16 | 15962306a36Sopenharmony_ci rtlhal->type_apa << 24; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 16262306a36Sopenharmony_ci "===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n", 16362306a36Sopenharmony_ci cond1, cond2); 16462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 16562306a36Sopenharmony_ci "===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n", 16662306a36Sopenharmony_ci driver1, driver2); 16762306a36Sopenharmony_ci 16862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 16962306a36Sopenharmony_ci "(Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf); 17062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 17162306a36Sopenharmony_ci "(Board, Package) = (0x%X, 0x%X)\n", 17262306a36Sopenharmony_ci rtlhal->board_type, rtlhal->package_type); 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci /*============== Value Defined Check ===============*/ 17562306a36Sopenharmony_ci /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/ 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) != 17862306a36Sopenharmony_ci (driver1 & 0x0000F000))) 17962306a36Sopenharmony_ci return false; 18062306a36Sopenharmony_ci if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) != 18162306a36Sopenharmony_ci (driver1 & 0x0F000000))) 18262306a36Sopenharmony_ci return false; 18362306a36Sopenharmony_ci 18462306a36Sopenharmony_ci /*=============== Bit Defined Check ================*/ 18562306a36Sopenharmony_ci /* We don't care [31:28] */ 18662306a36Sopenharmony_ci 18762306a36Sopenharmony_ci cond1 &= 0x00FF0FFF; 18862306a36Sopenharmony_ci driver1 &= 0x00FF0FFF; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci if ((cond1 & driver1) == cond1) { 19162306a36Sopenharmony_ci u32 mask = 0; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/ 19462306a36Sopenharmony_ci return true; 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci if ((cond1 & BIT(0)) != 0) /*GLNA*/ 19762306a36Sopenharmony_ci mask |= 0x000000FF; 19862306a36Sopenharmony_ci if ((cond1 & BIT(1)) != 0) /*GPA*/ 19962306a36Sopenharmony_ci mask |= 0x0000FF00; 20062306a36Sopenharmony_ci if ((cond1 & BIT(2)) != 0) /*ALNA*/ 20162306a36Sopenharmony_ci mask |= 0x00FF0000; 20262306a36Sopenharmony_ci if ((cond1 & BIT(3)) != 0) /*APA*/ 20362306a36Sopenharmony_ci mask |= 0xFF000000; 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci /* BoardType of each RF path is matched*/ 20662306a36Sopenharmony_ci if ((cond2 & mask) == (driver2 & mask)) 20762306a36Sopenharmony_ci return true; 20862306a36Sopenharmony_ci else 20962306a36Sopenharmony_ci return false; 21062306a36Sopenharmony_ci } 21162306a36Sopenharmony_ci return false; 21262306a36Sopenharmony_ci} 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_cistatic void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr, 21562306a36Sopenharmony_ci u32 data, enum radio_path rfpath, 21662306a36Sopenharmony_ci u32 regaddr) 21762306a36Sopenharmony_ci{ 21862306a36Sopenharmony_ci if (addr == 0xfe || addr == 0xffe) { 21962306a36Sopenharmony_ci /* In order not to disturb BT music 22062306a36Sopenharmony_ci * when wifi init.(1ant NIC only) 22162306a36Sopenharmony_ci */ 22262306a36Sopenharmony_ci mdelay(50); 22362306a36Sopenharmony_ci } else { 22462306a36Sopenharmony_ci rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data); 22562306a36Sopenharmony_ci udelay(1); 22662306a36Sopenharmony_ci } 22762306a36Sopenharmony_ci} 22862306a36Sopenharmony_cistatic void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw, 22962306a36Sopenharmony_ci u32 addr, u32 data) 23062306a36Sopenharmony_ci{ 23162306a36Sopenharmony_ci u32 content = 0x1000; /*RF Content: radio_a_txt*/ 23262306a36Sopenharmony_ci u32 maskforphyset = (u32)(content & 0xE000); 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A, 23562306a36Sopenharmony_ci addr | maskforphyset); 23662306a36Sopenharmony_ci 23762306a36Sopenharmony_ci} 23862306a36Sopenharmony_ci 23962306a36Sopenharmony_cistatic void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) 24062306a36Sopenharmony_ci{ 24162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 24262306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci u8 band, path, txnum, section; 24562306a36Sopenharmony_ci 24662306a36Sopenharmony_ci for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) 24762306a36Sopenharmony_ci for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path) 24862306a36Sopenharmony_ci for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum) 24962306a36Sopenharmony_ci for (section = 0; 25062306a36Sopenharmony_ci section < TX_PWR_BY_RATE_NUM_SECTION; 25162306a36Sopenharmony_ci ++section) 25262306a36Sopenharmony_ci rtlphy->tx_power_by_rate_offset 25362306a36Sopenharmony_ci [band][path][txnum][section] = 0; 25462306a36Sopenharmony_ci} 25562306a36Sopenharmony_ci 25662306a36Sopenharmony_cistatic void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw, 25762306a36Sopenharmony_ci u32 addr, u32 data) 25862306a36Sopenharmony_ci{ 25962306a36Sopenharmony_ci if (addr == 0xfe) { 26062306a36Sopenharmony_ci mdelay(50); 26162306a36Sopenharmony_ci } else if (addr == 0xfd) { 26262306a36Sopenharmony_ci mdelay(5); 26362306a36Sopenharmony_ci } else if (addr == 0xfc) { 26462306a36Sopenharmony_ci mdelay(1); 26562306a36Sopenharmony_ci } else if (addr == 0xfb) { 26662306a36Sopenharmony_ci udelay(50); 26762306a36Sopenharmony_ci } else if (addr == 0xfa) { 26862306a36Sopenharmony_ci udelay(5); 26962306a36Sopenharmony_ci } else if (addr == 0xf9) { 27062306a36Sopenharmony_ci udelay(1); 27162306a36Sopenharmony_ci } else { 27262306a36Sopenharmony_ci rtl_set_bbreg(hw, addr, MASKDWORD, data); 27362306a36Sopenharmony_ci udelay(1); 27462306a36Sopenharmony_ci } 27562306a36Sopenharmony_ci} 27662306a36Sopenharmony_ci 27762306a36Sopenharmony_cistatic void _rtl8723be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, 27862306a36Sopenharmony_ci u8 band, 27962306a36Sopenharmony_ci u8 path, u8 rate_section, 28062306a36Sopenharmony_ci u8 txnum, u8 value) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 28362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci if (path > RF90_PATH_D) { 28662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 28762306a36Sopenharmony_ci "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", 28862306a36Sopenharmony_ci path); 28962306a36Sopenharmony_ci return; 29062306a36Sopenharmony_ci } 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci if (band == BAND_ON_2_4G) { 29362306a36Sopenharmony_ci switch (rate_section) { 29462306a36Sopenharmony_ci case CCK: 29562306a36Sopenharmony_ci rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value; 29662306a36Sopenharmony_ci break; 29762306a36Sopenharmony_ci case OFDM: 29862306a36Sopenharmony_ci rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value; 29962306a36Sopenharmony_ci break; 30062306a36Sopenharmony_ci case HT_MCS0_MCS7: 30162306a36Sopenharmony_ci rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value; 30262306a36Sopenharmony_ci break; 30362306a36Sopenharmony_ci case HT_MCS8_MCS15: 30462306a36Sopenharmony_ci rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value; 30562306a36Sopenharmony_ci break; 30662306a36Sopenharmony_ci default: 30762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 30862306a36Sopenharmony_ci "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n", 30962306a36Sopenharmony_ci rate_section, path, txnum); 31062306a36Sopenharmony_ci break; 31162306a36Sopenharmony_ci } 31262306a36Sopenharmony_ci } else { 31362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 31462306a36Sopenharmony_ci "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", 31562306a36Sopenharmony_ci band); 31662306a36Sopenharmony_ci } 31762306a36Sopenharmony_ci 31862306a36Sopenharmony_ci} 31962306a36Sopenharmony_ci 32062306a36Sopenharmony_cistatic u8 _rtl8723be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, 32162306a36Sopenharmony_ci u8 band, u8 path, u8 txnum, 32262306a36Sopenharmony_ci u8 rate_section) 32362306a36Sopenharmony_ci{ 32462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 32562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 32662306a36Sopenharmony_ci u8 value = 0; 32762306a36Sopenharmony_ci if (path > RF90_PATH_D) { 32862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 32962306a36Sopenharmony_ci "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n", 33062306a36Sopenharmony_ci path); 33162306a36Sopenharmony_ci return 0; 33262306a36Sopenharmony_ci } 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci if (band == BAND_ON_2_4G) { 33562306a36Sopenharmony_ci switch (rate_section) { 33662306a36Sopenharmony_ci case CCK: 33762306a36Sopenharmony_ci value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0]; 33862306a36Sopenharmony_ci break; 33962306a36Sopenharmony_ci case OFDM: 34062306a36Sopenharmony_ci value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1]; 34162306a36Sopenharmony_ci break; 34262306a36Sopenharmony_ci case HT_MCS0_MCS7: 34362306a36Sopenharmony_ci value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2]; 34462306a36Sopenharmony_ci break; 34562306a36Sopenharmony_ci case HT_MCS8_MCS15: 34662306a36Sopenharmony_ci value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3]; 34762306a36Sopenharmony_ci break; 34862306a36Sopenharmony_ci default: 34962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 35062306a36Sopenharmony_ci "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", 35162306a36Sopenharmony_ci rate_section, path, txnum); 35262306a36Sopenharmony_ci break; 35362306a36Sopenharmony_ci } 35462306a36Sopenharmony_ci } else { 35562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 35662306a36Sopenharmony_ci "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", 35762306a36Sopenharmony_ci band); 35862306a36Sopenharmony_ci } 35962306a36Sopenharmony_ci 36062306a36Sopenharmony_ci return value; 36162306a36Sopenharmony_ci} 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_cistatic void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) 36462306a36Sopenharmony_ci{ 36562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 36662306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 36762306a36Sopenharmony_ci u16 rawvalue = 0; 36862306a36Sopenharmony_ci u8 base = 0, path = 0; 36962306a36Sopenharmony_ci 37062306a36Sopenharmony_ci for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { 37162306a36Sopenharmony_ci if (path == RF90_PATH_A) { 37262306a36Sopenharmony_ci rawvalue = (u16)(rtlphy->tx_power_by_rate_offset 37362306a36Sopenharmony_ci [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF; 37462306a36Sopenharmony_ci base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); 37562306a36Sopenharmony_ci _rtl8723be_phy_set_txpower_by_rate_base(hw, 37662306a36Sopenharmony_ci BAND_ON_2_4G, path, CCK, RF_1TX, base); 37762306a36Sopenharmony_ci } else if (path == RF90_PATH_B) { 37862306a36Sopenharmony_ci rawvalue = (u16)(rtlphy->tx_power_by_rate_offset 37962306a36Sopenharmony_ci [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF; 38062306a36Sopenharmony_ci base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); 38162306a36Sopenharmony_ci _rtl8723be_phy_set_txpower_by_rate_base(hw, 38262306a36Sopenharmony_ci BAND_ON_2_4G, 38362306a36Sopenharmony_ci path, CCK, 38462306a36Sopenharmony_ci RF_1TX, base); 38562306a36Sopenharmony_ci } 38662306a36Sopenharmony_ci rawvalue = (u16)(rtlphy->tx_power_by_rate_offset 38762306a36Sopenharmony_ci [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF; 38862306a36Sopenharmony_ci base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); 38962306a36Sopenharmony_ci _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, 39062306a36Sopenharmony_ci path, OFDM, RF_1TX, 39162306a36Sopenharmony_ci base); 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_ci rawvalue = (u16)(rtlphy->tx_power_by_rate_offset 39462306a36Sopenharmony_ci [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF; 39562306a36Sopenharmony_ci base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); 39662306a36Sopenharmony_ci _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, 39762306a36Sopenharmony_ci path, HT_MCS0_MCS7, 39862306a36Sopenharmony_ci RF_1TX, base); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci rawvalue = (u16)(rtlphy->tx_power_by_rate_offset 40162306a36Sopenharmony_ci [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF; 40262306a36Sopenharmony_ci base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); 40362306a36Sopenharmony_ci _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, 40462306a36Sopenharmony_ci path, HT_MCS8_MCS15, 40562306a36Sopenharmony_ci RF_2TX, base); 40662306a36Sopenharmony_ci } 40762306a36Sopenharmony_ci} 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_cistatic void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start, 41062306a36Sopenharmony_ci u8 end, u8 base_val) 41162306a36Sopenharmony_ci{ 41262306a36Sopenharmony_ci s8 i = 0; 41362306a36Sopenharmony_ci u8 temp_value = 0; 41462306a36Sopenharmony_ci u32 temp_data = 0; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci for (i = 3; i >= 0; --i) { 41762306a36Sopenharmony_ci if (i >= start && i <= end) { 41862306a36Sopenharmony_ci /* Get the exact value */ 41962306a36Sopenharmony_ci temp_value = (u8)(*data >> (i * 8)) & 0xF; 42062306a36Sopenharmony_ci temp_value += ((u8)((*data >> (i*8 + 4)) & 0xF)) * 10; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci /* Change the value to a relative value */ 42362306a36Sopenharmony_ci temp_value = (temp_value > base_val) ? 42462306a36Sopenharmony_ci temp_value - base_val : 42562306a36Sopenharmony_ci base_val - temp_value; 42662306a36Sopenharmony_ci } else { 42762306a36Sopenharmony_ci temp_value = (u8)(*data >> (i * 8)) & 0xFF; 42862306a36Sopenharmony_ci } 42962306a36Sopenharmony_ci temp_data <<= 8; 43062306a36Sopenharmony_ci temp_data |= temp_value; 43162306a36Sopenharmony_ci } 43262306a36Sopenharmony_ci *data = temp_data; 43362306a36Sopenharmony_ci} 43462306a36Sopenharmony_ci 43562306a36Sopenharmony_cistatic void _rtl8723be_phy_convert_txpower_dbm_to_relative_value( 43662306a36Sopenharmony_ci struct ieee80211_hw *hw) 43762306a36Sopenharmony_ci{ 43862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 43962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 44062306a36Sopenharmony_ci u8 base = 0, rfpath = RF90_PATH_A; 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci base = _rtl8723be_phy_get_txpower_by_rate_base(hw, 44362306a36Sopenharmony_ci BAND_ON_2_4G, rfpath, RF_1TX, CCK); 44462306a36Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 44562306a36Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2], 44662306a36Sopenharmony_ci 1, 1, base); 44762306a36Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 44862306a36Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3], 44962306a36Sopenharmony_ci 1, 3, base); 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, 45262306a36Sopenharmony_ci RF_1TX, OFDM); 45362306a36Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 45462306a36Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0], 45562306a36Sopenharmony_ci 0, 3, base); 45662306a36Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 45762306a36Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1], 45862306a36Sopenharmony_ci 0, 3, base); 45962306a36Sopenharmony_ci 46062306a36Sopenharmony_ci base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, 46162306a36Sopenharmony_ci rfpath, RF_1TX, HT_MCS0_MCS7); 46262306a36Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 46362306a36Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4], 46462306a36Sopenharmony_ci 0, 3, base); 46562306a36Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 46662306a36Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][5], 46762306a36Sopenharmony_ci 0, 3, base); 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, 47062306a36Sopenharmony_ci rfpath, RF_2TX, 47162306a36Sopenharmony_ci HT_MCS8_MCS15); 47262306a36Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 47362306a36Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6], 47462306a36Sopenharmony_ci 0, 3, base); 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 47762306a36Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][7], 47862306a36Sopenharmony_ci 0, 3, base); 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, 48162306a36Sopenharmony_ci "<===%s\n", __func__); 48262306a36Sopenharmony_ci} 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_cistatic void phy_txpower_by_rate_config(struct ieee80211_hw *hw) 48562306a36Sopenharmony_ci{ 48662306a36Sopenharmony_ci _rtl8723be_phy_store_txpower_by_rate_base(hw); 48762306a36Sopenharmony_ci _rtl8723be_phy_convert_txpower_dbm_to_relative_value(hw); 48862306a36Sopenharmony_ci} 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_cistatic bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw) 49162306a36Sopenharmony_ci{ 49262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 49362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 49462306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 49562306a36Sopenharmony_ci bool rtstatus; 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci /* switch ant to BT */ 49862306a36Sopenharmony_ci if (rtlpriv->rtlhal.interface == INTF_USB) { 49962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, 0x948, 0x0); 50062306a36Sopenharmony_ci } else { 50162306a36Sopenharmony_ci if (rtlpriv->btcoexist.btc_info.single_ant_path == 0) 50262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, 0x948, 0x280); 50362306a36Sopenharmony_ci else 50462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, 0x948, 0x0); 50562306a36Sopenharmony_ci } 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ci rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw, 50862306a36Sopenharmony_ci BASEBAND_CONFIG_PHY_REG); 50962306a36Sopenharmony_ci if (!rtstatus) { 51062306a36Sopenharmony_ci pr_err("Write BB Reg Fail!!\n"); 51162306a36Sopenharmony_ci return false; 51262306a36Sopenharmony_ci } 51362306a36Sopenharmony_ci _rtl8723be_phy_init_tx_power_by_rate(hw); 51462306a36Sopenharmony_ci if (!rtlefuse->autoload_failflag) { 51562306a36Sopenharmony_ci rtlphy->pwrgroup_cnt = 0; 51662306a36Sopenharmony_ci rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw, 51762306a36Sopenharmony_ci BASEBAND_CONFIG_PHY_REG); 51862306a36Sopenharmony_ci } 51962306a36Sopenharmony_ci phy_txpower_by_rate_config(hw); 52062306a36Sopenharmony_ci if (!rtstatus) { 52162306a36Sopenharmony_ci pr_err("BB_PG Reg Fail!!\n"); 52262306a36Sopenharmony_ci return false; 52362306a36Sopenharmony_ci } 52462306a36Sopenharmony_ci rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw, 52562306a36Sopenharmony_ci BASEBAND_CONFIG_AGC_TAB); 52662306a36Sopenharmony_ci if (!rtstatus) { 52762306a36Sopenharmony_ci pr_err("AGC Table Fail\n"); 52862306a36Sopenharmony_ci return false; 52962306a36Sopenharmony_ci } 53062306a36Sopenharmony_ci rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw, 53162306a36Sopenharmony_ci RFPGA0_XA_HSSIPARAMETER2, 53262306a36Sopenharmony_ci 0x200)); 53362306a36Sopenharmony_ci return true; 53462306a36Sopenharmony_ci} 53562306a36Sopenharmony_ci 53662306a36Sopenharmony_cistatic bool rtl8723be_phy_config_with_headerfile(struct ieee80211_hw *hw, 53762306a36Sopenharmony_ci u32 *array_table, 53862306a36Sopenharmony_ci u16 arraylen, 53962306a36Sopenharmony_ci void (*set_reg)(struct ieee80211_hw *hw, u32 regaddr, u32 data)) 54062306a36Sopenharmony_ci{ 54162306a36Sopenharmony_ci #define COND_ELSE 2 54262306a36Sopenharmony_ci #define COND_ENDIF 3 54362306a36Sopenharmony_ci 54462306a36Sopenharmony_ci int i = 0; 54562306a36Sopenharmony_ci u8 cond; 54662306a36Sopenharmony_ci bool matched = true, skipped = false; 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci while ((i + 1) < arraylen) { 54962306a36Sopenharmony_ci u32 v1 = array_table[i]; 55062306a36Sopenharmony_ci u32 v2 = array_table[i + 1]; 55162306a36Sopenharmony_ci 55262306a36Sopenharmony_ci if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/ 55362306a36Sopenharmony_ci if (v1 & BIT(31)) {/* positive condition*/ 55462306a36Sopenharmony_ci cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28); 55562306a36Sopenharmony_ci if (cond == COND_ENDIF) { /*end*/ 55662306a36Sopenharmony_ci matched = true; 55762306a36Sopenharmony_ci skipped = false; 55862306a36Sopenharmony_ci } else if (cond == COND_ELSE) { /*else*/ 55962306a36Sopenharmony_ci matched = skipped ? false : true; 56062306a36Sopenharmony_ci } else {/*if , else if*/ 56162306a36Sopenharmony_ci if (skipped) { 56262306a36Sopenharmony_ci matched = false; 56362306a36Sopenharmony_ci } else { 56462306a36Sopenharmony_ci if (_rtl8723be_check_positive( 56562306a36Sopenharmony_ci hw, v1, v2)) { 56662306a36Sopenharmony_ci matched = true; 56762306a36Sopenharmony_ci skipped = true; 56862306a36Sopenharmony_ci } else { 56962306a36Sopenharmony_ci matched = false; 57062306a36Sopenharmony_ci skipped = false; 57162306a36Sopenharmony_ci } 57262306a36Sopenharmony_ci } 57362306a36Sopenharmony_ci } 57462306a36Sopenharmony_ci } else if (v1 & BIT(30)) { /*negative condition*/ 57562306a36Sopenharmony_ci /*do nothing*/ 57662306a36Sopenharmony_ci } 57762306a36Sopenharmony_ci } else { 57862306a36Sopenharmony_ci if (matched) 57962306a36Sopenharmony_ci set_reg(hw, v1, v2); 58062306a36Sopenharmony_ci } 58162306a36Sopenharmony_ci i = i + 2; 58262306a36Sopenharmony_ci } 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci return true; 58562306a36Sopenharmony_ci} 58662306a36Sopenharmony_ci 58762306a36Sopenharmony_cistatic bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) 58862306a36Sopenharmony_ci{ 58962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n"); 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci return rtl8723be_phy_config_with_headerfile(hw, 59462306a36Sopenharmony_ci RTL8723BEMAC_1T_ARRAY, RTL8723BEMAC_1T_ARRAYLEN, 59562306a36Sopenharmony_ci rtl_write_byte_with_val32); 59662306a36Sopenharmony_ci} 59762306a36Sopenharmony_ci 59862306a36Sopenharmony_cistatic bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, 59962306a36Sopenharmony_ci u8 configtype) 60062306a36Sopenharmony_ci{ 60162306a36Sopenharmony_ci 60262306a36Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) 60362306a36Sopenharmony_ci return rtl8723be_phy_config_with_headerfile(hw, 60462306a36Sopenharmony_ci RTL8723BEPHY_REG_1TARRAY, 60562306a36Sopenharmony_ci RTL8723BEPHY_REG_1TARRAYLEN, 60662306a36Sopenharmony_ci _rtl8723be_config_bb_reg); 60762306a36Sopenharmony_ci else if (configtype == BASEBAND_CONFIG_AGC_TAB) 60862306a36Sopenharmony_ci return rtl8723be_phy_config_with_headerfile(hw, 60962306a36Sopenharmony_ci RTL8723BEAGCTAB_1TARRAY, 61062306a36Sopenharmony_ci RTL8723BEAGCTAB_1TARRAYLEN, 61162306a36Sopenharmony_ci rtl_set_bbreg_with_dwmask); 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci return false; 61462306a36Sopenharmony_ci} 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cistatic u8 _rtl8723be_get_rate_section_index(u32 regaddr) 61762306a36Sopenharmony_ci{ 61862306a36Sopenharmony_ci u8 index = 0; 61962306a36Sopenharmony_ci 62062306a36Sopenharmony_ci switch (regaddr) { 62162306a36Sopenharmony_ci case RTXAGC_A_RATE18_06: 62262306a36Sopenharmony_ci index = 0; 62362306a36Sopenharmony_ci break; 62462306a36Sopenharmony_ci case RTXAGC_A_RATE54_24: 62562306a36Sopenharmony_ci index = 1; 62662306a36Sopenharmony_ci break; 62762306a36Sopenharmony_ci case RTXAGC_A_CCK1_MCS32: 62862306a36Sopenharmony_ci index = 2; 62962306a36Sopenharmony_ci break; 63062306a36Sopenharmony_ci case RTXAGC_B_CCK11_A_CCK2_11: 63162306a36Sopenharmony_ci index = 3; 63262306a36Sopenharmony_ci break; 63362306a36Sopenharmony_ci case RTXAGC_A_MCS03_MCS00: 63462306a36Sopenharmony_ci index = 4; 63562306a36Sopenharmony_ci break; 63662306a36Sopenharmony_ci case RTXAGC_A_MCS07_MCS04: 63762306a36Sopenharmony_ci index = 5; 63862306a36Sopenharmony_ci break; 63962306a36Sopenharmony_ci case RTXAGC_A_MCS11_MCS08: 64062306a36Sopenharmony_ci index = 6; 64162306a36Sopenharmony_ci break; 64262306a36Sopenharmony_ci case RTXAGC_A_MCS15_MCS12: 64362306a36Sopenharmony_ci index = 7; 64462306a36Sopenharmony_ci break; 64562306a36Sopenharmony_ci case RTXAGC_B_RATE18_06: 64662306a36Sopenharmony_ci index = 0; 64762306a36Sopenharmony_ci break; 64862306a36Sopenharmony_ci case RTXAGC_B_RATE54_24: 64962306a36Sopenharmony_ci index = 1; 65062306a36Sopenharmony_ci break; 65162306a36Sopenharmony_ci case RTXAGC_B_CCK1_55_MCS32: 65262306a36Sopenharmony_ci index = 2; 65362306a36Sopenharmony_ci break; 65462306a36Sopenharmony_ci case RTXAGC_B_MCS03_MCS00: 65562306a36Sopenharmony_ci index = 4; 65662306a36Sopenharmony_ci break; 65762306a36Sopenharmony_ci case RTXAGC_B_MCS07_MCS04: 65862306a36Sopenharmony_ci index = 5; 65962306a36Sopenharmony_ci break; 66062306a36Sopenharmony_ci case RTXAGC_B_MCS11_MCS08: 66162306a36Sopenharmony_ci index = 6; 66262306a36Sopenharmony_ci break; 66362306a36Sopenharmony_ci case RTXAGC_B_MCS15_MCS12: 66462306a36Sopenharmony_ci index = 7; 66562306a36Sopenharmony_ci break; 66662306a36Sopenharmony_ci default: 66762306a36Sopenharmony_ci regaddr &= 0xFFF; 66862306a36Sopenharmony_ci if (regaddr >= 0xC20 && regaddr <= 0xC4C) 66962306a36Sopenharmony_ci index = (u8)((regaddr - 0xC20) / 4); 67062306a36Sopenharmony_ci else if (regaddr >= 0xE20 && regaddr <= 0xE4C) 67162306a36Sopenharmony_ci index = (u8)((regaddr - 0xE20) / 4); 67262306a36Sopenharmony_ci break; 67362306a36Sopenharmony_ci } 67462306a36Sopenharmony_ci return index; 67562306a36Sopenharmony_ci} 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_cistatic void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw, 67862306a36Sopenharmony_ci u32 band, u32 rfpath, 67962306a36Sopenharmony_ci u32 txnum, u32 regaddr, 68062306a36Sopenharmony_ci u32 bitmask, u32 data) 68162306a36Sopenharmony_ci{ 68262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 68362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 68462306a36Sopenharmony_ci u8 rate_section = _rtl8723be_get_rate_section_index(regaddr); 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci if (band != BAND_ON_2_4G && band != BAND_ON_5G) { 68762306a36Sopenharmony_ci rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band); 68862306a36Sopenharmony_ci return; 68962306a36Sopenharmony_ci } 69062306a36Sopenharmony_ci if (rfpath > MAX_RF_PATH - 1) { 69162306a36Sopenharmony_ci rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, 69262306a36Sopenharmony_ci "Invalid RfPath %d\n", rfpath); 69362306a36Sopenharmony_ci return; 69462306a36Sopenharmony_ci } 69562306a36Sopenharmony_ci if (txnum > MAX_RF_PATH - 1) { 69662306a36Sopenharmony_ci rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum); 69762306a36Sopenharmony_ci return; 69862306a36Sopenharmony_ci } 69962306a36Sopenharmony_ci 70062306a36Sopenharmony_ci rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = 70162306a36Sopenharmony_ci data; 70262306a36Sopenharmony_ci 70362306a36Sopenharmony_ci} 70462306a36Sopenharmony_ci 70562306a36Sopenharmony_cistatic bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, 70662306a36Sopenharmony_ci u8 configtype) 70762306a36Sopenharmony_ci{ 70862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 70962306a36Sopenharmony_ci int i; 71062306a36Sopenharmony_ci u32 *phy_regarray_table_pg; 71162306a36Sopenharmony_ci u16 phy_regarray_pg_len; 71262306a36Sopenharmony_ci u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0; 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN; 71562306a36Sopenharmony_ci phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG; 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 71862306a36Sopenharmony_ci for (i = 0; i < phy_regarray_pg_len; i = i + 6) { 71962306a36Sopenharmony_ci v1 = phy_regarray_table_pg[i]; 72062306a36Sopenharmony_ci v2 = phy_regarray_table_pg[i+1]; 72162306a36Sopenharmony_ci v3 = phy_regarray_table_pg[i+2]; 72262306a36Sopenharmony_ci v4 = phy_regarray_table_pg[i+3]; 72362306a36Sopenharmony_ci v5 = phy_regarray_table_pg[i+4]; 72462306a36Sopenharmony_ci v6 = phy_regarray_table_pg[i+5]; 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci if (v1 < 0xcdcdcdcd) { 72762306a36Sopenharmony_ci if (phy_regarray_table_pg[i] == 0xfe || 72862306a36Sopenharmony_ci phy_regarray_table_pg[i] == 0xffe) 72962306a36Sopenharmony_ci mdelay(50); 73062306a36Sopenharmony_ci else 73162306a36Sopenharmony_ci _rtl8723be_store_tx_power_by_rate(hw, 73262306a36Sopenharmony_ci v1, v2, v3, v4, v5, v6); 73362306a36Sopenharmony_ci continue; 73462306a36Sopenharmony_ci } 73562306a36Sopenharmony_ci } 73662306a36Sopenharmony_ci } else { 73762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, 73862306a36Sopenharmony_ci "configtype != BaseBand_Config_PHY_REG\n"); 73962306a36Sopenharmony_ci } 74062306a36Sopenharmony_ci return true; 74162306a36Sopenharmony_ci} 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_cibool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, 74462306a36Sopenharmony_ci enum radio_path rfpath) 74562306a36Sopenharmony_ci{ 74662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 74762306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 74862306a36Sopenharmony_ci bool ret = true; 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); 75162306a36Sopenharmony_ci switch (rfpath) { 75262306a36Sopenharmony_ci case RF90_PATH_A: 75362306a36Sopenharmony_ci ret = rtl8723be_phy_config_with_headerfile(hw, 75462306a36Sopenharmony_ci RTL8723BE_RADIOA_1TARRAY, 75562306a36Sopenharmony_ci RTL8723BE_RADIOA_1TARRAYLEN, 75662306a36Sopenharmony_ci _rtl8723be_config_rf_radio_a); 75762306a36Sopenharmony_ci 75862306a36Sopenharmony_ci if (rtlhal->oem_id == RT_CID_819X_HP) 75962306a36Sopenharmony_ci _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD); 76062306a36Sopenharmony_ci break; 76162306a36Sopenharmony_ci case RF90_PATH_B: 76262306a36Sopenharmony_ci case RF90_PATH_C: 76362306a36Sopenharmony_ci break; 76462306a36Sopenharmony_ci case RF90_PATH_D: 76562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 76662306a36Sopenharmony_ci "switch case %#x not processed\n", rfpath); 76762306a36Sopenharmony_ci break; 76862306a36Sopenharmony_ci } 76962306a36Sopenharmony_ci return ret; 77062306a36Sopenharmony_ci} 77162306a36Sopenharmony_ci 77262306a36Sopenharmony_civoid rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) 77362306a36Sopenharmony_ci{ 77462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 77562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 77662306a36Sopenharmony_ci 77762306a36Sopenharmony_ci rtlphy->default_initialgain[0] = 77862306a36Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); 77962306a36Sopenharmony_ci rtlphy->default_initialgain[1] = 78062306a36Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); 78162306a36Sopenharmony_ci rtlphy->default_initialgain[2] = 78262306a36Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); 78362306a36Sopenharmony_ci rtlphy->default_initialgain[3] = 78462306a36Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 78762306a36Sopenharmony_ci "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", 78862306a36Sopenharmony_ci rtlphy->default_initialgain[0], 78962306a36Sopenharmony_ci rtlphy->default_initialgain[1], 79062306a36Sopenharmony_ci rtlphy->default_initialgain[2], 79162306a36Sopenharmony_ci rtlphy->default_initialgain[3]); 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, 79462306a36Sopenharmony_ci MASKBYTE0); 79562306a36Sopenharmony_ci rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, 79662306a36Sopenharmony_ci MASKDWORD); 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 79962306a36Sopenharmony_ci "Default framesync (0x%x) = 0x%x\n", 80062306a36Sopenharmony_ci ROFDM0_RXDETECTOR3, rtlphy->framesync); 80162306a36Sopenharmony_ci} 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_cistatic u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path, 80462306a36Sopenharmony_ci u8 rate) 80562306a36Sopenharmony_ci{ 80662306a36Sopenharmony_ci u8 rate_section = 0; 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci switch (rate) { 80962306a36Sopenharmony_ci case DESC92C_RATE1M: 81062306a36Sopenharmony_ci rate_section = 2; 81162306a36Sopenharmony_ci break; 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci case DESC92C_RATE2M: 81462306a36Sopenharmony_ci case DESC92C_RATE5_5M: 81562306a36Sopenharmony_ci if (path == RF90_PATH_A) 81662306a36Sopenharmony_ci rate_section = 3; 81762306a36Sopenharmony_ci else if (path == RF90_PATH_B) 81862306a36Sopenharmony_ci rate_section = 2; 81962306a36Sopenharmony_ci break; 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci case DESC92C_RATE11M: 82262306a36Sopenharmony_ci rate_section = 3; 82362306a36Sopenharmony_ci break; 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci case DESC92C_RATE6M: 82662306a36Sopenharmony_ci case DESC92C_RATE9M: 82762306a36Sopenharmony_ci case DESC92C_RATE12M: 82862306a36Sopenharmony_ci case DESC92C_RATE18M: 82962306a36Sopenharmony_ci rate_section = 0; 83062306a36Sopenharmony_ci break; 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci case DESC92C_RATE24M: 83362306a36Sopenharmony_ci case DESC92C_RATE36M: 83462306a36Sopenharmony_ci case DESC92C_RATE48M: 83562306a36Sopenharmony_ci case DESC92C_RATE54M: 83662306a36Sopenharmony_ci rate_section = 1; 83762306a36Sopenharmony_ci break; 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci case DESC92C_RATEMCS0: 84062306a36Sopenharmony_ci case DESC92C_RATEMCS1: 84162306a36Sopenharmony_ci case DESC92C_RATEMCS2: 84262306a36Sopenharmony_ci case DESC92C_RATEMCS3: 84362306a36Sopenharmony_ci rate_section = 4; 84462306a36Sopenharmony_ci break; 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci case DESC92C_RATEMCS4: 84762306a36Sopenharmony_ci case DESC92C_RATEMCS5: 84862306a36Sopenharmony_ci case DESC92C_RATEMCS6: 84962306a36Sopenharmony_ci case DESC92C_RATEMCS7: 85062306a36Sopenharmony_ci rate_section = 5; 85162306a36Sopenharmony_ci break; 85262306a36Sopenharmony_ci 85362306a36Sopenharmony_ci case DESC92C_RATEMCS8: 85462306a36Sopenharmony_ci case DESC92C_RATEMCS9: 85562306a36Sopenharmony_ci case DESC92C_RATEMCS10: 85662306a36Sopenharmony_ci case DESC92C_RATEMCS11: 85762306a36Sopenharmony_ci rate_section = 6; 85862306a36Sopenharmony_ci break; 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci case DESC92C_RATEMCS12: 86162306a36Sopenharmony_ci case DESC92C_RATEMCS13: 86262306a36Sopenharmony_ci case DESC92C_RATEMCS14: 86362306a36Sopenharmony_ci case DESC92C_RATEMCS15: 86462306a36Sopenharmony_ci rate_section = 7; 86562306a36Sopenharmony_ci break; 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci default: 86862306a36Sopenharmony_ci WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n"); 86962306a36Sopenharmony_ci break; 87062306a36Sopenharmony_ci } 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci return rate_section; 87362306a36Sopenharmony_ci} 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_cistatic u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw, 87662306a36Sopenharmony_ci enum band_type band, 87762306a36Sopenharmony_ci enum radio_path rfpath, u8 rate) 87862306a36Sopenharmony_ci{ 87962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 88062306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 88162306a36Sopenharmony_ci u8 shift = 0, rate_section, tx_num; 88262306a36Sopenharmony_ci s8 tx_pwr_diff = 0; 88362306a36Sopenharmony_ci 88462306a36Sopenharmony_ci rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath, 88562306a36Sopenharmony_ci rate); 88662306a36Sopenharmony_ci tx_num = RF_TX_NUM_NONIMPLEMENT; 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ci if (tx_num == RF_TX_NUM_NONIMPLEMENT) { 88962306a36Sopenharmony_ci if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15) 89062306a36Sopenharmony_ci tx_num = RF_2TX; 89162306a36Sopenharmony_ci else 89262306a36Sopenharmony_ci tx_num = RF_1TX; 89362306a36Sopenharmony_ci } 89462306a36Sopenharmony_ci 89562306a36Sopenharmony_ci switch (rate) { 89662306a36Sopenharmony_ci case DESC92C_RATE6M: 89762306a36Sopenharmony_ci case DESC92C_RATE24M: 89862306a36Sopenharmony_ci case DESC92C_RATEMCS0: 89962306a36Sopenharmony_ci case DESC92C_RATEMCS4: 90062306a36Sopenharmony_ci case DESC92C_RATEMCS8: 90162306a36Sopenharmony_ci case DESC92C_RATEMCS12: 90262306a36Sopenharmony_ci shift = 0; 90362306a36Sopenharmony_ci break; 90462306a36Sopenharmony_ci case DESC92C_RATE1M: 90562306a36Sopenharmony_ci case DESC92C_RATE2M: 90662306a36Sopenharmony_ci case DESC92C_RATE9M: 90762306a36Sopenharmony_ci case DESC92C_RATE36M: 90862306a36Sopenharmony_ci case DESC92C_RATEMCS1: 90962306a36Sopenharmony_ci case DESC92C_RATEMCS5: 91062306a36Sopenharmony_ci case DESC92C_RATEMCS9: 91162306a36Sopenharmony_ci case DESC92C_RATEMCS13: 91262306a36Sopenharmony_ci shift = 8; 91362306a36Sopenharmony_ci break; 91462306a36Sopenharmony_ci case DESC92C_RATE5_5M: 91562306a36Sopenharmony_ci case DESC92C_RATE12M: 91662306a36Sopenharmony_ci case DESC92C_RATE48M: 91762306a36Sopenharmony_ci case DESC92C_RATEMCS2: 91862306a36Sopenharmony_ci case DESC92C_RATEMCS6: 91962306a36Sopenharmony_ci case DESC92C_RATEMCS10: 92062306a36Sopenharmony_ci case DESC92C_RATEMCS14: 92162306a36Sopenharmony_ci shift = 16; 92262306a36Sopenharmony_ci break; 92362306a36Sopenharmony_ci case DESC92C_RATE11M: 92462306a36Sopenharmony_ci case DESC92C_RATE18M: 92562306a36Sopenharmony_ci case DESC92C_RATE54M: 92662306a36Sopenharmony_ci case DESC92C_RATEMCS3: 92762306a36Sopenharmony_ci case DESC92C_RATEMCS7: 92862306a36Sopenharmony_ci case DESC92C_RATEMCS11: 92962306a36Sopenharmony_ci case DESC92C_RATEMCS15: 93062306a36Sopenharmony_ci shift = 24; 93162306a36Sopenharmony_ci break; 93262306a36Sopenharmony_ci default: 93362306a36Sopenharmony_ci WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n"); 93462306a36Sopenharmony_ci break; 93562306a36Sopenharmony_ci } 93662306a36Sopenharmony_ci tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num] 93762306a36Sopenharmony_ci [rate_section] >> shift) & 0xff; 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ci return tx_pwr_diff; 94062306a36Sopenharmony_ci} 94162306a36Sopenharmony_ci 94262306a36Sopenharmony_cistatic u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path, 94362306a36Sopenharmony_ci u8 rate, u8 bandwidth, u8 channel) 94462306a36Sopenharmony_ci{ 94562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 94662306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 94762306a36Sopenharmony_ci u8 index = (channel - 1); 94862306a36Sopenharmony_ci u8 txpower = 0; 94962306a36Sopenharmony_ci u8 power_diff_byrate = 0; 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci if (channel > 14 || channel < 1) { 95262306a36Sopenharmony_ci index = 0; 95362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 95462306a36Sopenharmony_ci "Illegal channel!\n"); 95562306a36Sopenharmony_ci } 95662306a36Sopenharmony_ci if (RX_HAL_IS_CCK_RATE(rate)) 95762306a36Sopenharmony_ci txpower = rtlefuse->txpwrlevel_cck[path][index]; 95862306a36Sopenharmony_ci else if (DESC92C_RATE6M <= rate) 95962306a36Sopenharmony_ci txpower = rtlefuse->txpwrlevel_ht40_1s[path][index]; 96062306a36Sopenharmony_ci else 96162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 96262306a36Sopenharmony_ci "invalid rate\n"); 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_ci if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M && 96562306a36Sopenharmony_ci !RX_HAL_IS_CCK_RATE(rate)) 96662306a36Sopenharmony_ci txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S]; 96762306a36Sopenharmony_ci 96862306a36Sopenharmony_ci if (bandwidth == HT_CHANNEL_WIDTH_20) { 96962306a36Sopenharmony_ci if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) 97062306a36Sopenharmony_ci txpower += rtlefuse->txpwr_ht20diff[0][TX_1S]; 97162306a36Sopenharmony_ci if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) 97262306a36Sopenharmony_ci txpower += rtlefuse->txpwr_ht20diff[0][TX_2S]; 97362306a36Sopenharmony_ci } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { 97462306a36Sopenharmony_ci if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) 97562306a36Sopenharmony_ci txpower += rtlefuse->txpwr_ht40diff[0][TX_1S]; 97662306a36Sopenharmony_ci if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) 97762306a36Sopenharmony_ci txpower += rtlefuse->txpwr_ht40diff[0][TX_2S]; 97862306a36Sopenharmony_ci } 97962306a36Sopenharmony_ci 98062306a36Sopenharmony_ci if (rtlefuse->eeprom_regulatory != 2) 98162306a36Sopenharmony_ci power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw, 98262306a36Sopenharmony_ci BAND_ON_2_4G, 98362306a36Sopenharmony_ci path, rate); 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci txpower += power_diff_byrate; 98662306a36Sopenharmony_ci 98762306a36Sopenharmony_ci if (txpower > MAX_POWER_INDEX) 98862306a36Sopenharmony_ci txpower = MAX_POWER_INDEX; 98962306a36Sopenharmony_ci 99062306a36Sopenharmony_ci return txpower; 99162306a36Sopenharmony_ci} 99262306a36Sopenharmony_ci 99362306a36Sopenharmony_cistatic void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw, 99462306a36Sopenharmony_ci u8 power_index, u8 path, u8 rate) 99562306a36Sopenharmony_ci{ 99662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 99762306a36Sopenharmony_ci if (path == RF90_PATH_A) { 99862306a36Sopenharmony_ci switch (rate) { 99962306a36Sopenharmony_ci case DESC92C_RATE1M: 100062306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32, 100162306a36Sopenharmony_ci MASKBYTE1, power_index); 100262306a36Sopenharmony_ci break; 100362306a36Sopenharmony_ci case DESC92C_RATE2M: 100462306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, 100562306a36Sopenharmony_ci MASKBYTE1, power_index); 100662306a36Sopenharmony_ci break; 100762306a36Sopenharmony_ci case DESC92C_RATE5_5M: 100862306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, 100962306a36Sopenharmony_ci MASKBYTE2, power_index); 101062306a36Sopenharmony_ci break; 101162306a36Sopenharmony_ci case DESC92C_RATE11M: 101262306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, 101362306a36Sopenharmony_ci MASKBYTE3, power_index); 101462306a36Sopenharmony_ci break; 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci case DESC92C_RATE6M: 101762306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, 101862306a36Sopenharmony_ci MASKBYTE0, power_index); 101962306a36Sopenharmony_ci break; 102062306a36Sopenharmony_ci case DESC92C_RATE9M: 102162306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, 102262306a36Sopenharmony_ci MASKBYTE1, power_index); 102362306a36Sopenharmony_ci break; 102462306a36Sopenharmony_ci case DESC92C_RATE12M: 102562306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, 102662306a36Sopenharmony_ci MASKBYTE2, power_index); 102762306a36Sopenharmony_ci break; 102862306a36Sopenharmony_ci case DESC92C_RATE18M: 102962306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, 103062306a36Sopenharmony_ci MASKBYTE3, power_index); 103162306a36Sopenharmony_ci break; 103262306a36Sopenharmony_ci 103362306a36Sopenharmony_ci case DESC92C_RATE24M: 103462306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, 103562306a36Sopenharmony_ci MASKBYTE0, power_index); 103662306a36Sopenharmony_ci break; 103762306a36Sopenharmony_ci case DESC92C_RATE36M: 103862306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, 103962306a36Sopenharmony_ci MASKBYTE1, power_index); 104062306a36Sopenharmony_ci break; 104162306a36Sopenharmony_ci case DESC92C_RATE48M: 104262306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, 104362306a36Sopenharmony_ci MASKBYTE2, power_index); 104462306a36Sopenharmony_ci break; 104562306a36Sopenharmony_ci case DESC92C_RATE54M: 104662306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, 104762306a36Sopenharmony_ci MASKBYTE3, power_index); 104862306a36Sopenharmony_ci break; 104962306a36Sopenharmony_ci 105062306a36Sopenharmony_ci case DESC92C_RATEMCS0: 105162306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, 105262306a36Sopenharmony_ci MASKBYTE0, power_index); 105362306a36Sopenharmony_ci break; 105462306a36Sopenharmony_ci case DESC92C_RATEMCS1: 105562306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, 105662306a36Sopenharmony_ci MASKBYTE1, power_index); 105762306a36Sopenharmony_ci break; 105862306a36Sopenharmony_ci case DESC92C_RATEMCS2: 105962306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, 106062306a36Sopenharmony_ci MASKBYTE2, power_index); 106162306a36Sopenharmony_ci break; 106262306a36Sopenharmony_ci case DESC92C_RATEMCS3: 106362306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, 106462306a36Sopenharmony_ci MASKBYTE3, power_index); 106562306a36Sopenharmony_ci break; 106662306a36Sopenharmony_ci 106762306a36Sopenharmony_ci case DESC92C_RATEMCS4: 106862306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, 106962306a36Sopenharmony_ci MASKBYTE0, power_index); 107062306a36Sopenharmony_ci break; 107162306a36Sopenharmony_ci case DESC92C_RATEMCS5: 107262306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, 107362306a36Sopenharmony_ci MASKBYTE1, power_index); 107462306a36Sopenharmony_ci break; 107562306a36Sopenharmony_ci case DESC92C_RATEMCS6: 107662306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, 107762306a36Sopenharmony_ci MASKBYTE2, power_index); 107862306a36Sopenharmony_ci break; 107962306a36Sopenharmony_ci case DESC92C_RATEMCS7: 108062306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, 108162306a36Sopenharmony_ci MASKBYTE3, power_index); 108262306a36Sopenharmony_ci break; 108362306a36Sopenharmony_ci 108462306a36Sopenharmony_ci case DESC92C_RATEMCS8: 108562306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, 108662306a36Sopenharmony_ci MASKBYTE0, power_index); 108762306a36Sopenharmony_ci break; 108862306a36Sopenharmony_ci case DESC92C_RATEMCS9: 108962306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, 109062306a36Sopenharmony_ci MASKBYTE1, power_index); 109162306a36Sopenharmony_ci break; 109262306a36Sopenharmony_ci case DESC92C_RATEMCS10: 109362306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, 109462306a36Sopenharmony_ci MASKBYTE2, power_index); 109562306a36Sopenharmony_ci break; 109662306a36Sopenharmony_ci case DESC92C_RATEMCS11: 109762306a36Sopenharmony_ci rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, 109862306a36Sopenharmony_ci MASKBYTE3, power_index); 109962306a36Sopenharmony_ci break; 110062306a36Sopenharmony_ci 110162306a36Sopenharmony_ci default: 110262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n"); 110362306a36Sopenharmony_ci break; 110462306a36Sopenharmony_ci } 110562306a36Sopenharmony_ci } else { 110662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n"); 110762306a36Sopenharmony_ci } 110862306a36Sopenharmony_ci} 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_civoid rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) 111162306a36Sopenharmony_ci{ 111262306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 111362306a36Sopenharmony_ci u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M, 111462306a36Sopenharmony_ci DESC92C_RATE5_5M, DESC92C_RATE11M}; 111562306a36Sopenharmony_ci u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M, 111662306a36Sopenharmony_ci DESC92C_RATE12M, DESC92C_RATE18M, 111762306a36Sopenharmony_ci DESC92C_RATE24M, DESC92C_RATE36M, 111862306a36Sopenharmony_ci DESC92C_RATE48M, DESC92C_RATE54M}; 111962306a36Sopenharmony_ci u8 ht_rates_1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1, 112062306a36Sopenharmony_ci DESC92C_RATEMCS2, DESC92C_RATEMCS3, 112162306a36Sopenharmony_ci DESC92C_RATEMCS4, DESC92C_RATEMCS5, 112262306a36Sopenharmony_ci DESC92C_RATEMCS6, DESC92C_RATEMCS7}; 112362306a36Sopenharmony_ci u8 i; 112462306a36Sopenharmony_ci u8 power_index; 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_ci if (!rtlefuse->txpwr_fromeprom) 112762306a36Sopenharmony_ci return; 112862306a36Sopenharmony_ci 112962306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(cck_rates); i++) { 113062306a36Sopenharmony_ci power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, 113162306a36Sopenharmony_ci cck_rates[i], 113262306a36Sopenharmony_ci rtl_priv(hw)->phy.current_chan_bw, 113362306a36Sopenharmony_ci channel); 113462306a36Sopenharmony_ci _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, 113562306a36Sopenharmony_ci cck_rates[i]); 113662306a36Sopenharmony_ci } 113762306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ofdm_rates); i++) { 113862306a36Sopenharmony_ci power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, 113962306a36Sopenharmony_ci ofdm_rates[i], 114062306a36Sopenharmony_ci rtl_priv(hw)->phy.current_chan_bw, 114162306a36Sopenharmony_ci channel); 114262306a36Sopenharmony_ci _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, 114362306a36Sopenharmony_ci ofdm_rates[i]); 114462306a36Sopenharmony_ci } 114562306a36Sopenharmony_ci for (i = 0; i < ARRAY_SIZE(ht_rates_1t); i++) { 114662306a36Sopenharmony_ci power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A, 114762306a36Sopenharmony_ci ht_rates_1t[i], 114862306a36Sopenharmony_ci rtl_priv(hw)->phy.current_chan_bw, 114962306a36Sopenharmony_ci channel); 115062306a36Sopenharmony_ci _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A, 115162306a36Sopenharmony_ci ht_rates_1t[i]); 115262306a36Sopenharmony_ci } 115362306a36Sopenharmony_ci} 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_civoid rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) 115662306a36Sopenharmony_ci{ 115762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 115862306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 115962306a36Sopenharmony_ci enum io_type iotype; 116062306a36Sopenharmony_ci 116162306a36Sopenharmony_ci if (!is_hal_stop(rtlhal)) { 116262306a36Sopenharmony_ci switch (operation) { 116362306a36Sopenharmony_ci case SCAN_OPT_BACKUP_BAND0: 116462306a36Sopenharmony_ci iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; 116562306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, 116662306a36Sopenharmony_ci (u8 *)&iotype); 116762306a36Sopenharmony_ci 116862306a36Sopenharmony_ci break; 116962306a36Sopenharmony_ci case SCAN_OPT_RESTORE: 117062306a36Sopenharmony_ci iotype = IO_CMD_RESUME_DM_BY_SCAN; 117162306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, 117262306a36Sopenharmony_ci (u8 *)&iotype); 117362306a36Sopenharmony_ci break; 117462306a36Sopenharmony_ci default: 117562306a36Sopenharmony_ci pr_err("Unknown Scan Backup operation.\n"); 117662306a36Sopenharmony_ci break; 117762306a36Sopenharmony_ci } 117862306a36Sopenharmony_ci } 117962306a36Sopenharmony_ci} 118062306a36Sopenharmony_ci 118162306a36Sopenharmony_civoid rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw) 118262306a36Sopenharmony_ci{ 118362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 118462306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 118562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 118662306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 118762306a36Sopenharmony_ci u8 reg_bw_opmode; 118862306a36Sopenharmony_ci u8 reg_prsr_rsc; 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, 119162306a36Sopenharmony_ci "Switch to %s bandwidth\n", 119262306a36Sopenharmony_ci rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? 119362306a36Sopenharmony_ci "20MHz" : "40MHz"); 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) { 119662306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 119762306a36Sopenharmony_ci return; 119862306a36Sopenharmony_ci } 119962306a36Sopenharmony_ci 120062306a36Sopenharmony_ci reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); 120162306a36Sopenharmony_ci reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); 120262306a36Sopenharmony_ci 120362306a36Sopenharmony_ci switch (rtlphy->current_chan_bw) { 120462306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 120562306a36Sopenharmony_ci reg_bw_opmode |= BW_OPMODE_20MHZ; 120662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 120762306a36Sopenharmony_ci break; 120862306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 120962306a36Sopenharmony_ci reg_bw_opmode &= ~BW_OPMODE_20MHZ; 121062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 121162306a36Sopenharmony_ci reg_prsr_rsc = (reg_prsr_rsc & 0x90) | 121262306a36Sopenharmony_ci (mac->cur_40_prime_sc << 5); 121362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); 121462306a36Sopenharmony_ci break; 121562306a36Sopenharmony_ci default: 121662306a36Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 121762306a36Sopenharmony_ci rtlphy->current_chan_bw); 121862306a36Sopenharmony_ci break; 121962306a36Sopenharmony_ci } 122062306a36Sopenharmony_ci 122162306a36Sopenharmony_ci switch (rtlphy->current_chan_bw) { 122262306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 122362306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); 122462306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); 122562306a36Sopenharmony_ci /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/ 122662306a36Sopenharmony_ci break; 122762306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 122862306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); 122962306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); 123062306a36Sopenharmony_ci 123162306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, 123262306a36Sopenharmony_ci (mac->cur_40_prime_sc >> 1)); 123362306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); 123462306a36Sopenharmony_ci /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/ 123562306a36Sopenharmony_ci 123662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), 123762306a36Sopenharmony_ci (mac->cur_40_prime_sc == 123862306a36Sopenharmony_ci HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); 123962306a36Sopenharmony_ci break; 124062306a36Sopenharmony_ci default: 124162306a36Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 124262306a36Sopenharmony_ci rtlphy->current_chan_bw); 124362306a36Sopenharmony_ci break; 124462306a36Sopenharmony_ci } 124562306a36Sopenharmony_ci rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); 124662306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 124762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "\n"); 124862306a36Sopenharmony_ci} 124962306a36Sopenharmony_ci 125062306a36Sopenharmony_civoid rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw, 125162306a36Sopenharmony_ci enum nl80211_channel_type ch_type) 125262306a36Sopenharmony_ci{ 125362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 125462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 125562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 125662306a36Sopenharmony_ci u8 tmp_bw = rtlphy->current_chan_bw; 125762306a36Sopenharmony_ci 125862306a36Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 125962306a36Sopenharmony_ci return; 126062306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = true; 126162306a36Sopenharmony_ci if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 126262306a36Sopenharmony_ci rtl8723be_phy_set_bw_mode_callback(hw); 126362306a36Sopenharmony_ci } else { 126462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 126562306a36Sopenharmony_ci "false driver sleep or unload\n"); 126662306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 126762306a36Sopenharmony_ci rtlphy->current_chan_bw = tmp_bw; 126862306a36Sopenharmony_ci } 126962306a36Sopenharmony_ci} 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_civoid rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw) 127262306a36Sopenharmony_ci{ 127362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 127462306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 127562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 127662306a36Sopenharmony_ci u32 delay = 0; 127762306a36Sopenharmony_ci 127862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, 127962306a36Sopenharmony_ci "switch to channel%d\n", rtlphy->current_channel); 128062306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) 128162306a36Sopenharmony_ci return; 128262306a36Sopenharmony_ci do { 128362306a36Sopenharmony_ci if (!rtlphy->sw_chnl_inprogress) 128462306a36Sopenharmony_ci break; 128562306a36Sopenharmony_ci if (!_rtl8723be_phy_sw_chnl_step_by_step(hw, 128662306a36Sopenharmony_ci rtlphy->current_channel, 128762306a36Sopenharmony_ci &rtlphy->sw_chnl_stage, 128862306a36Sopenharmony_ci &rtlphy->sw_chnl_step, 128962306a36Sopenharmony_ci &delay)) { 129062306a36Sopenharmony_ci if (delay > 0) 129162306a36Sopenharmony_ci mdelay(delay); 129262306a36Sopenharmony_ci else 129362306a36Sopenharmony_ci continue; 129462306a36Sopenharmony_ci } else { 129562306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 129662306a36Sopenharmony_ci } 129762306a36Sopenharmony_ci break; 129862306a36Sopenharmony_ci } while (true); 129962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); 130062306a36Sopenharmony_ci} 130162306a36Sopenharmony_ci 130262306a36Sopenharmony_ciu8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw) 130362306a36Sopenharmony_ci{ 130462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 130562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 130662306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci if (rtlphy->sw_chnl_inprogress) 130962306a36Sopenharmony_ci return 0; 131062306a36Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 131162306a36Sopenharmony_ci return 0; 131262306a36Sopenharmony_ci WARN_ONCE((rtlphy->current_channel > 14), 131362306a36Sopenharmony_ci "rtl8723be: WIRELESS_MODE_G but channel>14"); 131462306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = true; 131562306a36Sopenharmony_ci rtlphy->sw_chnl_stage = 0; 131662306a36Sopenharmony_ci rtlphy->sw_chnl_step = 0; 131762306a36Sopenharmony_ci if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 131862306a36Sopenharmony_ci rtl8723be_phy_sw_chnl_callback(hw); 131962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, 132062306a36Sopenharmony_ci "sw_chnl_inprogress false schedule workitem current channel %d\n", 132162306a36Sopenharmony_ci rtlphy->current_channel); 132262306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 132362306a36Sopenharmony_ci } else { 132462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, 132562306a36Sopenharmony_ci "sw_chnl_inprogress false driver sleep or unload\n"); 132662306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 132762306a36Sopenharmony_ci } 132862306a36Sopenharmony_ci return 1; 132962306a36Sopenharmony_ci} 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_cistatic bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 133262306a36Sopenharmony_ci u8 channel, u8 *stage, 133362306a36Sopenharmony_ci u8 *step, u32 *delay) 133462306a36Sopenharmony_ci{ 133562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 133662306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 133762306a36Sopenharmony_ci struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; 133862306a36Sopenharmony_ci u32 precommoncmdcnt; 133962306a36Sopenharmony_ci struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; 134062306a36Sopenharmony_ci u32 postcommoncmdcnt; 134162306a36Sopenharmony_ci struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; 134262306a36Sopenharmony_ci u32 rfdependcmdcnt; 134362306a36Sopenharmony_ci struct swchnlcmd *currentcmd = NULL; 134462306a36Sopenharmony_ci u8 rfpath; 134562306a36Sopenharmony_ci u8 num_total_rfpath = rtlphy->num_total_rfpath; 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_ci precommoncmdcnt = 0; 134862306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 134962306a36Sopenharmony_ci MAX_PRECMD_CNT, 135062306a36Sopenharmony_ci CMDID_SET_TXPOWEROWER_LEVEL, 135162306a36Sopenharmony_ci 0, 0, 0); 135262306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 135362306a36Sopenharmony_ci MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); 135462306a36Sopenharmony_ci 135562306a36Sopenharmony_ci postcommoncmdcnt = 0; 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, 135862306a36Sopenharmony_ci MAX_POSTCMD_CNT, CMDID_END, 135962306a36Sopenharmony_ci 0, 0, 0); 136062306a36Sopenharmony_ci 136162306a36Sopenharmony_ci rfdependcmdcnt = 0; 136262306a36Sopenharmony_ci 136362306a36Sopenharmony_ci WARN_ONCE((channel < 1 || channel > 14), 136462306a36Sopenharmony_ci "rtl8723be: illegal channel for Zebra: %d\n", channel); 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 136762306a36Sopenharmony_ci MAX_RFDEPENDCMD_CNT, 136862306a36Sopenharmony_ci CMDID_RF_WRITEREG, 136962306a36Sopenharmony_ci RF_CHNLBW, channel, 10); 137062306a36Sopenharmony_ci 137162306a36Sopenharmony_ci rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 137262306a36Sopenharmony_ci MAX_RFDEPENDCMD_CNT, 137362306a36Sopenharmony_ci CMDID_END, 0, 0, 0); 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_ci do { 137662306a36Sopenharmony_ci switch (*stage) { 137762306a36Sopenharmony_ci case 0: 137862306a36Sopenharmony_ci currentcmd = &precommoncmd[*step]; 137962306a36Sopenharmony_ci break; 138062306a36Sopenharmony_ci case 1: 138162306a36Sopenharmony_ci currentcmd = &rfdependcmd[*step]; 138262306a36Sopenharmony_ci break; 138362306a36Sopenharmony_ci case 2: 138462306a36Sopenharmony_ci currentcmd = &postcommoncmd[*step]; 138562306a36Sopenharmony_ci break; 138662306a36Sopenharmony_ci default: 138762306a36Sopenharmony_ci pr_err("Invalid 'stage' = %d, Check it!\n", 138862306a36Sopenharmony_ci *stage); 138962306a36Sopenharmony_ci return true; 139062306a36Sopenharmony_ci } 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci if (currentcmd->cmdid == CMDID_END) { 139362306a36Sopenharmony_ci if ((*stage) == 2) { 139462306a36Sopenharmony_ci return true; 139562306a36Sopenharmony_ci } else { 139662306a36Sopenharmony_ci (*stage)++; 139762306a36Sopenharmony_ci (*step) = 0; 139862306a36Sopenharmony_ci continue; 139962306a36Sopenharmony_ci } 140062306a36Sopenharmony_ci } 140162306a36Sopenharmony_ci 140262306a36Sopenharmony_ci switch (currentcmd->cmdid) { 140362306a36Sopenharmony_ci case CMDID_SET_TXPOWEROWER_LEVEL: 140462306a36Sopenharmony_ci rtl8723be_phy_set_txpower_level(hw, channel); 140562306a36Sopenharmony_ci break; 140662306a36Sopenharmony_ci case CMDID_WRITEPORT_ULONG: 140762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, currentcmd->para1, 140862306a36Sopenharmony_ci currentcmd->para2); 140962306a36Sopenharmony_ci break; 141062306a36Sopenharmony_ci case CMDID_WRITEPORT_USHORT: 141162306a36Sopenharmony_ci rtl_write_word(rtlpriv, currentcmd->para1, 141262306a36Sopenharmony_ci (u16)currentcmd->para2); 141362306a36Sopenharmony_ci break; 141462306a36Sopenharmony_ci case CMDID_WRITEPORT_UCHAR: 141562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, currentcmd->para1, 141662306a36Sopenharmony_ci (u8)currentcmd->para2); 141762306a36Sopenharmony_ci break; 141862306a36Sopenharmony_ci case CMDID_RF_WRITEREG: 141962306a36Sopenharmony_ci for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { 142062306a36Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath] = 142162306a36Sopenharmony_ci ((rtlphy->rfreg_chnlval[rfpath] & 142262306a36Sopenharmony_ci 0xfffffc00) | currentcmd->para2); 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci rtl_set_rfreg(hw, (enum radio_path)rfpath, 142562306a36Sopenharmony_ci currentcmd->para1, 142662306a36Sopenharmony_ci RFREG_OFFSET_MASK, 142762306a36Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath]); 142862306a36Sopenharmony_ci } 142962306a36Sopenharmony_ci break; 143062306a36Sopenharmony_ci default: 143162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 143262306a36Sopenharmony_ci "switch case %#x not processed\n", 143362306a36Sopenharmony_ci currentcmd->cmdid); 143462306a36Sopenharmony_ci break; 143562306a36Sopenharmony_ci } 143662306a36Sopenharmony_ci 143762306a36Sopenharmony_ci break; 143862306a36Sopenharmony_ci } while (true); 143962306a36Sopenharmony_ci 144062306a36Sopenharmony_ci (*delay) = currentcmd->msdelay; 144162306a36Sopenharmony_ci (*step)++; 144262306a36Sopenharmony_ci return false; 144362306a36Sopenharmony_ci} 144462306a36Sopenharmony_ci 144562306a36Sopenharmony_cistatic u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw) 144662306a36Sopenharmony_ci{ 144762306a36Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c, tmp; 144862306a36Sopenharmony_ci u8 result = 0x00; 144962306a36Sopenharmony_ci 145062306a36Sopenharmony_ci /* leave IQK mode */ 145162306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 145262306a36Sopenharmony_ci /* switch to path A */ 145362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000); 145462306a36Sopenharmony_ci /* enable path A PA in TXIQK mode */ 145562306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); 145662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000); 145762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f); 145862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87); 145962306a36Sopenharmony_ci 146062306a36Sopenharmony_ci /* 1. TX IQK */ 146162306a36Sopenharmony_ci /* path-A IQK setting */ 146262306a36Sopenharmony_ci /* IQK setting */ 146362306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); 146462306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 146562306a36Sopenharmony_ci /* path-A IQK setting */ 146662306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); 146762306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 146862306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 146962306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea); 147262306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000); 147362306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); 147462306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); 147562306a36Sopenharmony_ci /* LO calibration setting */ 147662306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); 147762306a36Sopenharmony_ci /* enter IQK mode */ 147862306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 147962306a36Sopenharmony_ci 148062306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 148162306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); 148262306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 148562306a36Sopenharmony_ci 148662306a36Sopenharmony_ci /* leave IQK mode */ 148762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_ci /* Check failed */ 149062306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); 149162306a36Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); 149262306a36Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); 149362306a36Sopenharmony_ci 149462306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 149562306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 149662306a36Sopenharmony_ci (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) 149762306a36Sopenharmony_ci result |= 0x01; 149862306a36Sopenharmony_ci else /* if Tx not OK, ignore Rx */ 149962306a36Sopenharmony_ci return result; 150062306a36Sopenharmony_ci 150162306a36Sopenharmony_ci /* Allen 20131125 */ 150262306a36Sopenharmony_ci tmp = (reg_e9c & 0x03FF0000) >> 16; 150362306a36Sopenharmony_ci if ((tmp & 0x200) > 0) 150462306a36Sopenharmony_ci tmp = 0x400 - tmp; 150562306a36Sopenharmony_ci 150662306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 150762306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && 150862306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && 150962306a36Sopenharmony_ci (tmp < 0xf)) 151062306a36Sopenharmony_ci result |= 0x01; 151162306a36Sopenharmony_ci else /* if Tx not OK, ignore Rx */ 151262306a36Sopenharmony_ci return result; 151362306a36Sopenharmony_ci 151462306a36Sopenharmony_ci return result; 151562306a36Sopenharmony_ci} 151662306a36Sopenharmony_ci 151762306a36Sopenharmony_ci/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ 151862306a36Sopenharmony_cistatic u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw) 151962306a36Sopenharmony_ci{ 152062306a36Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp; 152162306a36Sopenharmony_ci u8 result = 0x00; 152262306a36Sopenharmony_ci 152362306a36Sopenharmony_ci /* leave IQK mode */ 152462306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci /* switch to path A */ 152762306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000); 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci /* 1 Get TXIMR setting */ 153062306a36Sopenharmony_ci /* modify RXIQK mode table */ 153162306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1); 153262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 153362306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); 153462306a36Sopenharmony_ci /* LNA2 off, PA on for Dcut */ 153562306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7); 153662306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 153762306a36Sopenharmony_ci 153862306a36Sopenharmony_ci /* IQK setting */ 153962306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); 154062306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 154162306a36Sopenharmony_ci 154262306a36Sopenharmony_ci /* path-A IQK setting */ 154362306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); 154462306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 154562306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 154662306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 154762306a36Sopenharmony_ci 154862306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0); 154962306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000); 155062306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); 155162306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); 155262306a36Sopenharmony_ci 155362306a36Sopenharmony_ci /* LO calibration setting */ 155462306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); 155562306a36Sopenharmony_ci 155662306a36Sopenharmony_ci /* enter IQK mode */ 155762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 155862306a36Sopenharmony_ci 155962306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 156062306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); 156162306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_ci /* leave IQK mode */ 156662306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 156762306a36Sopenharmony_ci 156862306a36Sopenharmony_ci /* Check failed */ 156962306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 157062306a36Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); 157162306a36Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); 157262306a36Sopenharmony_ci 157362306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 157462306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 157562306a36Sopenharmony_ci (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) 157662306a36Sopenharmony_ci result |= 0x01; 157762306a36Sopenharmony_ci else /* if Tx not OK, ignore Rx */ 157862306a36Sopenharmony_ci return result; 157962306a36Sopenharmony_ci 158062306a36Sopenharmony_ci /* Allen 20131125 */ 158162306a36Sopenharmony_ci tmp = (reg_e9c & 0x03FF0000) >> 16; 158262306a36Sopenharmony_ci if ((tmp & 0x200) > 0) 158362306a36Sopenharmony_ci tmp = 0x400 - tmp; 158462306a36Sopenharmony_ci 158562306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 158662306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && 158762306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && 158862306a36Sopenharmony_ci (tmp < 0xf)) 158962306a36Sopenharmony_ci result |= 0x01; 159062306a36Sopenharmony_ci else /* if Tx not OK, ignore Rx */ 159162306a36Sopenharmony_ci return result; 159262306a36Sopenharmony_ci 159362306a36Sopenharmony_ci u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) | 159462306a36Sopenharmony_ci ((reg_e9c & 0x3FF0000) >> 16); 159562306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp); 159662306a36Sopenharmony_ci 159762306a36Sopenharmony_ci /* 1 RX IQK */ 159862306a36Sopenharmony_ci /* modify RXIQK mode table */ 159962306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 160062306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1); 160162306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 160262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); 160362306a36Sopenharmony_ci /* LAN2 on, PA off for Dcut */ 160462306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77); 160562306a36Sopenharmony_ci 160662306a36Sopenharmony_ci /* PA, PAD setting */ 160762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80); 160862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f); 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci /* IQK setting */ 161162306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 161262306a36Sopenharmony_ci 161362306a36Sopenharmony_ci /* path-A IQK setting */ 161462306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 161562306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c); 161662306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 161762306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 161862306a36Sopenharmony_ci 161962306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000); 162062306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f); 162162306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); 162262306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); 162362306a36Sopenharmony_ci 162462306a36Sopenharmony_ci /* LO calibration setting */ 162562306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1); 162662306a36Sopenharmony_ci 162762306a36Sopenharmony_ci /* enter IQK mode */ 162862306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci /* One shot, path A LOK & IQK */ 163162306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); 163262306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 163362306a36Sopenharmony_ci 163462306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 163562306a36Sopenharmony_ci 163662306a36Sopenharmony_ci /* leave IQK mode */ 163762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 163862306a36Sopenharmony_ci 163962306a36Sopenharmony_ci /* Check failed */ 164062306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 164162306a36Sopenharmony_ci reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci /* leave IQK mode */ 164462306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 164562306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780); 164662306a36Sopenharmony_ci 164762306a36Sopenharmony_ci /* Allen 20131125 */ 164862306a36Sopenharmony_ci tmp = (reg_eac & 0x03FF0000) >> 16; 164962306a36Sopenharmony_ci if ((tmp & 0x200) > 0) 165062306a36Sopenharmony_ci tmp = 0x400 - tmp; 165162306a36Sopenharmony_ci /* if Tx is OK, check whether Rx is OK */ 165262306a36Sopenharmony_ci if (!(reg_eac & BIT(27)) && 165362306a36Sopenharmony_ci (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && 165462306a36Sopenharmony_ci (((reg_eac & 0x03FF0000) >> 16) != 0x36)) 165562306a36Sopenharmony_ci result |= 0x02; 165662306a36Sopenharmony_ci else if (!(reg_eac & BIT(27)) && 165762306a36Sopenharmony_ci (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) && 165862306a36Sopenharmony_ci (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) && 165962306a36Sopenharmony_ci (tmp < 0xf)) 166062306a36Sopenharmony_ci result |= 0x02; 166162306a36Sopenharmony_ci 166262306a36Sopenharmony_ci return result; 166362306a36Sopenharmony_ci} 166462306a36Sopenharmony_ci 166562306a36Sopenharmony_cistatic u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw) 166662306a36Sopenharmony_ci{ 166762306a36Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c, tmp; 166862306a36Sopenharmony_ci u8 result = 0x00; 166962306a36Sopenharmony_ci 167062306a36Sopenharmony_ci /* leave IQK mode */ 167162306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 167262306a36Sopenharmony_ci /* switch to path B */ 167362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280); 167462306a36Sopenharmony_ci 167562306a36Sopenharmony_ci /* enable path B PA in TXIQK mode */ 167662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020); 167762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1); 167862306a36Sopenharmony_ci 167962306a36Sopenharmony_ci /* 1 Tx IQK */ 168062306a36Sopenharmony_ci /* IQK setting */ 168162306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); 168262306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 168362306a36Sopenharmony_ci /* path-A IQK setting */ 168462306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); 168562306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 168662306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 168762306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 168862306a36Sopenharmony_ci 168962306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea); 169062306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000); 169162306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); 169262306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_ci /* LO calibration setting */ 169562306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); 169662306a36Sopenharmony_ci 169762306a36Sopenharmony_ci /* enter IQK mode */ 169862306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 169962306a36Sopenharmony_ci 170062306a36Sopenharmony_ci /* One shot, path B LOK & IQK */ 170162306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); 170262306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_ci /* leave IQK mode */ 170762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 170862306a36Sopenharmony_ci 170962306a36Sopenharmony_ci /* Check failed */ 171062306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 171162306a36Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); 171262306a36Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); 171362306a36Sopenharmony_ci 171462306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 171562306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 171662306a36Sopenharmony_ci (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) 171762306a36Sopenharmony_ci result |= 0x01; 171862306a36Sopenharmony_ci else 171962306a36Sopenharmony_ci return result; 172062306a36Sopenharmony_ci 172162306a36Sopenharmony_ci /* Allen 20131125 */ 172262306a36Sopenharmony_ci tmp = (reg_e9c & 0x03FF0000) >> 16; 172362306a36Sopenharmony_ci if ((tmp & 0x200) > 0) 172462306a36Sopenharmony_ci tmp = 0x400 - tmp; 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 172762306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && 172862306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && 172962306a36Sopenharmony_ci (tmp < 0xf)) 173062306a36Sopenharmony_ci result |= 0x01; 173162306a36Sopenharmony_ci else 173262306a36Sopenharmony_ci return result; 173362306a36Sopenharmony_ci 173462306a36Sopenharmony_ci return result; 173562306a36Sopenharmony_ci} 173662306a36Sopenharmony_ci 173762306a36Sopenharmony_ci/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ 173862306a36Sopenharmony_cistatic u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw) 173962306a36Sopenharmony_ci{ 174062306a36Sopenharmony_ci u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp; 174162306a36Sopenharmony_ci u8 result = 0x00; 174262306a36Sopenharmony_ci 174362306a36Sopenharmony_ci /* leave IQK mode */ 174462306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 174562306a36Sopenharmony_ci /* switch to path B */ 174662306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280); 174762306a36Sopenharmony_ci 174862306a36Sopenharmony_ci /* 1 Get TXIMR setting */ 174962306a36Sopenharmony_ci /* modify RXIQK mode table */ 175062306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); 175162306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 175262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); 175362306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7); 175462306a36Sopenharmony_ci 175562306a36Sopenharmony_ci /* open PA S1 & SMIXER */ 175662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020); 175762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed); 175862306a36Sopenharmony_ci 175962306a36Sopenharmony_ci /* IQK setting */ 176062306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); 176162306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 176262306a36Sopenharmony_ci 176362306a36Sopenharmony_ci /* path-B IQK setting */ 176462306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); 176562306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 176662306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 176762306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 176862306a36Sopenharmony_ci 176962306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0); 177062306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000); 177162306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); 177262306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); 177362306a36Sopenharmony_ci 177462306a36Sopenharmony_ci /* LO calibration setting */ 177562306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); 177662306a36Sopenharmony_ci /* enter IQK mode */ 177762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 177862306a36Sopenharmony_ci 177962306a36Sopenharmony_ci /* One shot, path B TXIQK @ RXIQK */ 178062306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); 178162306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 178262306a36Sopenharmony_ci 178362306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci /* leave IQK mode */ 178662306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 178762306a36Sopenharmony_ci /* Check failed */ 178862306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 178962306a36Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); 179062306a36Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); 179162306a36Sopenharmony_ci 179262306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 179362306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 179462306a36Sopenharmony_ci (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) 179562306a36Sopenharmony_ci result |= 0x01; 179662306a36Sopenharmony_ci else /* if Tx not OK, ignore Rx */ 179762306a36Sopenharmony_ci return result; 179862306a36Sopenharmony_ci 179962306a36Sopenharmony_ci /* Allen 20131125 */ 180062306a36Sopenharmony_ci tmp = (reg_e9c & 0x03FF0000) >> 16; 180162306a36Sopenharmony_ci if ((tmp & 0x200) > 0) 180262306a36Sopenharmony_ci tmp = 0x400 - tmp; 180362306a36Sopenharmony_ci 180462306a36Sopenharmony_ci if (!(reg_eac & BIT(28)) && 180562306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && 180662306a36Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && 180762306a36Sopenharmony_ci (tmp < 0xf)) 180862306a36Sopenharmony_ci result |= 0x01; 180962306a36Sopenharmony_ci else 181062306a36Sopenharmony_ci return result; 181162306a36Sopenharmony_ci 181262306a36Sopenharmony_ci u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) | 181362306a36Sopenharmony_ci ((reg_e9c & 0x3FF0000) >> 16); 181462306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp); 181562306a36Sopenharmony_ci 181662306a36Sopenharmony_ci /* 1 RX IQK */ 181762306a36Sopenharmony_ci 181862306a36Sopenharmony_ci /* <20121009, Kordan> RF Mode = 3 */ 181962306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 182062306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1); 182162306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 182262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); 182362306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77); 182462306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0); 182562306a36Sopenharmony_ci 182662306a36Sopenharmony_ci /* open PA S1 & close SMIXER */ 182762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020); 182862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd); 182962306a36Sopenharmony_ci 183062306a36Sopenharmony_ci /* IQK setting */ 183162306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 183262306a36Sopenharmony_ci 183362306a36Sopenharmony_ci /* path-B IQK setting */ 183462306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 183562306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c); 183662306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 183762306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 183862306a36Sopenharmony_ci 183962306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000); 184062306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f); 184162306a36Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); 184262306a36Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); 184362306a36Sopenharmony_ci 184462306a36Sopenharmony_ci /* LO calibration setting */ 184562306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1); 184662306a36Sopenharmony_ci /* enter IQK mode */ 184762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 184862306a36Sopenharmony_ci 184962306a36Sopenharmony_ci /* One shot, path B LOK & IQK */ 185062306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); 185162306a36Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 185262306a36Sopenharmony_ci 185362306a36Sopenharmony_ci mdelay(IQK_DELAY_TIME); 185462306a36Sopenharmony_ci 185562306a36Sopenharmony_ci /* leave IQK mode */ 185662306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 185762306a36Sopenharmony_ci /* Check failed */ 185862306a36Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 185962306a36Sopenharmony_ci reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); 186062306a36Sopenharmony_ci 186162306a36Sopenharmony_ci /* Allen 20131125 */ 186262306a36Sopenharmony_ci tmp = (reg_eac & 0x03FF0000) >> 16; 186362306a36Sopenharmony_ci if ((tmp & 0x200) > 0) 186462306a36Sopenharmony_ci tmp = 0x400 - tmp; 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci /* if Tx is OK, check whether Rx is OK */ 186762306a36Sopenharmony_ci if (!(reg_eac & BIT(27)) && 186862306a36Sopenharmony_ci (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && 186962306a36Sopenharmony_ci (((reg_eac & 0x03FF0000) >> 16) != 0x36)) 187062306a36Sopenharmony_ci result |= 0x02; 187162306a36Sopenharmony_ci else if (!(reg_eac & BIT(27)) && 187262306a36Sopenharmony_ci (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) && 187362306a36Sopenharmony_ci (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) && 187462306a36Sopenharmony_ci (tmp < 0xf)) 187562306a36Sopenharmony_ci result |= 0x02; 187662306a36Sopenharmony_ci else 187762306a36Sopenharmony_ci return result; 187862306a36Sopenharmony_ci 187962306a36Sopenharmony_ci return result; 188062306a36Sopenharmony_ci} 188162306a36Sopenharmony_ci 188262306a36Sopenharmony_cistatic void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, 188362306a36Sopenharmony_ci bool b_iqk_ok, 188462306a36Sopenharmony_ci long result[][8], 188562306a36Sopenharmony_ci u8 final_candidate, 188662306a36Sopenharmony_ci bool btxonly) 188762306a36Sopenharmony_ci{ 188862306a36Sopenharmony_ci u32 oldval_1, x, tx1_a, reg; 188962306a36Sopenharmony_ci long y, tx1_c; 189062306a36Sopenharmony_ci 189162306a36Sopenharmony_ci if (final_candidate == 0xFF) { 189262306a36Sopenharmony_ci return; 189362306a36Sopenharmony_ci } else if (b_iqk_ok) { 189462306a36Sopenharmony_ci oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 189562306a36Sopenharmony_ci MASKDWORD) >> 22) & 0x3FF; 189662306a36Sopenharmony_ci x = result[final_candidate][4]; 189762306a36Sopenharmony_ci if ((x & 0x00000200) != 0) 189862306a36Sopenharmony_ci x = x | 0xFFFFFC00; 189962306a36Sopenharmony_ci tx1_a = (x * oldval_1) >> 8; 190062306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); 190162306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), 190262306a36Sopenharmony_ci ((x * oldval_1 >> 7) & 0x1)); 190362306a36Sopenharmony_ci y = result[final_candidate][5]; 190462306a36Sopenharmony_ci if ((y & 0x00000200) != 0) 190562306a36Sopenharmony_ci y = y | 0xFFFFFC00; 190662306a36Sopenharmony_ci tx1_c = (y * oldval_1) >> 8; 190762306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, 190862306a36Sopenharmony_ci ((tx1_c & 0x3C0) >> 6)); 190962306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, 191062306a36Sopenharmony_ci (tx1_c & 0x3F)); 191162306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), 191262306a36Sopenharmony_ci ((y * oldval_1 >> 7) & 0x1)); 191362306a36Sopenharmony_ci if (btxonly) 191462306a36Sopenharmony_ci return; 191562306a36Sopenharmony_ci reg = result[final_candidate][6]; 191662306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); 191762306a36Sopenharmony_ci reg = result[final_candidate][7] & 0x3F; 191862306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); 191962306a36Sopenharmony_ci reg = (result[final_candidate][7] >> 6) & 0xF; 192062306a36Sopenharmony_ci /* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */ 192162306a36Sopenharmony_ci } 192262306a36Sopenharmony_ci} 192362306a36Sopenharmony_ci 192462306a36Sopenharmony_cistatic bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw, 192562306a36Sopenharmony_ci long result[][8], u8 c1, u8 c2) 192662306a36Sopenharmony_ci{ 192762306a36Sopenharmony_ci u32 i, j, diff, simularity_bitmap, bound = 0; 192862306a36Sopenharmony_ci 192962306a36Sopenharmony_ci u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ 193062306a36Sopenharmony_ci bool bresult = true; /* is2t = true*/ 193162306a36Sopenharmony_ci s32 tmp1 = 0, tmp2 = 0; 193262306a36Sopenharmony_ci 193362306a36Sopenharmony_ci bound = 8; 193462306a36Sopenharmony_ci 193562306a36Sopenharmony_ci simularity_bitmap = 0; 193662306a36Sopenharmony_ci 193762306a36Sopenharmony_ci for (i = 0; i < bound; i++) { 193862306a36Sopenharmony_ci if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) { 193962306a36Sopenharmony_ci if ((result[c1][i] & 0x00000200) != 0) 194062306a36Sopenharmony_ci tmp1 = result[c1][i] | 0xFFFFFC00; 194162306a36Sopenharmony_ci else 194262306a36Sopenharmony_ci tmp1 = result[c1][i]; 194362306a36Sopenharmony_ci 194462306a36Sopenharmony_ci if ((result[c2][i] & 0x00000200) != 0) 194562306a36Sopenharmony_ci tmp2 = result[c2][i] | 0xFFFFFC00; 194662306a36Sopenharmony_ci else 194762306a36Sopenharmony_ci tmp2 = result[c2][i]; 194862306a36Sopenharmony_ci } else { 194962306a36Sopenharmony_ci tmp1 = result[c1][i]; 195062306a36Sopenharmony_ci tmp2 = result[c2][i]; 195162306a36Sopenharmony_ci } 195262306a36Sopenharmony_ci 195362306a36Sopenharmony_ci diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); 195462306a36Sopenharmony_ci 195562306a36Sopenharmony_ci if (diff > MAX_TOLERANCE) { 195662306a36Sopenharmony_ci if ((i == 2 || i == 6) && !simularity_bitmap) { 195762306a36Sopenharmony_ci if (result[c1][i] + result[c1][i + 1] == 0) 195862306a36Sopenharmony_ci final_candidate[(i / 4)] = c2; 195962306a36Sopenharmony_ci else if (result[c2][i] + result[c2][i + 1] == 0) 196062306a36Sopenharmony_ci final_candidate[(i / 4)] = c1; 196162306a36Sopenharmony_ci else 196262306a36Sopenharmony_ci simularity_bitmap |= (1 << i); 196362306a36Sopenharmony_ci } else 196462306a36Sopenharmony_ci simularity_bitmap |= (1 << i); 196562306a36Sopenharmony_ci } 196662306a36Sopenharmony_ci } 196762306a36Sopenharmony_ci 196862306a36Sopenharmony_ci if (simularity_bitmap == 0) { 196962306a36Sopenharmony_ci for (i = 0; i < (bound / 4); i++) { 197062306a36Sopenharmony_ci if (final_candidate[i] != 0xFF) { 197162306a36Sopenharmony_ci for (j = i * 4; j < (i + 1) * 4 - 2; j++) 197262306a36Sopenharmony_ci result[3][j] = 197362306a36Sopenharmony_ci result[final_candidate[i]][j]; 197462306a36Sopenharmony_ci bresult = false; 197562306a36Sopenharmony_ci } 197662306a36Sopenharmony_ci } 197762306a36Sopenharmony_ci return bresult; 197862306a36Sopenharmony_ci } else { 197962306a36Sopenharmony_ci if (!(simularity_bitmap & 0x03)) { /* path A TX OK */ 198062306a36Sopenharmony_ci for (i = 0; i < 2; i++) 198162306a36Sopenharmony_ci result[3][i] = result[c1][i]; 198262306a36Sopenharmony_ci } 198362306a36Sopenharmony_ci if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */ 198462306a36Sopenharmony_ci for (i = 2; i < 4; i++) 198562306a36Sopenharmony_ci result[3][i] = result[c1][i]; 198662306a36Sopenharmony_ci } 198762306a36Sopenharmony_ci if (!(simularity_bitmap & 0x30)) { /* path B TX OK */ 198862306a36Sopenharmony_ci for (i = 4; i < 6; i++) 198962306a36Sopenharmony_ci result[3][i] = result[c1][i]; 199062306a36Sopenharmony_ci } 199162306a36Sopenharmony_ci if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */ 199262306a36Sopenharmony_ci for (i = 6; i < 8; i++) 199362306a36Sopenharmony_ci result[3][i] = result[c1][i]; 199462306a36Sopenharmony_ci } 199562306a36Sopenharmony_ci return false; 199662306a36Sopenharmony_ci } 199762306a36Sopenharmony_ci} 199862306a36Sopenharmony_ci 199962306a36Sopenharmony_cistatic void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, 200062306a36Sopenharmony_ci long result[][8], u8 t, bool is2t) 200162306a36Sopenharmony_ci{ 200262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 200362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 200462306a36Sopenharmony_ci u32 i; 200562306a36Sopenharmony_ci u8 patha_ok, pathb_ok; 200662306a36Sopenharmony_ci u32 adda_reg[IQK_ADDA_REG_NUM] = { 200762306a36Sopenharmony_ci 0x85c, 0xe6c, 0xe70, 0xe74, 200862306a36Sopenharmony_ci 0xe78, 0xe7c, 0xe80, 0xe84, 200962306a36Sopenharmony_ci 0xe88, 0xe8c, 0xed0, 0xed4, 201062306a36Sopenharmony_ci 0xed8, 0xedc, 0xee0, 0xeec 201162306a36Sopenharmony_ci }; 201262306a36Sopenharmony_ci 201362306a36Sopenharmony_ci u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { 201462306a36Sopenharmony_ci 0x522, 0x550, 0x551, 0x040 201562306a36Sopenharmony_ci }; 201662306a36Sopenharmony_ci u32 iqk_bb_reg[IQK_BB_REG_NUM] = { 201762306a36Sopenharmony_ci ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, 201862306a36Sopenharmony_ci RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c, 201962306a36Sopenharmony_ci 0x870, 0x860, 202062306a36Sopenharmony_ci 0x864, 0xa04 202162306a36Sopenharmony_ci }; 202262306a36Sopenharmony_ci const u32 retrycount = 2; 202362306a36Sopenharmony_ci 202462306a36Sopenharmony_ci u32 path_sel_bb;/* path_sel_rf */ 202562306a36Sopenharmony_ci 202662306a36Sopenharmony_ci u8 tmp_reg_c50, tmp_reg_c58; 202762306a36Sopenharmony_ci 202862306a36Sopenharmony_ci tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0); 202962306a36Sopenharmony_ci tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0); 203062306a36Sopenharmony_ci 203162306a36Sopenharmony_ci if (t == 0) { 203262306a36Sopenharmony_ci rtl8723_save_adda_registers(hw, adda_reg, 203362306a36Sopenharmony_ci rtlphy->adda_backup, 16); 203462306a36Sopenharmony_ci rtl8723_phy_save_mac_registers(hw, iqk_mac_reg, 203562306a36Sopenharmony_ci rtlphy->iqk_mac_backup); 203662306a36Sopenharmony_ci rtl8723_save_adda_registers(hw, iqk_bb_reg, 203762306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 203862306a36Sopenharmony_ci IQK_BB_REG_NUM); 203962306a36Sopenharmony_ci } 204062306a36Sopenharmony_ci rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t); 204162306a36Sopenharmony_ci if (t == 0) { 204262306a36Sopenharmony_ci rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw, 204362306a36Sopenharmony_ci RFPGA0_XA_HSSIPARAMETER1, 204462306a36Sopenharmony_ci BIT(8)); 204562306a36Sopenharmony_ci } 204662306a36Sopenharmony_ci 204762306a36Sopenharmony_ci path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD); 204862306a36Sopenharmony_ci 204962306a36Sopenharmony_ci rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg, 205062306a36Sopenharmony_ci rtlphy->iqk_mac_backup); 205162306a36Sopenharmony_ci /*BB Setting*/ 205262306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf); 205362306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); 205462306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); 205562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); 205662306a36Sopenharmony_ci 205762306a36Sopenharmony_ci /* path A TX IQK */ 205862306a36Sopenharmony_ci for (i = 0; i < retrycount; i++) { 205962306a36Sopenharmony_ci patha_ok = _rtl8723be_phy_path_a_iqk(hw); 206062306a36Sopenharmony_ci if (patha_ok == 0x01) { 206162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 206262306a36Sopenharmony_ci "Path A Tx IQK Success!!\n"); 206362306a36Sopenharmony_ci result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & 206462306a36Sopenharmony_ci 0x3FF0000) >> 16; 206562306a36Sopenharmony_ci result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 206662306a36Sopenharmony_ci 0x3FF0000) >> 16; 206762306a36Sopenharmony_ci break; 206862306a36Sopenharmony_ci } else { 206962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 207062306a36Sopenharmony_ci "Path A Tx IQK Fail!!\n"); 207162306a36Sopenharmony_ci } 207262306a36Sopenharmony_ci } 207362306a36Sopenharmony_ci /* path A RX IQK */ 207462306a36Sopenharmony_ci for (i = 0; i < retrycount; i++) { 207562306a36Sopenharmony_ci patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw); 207662306a36Sopenharmony_ci if (patha_ok == 0x03) { 207762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 207862306a36Sopenharmony_ci "Path A Rx IQK Success!!\n"); 207962306a36Sopenharmony_ci result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & 208062306a36Sopenharmony_ci 0x3FF0000) >> 16; 208162306a36Sopenharmony_ci result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & 208262306a36Sopenharmony_ci 0x3FF0000) >> 16; 208362306a36Sopenharmony_ci break; 208462306a36Sopenharmony_ci } 208562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 208662306a36Sopenharmony_ci "Path A Rx IQK Fail!!\n"); 208762306a36Sopenharmony_ci } 208862306a36Sopenharmony_ci 208962306a36Sopenharmony_ci if (0x00 == patha_ok) 209062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n"); 209162306a36Sopenharmony_ci 209262306a36Sopenharmony_ci if (is2t) { 209362306a36Sopenharmony_ci /* path B TX IQK */ 209462306a36Sopenharmony_ci for (i = 0; i < retrycount; i++) { 209562306a36Sopenharmony_ci pathb_ok = _rtl8723be_phy_path_b_iqk(hw); 209662306a36Sopenharmony_ci if (pathb_ok == 0x01) { 209762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 209862306a36Sopenharmony_ci "Path B Tx IQK Success!!\n"); 209962306a36Sopenharmony_ci result[t][4] = (rtl_get_bbreg(hw, 0xe94, 210062306a36Sopenharmony_ci MASKDWORD) & 210162306a36Sopenharmony_ci 0x3FF0000) >> 16; 210262306a36Sopenharmony_ci result[t][5] = (rtl_get_bbreg(hw, 0xe9c, 210362306a36Sopenharmony_ci MASKDWORD) & 210462306a36Sopenharmony_ci 0x3FF0000) >> 16; 210562306a36Sopenharmony_ci break; 210662306a36Sopenharmony_ci } 210762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 210862306a36Sopenharmony_ci "Path B Tx IQK Fail!!\n"); 210962306a36Sopenharmony_ci } 211062306a36Sopenharmony_ci /* path B RX IQK */ 211162306a36Sopenharmony_ci for (i = 0; i < retrycount; i++) { 211262306a36Sopenharmony_ci pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw); 211362306a36Sopenharmony_ci if (pathb_ok == 0x03) { 211462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 211562306a36Sopenharmony_ci "Path B Rx IQK Success!!\n"); 211662306a36Sopenharmony_ci result[t][6] = (rtl_get_bbreg(hw, 0xea4, 211762306a36Sopenharmony_ci MASKDWORD) & 211862306a36Sopenharmony_ci 0x3FF0000) >> 16; 211962306a36Sopenharmony_ci result[t][7] = (rtl_get_bbreg(hw, 0xeac, 212062306a36Sopenharmony_ci MASKDWORD) & 212162306a36Sopenharmony_ci 0x3FF0000) >> 16; 212262306a36Sopenharmony_ci break; 212362306a36Sopenharmony_ci } 212462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 212562306a36Sopenharmony_ci "Path B Rx IQK Fail!!\n"); 212662306a36Sopenharmony_ci } 212762306a36Sopenharmony_ci } 212862306a36Sopenharmony_ci 212962306a36Sopenharmony_ci /* Back to BB mode, load original value */ 213062306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0); 213162306a36Sopenharmony_ci 213262306a36Sopenharmony_ci if (t != 0) { 213362306a36Sopenharmony_ci rtl8723_phy_reload_adda_registers(hw, adda_reg, 213462306a36Sopenharmony_ci rtlphy->adda_backup, 16); 213562306a36Sopenharmony_ci rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg, 213662306a36Sopenharmony_ci rtlphy->iqk_mac_backup); 213762306a36Sopenharmony_ci rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg, 213862306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 213962306a36Sopenharmony_ci IQK_BB_REG_NUM); 214062306a36Sopenharmony_ci 214162306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb); 214262306a36Sopenharmony_ci /*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/ 214362306a36Sopenharmony_ci 214462306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50); 214562306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50); 214662306a36Sopenharmony_ci if (is2t) { 214762306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50); 214862306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58); 214962306a36Sopenharmony_ci } 215062306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00); 215162306a36Sopenharmony_ci rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00); 215262306a36Sopenharmony_ci } 215362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n"); 215462306a36Sopenharmony_ci} 215562306a36Sopenharmony_ci 215662306a36Sopenharmony_cistatic u8 _get_right_chnl_place_for_iqk(u8 chnl) 215762306a36Sopenharmony_ci{ 215862306a36Sopenharmony_ci u8 channel_all[TARGET_CHNL_NUM_2G_5G] = { 215962306a36Sopenharmony_ci 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 216062306a36Sopenharmony_ci 13, 14, 36, 38, 40, 42, 44, 46, 216162306a36Sopenharmony_ci 48, 50, 52, 54, 56, 58, 60, 62, 64, 216262306a36Sopenharmony_ci 100, 102, 104, 106, 108, 110, 216362306a36Sopenharmony_ci 112, 114, 116, 118, 120, 122, 216462306a36Sopenharmony_ci 124, 126, 128, 130, 132, 134, 136, 216562306a36Sopenharmony_ci 138, 140, 149, 151, 153, 155, 157, 216662306a36Sopenharmony_ci 159, 161, 163, 165}; 216762306a36Sopenharmony_ci u8 place = chnl; 216862306a36Sopenharmony_ci 216962306a36Sopenharmony_ci if (chnl > 14) { 217062306a36Sopenharmony_ci for (place = 14; place < sizeof(channel_all); place++) { 217162306a36Sopenharmony_ci if (channel_all[place] == chnl) 217262306a36Sopenharmony_ci return place - 13; 217362306a36Sopenharmony_ci } 217462306a36Sopenharmony_ci } 217562306a36Sopenharmony_ci return 0; 217662306a36Sopenharmony_ci} 217762306a36Sopenharmony_ci 217862306a36Sopenharmony_cistatic void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) 217962306a36Sopenharmony_ci{ 218062306a36Sopenharmony_ci u8 tmpreg; 218162306a36Sopenharmony_ci u32 rf_a_mode = 0, rf_b_mode = 0; 218262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 218362306a36Sopenharmony_ci 218462306a36Sopenharmony_ci tmpreg = rtl_read_byte(rtlpriv, 0xd03); 218562306a36Sopenharmony_ci 218662306a36Sopenharmony_ci if ((tmpreg & 0x70) != 0) 218762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); 218862306a36Sopenharmony_ci else 218962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 219062306a36Sopenharmony_ci 219162306a36Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 219262306a36Sopenharmony_ci rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); 219362306a36Sopenharmony_ci 219462306a36Sopenharmony_ci if (is2t) 219562306a36Sopenharmony_ci rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, 219662306a36Sopenharmony_ci MASK12BITS); 219762306a36Sopenharmony_ci 219862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, 219962306a36Sopenharmony_ci (rf_a_mode & 0x8FFFF) | 0x10000); 220062306a36Sopenharmony_ci 220162306a36Sopenharmony_ci if (is2t) 220262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, 220362306a36Sopenharmony_ci (rf_b_mode & 0x8FFFF) | 0x10000); 220462306a36Sopenharmony_ci } 220562306a36Sopenharmony_ci rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); 220662306a36Sopenharmony_ci 220762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0); 220862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a); 220962306a36Sopenharmony_ci 221062306a36Sopenharmony_ci /* In order not to disturb BT music when wifi init.(1ant NIC only) */ 221162306a36Sopenharmony_ci /*mdelay(100);*/ 221262306a36Sopenharmony_ci /* In order not to disturb BT music when wifi init.(1ant NIC only) */ 221362306a36Sopenharmony_ci mdelay(50); 221462306a36Sopenharmony_ci 221562306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0); 221662306a36Sopenharmony_ci 221762306a36Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 221862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg); 221962306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); 222062306a36Sopenharmony_ci 222162306a36Sopenharmony_ci if (is2t) 222262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, 222362306a36Sopenharmony_ci MASK12BITS, rf_b_mode); 222462306a36Sopenharmony_ci } else { 222562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 222662306a36Sopenharmony_ci } 222762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); 222862306a36Sopenharmony_ci} 222962306a36Sopenharmony_ci 223062306a36Sopenharmony_cistatic void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, 223162306a36Sopenharmony_ci bool bmain, bool is2t) 223262306a36Sopenharmony_ci{ 223362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 223462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); 223562306a36Sopenharmony_ci 223662306a36Sopenharmony_ci if (bmain) /* left antenna */ 223762306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1); 223862306a36Sopenharmony_ci else 223962306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2); 224062306a36Sopenharmony_ci} 224162306a36Sopenharmony_ci 224262306a36Sopenharmony_ci#undef IQK_ADDA_REG_NUM 224362306a36Sopenharmony_ci#undef IQK_DELAY_TIME 224462306a36Sopenharmony_ci/* IQK is merge from Merge Temp */ 224562306a36Sopenharmony_civoid rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) 224662306a36Sopenharmony_ci{ 224762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 224862306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 224962306a36Sopenharmony_ci long result[4][8]; 225062306a36Sopenharmony_ci u8 i, final_candidate, idx; 225162306a36Sopenharmony_ci bool b_patha_ok, b_pathb_ok; 225262306a36Sopenharmony_ci long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4; 225362306a36Sopenharmony_ci long reg_tmp = 0; 225462306a36Sopenharmony_ci bool is12simular, is13simular, is23simular; 225562306a36Sopenharmony_ci u32 iqk_bb_reg[9] = { 225662306a36Sopenharmony_ci ROFDM0_XARXIQIMBALANCE, 225762306a36Sopenharmony_ci ROFDM0_XBRXIQIMBALANCE, 225862306a36Sopenharmony_ci ROFDM0_ECCATHRESHOLD, 225962306a36Sopenharmony_ci ROFDM0_AGCRSSITABLE, 226062306a36Sopenharmony_ci ROFDM0_XATXIQIMBALANCE, 226162306a36Sopenharmony_ci ROFDM0_XBTXIQIMBALANCE, 226262306a36Sopenharmony_ci ROFDM0_XCTXAFE, 226362306a36Sopenharmony_ci ROFDM0_XDTXAFE, 226462306a36Sopenharmony_ci ROFDM0_RXIQEXTANTA 226562306a36Sopenharmony_ci }; 226662306a36Sopenharmony_ci u32 path_sel_bb = 0; /* path_sel_rf = 0 */ 226762306a36Sopenharmony_ci 226862306a36Sopenharmony_ci if (rtlphy->lck_inprogress) 226962306a36Sopenharmony_ci return; 227062306a36Sopenharmony_ci 227162306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.iqk_lock); 227262306a36Sopenharmony_ci rtlphy->lck_inprogress = true; 227362306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.iqk_lock); 227462306a36Sopenharmony_ci 227562306a36Sopenharmony_ci if (b_recovery) { 227662306a36Sopenharmony_ci rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg, 227762306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 9); 227862306a36Sopenharmony_ci goto label_done; 227962306a36Sopenharmony_ci } 228062306a36Sopenharmony_ci /* Save RF Path */ 228162306a36Sopenharmony_ci path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD); 228262306a36Sopenharmony_ci /* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */ 228362306a36Sopenharmony_ci 228462306a36Sopenharmony_ci for (i = 0; i < 8; i++) { 228562306a36Sopenharmony_ci result[0][i] = 0; 228662306a36Sopenharmony_ci result[1][i] = 0; 228762306a36Sopenharmony_ci result[2][i] = 0; 228862306a36Sopenharmony_ci result[3][i] = 0; 228962306a36Sopenharmony_ci } 229062306a36Sopenharmony_ci final_candidate = 0xff; 229162306a36Sopenharmony_ci b_patha_ok = false; 229262306a36Sopenharmony_ci b_pathb_ok = false; 229362306a36Sopenharmony_ci is12simular = false; 229462306a36Sopenharmony_ci is23simular = false; 229562306a36Sopenharmony_ci is13simular = false; 229662306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 229762306a36Sopenharmony_ci _rtl8723be_phy_iq_calibrate(hw, result, i, true); 229862306a36Sopenharmony_ci if (i == 1) { 229962306a36Sopenharmony_ci is12simular = _rtl8723be_phy_simularity_compare(hw, 230062306a36Sopenharmony_ci result, 230162306a36Sopenharmony_ci 0, 1); 230262306a36Sopenharmony_ci if (is12simular) { 230362306a36Sopenharmony_ci final_candidate = 0; 230462306a36Sopenharmony_ci break; 230562306a36Sopenharmony_ci } 230662306a36Sopenharmony_ci } 230762306a36Sopenharmony_ci if (i == 2) { 230862306a36Sopenharmony_ci is13simular = _rtl8723be_phy_simularity_compare(hw, 230962306a36Sopenharmony_ci result, 231062306a36Sopenharmony_ci 0, 2); 231162306a36Sopenharmony_ci if (is13simular) { 231262306a36Sopenharmony_ci final_candidate = 0; 231362306a36Sopenharmony_ci break; 231462306a36Sopenharmony_ci } 231562306a36Sopenharmony_ci is23simular = _rtl8723be_phy_simularity_compare(hw, 231662306a36Sopenharmony_ci result, 231762306a36Sopenharmony_ci 1, 2); 231862306a36Sopenharmony_ci if (is23simular) { 231962306a36Sopenharmony_ci final_candidate = 1; 232062306a36Sopenharmony_ci } else { 232162306a36Sopenharmony_ci for (i = 0; i < 8; i++) 232262306a36Sopenharmony_ci reg_tmp += result[3][i]; 232362306a36Sopenharmony_ci 232462306a36Sopenharmony_ci if (reg_tmp != 0) 232562306a36Sopenharmony_ci final_candidate = 3; 232662306a36Sopenharmony_ci else 232762306a36Sopenharmony_ci final_candidate = 0xFF; 232862306a36Sopenharmony_ci } 232962306a36Sopenharmony_ci } 233062306a36Sopenharmony_ci } 233162306a36Sopenharmony_ci for (i = 0; i < 4; i++) { 233262306a36Sopenharmony_ci reg_e94 = result[i][0]; 233362306a36Sopenharmony_ci reg_e9c = result[i][1]; 233462306a36Sopenharmony_ci reg_ea4 = result[i][2]; 233562306a36Sopenharmony_ci reg_eb4 = result[i][4]; 233662306a36Sopenharmony_ci reg_ebc = result[i][5]; 233762306a36Sopenharmony_ci reg_ec4 = result[i][6]; 233862306a36Sopenharmony_ci } 233962306a36Sopenharmony_ci if (final_candidate != 0xff) { 234062306a36Sopenharmony_ci reg_e94 = result[final_candidate][0]; 234162306a36Sopenharmony_ci rtlphy->reg_e94 = reg_e94; 234262306a36Sopenharmony_ci reg_e9c = result[final_candidate][1]; 234362306a36Sopenharmony_ci rtlphy->reg_e9c = reg_e9c; 234462306a36Sopenharmony_ci reg_ea4 = result[final_candidate][2]; 234562306a36Sopenharmony_ci reg_eb4 = result[final_candidate][4]; 234662306a36Sopenharmony_ci rtlphy->reg_eb4 = reg_eb4; 234762306a36Sopenharmony_ci reg_ebc = result[final_candidate][5]; 234862306a36Sopenharmony_ci rtlphy->reg_ebc = reg_ebc; 234962306a36Sopenharmony_ci reg_ec4 = result[final_candidate][6]; 235062306a36Sopenharmony_ci b_patha_ok = true; 235162306a36Sopenharmony_ci b_pathb_ok = true; 235262306a36Sopenharmony_ci } else { 235362306a36Sopenharmony_ci rtlphy->reg_e94 = 0x100; 235462306a36Sopenharmony_ci rtlphy->reg_eb4 = 0x100; 235562306a36Sopenharmony_ci rtlphy->reg_e9c = 0x0; 235662306a36Sopenharmony_ci rtlphy->reg_ebc = 0x0; 235762306a36Sopenharmony_ci } 235862306a36Sopenharmony_ci if (reg_e94 != 0) 235962306a36Sopenharmony_ci rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, 236062306a36Sopenharmony_ci final_candidate, 236162306a36Sopenharmony_ci (reg_ea4 == 0)); 236262306a36Sopenharmony_ci if (reg_eb4 != 0) 236362306a36Sopenharmony_ci _rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result, 236462306a36Sopenharmony_ci final_candidate, 236562306a36Sopenharmony_ci (reg_ec4 == 0)); 236662306a36Sopenharmony_ci 236762306a36Sopenharmony_ci idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel); 236862306a36Sopenharmony_ci 236962306a36Sopenharmony_ci if (final_candidate < 4) { 237062306a36Sopenharmony_ci for (i = 0; i < IQK_MATRIX_REG_NUM; i++) 237162306a36Sopenharmony_ci rtlphy->iqk_matrix[idx].value[0][i] = 237262306a36Sopenharmony_ci result[final_candidate][i]; 237362306a36Sopenharmony_ci rtlphy->iqk_matrix[idx].iqk_done = true; 237462306a36Sopenharmony_ci 237562306a36Sopenharmony_ci } 237662306a36Sopenharmony_ci rtl8723_save_adda_registers(hw, iqk_bb_reg, 237762306a36Sopenharmony_ci rtlphy->iqk_bb_backup, 9); 237862306a36Sopenharmony_ci 237962306a36Sopenharmony_ci rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb); 238062306a36Sopenharmony_ci /* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */ 238162306a36Sopenharmony_ci 238262306a36Sopenharmony_cilabel_done: 238362306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.iqk_lock); 238462306a36Sopenharmony_ci rtlphy->lck_inprogress = false; 238562306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.iqk_lock); 238662306a36Sopenharmony_ci} 238762306a36Sopenharmony_ci 238862306a36Sopenharmony_civoid rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw) 238962306a36Sopenharmony_ci{ 239062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 239162306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 239262306a36Sopenharmony_ci struct rtl_hal *rtlhal = &rtlpriv->rtlhal; 239362306a36Sopenharmony_ci u32 timeout = 2000, timecount = 0; 239462306a36Sopenharmony_ci 239562306a36Sopenharmony_ci while (rtlpriv->mac80211.act_scanning && timecount < timeout) { 239662306a36Sopenharmony_ci udelay(50); 239762306a36Sopenharmony_ci timecount += 50; 239862306a36Sopenharmony_ci } 239962306a36Sopenharmony_ci 240062306a36Sopenharmony_ci rtlphy->lck_inprogress = true; 240162306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_IQK, 240262306a36Sopenharmony_ci "LCK:Start!!! currentband %x delay %d ms\n", 240362306a36Sopenharmony_ci rtlhal->current_bandtype, timecount); 240462306a36Sopenharmony_ci 240562306a36Sopenharmony_ci _rtl8723be_phy_lc_calibrate(hw, false); 240662306a36Sopenharmony_ci 240762306a36Sopenharmony_ci rtlphy->lck_inprogress = false; 240862306a36Sopenharmony_ci} 240962306a36Sopenharmony_ci 241062306a36Sopenharmony_civoid rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) 241162306a36Sopenharmony_ci{ 241262306a36Sopenharmony_ci _rtl8723be_phy_set_rfpath_switch(hw, bmain, true); 241362306a36Sopenharmony_ci} 241462306a36Sopenharmony_ci 241562306a36Sopenharmony_cibool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) 241662306a36Sopenharmony_ci{ 241762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 241862306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 241962306a36Sopenharmony_ci bool b_postprocessing = false; 242062306a36Sopenharmony_ci 242162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 242262306a36Sopenharmony_ci "-->IO Cmd(%#x), set_io_inprogress(%d)\n", 242362306a36Sopenharmony_ci iotype, rtlphy->set_io_inprogress); 242462306a36Sopenharmony_ci do { 242562306a36Sopenharmony_ci switch (iotype) { 242662306a36Sopenharmony_ci case IO_CMD_RESUME_DM_BY_SCAN: 242762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 242862306a36Sopenharmony_ci "[IO CMD] Resume DM after scan.\n"); 242962306a36Sopenharmony_ci b_postprocessing = true; 243062306a36Sopenharmony_ci break; 243162306a36Sopenharmony_ci case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 243262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 243362306a36Sopenharmony_ci "[IO CMD] Pause DM before scan.\n"); 243462306a36Sopenharmony_ci b_postprocessing = true; 243562306a36Sopenharmony_ci break; 243662306a36Sopenharmony_ci default: 243762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 243862306a36Sopenharmony_ci "switch case %#x not processed\n", iotype); 243962306a36Sopenharmony_ci break; 244062306a36Sopenharmony_ci } 244162306a36Sopenharmony_ci } while (false); 244262306a36Sopenharmony_ci if (b_postprocessing && !rtlphy->set_io_inprogress) { 244362306a36Sopenharmony_ci rtlphy->set_io_inprogress = true; 244462306a36Sopenharmony_ci rtlphy->current_io_type = iotype; 244562306a36Sopenharmony_ci } else { 244662306a36Sopenharmony_ci return false; 244762306a36Sopenharmony_ci } 244862306a36Sopenharmony_ci rtl8723be_phy_set_io(hw); 244962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); 245062306a36Sopenharmony_ci return true; 245162306a36Sopenharmony_ci} 245262306a36Sopenharmony_ci 245362306a36Sopenharmony_cistatic void rtl8723be_phy_set_io(struct ieee80211_hw *hw) 245462306a36Sopenharmony_ci{ 245562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 245662306a36Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 245762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 245862306a36Sopenharmony_ci 245962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 246062306a36Sopenharmony_ci "--->Cmd(%#x), set_io_inprogress(%d)\n", 246162306a36Sopenharmony_ci rtlphy->current_io_type, rtlphy->set_io_inprogress); 246262306a36Sopenharmony_ci switch (rtlphy->current_io_type) { 246362306a36Sopenharmony_ci case IO_CMD_RESUME_DM_BY_SCAN: 246462306a36Sopenharmony_ci dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; 246562306a36Sopenharmony_ci /*rtl92c_dm_write_dig(hw);*/ 246662306a36Sopenharmony_ci rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel); 246762306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83); 246862306a36Sopenharmony_ci break; 246962306a36Sopenharmony_ci case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 247062306a36Sopenharmony_ci rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; 247162306a36Sopenharmony_ci dm_digtable->cur_igvalue = 0x17; 247262306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40); 247362306a36Sopenharmony_ci break; 247462306a36Sopenharmony_ci default: 247562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 247662306a36Sopenharmony_ci "switch case %#x not processed\n", 247762306a36Sopenharmony_ci rtlphy->current_io_type); 247862306a36Sopenharmony_ci break; 247962306a36Sopenharmony_ci } 248062306a36Sopenharmony_ci rtlphy->set_io_inprogress = false; 248162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 248262306a36Sopenharmony_ci "(%#x)\n", rtlphy->current_io_type); 248362306a36Sopenharmony_ci} 248462306a36Sopenharmony_ci 248562306a36Sopenharmony_cistatic void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw) 248662306a36Sopenharmony_ci{ 248762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 248862306a36Sopenharmony_ci 248962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); 249062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 249162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 249262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 249362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 249462306a36Sopenharmony_ci} 249562306a36Sopenharmony_ci 249662306a36Sopenharmony_cistatic void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw) 249762306a36Sopenharmony_ci{ 249862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 249962306a36Sopenharmony_ci 250062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 250162306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 250262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 250362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); 250462306a36Sopenharmony_ci} 250562306a36Sopenharmony_ci 250662306a36Sopenharmony_cistatic bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, 250762306a36Sopenharmony_ci enum rf_pwrstate rfpwr_state) 250862306a36Sopenharmony_ci{ 250962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 251062306a36Sopenharmony_ci struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 251162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 251262306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 251362306a36Sopenharmony_ci bool bresult = true; 251462306a36Sopenharmony_ci u8 i, queue_id; 251562306a36Sopenharmony_ci struct rtl8192_tx_ring *ring = NULL; 251662306a36Sopenharmony_ci 251762306a36Sopenharmony_ci switch (rfpwr_state) { 251862306a36Sopenharmony_ci case ERFON: 251962306a36Sopenharmony_ci if ((ppsc->rfpwr_state == ERFOFF) && 252062306a36Sopenharmony_ci RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { 252162306a36Sopenharmony_ci bool rtstatus; 252262306a36Sopenharmony_ci u32 initializecount = 0; 252362306a36Sopenharmony_ci do { 252462306a36Sopenharmony_ci initializecount++; 252562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 252662306a36Sopenharmony_ci "IPS Set eRf nic enable\n"); 252762306a36Sopenharmony_ci rtstatus = rtl_ps_enable_nic(hw); 252862306a36Sopenharmony_ci } while (!rtstatus && (initializecount < 10)); 252962306a36Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 253062306a36Sopenharmony_ci } else { 253162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 253262306a36Sopenharmony_ci "Set ERFON slept:%d ms\n", 253362306a36Sopenharmony_ci jiffies_to_msecs(jiffies - 253462306a36Sopenharmony_ci ppsc->last_sleep_jiffies)); 253562306a36Sopenharmony_ci ppsc->last_awake_jiffies = jiffies; 253662306a36Sopenharmony_ci rtl8723be_phy_set_rf_on(hw); 253762306a36Sopenharmony_ci } 253862306a36Sopenharmony_ci if (mac->link_state == MAC80211_LINKED) 253962306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK); 254062306a36Sopenharmony_ci else 254162306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); 254262306a36Sopenharmony_ci 254362306a36Sopenharmony_ci break; 254462306a36Sopenharmony_ci 254562306a36Sopenharmony_ci case ERFOFF: 254662306a36Sopenharmony_ci for (queue_id = 0, i = 0; 254762306a36Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 254862306a36Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 254962306a36Sopenharmony_ci /* Don't check BEACON Q. 255062306a36Sopenharmony_ci * BEACON Q is always not empty, 255162306a36Sopenharmony_ci * because '_rtl8723be_cmd_send_packet' 255262306a36Sopenharmony_ci */ 255362306a36Sopenharmony_ci if (queue_id == BEACON_QUEUE || 255462306a36Sopenharmony_ci skb_queue_len(&ring->queue) == 0) { 255562306a36Sopenharmony_ci queue_id++; 255662306a36Sopenharmony_ci continue; 255762306a36Sopenharmony_ci } else { 255862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 255962306a36Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", 256062306a36Sopenharmony_ci (i + 1), queue_id, 256162306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 256262306a36Sopenharmony_ci 256362306a36Sopenharmony_ci udelay(10); 256462306a36Sopenharmony_ci i++; 256562306a36Sopenharmony_ci } 256662306a36Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 256762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 256862306a36Sopenharmony_ci "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", 256962306a36Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 257062306a36Sopenharmony_ci queue_id, 257162306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 257262306a36Sopenharmony_ci break; 257362306a36Sopenharmony_ci } 257462306a36Sopenharmony_ci } 257562306a36Sopenharmony_ci 257662306a36Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { 257762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 257862306a36Sopenharmony_ci "IPS Set eRf nic disable\n"); 257962306a36Sopenharmony_ci rtl_ps_disable_nic(hw); 258062306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 258162306a36Sopenharmony_ci } else { 258262306a36Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { 258362306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 258462306a36Sopenharmony_ci LED_CTL_NO_LINK); 258562306a36Sopenharmony_ci } else { 258662306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 258762306a36Sopenharmony_ci LED_CTL_POWER_OFF); 258862306a36Sopenharmony_ci } 258962306a36Sopenharmony_ci } 259062306a36Sopenharmony_ci break; 259162306a36Sopenharmony_ci 259262306a36Sopenharmony_ci case ERFSLEEP: 259362306a36Sopenharmony_ci if (ppsc->rfpwr_state == ERFOFF) 259462306a36Sopenharmony_ci break; 259562306a36Sopenharmony_ci for (queue_id = 0, i = 0; 259662306a36Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 259762306a36Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 259862306a36Sopenharmony_ci if (skb_queue_len(&ring->queue) == 0) { 259962306a36Sopenharmony_ci queue_id++; 260062306a36Sopenharmony_ci continue; 260162306a36Sopenharmony_ci } else { 260262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 260362306a36Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", 260462306a36Sopenharmony_ci (i + 1), queue_id, 260562306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 260662306a36Sopenharmony_ci 260762306a36Sopenharmony_ci udelay(10); 260862306a36Sopenharmony_ci i++; 260962306a36Sopenharmony_ci } 261062306a36Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 261162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 261262306a36Sopenharmony_ci "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", 261362306a36Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 261462306a36Sopenharmony_ci queue_id, 261562306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 261662306a36Sopenharmony_ci break; 261762306a36Sopenharmony_ci } 261862306a36Sopenharmony_ci } 261962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 262062306a36Sopenharmony_ci "Set ERFSLEEP awaked:%d ms\n", 262162306a36Sopenharmony_ci jiffies_to_msecs(jiffies - 262262306a36Sopenharmony_ci ppsc->last_awake_jiffies)); 262362306a36Sopenharmony_ci ppsc->last_sleep_jiffies = jiffies; 262462306a36Sopenharmony_ci _rtl8723be_phy_set_rf_sleep(hw); 262562306a36Sopenharmony_ci break; 262662306a36Sopenharmony_ci 262762306a36Sopenharmony_ci default: 262862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 262962306a36Sopenharmony_ci "switch case %#x not processed\n", rfpwr_state); 263062306a36Sopenharmony_ci bresult = false; 263162306a36Sopenharmony_ci break; 263262306a36Sopenharmony_ci } 263362306a36Sopenharmony_ci if (bresult) 263462306a36Sopenharmony_ci ppsc->rfpwr_state = rfpwr_state; 263562306a36Sopenharmony_ci return bresult; 263662306a36Sopenharmony_ci} 263762306a36Sopenharmony_ci 263862306a36Sopenharmony_cibool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, 263962306a36Sopenharmony_ci enum rf_pwrstate rfpwr_state) 264062306a36Sopenharmony_ci{ 264162306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 264262306a36Sopenharmony_ci 264362306a36Sopenharmony_ci bool bresult = false; 264462306a36Sopenharmony_ci 264562306a36Sopenharmony_ci if (rfpwr_state == ppsc->rfpwr_state) 264662306a36Sopenharmony_ci return bresult; 264762306a36Sopenharmony_ci bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state); 264862306a36Sopenharmony_ci return bresult; 264962306a36Sopenharmony_ci} 2650