18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 2009-2014 Realtek Corporation.*/ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "../wifi.h" 58c2ecf20Sopenharmony_ci#include "../pci.h" 68c2ecf20Sopenharmony_ci#include "../ps.h" 78c2ecf20Sopenharmony_ci#include "reg.h" 88c2ecf20Sopenharmony_ci#include "def.h" 98c2ecf20Sopenharmony_ci#include "phy.h" 108c2ecf20Sopenharmony_ci#include "rf.h" 118c2ecf20Sopenharmony_ci#include "dm.h" 128c2ecf20Sopenharmony_ci#include "table.h" 138c2ecf20Sopenharmony_ci 148c2ecf20Sopenharmony_cistatic u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, 158c2ecf20Sopenharmony_ci enum radio_path rfpath, u32 offset); 168c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, 178c2ecf20Sopenharmony_ci enum radio_path rfpath, u32 offset, 188c2ecf20Sopenharmony_ci u32 data); 198c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw); 208c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); 218c2ecf20Sopenharmony_cistatic bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw, 228c2ecf20Sopenharmony_ci u8 configtype); 238c2ecf20Sopenharmony_cistatic bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw, 248c2ecf20Sopenharmony_ci u8 configtype); 258c2ecf20Sopenharmony_cistatic void phy_init_bb_rf_register_def(struct ieee80211_hw *hw); 268c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, 278c2ecf20Sopenharmony_ci u32 cmdtableidx, u32 cmdtablesz, 288c2ecf20Sopenharmony_ci enum swchnlcmd_id cmdid, 298c2ecf20Sopenharmony_ci u32 para1, u32 para2, 308c2ecf20Sopenharmony_ci u32 msdelay); 318c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 328c2ecf20Sopenharmony_ci u8 channel, u8 *stage, 338c2ecf20Sopenharmony_ci u8 *step, u32 *delay); 348c2ecf20Sopenharmony_cistatic long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, 358c2ecf20Sopenharmony_ci enum wireless_mode wirelessmode, 368c2ecf20Sopenharmony_ci u8 txpwridx); 378c2ecf20Sopenharmony_cistatic void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw); 388c2ecf20Sopenharmony_cistatic void rtl92ee_phy_set_io(struct ieee80211_hw *hw); 398c2ecf20Sopenharmony_ci 408c2ecf20Sopenharmony_ciu32 rtl92ee_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) 418c2ecf20Sopenharmony_ci{ 428c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 438c2ecf20Sopenharmony_ci u32 returnvalue, originalvalue, bitshift; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 468c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x)\n", regaddr, bitmask); 478c2ecf20Sopenharmony_ci originalvalue = rtl_read_dword(rtlpriv, regaddr); 488c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 498c2ecf20Sopenharmony_ci returnvalue = (originalvalue & bitmask) >> bitshift; 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 528c2ecf20Sopenharmony_ci "BBR MASK=0x%x Addr[0x%x]=0x%x\n", 538c2ecf20Sopenharmony_ci bitmask, regaddr, originalvalue); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci return returnvalue; 568c2ecf20Sopenharmony_ci} 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_civoid rtl92ee_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, 598c2ecf20Sopenharmony_ci u32 bitmask, u32 data) 608c2ecf20Sopenharmony_ci{ 618c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 628c2ecf20Sopenharmony_ci u32 originalvalue, bitshift; 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 658c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x)\n", 668c2ecf20Sopenharmony_ci regaddr, bitmask, data); 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci if (bitmask != MASKDWORD) { 698c2ecf20Sopenharmony_ci originalvalue = rtl_read_dword(rtlpriv, regaddr); 708c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 718c2ecf20Sopenharmony_ci data = ((originalvalue & (~bitmask)) | (data << bitshift)); 728c2ecf20Sopenharmony_ci } 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, regaddr, data); 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 778c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x)\n", 788c2ecf20Sopenharmony_ci regaddr, bitmask, data); 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ciu32 rtl92ee_phy_query_rf_reg(struct ieee80211_hw *hw, 828c2ecf20Sopenharmony_ci enum radio_path rfpath, u32 regaddr, u32 bitmask) 838c2ecf20Sopenharmony_ci{ 848c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 858c2ecf20Sopenharmony_ci u32 original_value, readback_value, bitshift; 868c2ecf20Sopenharmony_ci 878c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 888c2ecf20Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", 898c2ecf20Sopenharmony_ci regaddr, rfpath, bitmask); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci original_value = _rtl92ee_phy_rf_serial_read(hw , rfpath, regaddr); 948c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 958c2ecf20Sopenharmony_ci readback_value = (original_value & bitmask) >> bitshift; 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 988c2ecf20Sopenharmony_ci 998c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1008c2ecf20Sopenharmony_ci "regaddr(%#x),rfpath(%#x),bitmask(%#x),original_value(%#x)\n", 1018c2ecf20Sopenharmony_ci regaddr, rfpath, bitmask, original_value); 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci return readback_value; 1048c2ecf20Sopenharmony_ci} 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_civoid rtl92ee_phy_set_rf_reg(struct ieee80211_hw *hw, 1078c2ecf20Sopenharmony_ci enum radio_path rfpath, 1088c2ecf20Sopenharmony_ci u32 addr, u32 bitmask, u32 data) 1098c2ecf20Sopenharmony_ci{ 1108c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1118c2ecf20Sopenharmony_ci u32 original_value, bitshift; 1128c2ecf20Sopenharmony_ci 1138c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1148c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 1158c2ecf20Sopenharmony_ci addr, bitmask, data, rfpath); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci if (bitmask != RFREG_OFFSET_MASK) { 1208c2ecf20Sopenharmony_ci original_value = _rtl92ee_phy_rf_serial_read(hw, rfpath, addr); 1218c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 1228c2ecf20Sopenharmony_ci data = (original_value & (~bitmask)) | (data << bitshift); 1238c2ecf20Sopenharmony_ci } 1248c2ecf20Sopenharmony_ci 1258c2ecf20Sopenharmony_ci _rtl92ee_phy_rf_serial_write(hw, rfpath, addr, data); 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 1288c2ecf20Sopenharmony_ci 1298c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1308c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 1318c2ecf20Sopenharmony_ci addr, bitmask, data, rfpath); 1328c2ecf20Sopenharmony_ci} 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cistatic u32 _rtl92ee_phy_rf_serial_read(struct ieee80211_hw *hw, 1358c2ecf20Sopenharmony_ci enum radio_path rfpath, u32 offset) 1368c2ecf20Sopenharmony_ci{ 1378c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1388c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 1398c2ecf20Sopenharmony_ci struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 1408c2ecf20Sopenharmony_ci u32 newoffset; 1418c2ecf20Sopenharmony_ci u32 tmplong, tmplong2; 1428c2ecf20Sopenharmony_ci u8 rfpi_enable = 0; 1438c2ecf20Sopenharmony_ci u32 retvalue; 1448c2ecf20Sopenharmony_ci 1458c2ecf20Sopenharmony_ci offset &= 0xff; 1468c2ecf20Sopenharmony_ci newoffset = offset; 1478c2ecf20Sopenharmony_ci if (RT_CANNOT_IO(hw)) { 1488c2ecf20Sopenharmony_ci pr_err("return all one\n"); 1498c2ecf20Sopenharmony_ci return 0xFFFFFFFF; 1508c2ecf20Sopenharmony_ci } 1518c2ecf20Sopenharmony_ci tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); 1528c2ecf20Sopenharmony_ci if (rfpath == RF90_PATH_A) 1538c2ecf20Sopenharmony_ci tmplong2 = tmplong; 1548c2ecf20Sopenharmony_ci else 1558c2ecf20Sopenharmony_ci tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); 1568c2ecf20Sopenharmony_ci tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | 1578c2ecf20Sopenharmony_ci (newoffset << 23) | BLSSIREADEDGE; 1588c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, 1598c2ecf20Sopenharmony_ci tmplong & (~BLSSIREADEDGE)); 1608c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); 1618c2ecf20Sopenharmony_ci udelay(20); 1628c2ecf20Sopenharmony_ci if (rfpath == RF90_PATH_A) 1638c2ecf20Sopenharmony_ci rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, 1648c2ecf20Sopenharmony_ci BIT(8)); 1658c2ecf20Sopenharmony_ci else if (rfpath == RF90_PATH_B) 1668c2ecf20Sopenharmony_ci rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, 1678c2ecf20Sopenharmony_ci BIT(8)); 1688c2ecf20Sopenharmony_ci if (rfpi_enable) 1698c2ecf20Sopenharmony_ci retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, 1708c2ecf20Sopenharmony_ci BLSSIREADBACKDATA); 1718c2ecf20Sopenharmony_ci else 1728c2ecf20Sopenharmony_ci retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, 1738c2ecf20Sopenharmony_ci BLSSIREADBACKDATA); 1748c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1758c2ecf20Sopenharmony_ci "RFR-%d Addr[0x%x]=0x%x\n", 1768c2ecf20Sopenharmony_ci rfpath, pphyreg->rf_rb, retvalue); 1778c2ecf20Sopenharmony_ci return retvalue; 1788c2ecf20Sopenharmony_ci} 1798c2ecf20Sopenharmony_ci 1808c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_rf_serial_write(struct ieee80211_hw *hw, 1818c2ecf20Sopenharmony_ci enum radio_path rfpath, u32 offset, 1828c2ecf20Sopenharmony_ci u32 data) 1838c2ecf20Sopenharmony_ci{ 1848c2ecf20Sopenharmony_ci u32 data_and_addr; 1858c2ecf20Sopenharmony_ci u32 newoffset; 1868c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1878c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 1888c2ecf20Sopenharmony_ci struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 1898c2ecf20Sopenharmony_ci 1908c2ecf20Sopenharmony_ci if (RT_CANNOT_IO(hw)) { 1918c2ecf20Sopenharmony_ci pr_err("stop\n"); 1928c2ecf20Sopenharmony_ci return; 1938c2ecf20Sopenharmony_ci } 1948c2ecf20Sopenharmony_ci offset &= 0xff; 1958c2ecf20Sopenharmony_ci newoffset = offset; 1968c2ecf20Sopenharmony_ci data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; 1978c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); 1988c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1998c2ecf20Sopenharmony_ci "RFW-%d Addr[0x%x]=0x%x\n", rfpath, 2008c2ecf20Sopenharmony_ci pphyreg->rf3wire_offset, data_and_addr); 2018c2ecf20Sopenharmony_ci} 2028c2ecf20Sopenharmony_ci 2038c2ecf20Sopenharmony_cibool rtl92ee_phy_mac_config(struct ieee80211_hw *hw) 2048c2ecf20Sopenharmony_ci{ 2058c2ecf20Sopenharmony_ci return _rtl92ee_phy_config_mac_with_headerfile(hw); 2068c2ecf20Sopenharmony_ci} 2078c2ecf20Sopenharmony_ci 2088c2ecf20Sopenharmony_cibool rtl92ee_phy_bb_config(struct ieee80211_hw *hw) 2098c2ecf20Sopenharmony_ci{ 2108c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2118c2ecf20Sopenharmony_ci bool rtstatus = true; 2128c2ecf20Sopenharmony_ci u16 regval; 2138c2ecf20Sopenharmony_ci u32 tmp; 2148c2ecf20Sopenharmony_ci u8 crystal_cap; 2158c2ecf20Sopenharmony_ci 2168c2ecf20Sopenharmony_ci phy_init_bb_rf_register_def(hw); 2178c2ecf20Sopenharmony_ci regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 2188c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, 2198c2ecf20Sopenharmony_ci regval | BIT(13) | BIT(0) | BIT(1)); 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); 2228c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 2238c2ecf20Sopenharmony_ci FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | 2248c2ecf20Sopenharmony_ci FEN_BB_GLB_RSTN | FEN_BBRSTB); 2258c2ecf20Sopenharmony_ci 2268c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); 2278c2ecf20Sopenharmony_ci 2288c2ecf20Sopenharmony_ci tmp = rtl_read_dword(rtlpriv, 0x4c); 2298c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23)); 2308c2ecf20Sopenharmony_ci 2318c2ecf20Sopenharmony_ci rtstatus = _rtl92ee_phy_bb8192ee_config_parafile(hw); 2328c2ecf20Sopenharmony_ci 2338c2ecf20Sopenharmony_ci crystal_cap = rtlpriv->efuse.eeprom_crystalcap & 0x3F; 2348c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, 2358c2ecf20Sopenharmony_ci (crystal_cap | (crystal_cap << 6))); 2368c2ecf20Sopenharmony_ci return rtstatus; 2378c2ecf20Sopenharmony_ci} 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_cibool rtl92ee_phy_rf_config(struct ieee80211_hw *hw) 2408c2ecf20Sopenharmony_ci{ 2418c2ecf20Sopenharmony_ci return rtl92ee_phy_rf6052_config(hw); 2428c2ecf20Sopenharmony_ci} 2438c2ecf20Sopenharmony_ci 2448c2ecf20Sopenharmony_cistatic bool _check_condition(struct ieee80211_hw *hw, 2458c2ecf20Sopenharmony_ci const u32 condition) 2468c2ecf20Sopenharmony_ci{ 2478c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 2488c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 2498c2ecf20Sopenharmony_ci u32 _board = rtlefuse->board_type; /*need efuse define*/ 2508c2ecf20Sopenharmony_ci u32 _interface = rtlhal->interface; 2518c2ecf20Sopenharmony_ci u32 _platform = 0x08;/*SupportPlatform */ 2528c2ecf20Sopenharmony_ci u32 cond = condition; 2538c2ecf20Sopenharmony_ci 2548c2ecf20Sopenharmony_ci if (condition == 0xCDCDCDCD) 2558c2ecf20Sopenharmony_ci return true; 2568c2ecf20Sopenharmony_ci 2578c2ecf20Sopenharmony_ci cond = condition & 0xFF; 2588c2ecf20Sopenharmony_ci if ((_board != cond) && (cond != 0xFF)) 2598c2ecf20Sopenharmony_ci return false; 2608c2ecf20Sopenharmony_ci 2618c2ecf20Sopenharmony_ci cond = condition & 0xFF00; 2628c2ecf20Sopenharmony_ci cond = cond >> 8; 2638c2ecf20Sopenharmony_ci if ((_interface & cond) == 0 && cond != 0x07) 2648c2ecf20Sopenharmony_ci return false; 2658c2ecf20Sopenharmony_ci 2668c2ecf20Sopenharmony_ci cond = condition & 0xFF0000; 2678c2ecf20Sopenharmony_ci cond = cond >> 16; 2688c2ecf20Sopenharmony_ci if ((_platform & cond) == 0 && cond != 0x0F) 2698c2ecf20Sopenharmony_ci return false; 2708c2ecf20Sopenharmony_ci 2718c2ecf20Sopenharmony_ci return true; 2728c2ecf20Sopenharmony_ci} 2738c2ecf20Sopenharmony_ci 2748c2ecf20Sopenharmony_cistatic void _rtl92ee_config_rf_reg(struct ieee80211_hw *hw, u32 addr, u32 data, 2758c2ecf20Sopenharmony_ci enum radio_path rfpath, u32 regaddr) 2768c2ecf20Sopenharmony_ci{ 2778c2ecf20Sopenharmony_ci if (addr == 0xfe || addr == 0xffe) { 2788c2ecf20Sopenharmony_ci mdelay(50); 2798c2ecf20Sopenharmony_ci } else { 2808c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data); 2818c2ecf20Sopenharmony_ci udelay(1); 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci if (addr == 0xb6) { 2848c2ecf20Sopenharmony_ci u32 getvalue; 2858c2ecf20Sopenharmony_ci u8 count = 0; 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD); 2888c2ecf20Sopenharmony_ci udelay(1); 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_ci while ((getvalue >> 8) != (data >> 8)) { 2918c2ecf20Sopenharmony_ci count++; 2928c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, rfpath, regaddr, 2938c2ecf20Sopenharmony_ci RFREG_OFFSET_MASK, data); 2948c2ecf20Sopenharmony_ci udelay(1); 2958c2ecf20Sopenharmony_ci getvalue = rtl_get_rfreg(hw, rfpath, addr, 2968c2ecf20Sopenharmony_ci MASKDWORD); 2978c2ecf20Sopenharmony_ci if (count > 5) 2988c2ecf20Sopenharmony_ci break; 2998c2ecf20Sopenharmony_ci } 3008c2ecf20Sopenharmony_ci } 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci if (addr == 0xb2) { 3038c2ecf20Sopenharmony_ci u32 getvalue; 3048c2ecf20Sopenharmony_ci u8 count = 0; 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci getvalue = rtl_get_rfreg(hw, rfpath, addr, MASKDWORD); 3078c2ecf20Sopenharmony_ci udelay(1); 3088c2ecf20Sopenharmony_ci 3098c2ecf20Sopenharmony_ci while (getvalue != data) { 3108c2ecf20Sopenharmony_ci count++; 3118c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, rfpath, regaddr, 3128c2ecf20Sopenharmony_ci RFREG_OFFSET_MASK, data); 3138c2ecf20Sopenharmony_ci udelay(1); 3148c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, rfpath, 0x18, 3158c2ecf20Sopenharmony_ci RFREG_OFFSET_MASK, 0x0fc07); 3168c2ecf20Sopenharmony_ci udelay(1); 3178c2ecf20Sopenharmony_ci getvalue = rtl_get_rfreg(hw, rfpath, addr, 3188c2ecf20Sopenharmony_ci MASKDWORD); 3198c2ecf20Sopenharmony_ci if (count > 5) 3208c2ecf20Sopenharmony_ci break; 3218c2ecf20Sopenharmony_ci } 3228c2ecf20Sopenharmony_ci } 3238c2ecf20Sopenharmony_ci } 3248c2ecf20Sopenharmony_ci} 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_cistatic void _rtl92ee_config_rf_radio_a(struct ieee80211_hw *hw, 3278c2ecf20Sopenharmony_ci u32 addr, u32 data) 3288c2ecf20Sopenharmony_ci{ 3298c2ecf20Sopenharmony_ci u32 content = 0x1000; /*RF Content: radio_a_txt*/ 3308c2ecf20Sopenharmony_ci u32 maskforphyset = (u32)(content & 0xE000); 3318c2ecf20Sopenharmony_ci 3328c2ecf20Sopenharmony_ci _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_A, 3338c2ecf20Sopenharmony_ci addr | maskforphyset); 3348c2ecf20Sopenharmony_ci} 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_cistatic void _rtl92ee_config_rf_radio_b(struct ieee80211_hw *hw, 3378c2ecf20Sopenharmony_ci u32 addr, u32 data) 3388c2ecf20Sopenharmony_ci{ 3398c2ecf20Sopenharmony_ci u32 content = 0x1001; /*RF Content: radio_b_txt*/ 3408c2ecf20Sopenharmony_ci u32 maskforphyset = (u32)(content & 0xE000); 3418c2ecf20Sopenharmony_ci 3428c2ecf20Sopenharmony_ci _rtl92ee_config_rf_reg(hw, addr, data, RF90_PATH_B, 3438c2ecf20Sopenharmony_ci addr | maskforphyset); 3448c2ecf20Sopenharmony_ci} 3458c2ecf20Sopenharmony_ci 3468c2ecf20Sopenharmony_cistatic void _rtl92ee_config_bb_reg(struct ieee80211_hw *hw, 3478c2ecf20Sopenharmony_ci u32 addr, u32 data) 3488c2ecf20Sopenharmony_ci{ 3498c2ecf20Sopenharmony_ci if (addr == 0xfe) 3508c2ecf20Sopenharmony_ci mdelay(50); 3518c2ecf20Sopenharmony_ci else if (addr == 0xfd) 3528c2ecf20Sopenharmony_ci mdelay(5); 3538c2ecf20Sopenharmony_ci else if (addr == 0xfc) 3548c2ecf20Sopenharmony_ci mdelay(1); 3558c2ecf20Sopenharmony_ci else if (addr == 0xfb) 3568c2ecf20Sopenharmony_ci udelay(50); 3578c2ecf20Sopenharmony_ci else if (addr == 0xfa) 3588c2ecf20Sopenharmony_ci udelay(5); 3598c2ecf20Sopenharmony_ci else if (addr == 0xf9) 3608c2ecf20Sopenharmony_ci udelay(1); 3618c2ecf20Sopenharmony_ci else 3628c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, addr, MASKDWORD , data); 3638c2ecf20Sopenharmony_ci 3648c2ecf20Sopenharmony_ci udelay(1); 3658c2ecf20Sopenharmony_ci} 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) 3688c2ecf20Sopenharmony_ci{ 3698c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3708c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 3718c2ecf20Sopenharmony_ci 3728c2ecf20Sopenharmony_ci u8 band = BAND_ON_2_4G, rf = 0, txnum = 0, sec = 0; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci for (; band <= BAND_ON_5G; ++band) 3758c2ecf20Sopenharmony_ci for (; rf < TX_PWR_BY_RATE_NUM_RF; ++rf) 3768c2ecf20Sopenharmony_ci for (; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum) 3778c2ecf20Sopenharmony_ci for (; sec < TX_PWR_BY_RATE_NUM_SECTION; ++sec) 3788c2ecf20Sopenharmony_ci rtlphy->tx_power_by_rate_offset 3798c2ecf20Sopenharmony_ci [band][rf][txnum][sec] = 0; 3808c2ecf20Sopenharmony_ci} 3818c2ecf20Sopenharmony_ci 3828c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, 3838c2ecf20Sopenharmony_ci u8 band, u8 path, 3848c2ecf20Sopenharmony_ci u8 rate_section, u8 txnum, 3858c2ecf20Sopenharmony_ci u8 value) 3868c2ecf20Sopenharmony_ci{ 3878c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3888c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 3898c2ecf20Sopenharmony_ci 3908c2ecf20Sopenharmony_ci if (path > RF90_PATH_D) { 3918c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 3928c2ecf20Sopenharmony_ci "Invalid Rf Path %d\n", path); 3938c2ecf20Sopenharmony_ci return; 3948c2ecf20Sopenharmony_ci } 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci if (band == BAND_ON_2_4G) { 3978c2ecf20Sopenharmony_ci switch (rate_section) { 3988c2ecf20Sopenharmony_ci case CCK: 3998c2ecf20Sopenharmony_ci rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value; 4008c2ecf20Sopenharmony_ci break; 4018c2ecf20Sopenharmony_ci case OFDM: 4028c2ecf20Sopenharmony_ci rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value; 4038c2ecf20Sopenharmony_ci break; 4048c2ecf20Sopenharmony_ci case HT_MCS0_MCS7: 4058c2ecf20Sopenharmony_ci rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value; 4068c2ecf20Sopenharmony_ci break; 4078c2ecf20Sopenharmony_ci case HT_MCS8_MCS15: 4088c2ecf20Sopenharmony_ci rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value; 4098c2ecf20Sopenharmony_ci break; 4108c2ecf20Sopenharmony_ci default: 4118c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 4128c2ecf20Sopenharmony_ci "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n", 4138c2ecf20Sopenharmony_ci rate_section, path, txnum); 4148c2ecf20Sopenharmony_ci break; 4158c2ecf20Sopenharmony_ci } 4168c2ecf20Sopenharmony_ci } else { 4178c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 4188c2ecf20Sopenharmony_ci "Invalid Band %d\n", band); 4198c2ecf20Sopenharmony_ci } 4208c2ecf20Sopenharmony_ci} 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_cistatic u8 _rtl92ee_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, 4238c2ecf20Sopenharmony_ci u8 band, u8 path, u8 txnum, 4248c2ecf20Sopenharmony_ci u8 rate_section) 4258c2ecf20Sopenharmony_ci{ 4268c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4278c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 4288c2ecf20Sopenharmony_ci u8 value = 0; 4298c2ecf20Sopenharmony_ci 4308c2ecf20Sopenharmony_ci if (path > RF90_PATH_D) { 4318c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 4328c2ecf20Sopenharmony_ci "Invalid Rf Path %d\n", path); 4338c2ecf20Sopenharmony_ci return 0; 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci 4368c2ecf20Sopenharmony_ci if (band == BAND_ON_2_4G) { 4378c2ecf20Sopenharmony_ci switch (rate_section) { 4388c2ecf20Sopenharmony_ci case CCK: 4398c2ecf20Sopenharmony_ci value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0]; 4408c2ecf20Sopenharmony_ci break; 4418c2ecf20Sopenharmony_ci case OFDM: 4428c2ecf20Sopenharmony_ci value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1]; 4438c2ecf20Sopenharmony_ci break; 4448c2ecf20Sopenharmony_ci case HT_MCS0_MCS7: 4458c2ecf20Sopenharmony_ci value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2]; 4468c2ecf20Sopenharmony_ci break; 4478c2ecf20Sopenharmony_ci case HT_MCS8_MCS15: 4488c2ecf20Sopenharmony_ci value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3]; 4498c2ecf20Sopenharmony_ci break; 4508c2ecf20Sopenharmony_ci default: 4518c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 4528c2ecf20Sopenharmony_ci "Invalid RateSection %d in 2.4G,Rf %d,%dTx\n", 4538c2ecf20Sopenharmony_ci rate_section, path, txnum); 4548c2ecf20Sopenharmony_ci break; 4558c2ecf20Sopenharmony_ci } 4568c2ecf20Sopenharmony_ci } else { 4578c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 4588c2ecf20Sopenharmony_ci "Invalid Band %d()\n", band); 4598c2ecf20Sopenharmony_ci } 4608c2ecf20Sopenharmony_ci return value; 4618c2ecf20Sopenharmony_ci} 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) 4648c2ecf20Sopenharmony_ci{ 4658c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4668c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 4678c2ecf20Sopenharmony_ci u16 raw = 0; 4688c2ecf20Sopenharmony_ci u8 base = 0, path = 0; 4698c2ecf20Sopenharmony_ci 4708c2ecf20Sopenharmony_ci for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { 4718c2ecf20Sopenharmony_ci if (path == RF90_PATH_A) { 4728c2ecf20Sopenharmony_ci raw = (u16)(rtlphy->tx_power_by_rate_offset 4738c2ecf20Sopenharmony_ci [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 4748c2ecf20Sopenharmony_ci 0xFF; 4758c2ecf20Sopenharmony_ci base = (raw >> 4) * 10 + (raw & 0xF); 4768c2ecf20Sopenharmony_ci _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, 4778c2ecf20Sopenharmony_ci path, CCK, RF_1TX, 4788c2ecf20Sopenharmony_ci base); 4798c2ecf20Sopenharmony_ci } else if (path == RF90_PATH_B) { 4808c2ecf20Sopenharmony_ci raw = (u16)(rtlphy->tx_power_by_rate_offset 4818c2ecf20Sopenharmony_ci [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 4828c2ecf20Sopenharmony_ci 0xFF; 4838c2ecf20Sopenharmony_ci base = (raw >> 4) * 10 + (raw & 0xF); 4848c2ecf20Sopenharmony_ci _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, 4858c2ecf20Sopenharmony_ci path, CCK, RF_1TX, 4868c2ecf20Sopenharmony_ci base); 4878c2ecf20Sopenharmony_ci } 4888c2ecf20Sopenharmony_ci raw = (u16)(rtlphy->tx_power_by_rate_offset 4898c2ecf20Sopenharmony_ci [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF; 4908c2ecf20Sopenharmony_ci base = (raw >> 4) * 10 + (raw & 0xF); 4918c2ecf20Sopenharmony_ci _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, 4928c2ecf20Sopenharmony_ci OFDM, RF_1TX, base); 4938c2ecf20Sopenharmony_ci 4948c2ecf20Sopenharmony_ci raw = (u16)(rtlphy->tx_power_by_rate_offset 4958c2ecf20Sopenharmony_ci [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF; 4968c2ecf20Sopenharmony_ci base = (raw >> 4) * 10 + (raw & 0xF); 4978c2ecf20Sopenharmony_ci _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, 4988c2ecf20Sopenharmony_ci HT_MCS0_MCS7, RF_1TX, 4998c2ecf20Sopenharmony_ci base); 5008c2ecf20Sopenharmony_ci 5018c2ecf20Sopenharmony_ci raw = (u16)(rtlphy->tx_power_by_rate_offset 5028c2ecf20Sopenharmony_ci [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF; 5038c2ecf20Sopenharmony_ci base = (raw >> 4) * 10 + (raw & 0xF); 5048c2ecf20Sopenharmony_ci _rtl92ee_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, 5058c2ecf20Sopenharmony_ci HT_MCS8_MCS15, RF_2TX, 5068c2ecf20Sopenharmony_ci base); 5078c2ecf20Sopenharmony_ci } 5088c2ecf20Sopenharmony_ci} 5098c2ecf20Sopenharmony_ci 5108c2ecf20Sopenharmony_cistatic void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start, 5118c2ecf20Sopenharmony_ci u8 end, u8 base) 5128c2ecf20Sopenharmony_ci{ 5138c2ecf20Sopenharmony_ci s8 i = 0; 5148c2ecf20Sopenharmony_ci u8 tmp = 0; 5158c2ecf20Sopenharmony_ci u32 temp_data = 0; 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci for (i = 3; i >= 0; --i) { 5188c2ecf20Sopenharmony_ci if (i >= start && i <= end) { 5198c2ecf20Sopenharmony_ci /* Get the exact value */ 5208c2ecf20Sopenharmony_ci tmp = (u8)(*data >> (i * 8)) & 0xF; 5218c2ecf20Sopenharmony_ci tmp += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10; 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci /* Change the value to a relative value */ 5248c2ecf20Sopenharmony_ci tmp = (tmp > base) ? tmp - base : base - tmp; 5258c2ecf20Sopenharmony_ci } else { 5268c2ecf20Sopenharmony_ci tmp = (u8)(*data >> (i * 8)) & 0xFF; 5278c2ecf20Sopenharmony_ci } 5288c2ecf20Sopenharmony_ci temp_data <<= 8; 5298c2ecf20Sopenharmony_ci temp_data |= tmp; 5308c2ecf20Sopenharmony_ci } 5318c2ecf20Sopenharmony_ci *data = temp_data; 5328c2ecf20Sopenharmony_ci} 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_cistatic void phy_convert_txpwr_dbm_to_rel_val(struct ieee80211_hw *hw) 5358c2ecf20Sopenharmony_ci{ 5368c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5378c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 5388c2ecf20Sopenharmony_ci u8 base = 0, rf = 0, band = BAND_ON_2_4G; 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci for (rf = RF90_PATH_A; rf <= RF90_PATH_B; ++rf) { 5418c2ecf20Sopenharmony_ci if (rf == RF90_PATH_A) { 5428c2ecf20Sopenharmony_ci base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, 5438c2ecf20Sopenharmony_ci rf, RF_1TX, 5448c2ecf20Sopenharmony_ci CCK); 5458c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5468c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset 5478c2ecf20Sopenharmony_ci [band][rf][RF_1TX][2], 5488c2ecf20Sopenharmony_ci 1, 1, base); 5498c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5508c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset 5518c2ecf20Sopenharmony_ci [band][rf][RF_1TX][3], 5528c2ecf20Sopenharmony_ci 1, 3, base); 5538c2ecf20Sopenharmony_ci } else if (rf == RF90_PATH_B) { 5548c2ecf20Sopenharmony_ci base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, 5558c2ecf20Sopenharmony_ci rf, RF_1TX, 5568c2ecf20Sopenharmony_ci CCK); 5578c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5588c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset 5598c2ecf20Sopenharmony_ci [band][rf][RF_1TX][3], 5608c2ecf20Sopenharmony_ci 0, 0, base); 5618c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5628c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset 5638c2ecf20Sopenharmony_ci [band][rf][RF_1TX][2], 5648c2ecf20Sopenharmony_ci 1, 3, base); 5658c2ecf20Sopenharmony_ci } 5668c2ecf20Sopenharmony_ci base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf, 5678c2ecf20Sopenharmony_ci RF_1TX, OFDM); 5688c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5698c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][0], 5708c2ecf20Sopenharmony_ci 0, 3, base); 5718c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5728c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][1], 5738c2ecf20Sopenharmony_ci 0, 3, base); 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf, 5768c2ecf20Sopenharmony_ci RF_1TX, 5778c2ecf20Sopenharmony_ci HT_MCS0_MCS7); 5788c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5798c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][4], 5808c2ecf20Sopenharmony_ci 0, 3, base); 5818c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5828c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[band][rf][RF_1TX][5], 5838c2ecf20Sopenharmony_ci 0, 3, base); 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci base = _rtl92ee_phy_get_txpower_by_rate_base(hw, band, rf, 5868c2ecf20Sopenharmony_ci RF_2TX, 5878c2ecf20Sopenharmony_ci HT_MCS8_MCS15); 5888c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5898c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][6], 5908c2ecf20Sopenharmony_ci 0, 3, base); 5918c2ecf20Sopenharmony_ci 5928c2ecf20Sopenharmony_ci _phy_convert_txpower_dbm_to_relative_value( 5938c2ecf20Sopenharmony_ci &rtlphy->tx_power_by_rate_offset[band][rf][RF_2TX][7], 5948c2ecf20Sopenharmony_ci 0, 3, base); 5958c2ecf20Sopenharmony_ci } 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, 5988c2ecf20Sopenharmony_ci "<==%s\n", __func__); 5998c2ecf20Sopenharmony_ci} 6008c2ecf20Sopenharmony_ci 6018c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw) 6028c2ecf20Sopenharmony_ci{ 6038c2ecf20Sopenharmony_ci _rtl92ee_phy_store_txpower_by_rate_base(hw); 6048c2ecf20Sopenharmony_ci phy_convert_txpwr_dbm_to_rel_val(hw); 6058c2ecf20Sopenharmony_ci} 6068c2ecf20Sopenharmony_ci 6078c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_bb8192ee_config_parafile(struct ieee80211_hw *hw) 6088c2ecf20Sopenharmony_ci{ 6098c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6108c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 6118c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 6128c2ecf20Sopenharmony_ci bool rtstatus; 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_PHY_REG); 6158c2ecf20Sopenharmony_ci if (!rtstatus) { 6168c2ecf20Sopenharmony_ci pr_err("Write BB Reg Fail!!\n"); 6178c2ecf20Sopenharmony_ci return false; 6188c2ecf20Sopenharmony_ci } 6198c2ecf20Sopenharmony_ci 6208c2ecf20Sopenharmony_ci _rtl92ee_phy_init_tx_power_by_rate(hw); 6218c2ecf20Sopenharmony_ci if (!rtlefuse->autoload_failflag) { 6228c2ecf20Sopenharmony_ci rtlphy->pwrgroup_cnt = 0; 6238c2ecf20Sopenharmony_ci rtstatus = 6248c2ecf20Sopenharmony_ci phy_config_bb_with_pghdrfile(hw, BASEBAND_CONFIG_PHY_REG); 6258c2ecf20Sopenharmony_ci } 6268c2ecf20Sopenharmony_ci _rtl92ee_phy_txpower_by_rate_configuration(hw); 6278c2ecf20Sopenharmony_ci if (!rtstatus) { 6288c2ecf20Sopenharmony_ci pr_err("BB_PG Reg Fail!!\n"); 6298c2ecf20Sopenharmony_ci return false; 6308c2ecf20Sopenharmony_ci } 6318c2ecf20Sopenharmony_ci rtstatus = phy_config_bb_with_hdr_file(hw, BASEBAND_CONFIG_AGC_TAB); 6328c2ecf20Sopenharmony_ci if (!rtstatus) { 6338c2ecf20Sopenharmony_ci pr_err("AGC Table Fail\n"); 6348c2ecf20Sopenharmony_ci return false; 6358c2ecf20Sopenharmony_ci } 6368c2ecf20Sopenharmony_ci rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw, 6378c2ecf20Sopenharmony_ci RFPGA0_XA_HSSIPARAMETER2, 6388c2ecf20Sopenharmony_ci 0x200)); 6398c2ecf20Sopenharmony_ci 6408c2ecf20Sopenharmony_ci return true; 6418c2ecf20Sopenharmony_ci} 6428c2ecf20Sopenharmony_ci 6438c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) 6448c2ecf20Sopenharmony_ci{ 6458c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6468c2ecf20Sopenharmony_ci u32 i; 6478c2ecf20Sopenharmony_ci u32 arraylength; 6488c2ecf20Sopenharmony_ci u32 *ptrarray; 6498c2ecf20Sopenharmony_ci 6508c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl8192EMACPHY_Array\n"); 6518c2ecf20Sopenharmony_ci arraylength = RTL8192EE_MAC_ARRAY_LEN; 6528c2ecf20Sopenharmony_ci ptrarray = RTL8192EE_MAC_ARRAY; 6538c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 6548c2ecf20Sopenharmony_ci "Img:RTL8192EE_MAC_ARRAY LEN %d\n", arraylength); 6558c2ecf20Sopenharmony_ci for (i = 0; i < arraylength; i = i + 2) 6568c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]); 6578c2ecf20Sopenharmony_ci return true; 6588c2ecf20Sopenharmony_ci} 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_ci#define READ_NEXT_PAIR(v1, v2, i) \ 6618c2ecf20Sopenharmony_ci do { \ 6628c2ecf20Sopenharmony_ci i += 2; \ 6638c2ecf20Sopenharmony_ci v1 = array[i]; \ 6648c2ecf20Sopenharmony_ci v2 = array[i+1]; \ 6658c2ecf20Sopenharmony_ci } while (0) 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_cistatic bool phy_config_bb_with_hdr_file(struct ieee80211_hw *hw, 6688c2ecf20Sopenharmony_ci u8 configtype) 6698c2ecf20Sopenharmony_ci{ 6708c2ecf20Sopenharmony_ci int i; 6718c2ecf20Sopenharmony_ci u32 *array; 6728c2ecf20Sopenharmony_ci u16 len; 6738c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6748c2ecf20Sopenharmony_ci u32 v1 = 0, v2 = 0; 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 6778c2ecf20Sopenharmony_ci len = RTL8192EE_PHY_REG_ARRAY_LEN; 6788c2ecf20Sopenharmony_ci array = RTL8192EE_PHY_REG_ARRAY; 6798c2ecf20Sopenharmony_ci 6808c2ecf20Sopenharmony_ci for (i = 0; i < len; i = i + 2) { 6818c2ecf20Sopenharmony_ci v1 = array[i]; 6828c2ecf20Sopenharmony_ci v2 = array[i+1]; 6838c2ecf20Sopenharmony_ci if (v1 < 0xcdcdcdcd) { 6848c2ecf20Sopenharmony_ci _rtl92ee_config_bb_reg(hw, v1, v2); 6858c2ecf20Sopenharmony_ci } else {/*This line is the start line of branch.*/ 6868c2ecf20Sopenharmony_ci /* to protect READ_NEXT_PAIR not overrun */ 6878c2ecf20Sopenharmony_ci if (i >= len - 2) 6888c2ecf20Sopenharmony_ci break; 6898c2ecf20Sopenharmony_ci 6908c2ecf20Sopenharmony_ci if (!_check_condition(hw , array[i])) { 6918c2ecf20Sopenharmony_ci /*Discard the following pairs*/ 6928c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 6938c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && 6948c2ecf20Sopenharmony_ci v2 != 0xCDEF && 6958c2ecf20Sopenharmony_ci v2 != 0xCDCD && i < len - 2) { 6968c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 6978c2ecf20Sopenharmony_ci } 6988c2ecf20Sopenharmony_ci i -= 2; /* prevent from for-loop += 2*/ 6998c2ecf20Sopenharmony_ci } else { 7008c2ecf20Sopenharmony_ci /* Configure matched pairs and 7018c2ecf20Sopenharmony_ci * skip to end of if-else. 7028c2ecf20Sopenharmony_ci */ 7038c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 7048c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && 7058c2ecf20Sopenharmony_ci v2 != 0xCDEF && 7068c2ecf20Sopenharmony_ci v2 != 0xCDCD && i < len - 2) { 7078c2ecf20Sopenharmony_ci _rtl92ee_config_bb_reg(hw, v1, 7088c2ecf20Sopenharmony_ci v2); 7098c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 7108c2ecf20Sopenharmony_ci } 7118c2ecf20Sopenharmony_ci 7128c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && i < len - 2) 7138c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 7148c2ecf20Sopenharmony_ci } 7158c2ecf20Sopenharmony_ci } 7168c2ecf20Sopenharmony_ci } 7178c2ecf20Sopenharmony_ci } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { 7188c2ecf20Sopenharmony_ci len = RTL8192EE_AGC_TAB_ARRAY_LEN; 7198c2ecf20Sopenharmony_ci array = RTL8192EE_AGC_TAB_ARRAY; 7208c2ecf20Sopenharmony_ci 7218c2ecf20Sopenharmony_ci for (i = 0; i < len; i = i + 2) { 7228c2ecf20Sopenharmony_ci v1 = array[i]; 7238c2ecf20Sopenharmony_ci v2 = array[i+1]; 7248c2ecf20Sopenharmony_ci if (v1 < 0xCDCDCDCD) { 7258c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, array[i], MASKDWORD, 7268c2ecf20Sopenharmony_ci array[i + 1]); 7278c2ecf20Sopenharmony_ci udelay(1); 7288c2ecf20Sopenharmony_ci continue; 7298c2ecf20Sopenharmony_ci } else{/*This line is the start line of branch.*/ 7308c2ecf20Sopenharmony_ci /* to protect READ_NEXT_PAIR not overrun */ 7318c2ecf20Sopenharmony_ci if (i >= len - 2) 7328c2ecf20Sopenharmony_ci break; 7338c2ecf20Sopenharmony_ci 7348c2ecf20Sopenharmony_ci if (!_check_condition(hw , array[i])) { 7358c2ecf20Sopenharmony_ci /*Discard the following pairs*/ 7368c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 7378c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && 7388c2ecf20Sopenharmony_ci v2 != 0xCDEF && 7398c2ecf20Sopenharmony_ci v2 != 0xCDCD && 7408c2ecf20Sopenharmony_ci i < len - 2) { 7418c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 7428c2ecf20Sopenharmony_ci } 7438c2ecf20Sopenharmony_ci i -= 2; /* prevent from for-loop += 2*/ 7448c2ecf20Sopenharmony_ci } else { 7458c2ecf20Sopenharmony_ci /* Configure matched pairs and 7468c2ecf20Sopenharmony_ci * skip to end of if-else. 7478c2ecf20Sopenharmony_ci */ 7488c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1, v2, i); 7498c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && 7508c2ecf20Sopenharmony_ci v2 != 0xCDEF && 7518c2ecf20Sopenharmony_ci v2 != 0xCDCD && 7528c2ecf20Sopenharmony_ci i < len - 2) { 7538c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 7548c2ecf20Sopenharmony_ci array[i], 7558c2ecf20Sopenharmony_ci MASKDWORD, 7568c2ecf20Sopenharmony_ci array[i + 1]); 7578c2ecf20Sopenharmony_ci udelay(1); 7588c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1 , v2 , i); 7598c2ecf20Sopenharmony_ci } 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && 7628c2ecf20Sopenharmony_ci i < len - 2) { 7638c2ecf20Sopenharmony_ci READ_NEXT_PAIR(v1 , v2 , i); 7648c2ecf20Sopenharmony_ci } 7658c2ecf20Sopenharmony_ci } 7668c2ecf20Sopenharmony_ci } 7678c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 7688c2ecf20Sopenharmony_ci "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n", 7698c2ecf20Sopenharmony_ci array[i], 7708c2ecf20Sopenharmony_ci array[i + 1]); 7718c2ecf20Sopenharmony_ci } 7728c2ecf20Sopenharmony_ci } 7738c2ecf20Sopenharmony_ci return true; 7748c2ecf20Sopenharmony_ci} 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_cistatic u8 _rtl92ee_get_rate_section_index(u32 regaddr) 7778c2ecf20Sopenharmony_ci{ 7788c2ecf20Sopenharmony_ci u8 index = 0; 7798c2ecf20Sopenharmony_ci 7808c2ecf20Sopenharmony_ci switch (regaddr) { 7818c2ecf20Sopenharmony_ci case RTXAGC_A_RATE18_06: 7828c2ecf20Sopenharmony_ci case RTXAGC_B_RATE18_06: 7838c2ecf20Sopenharmony_ci index = 0; 7848c2ecf20Sopenharmony_ci break; 7858c2ecf20Sopenharmony_ci case RTXAGC_A_RATE54_24: 7868c2ecf20Sopenharmony_ci case RTXAGC_B_RATE54_24: 7878c2ecf20Sopenharmony_ci index = 1; 7888c2ecf20Sopenharmony_ci break; 7898c2ecf20Sopenharmony_ci case RTXAGC_A_CCK1_MCS32: 7908c2ecf20Sopenharmony_ci case RTXAGC_B_CCK1_55_MCS32: 7918c2ecf20Sopenharmony_ci index = 2; 7928c2ecf20Sopenharmony_ci break; 7938c2ecf20Sopenharmony_ci case RTXAGC_B_CCK11_A_CCK2_11: 7948c2ecf20Sopenharmony_ci index = 3; 7958c2ecf20Sopenharmony_ci break; 7968c2ecf20Sopenharmony_ci case RTXAGC_A_MCS03_MCS00: 7978c2ecf20Sopenharmony_ci case RTXAGC_B_MCS03_MCS00: 7988c2ecf20Sopenharmony_ci index = 4; 7998c2ecf20Sopenharmony_ci break; 8008c2ecf20Sopenharmony_ci case RTXAGC_A_MCS07_MCS04: 8018c2ecf20Sopenharmony_ci case RTXAGC_B_MCS07_MCS04: 8028c2ecf20Sopenharmony_ci index = 5; 8038c2ecf20Sopenharmony_ci break; 8048c2ecf20Sopenharmony_ci case RTXAGC_A_MCS11_MCS08: 8058c2ecf20Sopenharmony_ci case RTXAGC_B_MCS11_MCS08: 8068c2ecf20Sopenharmony_ci index = 6; 8078c2ecf20Sopenharmony_ci break; 8088c2ecf20Sopenharmony_ci case RTXAGC_A_MCS15_MCS12: 8098c2ecf20Sopenharmony_ci case RTXAGC_B_MCS15_MCS12: 8108c2ecf20Sopenharmony_ci index = 7; 8118c2ecf20Sopenharmony_ci break; 8128c2ecf20Sopenharmony_ci default: 8138c2ecf20Sopenharmony_ci regaddr &= 0xFFF; 8148c2ecf20Sopenharmony_ci if (regaddr >= 0xC20 && regaddr <= 0xC4C) 8158c2ecf20Sopenharmony_ci index = (u8)((regaddr - 0xC20) / 4); 8168c2ecf20Sopenharmony_ci else if (regaddr >= 0xE20 && regaddr <= 0xE4C) 8178c2ecf20Sopenharmony_ci index = (u8)((regaddr - 0xE20) / 4); 8188c2ecf20Sopenharmony_ci break; 8198c2ecf20Sopenharmony_ci } 8208c2ecf20Sopenharmony_ci return index; 8218c2ecf20Sopenharmony_ci} 8228c2ecf20Sopenharmony_ci 8238c2ecf20Sopenharmony_cistatic void _rtl92ee_store_tx_power_by_rate(struct ieee80211_hw *hw, 8248c2ecf20Sopenharmony_ci enum band_type band, 8258c2ecf20Sopenharmony_ci enum radio_path rfpath, 8268c2ecf20Sopenharmony_ci u32 txnum, u32 regaddr, 8278c2ecf20Sopenharmony_ci u32 bitmask, u32 data) 8288c2ecf20Sopenharmony_ci{ 8298c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8308c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 8318c2ecf20Sopenharmony_ci u8 section = _rtl92ee_get_rate_section_index(regaddr); 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_ci if (band != BAND_ON_2_4G && band != BAND_ON_5G) { 8348c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band); 8358c2ecf20Sopenharmony_ci return; 8368c2ecf20Sopenharmony_ci } 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_ci if (rfpath > MAX_RF_PATH - 1) { 8398c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, 8408c2ecf20Sopenharmony_ci "Invalid RfPath %d\n", rfpath); 8418c2ecf20Sopenharmony_ci return; 8428c2ecf20Sopenharmony_ci } 8438c2ecf20Sopenharmony_ci if (txnum > MAX_RF_PATH - 1) { 8448c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum); 8458c2ecf20Sopenharmony_ci return; 8468c2ecf20Sopenharmony_ci } 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][section] = data; 8498c2ecf20Sopenharmony_ci} 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_cistatic bool phy_config_bb_with_pghdrfile(struct ieee80211_hw *hw, 8528c2ecf20Sopenharmony_ci u8 configtype) 8538c2ecf20Sopenharmony_ci{ 8548c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8558c2ecf20Sopenharmony_ci int i; 8568c2ecf20Sopenharmony_ci u32 *phy_regarray_table_pg; 8578c2ecf20Sopenharmony_ci u16 phy_regarray_pg_len; 8588c2ecf20Sopenharmony_ci u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0; 8598c2ecf20Sopenharmony_ci 8608c2ecf20Sopenharmony_ci phy_regarray_pg_len = RTL8192EE_PHY_REG_ARRAY_PG_LEN; 8618c2ecf20Sopenharmony_ci phy_regarray_table_pg = RTL8192EE_PHY_REG_ARRAY_PG; 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 8648c2ecf20Sopenharmony_ci for (i = 0; i < phy_regarray_pg_len; i = i + 6) { 8658c2ecf20Sopenharmony_ci v1 = phy_regarray_table_pg[i]; 8668c2ecf20Sopenharmony_ci v2 = phy_regarray_table_pg[i+1]; 8678c2ecf20Sopenharmony_ci v3 = phy_regarray_table_pg[i+2]; 8688c2ecf20Sopenharmony_ci v4 = phy_regarray_table_pg[i+3]; 8698c2ecf20Sopenharmony_ci v5 = phy_regarray_table_pg[i+4]; 8708c2ecf20Sopenharmony_ci v6 = phy_regarray_table_pg[i+5]; 8718c2ecf20Sopenharmony_ci 8728c2ecf20Sopenharmony_ci if (v1 < 0xcdcdcdcd) { 8738c2ecf20Sopenharmony_ci _rtl92ee_store_tx_power_by_rate(hw, v1, v2, v3, 8748c2ecf20Sopenharmony_ci v4, v5, v6); 8758c2ecf20Sopenharmony_ci continue; 8768c2ecf20Sopenharmony_ci } 8778c2ecf20Sopenharmony_ci } 8788c2ecf20Sopenharmony_ci } else { 8798c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, 8808c2ecf20Sopenharmony_ci "configtype != BaseBand_Config_PHY_REG\n"); 8818c2ecf20Sopenharmony_ci } 8828c2ecf20Sopenharmony_ci return true; 8838c2ecf20Sopenharmony_ci} 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_ci#define READ_NEXT_RF_PAIR(v1, v2, i) \ 8868c2ecf20Sopenharmony_ci do { \ 8878c2ecf20Sopenharmony_ci i += 2; \ 8888c2ecf20Sopenharmony_ci v1 = array[i]; \ 8898c2ecf20Sopenharmony_ci v2 = array[i+1]; \ 8908c2ecf20Sopenharmony_ci } while (0) 8918c2ecf20Sopenharmony_ci 8928c2ecf20Sopenharmony_cibool rtl92ee_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, 8938c2ecf20Sopenharmony_ci enum radio_path rfpath) 8948c2ecf20Sopenharmony_ci{ 8958c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8968c2ecf20Sopenharmony_ci int i; 8978c2ecf20Sopenharmony_ci u32 *array; 8988c2ecf20Sopenharmony_ci u16 len; 8998c2ecf20Sopenharmony_ci u32 v1 = 0, v2 = 0; 9008c2ecf20Sopenharmony_ci 9018c2ecf20Sopenharmony_ci switch (rfpath) { 9028c2ecf20Sopenharmony_ci case RF90_PATH_A: 9038c2ecf20Sopenharmony_ci len = RTL8192EE_RADIOA_ARRAY_LEN; 9048c2ecf20Sopenharmony_ci array = RTL8192EE_RADIOA_ARRAY; 9058c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 9068c2ecf20Sopenharmony_ci "Radio_A:RTL8192EE_RADIOA_ARRAY %d\n", len); 9078c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); 9088c2ecf20Sopenharmony_ci for (i = 0; i < len; i = i + 2) { 9098c2ecf20Sopenharmony_ci v1 = array[i]; 9108c2ecf20Sopenharmony_ci v2 = array[i+1]; 9118c2ecf20Sopenharmony_ci if (v1 < 0xcdcdcdcd) { 9128c2ecf20Sopenharmony_ci _rtl92ee_config_rf_radio_a(hw, v1, v2); 9138c2ecf20Sopenharmony_ci continue; 9148c2ecf20Sopenharmony_ci } else {/*This line is the start line of branch.*/ 9158c2ecf20Sopenharmony_ci /* to protect READ_NEXT_PAIR not overrun */ 9168c2ecf20Sopenharmony_ci if (i >= len - 2) 9178c2ecf20Sopenharmony_ci break; 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci if (!_check_condition(hw , array[i])) { 9208c2ecf20Sopenharmony_ci /*Discard the following pairs*/ 9218c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9228c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && 9238c2ecf20Sopenharmony_ci v2 != 0xCDEF && 9248c2ecf20Sopenharmony_ci v2 != 0xCDCD && i < len - 2) { 9258c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9268c2ecf20Sopenharmony_ci } 9278c2ecf20Sopenharmony_ci i -= 2; /* prevent from for-loop += 2*/ 9288c2ecf20Sopenharmony_ci } else { 9298c2ecf20Sopenharmony_ci /* Configure matched pairs and 9308c2ecf20Sopenharmony_ci * skip to end of if-else. 9318c2ecf20Sopenharmony_ci */ 9328c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9338c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && 9348c2ecf20Sopenharmony_ci v2 != 0xCDEF && 9358c2ecf20Sopenharmony_ci v2 != 0xCDCD && i < len - 2) { 9368c2ecf20Sopenharmony_ci _rtl92ee_config_rf_radio_a(hw, 9378c2ecf20Sopenharmony_ci v1, 9388c2ecf20Sopenharmony_ci v2); 9398c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9408c2ecf20Sopenharmony_ci } 9418c2ecf20Sopenharmony_ci 9428c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && i < len - 2) 9438c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9448c2ecf20Sopenharmony_ci } 9458c2ecf20Sopenharmony_ci } 9468c2ecf20Sopenharmony_ci } 9478c2ecf20Sopenharmony_ci break; 9488c2ecf20Sopenharmony_ci 9498c2ecf20Sopenharmony_ci case RF90_PATH_B: 9508c2ecf20Sopenharmony_ci len = RTL8192EE_RADIOB_ARRAY_LEN; 9518c2ecf20Sopenharmony_ci array = RTL8192EE_RADIOB_ARRAY; 9528c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 9538c2ecf20Sopenharmony_ci "Radio_A:RTL8192EE_RADIOB_ARRAY %d\n", len); 9548c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); 9558c2ecf20Sopenharmony_ci for (i = 0; i < len; i = i + 2) { 9568c2ecf20Sopenharmony_ci v1 = array[i]; 9578c2ecf20Sopenharmony_ci v2 = array[i+1]; 9588c2ecf20Sopenharmony_ci if (v1 < 0xcdcdcdcd) { 9598c2ecf20Sopenharmony_ci _rtl92ee_config_rf_radio_b(hw, v1, v2); 9608c2ecf20Sopenharmony_ci continue; 9618c2ecf20Sopenharmony_ci } else {/*This line is the start line of branch.*/ 9628c2ecf20Sopenharmony_ci /* to protect READ_NEXT_PAIR not overrun */ 9638c2ecf20Sopenharmony_ci if (i >= len - 2) 9648c2ecf20Sopenharmony_ci break; 9658c2ecf20Sopenharmony_ci 9668c2ecf20Sopenharmony_ci if (!_check_condition(hw , array[i])) { 9678c2ecf20Sopenharmony_ci /*Discard the following pairs*/ 9688c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9698c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && 9708c2ecf20Sopenharmony_ci v2 != 0xCDEF && 9718c2ecf20Sopenharmony_ci v2 != 0xCDCD && i < len - 2) { 9728c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9738c2ecf20Sopenharmony_ci } 9748c2ecf20Sopenharmony_ci i -= 2; /* prevent from for-loop += 2*/ 9758c2ecf20Sopenharmony_ci } else { 9768c2ecf20Sopenharmony_ci /* Configure matched pairs and 9778c2ecf20Sopenharmony_ci * skip to end of if-else. 9788c2ecf20Sopenharmony_ci */ 9798c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9808c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && 9818c2ecf20Sopenharmony_ci v2 != 0xCDEF && 9828c2ecf20Sopenharmony_ci v2 != 0xCDCD && i < len - 2) { 9838c2ecf20Sopenharmony_ci _rtl92ee_config_rf_radio_b(hw, 9848c2ecf20Sopenharmony_ci v1, 9858c2ecf20Sopenharmony_ci v2); 9868c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9878c2ecf20Sopenharmony_ci } 9888c2ecf20Sopenharmony_ci 9898c2ecf20Sopenharmony_ci while (v2 != 0xDEAD && i < len - 2) 9908c2ecf20Sopenharmony_ci READ_NEXT_RF_PAIR(v1, v2, i); 9918c2ecf20Sopenharmony_ci } 9928c2ecf20Sopenharmony_ci } 9938c2ecf20Sopenharmony_ci } 9948c2ecf20Sopenharmony_ci break; 9958c2ecf20Sopenharmony_ci case RF90_PATH_C: 9968c2ecf20Sopenharmony_ci case RF90_PATH_D: 9978c2ecf20Sopenharmony_ci break; 9988c2ecf20Sopenharmony_ci } 9998c2ecf20Sopenharmony_ci return true; 10008c2ecf20Sopenharmony_ci} 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_civoid rtl92ee_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) 10038c2ecf20Sopenharmony_ci{ 10048c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10058c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 10068c2ecf20Sopenharmony_ci 10078c2ecf20Sopenharmony_ci rtlphy->default_initialgain[0] = 10088c2ecf20Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); 10098c2ecf20Sopenharmony_ci rtlphy->default_initialgain[1] = 10108c2ecf20Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); 10118c2ecf20Sopenharmony_ci rtlphy->default_initialgain[2] = 10128c2ecf20Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); 10138c2ecf20Sopenharmony_ci rtlphy->default_initialgain[3] = 10148c2ecf20Sopenharmony_ci (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); 10158c2ecf20Sopenharmony_ci 10168c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 10178c2ecf20Sopenharmony_ci "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", 10188c2ecf20Sopenharmony_ci rtlphy->default_initialgain[0], 10198c2ecf20Sopenharmony_ci rtlphy->default_initialgain[1], 10208c2ecf20Sopenharmony_ci rtlphy->default_initialgain[2], 10218c2ecf20Sopenharmony_ci rtlphy->default_initialgain[3]); 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_ci rtlphy->framesync = (u8)rtl_get_bbreg(hw, 10248c2ecf20Sopenharmony_ci ROFDM0_RXDETECTOR3, MASKBYTE0); 10258c2ecf20Sopenharmony_ci rtlphy->framesync_c34 = rtl_get_bbreg(hw, 10268c2ecf20Sopenharmony_ci ROFDM0_RXDETECTOR2, MASKDWORD); 10278c2ecf20Sopenharmony_ci 10288c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 10298c2ecf20Sopenharmony_ci "Default framesync (0x%x) = 0x%x\n", 10308c2ecf20Sopenharmony_ci ROFDM0_RXDETECTOR3, rtlphy->framesync); 10318c2ecf20Sopenharmony_ci} 10328c2ecf20Sopenharmony_ci 10338c2ecf20Sopenharmony_cistatic void phy_init_bb_rf_register_def(struct ieee80211_hw *hw) 10348c2ecf20Sopenharmony_ci{ 10358c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10368c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 10378c2ecf20Sopenharmony_ci 10388c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; 10398c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; 10408c2ecf20Sopenharmony_ci 10418c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; 10428c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; 10438c2ecf20Sopenharmony_ci 10448c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; 10458c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; 10468c2ecf20Sopenharmony_ci 10478c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = 10488c2ecf20Sopenharmony_ci RFPGA0_XA_LSSIPARAMETER; 10498c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = 10508c2ecf20Sopenharmony_ci RFPGA0_XB_LSSIPARAMETER; 10518c2ecf20Sopenharmony_ci 10528c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; 10538c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; 10548c2ecf20Sopenharmony_ci 10558c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; 10568c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; 10578c2ecf20Sopenharmony_ci 10588c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVEA_HSPI_READBACK; 10598c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVEB_HSPI_READBACK; 10608c2ecf20Sopenharmony_ci} 10618c2ecf20Sopenharmony_ci 10628c2ecf20Sopenharmony_civoid rtl92ee_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) 10638c2ecf20Sopenharmony_ci{ 10648c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10658c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 10668c2ecf20Sopenharmony_ci u8 txpwr_level; 10678c2ecf20Sopenharmony_ci long txpwr_dbm; 10688c2ecf20Sopenharmony_ci 10698c2ecf20Sopenharmony_ci txpwr_level = rtlphy->cur_cck_txpwridx; 10708c2ecf20Sopenharmony_ci txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_B, 10718c2ecf20Sopenharmony_ci txpwr_level); 10728c2ecf20Sopenharmony_ci txpwr_level = rtlphy->cur_ofdm24g_txpwridx; 10738c2ecf20Sopenharmony_ci if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, txpwr_level) > 10748c2ecf20Sopenharmony_ci txpwr_dbm) 10758c2ecf20Sopenharmony_ci txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, 10768c2ecf20Sopenharmony_ci txpwr_level); 10778c2ecf20Sopenharmony_ci txpwr_level = rtlphy->cur_ofdm24g_txpwridx; 10788c2ecf20Sopenharmony_ci if (_rtl92ee_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, 10798c2ecf20Sopenharmony_ci txpwr_level) > txpwr_dbm) 10808c2ecf20Sopenharmony_ci txpwr_dbm = _rtl92ee_phy_txpwr_idx_to_dbm(hw, 10818c2ecf20Sopenharmony_ci WIRELESS_MODE_N_24G, 10828c2ecf20Sopenharmony_ci txpwr_level); 10838c2ecf20Sopenharmony_ci *powerlevel = txpwr_dbm; 10848c2ecf20Sopenharmony_ci} 10858c2ecf20Sopenharmony_ci 10868c2ecf20Sopenharmony_cistatic u8 _rtl92ee_phy_get_ratesection_intxpower_byrate(enum radio_path path, 10878c2ecf20Sopenharmony_ci u8 rate) 10888c2ecf20Sopenharmony_ci{ 10898c2ecf20Sopenharmony_ci u8 rate_section = 0; 10908c2ecf20Sopenharmony_ci 10918c2ecf20Sopenharmony_ci switch (rate) { 10928c2ecf20Sopenharmony_ci case DESC92C_RATE1M: 10938c2ecf20Sopenharmony_ci rate_section = 2; 10948c2ecf20Sopenharmony_ci break; 10958c2ecf20Sopenharmony_ci case DESC92C_RATE2M: 10968c2ecf20Sopenharmony_ci case DESC92C_RATE5_5M: 10978c2ecf20Sopenharmony_ci if (path == RF90_PATH_A) 10988c2ecf20Sopenharmony_ci rate_section = 3; 10998c2ecf20Sopenharmony_ci else if (path == RF90_PATH_B) 11008c2ecf20Sopenharmony_ci rate_section = 2; 11018c2ecf20Sopenharmony_ci break; 11028c2ecf20Sopenharmony_ci case DESC92C_RATE11M: 11038c2ecf20Sopenharmony_ci rate_section = 3; 11048c2ecf20Sopenharmony_ci break; 11058c2ecf20Sopenharmony_ci case DESC92C_RATE6M: 11068c2ecf20Sopenharmony_ci case DESC92C_RATE9M: 11078c2ecf20Sopenharmony_ci case DESC92C_RATE12M: 11088c2ecf20Sopenharmony_ci case DESC92C_RATE18M: 11098c2ecf20Sopenharmony_ci rate_section = 0; 11108c2ecf20Sopenharmony_ci break; 11118c2ecf20Sopenharmony_ci case DESC92C_RATE24M: 11128c2ecf20Sopenharmony_ci case DESC92C_RATE36M: 11138c2ecf20Sopenharmony_ci case DESC92C_RATE48M: 11148c2ecf20Sopenharmony_ci case DESC92C_RATE54M: 11158c2ecf20Sopenharmony_ci rate_section = 1; 11168c2ecf20Sopenharmony_ci break; 11178c2ecf20Sopenharmony_ci case DESC92C_RATEMCS0: 11188c2ecf20Sopenharmony_ci case DESC92C_RATEMCS1: 11198c2ecf20Sopenharmony_ci case DESC92C_RATEMCS2: 11208c2ecf20Sopenharmony_ci case DESC92C_RATEMCS3: 11218c2ecf20Sopenharmony_ci rate_section = 4; 11228c2ecf20Sopenharmony_ci break; 11238c2ecf20Sopenharmony_ci case DESC92C_RATEMCS4: 11248c2ecf20Sopenharmony_ci case DESC92C_RATEMCS5: 11258c2ecf20Sopenharmony_ci case DESC92C_RATEMCS6: 11268c2ecf20Sopenharmony_ci case DESC92C_RATEMCS7: 11278c2ecf20Sopenharmony_ci rate_section = 5; 11288c2ecf20Sopenharmony_ci break; 11298c2ecf20Sopenharmony_ci case DESC92C_RATEMCS8: 11308c2ecf20Sopenharmony_ci case DESC92C_RATEMCS9: 11318c2ecf20Sopenharmony_ci case DESC92C_RATEMCS10: 11328c2ecf20Sopenharmony_ci case DESC92C_RATEMCS11: 11338c2ecf20Sopenharmony_ci rate_section = 6; 11348c2ecf20Sopenharmony_ci break; 11358c2ecf20Sopenharmony_ci case DESC92C_RATEMCS12: 11368c2ecf20Sopenharmony_ci case DESC92C_RATEMCS13: 11378c2ecf20Sopenharmony_ci case DESC92C_RATEMCS14: 11388c2ecf20Sopenharmony_ci case DESC92C_RATEMCS15: 11398c2ecf20Sopenharmony_ci rate_section = 7; 11408c2ecf20Sopenharmony_ci break; 11418c2ecf20Sopenharmony_ci default: 11428c2ecf20Sopenharmony_ci WARN_ONCE(true, "rtl8192ee: Rate_Section is Illegal\n"); 11438c2ecf20Sopenharmony_ci break; 11448c2ecf20Sopenharmony_ci } 11458c2ecf20Sopenharmony_ci return rate_section; 11468c2ecf20Sopenharmony_ci} 11478c2ecf20Sopenharmony_ci 11488c2ecf20Sopenharmony_cistatic u8 _rtl92ee_get_txpower_by_rate(struct ieee80211_hw *hw, 11498c2ecf20Sopenharmony_ci enum band_type band, 11508c2ecf20Sopenharmony_ci enum radio_path rf, u8 rate) 11518c2ecf20Sopenharmony_ci{ 11528c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11538c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 11548c2ecf20Sopenharmony_ci u8 shift = 0, sec, tx_num; 11558c2ecf20Sopenharmony_ci s8 diff = 0; 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_ci sec = _rtl92ee_phy_get_ratesection_intxpower_byrate(rf, rate); 11588c2ecf20Sopenharmony_ci tx_num = RF_TX_NUM_NONIMPLEMENT; 11598c2ecf20Sopenharmony_ci 11608c2ecf20Sopenharmony_ci if (tx_num == RF_TX_NUM_NONIMPLEMENT) { 11618c2ecf20Sopenharmony_ci if ((rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)) 11628c2ecf20Sopenharmony_ci tx_num = RF_2TX; 11638c2ecf20Sopenharmony_ci else 11648c2ecf20Sopenharmony_ci tx_num = RF_1TX; 11658c2ecf20Sopenharmony_ci } 11668c2ecf20Sopenharmony_ci 11678c2ecf20Sopenharmony_ci switch (rate) { 11688c2ecf20Sopenharmony_ci case DESC92C_RATE1M: 11698c2ecf20Sopenharmony_ci case DESC92C_RATE6M: 11708c2ecf20Sopenharmony_ci case DESC92C_RATE24M: 11718c2ecf20Sopenharmony_ci case DESC92C_RATEMCS0: 11728c2ecf20Sopenharmony_ci case DESC92C_RATEMCS4: 11738c2ecf20Sopenharmony_ci case DESC92C_RATEMCS8: 11748c2ecf20Sopenharmony_ci case DESC92C_RATEMCS12: 11758c2ecf20Sopenharmony_ci shift = 0; 11768c2ecf20Sopenharmony_ci break; 11778c2ecf20Sopenharmony_ci case DESC92C_RATE2M: 11788c2ecf20Sopenharmony_ci case DESC92C_RATE9M: 11798c2ecf20Sopenharmony_ci case DESC92C_RATE36M: 11808c2ecf20Sopenharmony_ci case DESC92C_RATEMCS1: 11818c2ecf20Sopenharmony_ci case DESC92C_RATEMCS5: 11828c2ecf20Sopenharmony_ci case DESC92C_RATEMCS9: 11838c2ecf20Sopenharmony_ci case DESC92C_RATEMCS13: 11848c2ecf20Sopenharmony_ci shift = 8; 11858c2ecf20Sopenharmony_ci break; 11868c2ecf20Sopenharmony_ci case DESC92C_RATE5_5M: 11878c2ecf20Sopenharmony_ci case DESC92C_RATE12M: 11888c2ecf20Sopenharmony_ci case DESC92C_RATE48M: 11898c2ecf20Sopenharmony_ci case DESC92C_RATEMCS2: 11908c2ecf20Sopenharmony_ci case DESC92C_RATEMCS6: 11918c2ecf20Sopenharmony_ci case DESC92C_RATEMCS10: 11928c2ecf20Sopenharmony_ci case DESC92C_RATEMCS14: 11938c2ecf20Sopenharmony_ci shift = 16; 11948c2ecf20Sopenharmony_ci break; 11958c2ecf20Sopenharmony_ci case DESC92C_RATE11M: 11968c2ecf20Sopenharmony_ci case DESC92C_RATE18M: 11978c2ecf20Sopenharmony_ci case DESC92C_RATE54M: 11988c2ecf20Sopenharmony_ci case DESC92C_RATEMCS3: 11998c2ecf20Sopenharmony_ci case DESC92C_RATEMCS7: 12008c2ecf20Sopenharmony_ci case DESC92C_RATEMCS11: 12018c2ecf20Sopenharmony_ci case DESC92C_RATEMCS15: 12028c2ecf20Sopenharmony_ci shift = 24; 12038c2ecf20Sopenharmony_ci break; 12048c2ecf20Sopenharmony_ci default: 12058c2ecf20Sopenharmony_ci WARN_ONCE(true, "rtl8192ee: Rate_Section is Illegal\n"); 12068c2ecf20Sopenharmony_ci break; 12078c2ecf20Sopenharmony_ci } 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rf][tx_num][sec] >> 12108c2ecf20Sopenharmony_ci shift) & 0xff; 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci return diff; 12138c2ecf20Sopenharmony_ci} 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_cistatic u8 _rtl92ee_get_txpower_index(struct ieee80211_hw *hw, 12168c2ecf20Sopenharmony_ci enum radio_path rfpath, u8 rate, 12178c2ecf20Sopenharmony_ci u8 bw, u8 channel) 12188c2ecf20Sopenharmony_ci{ 12198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 12208c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); 12218c2ecf20Sopenharmony_ci u8 index = (channel - 1); 12228c2ecf20Sopenharmony_ci u8 tx_power = 0; 12238c2ecf20Sopenharmony_ci u8 diff = 0; 12248c2ecf20Sopenharmony_ci 12258c2ecf20Sopenharmony_ci if (channel < 1 || channel > 14) { 12268c2ecf20Sopenharmony_ci index = 0; 12278c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_DMESG, 12288c2ecf20Sopenharmony_ci "Illegal channel!!\n"); 12298c2ecf20Sopenharmony_ci } 12308c2ecf20Sopenharmony_ci 12318c2ecf20Sopenharmony_ci if (IS_CCK_RATE((s8)rate)) 12328c2ecf20Sopenharmony_ci tx_power = rtlefuse->txpwrlevel_cck[rfpath][index]; 12338c2ecf20Sopenharmony_ci else if (DESC92C_RATE6M <= rate) 12348c2ecf20Sopenharmony_ci tx_power = rtlefuse->txpwrlevel_ht40_1s[rfpath][index]; 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ci /* OFDM-1T*/ 12378c2ecf20Sopenharmony_ci if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M && 12388c2ecf20Sopenharmony_ci !IS_CCK_RATE((s8)rate)) 12398c2ecf20Sopenharmony_ci tx_power += rtlefuse->txpwr_legacyhtdiff[rfpath][TX_1S]; 12408c2ecf20Sopenharmony_ci 12418c2ecf20Sopenharmony_ci /* BW20-1S, BW20-2S */ 12428c2ecf20Sopenharmony_ci if (bw == HT_CHANNEL_WIDTH_20) { 12438c2ecf20Sopenharmony_ci if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) 12448c2ecf20Sopenharmony_ci tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_1S]; 12458c2ecf20Sopenharmony_ci if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) 12468c2ecf20Sopenharmony_ci tx_power += rtlefuse->txpwr_ht20diff[rfpath][TX_2S]; 12478c2ecf20Sopenharmony_ci } else if (bw == HT_CHANNEL_WIDTH_20_40) {/* BW40-1S, BW40-2S */ 12488c2ecf20Sopenharmony_ci if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15) 12498c2ecf20Sopenharmony_ci tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_1S]; 12508c2ecf20Sopenharmony_ci if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) 12518c2ecf20Sopenharmony_ci tx_power += rtlefuse->txpwr_ht40diff[rfpath][TX_2S]; 12528c2ecf20Sopenharmony_ci } 12538c2ecf20Sopenharmony_ci 12548c2ecf20Sopenharmony_ci if (rtlefuse->eeprom_regulatory != 2) 12558c2ecf20Sopenharmony_ci diff = _rtl92ee_get_txpower_by_rate(hw, BAND_ON_2_4G, 12568c2ecf20Sopenharmony_ci rfpath, rate); 12578c2ecf20Sopenharmony_ci 12588c2ecf20Sopenharmony_ci tx_power += diff; 12598c2ecf20Sopenharmony_ci 12608c2ecf20Sopenharmony_ci if (tx_power > MAX_POWER_INDEX) 12618c2ecf20Sopenharmony_ci tx_power = MAX_POWER_INDEX; 12628c2ecf20Sopenharmony_ci 12638c2ecf20Sopenharmony_ci return tx_power; 12648c2ecf20Sopenharmony_ci} 12658c2ecf20Sopenharmony_ci 12668c2ecf20Sopenharmony_cistatic void _rtl92ee_set_txpower_index(struct ieee80211_hw *hw, u8 pwr_idx, 12678c2ecf20Sopenharmony_ci enum radio_path rfpath, u8 rate) 12688c2ecf20Sopenharmony_ci{ 12698c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 12708c2ecf20Sopenharmony_ci 12718c2ecf20Sopenharmony_ci if (rfpath == RF90_PATH_A) { 12728c2ecf20Sopenharmony_ci switch (rate) { 12738c2ecf20Sopenharmony_ci case DESC92C_RATE1M: 12748c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_CCK1_MCS32, MASKBYTE1, 12758c2ecf20Sopenharmony_ci pwr_idx); 12768c2ecf20Sopenharmony_ci break; 12778c2ecf20Sopenharmony_ci case DESC92C_RATE2M: 12788c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE1, 12798c2ecf20Sopenharmony_ci pwr_idx); 12808c2ecf20Sopenharmony_ci break; 12818c2ecf20Sopenharmony_ci case DESC92C_RATE5_5M: 12828c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE2, 12838c2ecf20Sopenharmony_ci pwr_idx); 12848c2ecf20Sopenharmony_ci break; 12858c2ecf20Sopenharmony_ci case DESC92C_RATE11M: 12868c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE3, 12878c2ecf20Sopenharmony_ci pwr_idx); 12888c2ecf20Sopenharmony_ci break; 12898c2ecf20Sopenharmony_ci case DESC92C_RATE6M: 12908c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE0, 12918c2ecf20Sopenharmony_ci pwr_idx); 12928c2ecf20Sopenharmony_ci break; 12938c2ecf20Sopenharmony_ci case DESC92C_RATE9M: 12948c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE1, 12958c2ecf20Sopenharmony_ci pwr_idx); 12968c2ecf20Sopenharmony_ci break; 12978c2ecf20Sopenharmony_ci case DESC92C_RATE12M: 12988c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE2, 12998c2ecf20Sopenharmony_ci pwr_idx); 13008c2ecf20Sopenharmony_ci break; 13018c2ecf20Sopenharmony_ci case DESC92C_RATE18M: 13028c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_RATE18_06, MASKBYTE3, 13038c2ecf20Sopenharmony_ci pwr_idx); 13048c2ecf20Sopenharmony_ci break; 13058c2ecf20Sopenharmony_ci case DESC92C_RATE24M: 13068c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE0, 13078c2ecf20Sopenharmony_ci pwr_idx); 13088c2ecf20Sopenharmony_ci break; 13098c2ecf20Sopenharmony_ci case DESC92C_RATE36M: 13108c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE1, 13118c2ecf20Sopenharmony_ci pwr_idx); 13128c2ecf20Sopenharmony_ci break; 13138c2ecf20Sopenharmony_ci case DESC92C_RATE48M: 13148c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE2, 13158c2ecf20Sopenharmony_ci pwr_idx); 13168c2ecf20Sopenharmony_ci break; 13178c2ecf20Sopenharmony_ci case DESC92C_RATE54M: 13188c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_RATE54_24, MASKBYTE3, 13198c2ecf20Sopenharmony_ci pwr_idx); 13208c2ecf20Sopenharmony_ci break; 13218c2ecf20Sopenharmony_ci case DESC92C_RATEMCS0: 13228c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE0, 13238c2ecf20Sopenharmony_ci pwr_idx); 13248c2ecf20Sopenharmony_ci break; 13258c2ecf20Sopenharmony_ci case DESC92C_RATEMCS1: 13268c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE1, 13278c2ecf20Sopenharmony_ci pwr_idx); 13288c2ecf20Sopenharmony_ci break; 13298c2ecf20Sopenharmony_ci case DESC92C_RATEMCS2: 13308c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE2, 13318c2ecf20Sopenharmony_ci pwr_idx); 13328c2ecf20Sopenharmony_ci break; 13338c2ecf20Sopenharmony_ci case DESC92C_RATEMCS3: 13348c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE3, 13358c2ecf20Sopenharmony_ci pwr_idx); 13368c2ecf20Sopenharmony_ci break; 13378c2ecf20Sopenharmony_ci case DESC92C_RATEMCS4: 13388c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE0, 13398c2ecf20Sopenharmony_ci pwr_idx); 13408c2ecf20Sopenharmony_ci break; 13418c2ecf20Sopenharmony_ci case DESC92C_RATEMCS5: 13428c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE1, 13438c2ecf20Sopenharmony_ci pwr_idx); 13448c2ecf20Sopenharmony_ci break; 13458c2ecf20Sopenharmony_ci case DESC92C_RATEMCS6: 13468c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE2, 13478c2ecf20Sopenharmony_ci pwr_idx); 13488c2ecf20Sopenharmony_ci break; 13498c2ecf20Sopenharmony_ci case DESC92C_RATEMCS7: 13508c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE3, 13518c2ecf20Sopenharmony_ci pwr_idx); 13528c2ecf20Sopenharmony_ci break; 13538c2ecf20Sopenharmony_ci case DESC92C_RATEMCS8: 13548c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE0, 13558c2ecf20Sopenharmony_ci pwr_idx); 13568c2ecf20Sopenharmony_ci break; 13578c2ecf20Sopenharmony_ci case DESC92C_RATEMCS9: 13588c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE1, 13598c2ecf20Sopenharmony_ci pwr_idx); 13608c2ecf20Sopenharmony_ci break; 13618c2ecf20Sopenharmony_ci case DESC92C_RATEMCS10: 13628c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE2, 13638c2ecf20Sopenharmony_ci pwr_idx); 13648c2ecf20Sopenharmony_ci break; 13658c2ecf20Sopenharmony_ci case DESC92C_RATEMCS11: 13668c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE3, 13678c2ecf20Sopenharmony_ci pwr_idx); 13688c2ecf20Sopenharmony_ci break; 13698c2ecf20Sopenharmony_ci case DESC92C_RATEMCS12: 13708c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE0, 13718c2ecf20Sopenharmony_ci pwr_idx); 13728c2ecf20Sopenharmony_ci break; 13738c2ecf20Sopenharmony_ci case DESC92C_RATEMCS13: 13748c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE1, 13758c2ecf20Sopenharmony_ci pwr_idx); 13768c2ecf20Sopenharmony_ci break; 13778c2ecf20Sopenharmony_ci case DESC92C_RATEMCS14: 13788c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE2, 13798c2ecf20Sopenharmony_ci pwr_idx); 13808c2ecf20Sopenharmony_ci break; 13818c2ecf20Sopenharmony_ci case DESC92C_RATEMCS15: 13828c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, MASKBYTE3, 13838c2ecf20Sopenharmony_ci pwr_idx); 13848c2ecf20Sopenharmony_ci break; 13858c2ecf20Sopenharmony_ci default: 13868c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 13878c2ecf20Sopenharmony_ci "Invalid Rate!!\n"); 13888c2ecf20Sopenharmony_ci break; 13898c2ecf20Sopenharmony_ci } 13908c2ecf20Sopenharmony_ci } else if (rfpath == RF90_PATH_B) { 13918c2ecf20Sopenharmony_ci switch (rate) { 13928c2ecf20Sopenharmony_ci case DESC92C_RATE1M: 13938c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE1, 13948c2ecf20Sopenharmony_ci pwr_idx); 13958c2ecf20Sopenharmony_ci break; 13968c2ecf20Sopenharmony_ci case DESC92C_RATE2M: 13978c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE2, 13988c2ecf20Sopenharmony_ci pwr_idx); 13998c2ecf20Sopenharmony_ci break; 14008c2ecf20Sopenharmony_ci case DESC92C_RATE5_5M: 14018c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_CCK1_55_MCS32, MASKBYTE3, 14028c2ecf20Sopenharmony_ci pwr_idx); 14038c2ecf20Sopenharmony_ci break; 14048c2ecf20Sopenharmony_ci case DESC92C_RATE11M: 14058c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE0, 14068c2ecf20Sopenharmony_ci pwr_idx); 14078c2ecf20Sopenharmony_ci break; 14088c2ecf20Sopenharmony_ci case DESC92C_RATE6M: 14098c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE0, 14108c2ecf20Sopenharmony_ci pwr_idx); 14118c2ecf20Sopenharmony_ci break; 14128c2ecf20Sopenharmony_ci case DESC92C_RATE9M: 14138c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE1, 14148c2ecf20Sopenharmony_ci pwr_idx); 14158c2ecf20Sopenharmony_ci break; 14168c2ecf20Sopenharmony_ci case DESC92C_RATE12M: 14178c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE2, 14188c2ecf20Sopenharmony_ci pwr_idx); 14198c2ecf20Sopenharmony_ci break; 14208c2ecf20Sopenharmony_ci case DESC92C_RATE18M: 14218c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_RATE18_06, MASKBYTE3, 14228c2ecf20Sopenharmony_ci pwr_idx); 14238c2ecf20Sopenharmony_ci break; 14248c2ecf20Sopenharmony_ci case DESC92C_RATE24M: 14258c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE0, 14268c2ecf20Sopenharmony_ci pwr_idx); 14278c2ecf20Sopenharmony_ci break; 14288c2ecf20Sopenharmony_ci case DESC92C_RATE36M: 14298c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE1, 14308c2ecf20Sopenharmony_ci pwr_idx); 14318c2ecf20Sopenharmony_ci break; 14328c2ecf20Sopenharmony_ci case DESC92C_RATE48M: 14338c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE2, 14348c2ecf20Sopenharmony_ci pwr_idx); 14358c2ecf20Sopenharmony_ci break; 14368c2ecf20Sopenharmony_ci case DESC92C_RATE54M: 14378c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_RATE54_24, MASKBYTE3, 14388c2ecf20Sopenharmony_ci pwr_idx); 14398c2ecf20Sopenharmony_ci break; 14408c2ecf20Sopenharmony_ci case DESC92C_RATEMCS0: 14418c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE0, 14428c2ecf20Sopenharmony_ci pwr_idx); 14438c2ecf20Sopenharmony_ci break; 14448c2ecf20Sopenharmony_ci case DESC92C_RATEMCS1: 14458c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE1, 14468c2ecf20Sopenharmony_ci pwr_idx); 14478c2ecf20Sopenharmony_ci break; 14488c2ecf20Sopenharmony_ci case DESC92C_RATEMCS2: 14498c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE2, 14508c2ecf20Sopenharmony_ci pwr_idx); 14518c2ecf20Sopenharmony_ci break; 14528c2ecf20Sopenharmony_ci case DESC92C_RATEMCS3: 14538c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, MASKBYTE3, 14548c2ecf20Sopenharmony_ci pwr_idx); 14558c2ecf20Sopenharmony_ci break; 14568c2ecf20Sopenharmony_ci case DESC92C_RATEMCS4: 14578c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE0, 14588c2ecf20Sopenharmony_ci pwr_idx); 14598c2ecf20Sopenharmony_ci break; 14608c2ecf20Sopenharmony_ci case DESC92C_RATEMCS5: 14618c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE1, 14628c2ecf20Sopenharmony_ci pwr_idx); 14638c2ecf20Sopenharmony_ci break; 14648c2ecf20Sopenharmony_ci case DESC92C_RATEMCS6: 14658c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE2, 14668c2ecf20Sopenharmony_ci pwr_idx); 14678c2ecf20Sopenharmony_ci break; 14688c2ecf20Sopenharmony_ci case DESC92C_RATEMCS7: 14698c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, MASKBYTE3, 14708c2ecf20Sopenharmony_ci pwr_idx); 14718c2ecf20Sopenharmony_ci break; 14728c2ecf20Sopenharmony_ci case DESC92C_RATEMCS8: 14738c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE0, 14748c2ecf20Sopenharmony_ci pwr_idx); 14758c2ecf20Sopenharmony_ci break; 14768c2ecf20Sopenharmony_ci case DESC92C_RATEMCS9: 14778c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE1, 14788c2ecf20Sopenharmony_ci pwr_idx); 14798c2ecf20Sopenharmony_ci break; 14808c2ecf20Sopenharmony_ci case DESC92C_RATEMCS10: 14818c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE2, 14828c2ecf20Sopenharmony_ci pwr_idx); 14838c2ecf20Sopenharmony_ci break; 14848c2ecf20Sopenharmony_ci case DESC92C_RATEMCS11: 14858c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, MASKBYTE3, 14868c2ecf20Sopenharmony_ci pwr_idx); 14878c2ecf20Sopenharmony_ci break; 14888c2ecf20Sopenharmony_ci case DESC92C_RATEMCS12: 14898c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE0, 14908c2ecf20Sopenharmony_ci pwr_idx); 14918c2ecf20Sopenharmony_ci break; 14928c2ecf20Sopenharmony_ci case DESC92C_RATEMCS13: 14938c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE1, 14948c2ecf20Sopenharmony_ci pwr_idx); 14958c2ecf20Sopenharmony_ci break; 14968c2ecf20Sopenharmony_ci case DESC92C_RATEMCS14: 14978c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE2, 14988c2ecf20Sopenharmony_ci pwr_idx); 14998c2ecf20Sopenharmony_ci break; 15008c2ecf20Sopenharmony_ci case DESC92C_RATEMCS15: 15018c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, MASKBYTE3, 15028c2ecf20Sopenharmony_ci pwr_idx); 15038c2ecf20Sopenharmony_ci break; 15048c2ecf20Sopenharmony_ci default: 15058c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 15068c2ecf20Sopenharmony_ci "Invalid Rate!!\n"); 15078c2ecf20Sopenharmony_ci break; 15088c2ecf20Sopenharmony_ci } 15098c2ecf20Sopenharmony_ci } else { 15108c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n"); 15118c2ecf20Sopenharmony_ci } 15128c2ecf20Sopenharmony_ci} 15138c2ecf20Sopenharmony_ci 15148c2ecf20Sopenharmony_cistatic void phy_set_txpower_index_by_rate_array(struct ieee80211_hw *hw, 15158c2ecf20Sopenharmony_ci enum radio_path rfpath, u8 bw, 15168c2ecf20Sopenharmony_ci u8 channel, u8 *rates, u8 size) 15178c2ecf20Sopenharmony_ci{ 15188c2ecf20Sopenharmony_ci u8 i; 15198c2ecf20Sopenharmony_ci u8 power_index; 15208c2ecf20Sopenharmony_ci 15218c2ecf20Sopenharmony_ci for (i = 0; i < size; i++) { 15228c2ecf20Sopenharmony_ci power_index = _rtl92ee_get_txpower_index(hw, rfpath, rates[i], 15238c2ecf20Sopenharmony_ci bw, channel); 15248c2ecf20Sopenharmony_ci _rtl92ee_set_txpower_index(hw, power_index, rfpath, rates[i]); 15258c2ecf20Sopenharmony_ci } 15268c2ecf20Sopenharmony_ci} 15278c2ecf20Sopenharmony_ci 15288c2ecf20Sopenharmony_cistatic void phy_set_txpower_index_by_rate_section(struct ieee80211_hw *hw, 15298c2ecf20Sopenharmony_ci enum radio_path rfpath, 15308c2ecf20Sopenharmony_ci u8 channel, 15318c2ecf20Sopenharmony_ci enum rate_section section) 15328c2ecf20Sopenharmony_ci{ 15338c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 15348c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 15358c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 15368c2ecf20Sopenharmony_ci 15378c2ecf20Sopenharmony_ci if (section == CCK) { 15388c2ecf20Sopenharmony_ci u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M, 15398c2ecf20Sopenharmony_ci DESC92C_RATE5_5M, DESC92C_RATE11M}; 15408c2ecf20Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_2_4G) 15418c2ecf20Sopenharmony_ci phy_set_txpower_index_by_rate_array(hw, rfpath, 15428c2ecf20Sopenharmony_ci rtlphy->current_chan_bw, 15438c2ecf20Sopenharmony_ci channel, cck_rates, 4); 15448c2ecf20Sopenharmony_ci } else if (section == OFDM) { 15458c2ecf20Sopenharmony_ci u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M, 15468c2ecf20Sopenharmony_ci DESC92C_RATE12M, DESC92C_RATE18M, 15478c2ecf20Sopenharmony_ci DESC92C_RATE24M, DESC92C_RATE36M, 15488c2ecf20Sopenharmony_ci DESC92C_RATE48M, DESC92C_RATE54M}; 15498c2ecf20Sopenharmony_ci phy_set_txpower_index_by_rate_array(hw, rfpath, 15508c2ecf20Sopenharmony_ci rtlphy->current_chan_bw, 15518c2ecf20Sopenharmony_ci channel, ofdm_rates, 8); 15528c2ecf20Sopenharmony_ci } else if (section == HT_MCS0_MCS7) { 15538c2ecf20Sopenharmony_ci u8 ht_rates1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1, 15548c2ecf20Sopenharmony_ci DESC92C_RATEMCS2, DESC92C_RATEMCS3, 15558c2ecf20Sopenharmony_ci DESC92C_RATEMCS4, DESC92C_RATEMCS5, 15568c2ecf20Sopenharmony_ci DESC92C_RATEMCS6, DESC92C_RATEMCS7}; 15578c2ecf20Sopenharmony_ci phy_set_txpower_index_by_rate_array(hw, rfpath, 15588c2ecf20Sopenharmony_ci rtlphy->current_chan_bw, 15598c2ecf20Sopenharmony_ci channel, ht_rates1t, 8); 15608c2ecf20Sopenharmony_ci } else if (section == HT_MCS8_MCS15) { 15618c2ecf20Sopenharmony_ci u8 ht_rates2t[] = {DESC92C_RATEMCS8, DESC92C_RATEMCS9, 15628c2ecf20Sopenharmony_ci DESC92C_RATEMCS10, DESC92C_RATEMCS11, 15638c2ecf20Sopenharmony_ci DESC92C_RATEMCS12, DESC92C_RATEMCS13, 15648c2ecf20Sopenharmony_ci DESC92C_RATEMCS14, DESC92C_RATEMCS15}; 15658c2ecf20Sopenharmony_ci phy_set_txpower_index_by_rate_array(hw, rfpath, 15668c2ecf20Sopenharmony_ci rtlphy->current_chan_bw, 15678c2ecf20Sopenharmony_ci channel, ht_rates2t, 8); 15688c2ecf20Sopenharmony_ci } else 15698c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, FPHY, PHY_TXPWR, 15708c2ecf20Sopenharmony_ci "Invalid RateSection %d\n", section); 15718c2ecf20Sopenharmony_ci} 15728c2ecf20Sopenharmony_ci 15738c2ecf20Sopenharmony_civoid rtl92ee_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) 15748c2ecf20Sopenharmony_ci{ 15758c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 15768c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtl_priv(hw)->phy; 15778c2ecf20Sopenharmony_ci enum radio_path rfpath; 15788c2ecf20Sopenharmony_ci 15798c2ecf20Sopenharmony_ci if (!rtlefuse->txpwr_fromeprom) 15808c2ecf20Sopenharmony_ci return; 15818c2ecf20Sopenharmony_ci for (rfpath = RF90_PATH_A; rfpath < rtlphy->num_total_rfpath; 15828c2ecf20Sopenharmony_ci rfpath++) { 15838c2ecf20Sopenharmony_ci phy_set_txpower_index_by_rate_section(hw, rfpath, 15848c2ecf20Sopenharmony_ci channel, CCK); 15858c2ecf20Sopenharmony_ci phy_set_txpower_index_by_rate_section(hw, rfpath, 15868c2ecf20Sopenharmony_ci channel, OFDM); 15878c2ecf20Sopenharmony_ci phy_set_txpower_index_by_rate_section(hw, rfpath, 15888c2ecf20Sopenharmony_ci channel, 15898c2ecf20Sopenharmony_ci HT_MCS0_MCS7); 15908c2ecf20Sopenharmony_ci 15918c2ecf20Sopenharmony_ci if (rtlphy->num_total_rfpath >= 2) 15928c2ecf20Sopenharmony_ci phy_set_txpower_index_by_rate_section(hw, 15938c2ecf20Sopenharmony_ci rfpath, channel, 15948c2ecf20Sopenharmony_ci HT_MCS8_MCS15); 15958c2ecf20Sopenharmony_ci } 15968c2ecf20Sopenharmony_ci} 15978c2ecf20Sopenharmony_ci 15988c2ecf20Sopenharmony_cistatic long _rtl92ee_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, 15998c2ecf20Sopenharmony_ci enum wireless_mode wirelessmode, 16008c2ecf20Sopenharmony_ci u8 txpwridx) 16018c2ecf20Sopenharmony_ci{ 16028c2ecf20Sopenharmony_ci long offset; 16038c2ecf20Sopenharmony_ci long pwrout_dbm; 16048c2ecf20Sopenharmony_ci 16058c2ecf20Sopenharmony_ci switch (wirelessmode) { 16068c2ecf20Sopenharmony_ci case WIRELESS_MODE_B: 16078c2ecf20Sopenharmony_ci offset = -7; 16088c2ecf20Sopenharmony_ci break; 16098c2ecf20Sopenharmony_ci case WIRELESS_MODE_G: 16108c2ecf20Sopenharmony_ci case WIRELESS_MODE_N_24G: 16118c2ecf20Sopenharmony_ci offset = -8; 16128c2ecf20Sopenharmony_ci break; 16138c2ecf20Sopenharmony_ci default: 16148c2ecf20Sopenharmony_ci offset = -8; 16158c2ecf20Sopenharmony_ci break; 16168c2ecf20Sopenharmony_ci } 16178c2ecf20Sopenharmony_ci pwrout_dbm = txpwridx / 2 + offset; 16188c2ecf20Sopenharmony_ci return pwrout_dbm; 16198c2ecf20Sopenharmony_ci} 16208c2ecf20Sopenharmony_ci 16218c2ecf20Sopenharmony_civoid rtl92ee_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) 16228c2ecf20Sopenharmony_ci{ 16238c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 16248c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 16258c2ecf20Sopenharmony_ci enum io_type iotype; 16268c2ecf20Sopenharmony_ci 16278c2ecf20Sopenharmony_ci if (!is_hal_stop(rtlhal)) { 16288c2ecf20Sopenharmony_ci switch (operation) { 16298c2ecf20Sopenharmony_ci case SCAN_OPT_BACKUP_BAND0: 16308c2ecf20Sopenharmony_ci iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; 16318c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, 16328c2ecf20Sopenharmony_ci (u8 *)&iotype); 16338c2ecf20Sopenharmony_ci 16348c2ecf20Sopenharmony_ci break; 16358c2ecf20Sopenharmony_ci case SCAN_OPT_RESTORE: 16368c2ecf20Sopenharmony_ci iotype = IO_CMD_RESUME_DM_BY_SCAN; 16378c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, 16388c2ecf20Sopenharmony_ci (u8 *)&iotype); 16398c2ecf20Sopenharmony_ci break; 16408c2ecf20Sopenharmony_ci default: 16418c2ecf20Sopenharmony_ci pr_err("Unknown Scan Backup operation.\n"); 16428c2ecf20Sopenharmony_ci break; 16438c2ecf20Sopenharmony_ci } 16448c2ecf20Sopenharmony_ci } 16458c2ecf20Sopenharmony_ci} 16468c2ecf20Sopenharmony_ci 16478c2ecf20Sopenharmony_civoid rtl92ee_phy_set_bw_mode_callback(struct ieee80211_hw *hw) 16488c2ecf20Sopenharmony_ci{ 16498c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 16508c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 16518c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 16528c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 16538c2ecf20Sopenharmony_ci u8 reg_bw_opmode; 16548c2ecf20Sopenharmony_ci u8 reg_prsr_rsc; 16558c2ecf20Sopenharmony_ci 16568c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, 16578c2ecf20Sopenharmony_ci "Switch to %s bandwidth\n", 16588c2ecf20Sopenharmony_ci rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? 16598c2ecf20Sopenharmony_ci "20MHz" : "40MHz"); 16608c2ecf20Sopenharmony_ci 16618c2ecf20Sopenharmony_ci if (is_hal_stop(rtlhal)) { 16628c2ecf20Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 16638c2ecf20Sopenharmony_ci return; 16648c2ecf20Sopenharmony_ci } 16658c2ecf20Sopenharmony_ci 16668c2ecf20Sopenharmony_ci reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); 16678c2ecf20Sopenharmony_ci reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); 16688c2ecf20Sopenharmony_ci 16698c2ecf20Sopenharmony_ci switch (rtlphy->current_chan_bw) { 16708c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 16718c2ecf20Sopenharmony_ci reg_bw_opmode |= BW_OPMODE_20MHZ; 16728c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 16738c2ecf20Sopenharmony_ci break; 16748c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 16758c2ecf20Sopenharmony_ci reg_bw_opmode &= ~BW_OPMODE_20MHZ; 16768c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 16778c2ecf20Sopenharmony_ci reg_prsr_rsc = (reg_prsr_rsc & 0x90) | 16788c2ecf20Sopenharmony_ci (mac->cur_40_prime_sc << 5); 16798c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); 16808c2ecf20Sopenharmony_ci break; 16818c2ecf20Sopenharmony_ci default: 16828c2ecf20Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 16838c2ecf20Sopenharmony_ci rtlphy->current_chan_bw); 16848c2ecf20Sopenharmony_ci break; 16858c2ecf20Sopenharmony_ci } 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci switch (rtlphy->current_chan_bw) { 16888c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 16898c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); 16908c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); 16918c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_TXPSEUDONOISEWGT, 16928c2ecf20Sopenharmony_ci (BIT(31) | BIT(30)), 0); 16938c2ecf20Sopenharmony_ci break; 16948c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 16958c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); 16968c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); 16978c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, 16988c2ecf20Sopenharmony_ci (mac->cur_40_prime_sc >> 1)); 16998c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, 17008c2ecf20Sopenharmony_ci mac->cur_40_prime_sc); 17018c2ecf20Sopenharmony_ci 17028c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), 17038c2ecf20Sopenharmony_ci (mac->cur_40_prime_sc == 17048c2ecf20Sopenharmony_ci HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); 17058c2ecf20Sopenharmony_ci break; 17068c2ecf20Sopenharmony_ci default: 17078c2ecf20Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 17088c2ecf20Sopenharmony_ci rtlphy->current_chan_bw); 17098c2ecf20Sopenharmony_ci break; 17108c2ecf20Sopenharmony_ci } 17118c2ecf20Sopenharmony_ci rtl92ee_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); 17128c2ecf20Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 17138c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_LOUD, "\n"); 17148c2ecf20Sopenharmony_ci} 17158c2ecf20Sopenharmony_ci 17168c2ecf20Sopenharmony_civoid rtl92ee_phy_set_bw_mode(struct ieee80211_hw *hw, 17178c2ecf20Sopenharmony_ci enum nl80211_channel_type ch_type) 17188c2ecf20Sopenharmony_ci{ 17198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 17208c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 17218c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 17228c2ecf20Sopenharmony_ci u8 tmp_bw = rtlphy->current_chan_bw; 17238c2ecf20Sopenharmony_ci 17248c2ecf20Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 17258c2ecf20Sopenharmony_ci return; 17268c2ecf20Sopenharmony_ci rtlphy->set_bwmode_inprogress = true; 17278c2ecf20Sopenharmony_ci if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 17288c2ecf20Sopenharmony_ci rtl92ee_phy_set_bw_mode_callback(hw); 17298c2ecf20Sopenharmony_ci } else { 17308c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 17318c2ecf20Sopenharmony_ci "false driver sleep or unload\n"); 17328c2ecf20Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 17338c2ecf20Sopenharmony_ci rtlphy->current_chan_bw = tmp_bw; 17348c2ecf20Sopenharmony_ci } 17358c2ecf20Sopenharmony_ci} 17368c2ecf20Sopenharmony_ci 17378c2ecf20Sopenharmony_civoid rtl92ee_phy_sw_chnl_callback(struct ieee80211_hw *hw) 17388c2ecf20Sopenharmony_ci{ 17398c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 17408c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 17418c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 17428c2ecf20Sopenharmony_ci u32 delay; 17438c2ecf20Sopenharmony_ci 17448c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, 17458c2ecf20Sopenharmony_ci "switch to channel%d\n", rtlphy->current_channel); 17468c2ecf20Sopenharmony_ci if (is_hal_stop(rtlhal)) 17478c2ecf20Sopenharmony_ci return; 17488c2ecf20Sopenharmony_ci do { 17498c2ecf20Sopenharmony_ci if (!rtlphy->sw_chnl_inprogress) 17508c2ecf20Sopenharmony_ci break; 17518c2ecf20Sopenharmony_ci if (!_rtl92ee_phy_sw_chnl_step_by_step 17528c2ecf20Sopenharmony_ci (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, 17538c2ecf20Sopenharmony_ci &rtlphy->sw_chnl_step, &delay)) { 17548c2ecf20Sopenharmony_ci if (delay > 0) 17558c2ecf20Sopenharmony_ci mdelay(delay); 17568c2ecf20Sopenharmony_ci else 17578c2ecf20Sopenharmony_ci continue; 17588c2ecf20Sopenharmony_ci } else { 17598c2ecf20Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 17608c2ecf20Sopenharmony_ci } 17618c2ecf20Sopenharmony_ci break; 17628c2ecf20Sopenharmony_ci } while (true); 17638c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); 17648c2ecf20Sopenharmony_ci} 17658c2ecf20Sopenharmony_ci 17668c2ecf20Sopenharmony_ciu8 rtl92ee_phy_sw_chnl(struct ieee80211_hw *hw) 17678c2ecf20Sopenharmony_ci{ 17688c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 17698c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 17708c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 17718c2ecf20Sopenharmony_ci 17728c2ecf20Sopenharmony_ci if (rtlphy->sw_chnl_inprogress) 17738c2ecf20Sopenharmony_ci return 0; 17748c2ecf20Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 17758c2ecf20Sopenharmony_ci return 0; 17768c2ecf20Sopenharmony_ci WARN_ONCE((rtlphy->current_channel > 14), 17778c2ecf20Sopenharmony_ci "rtl8192ee: WIRELESS_MODE_G but channel>14"); 17788c2ecf20Sopenharmony_ci rtlphy->sw_chnl_inprogress = true; 17798c2ecf20Sopenharmony_ci rtlphy->sw_chnl_stage = 0; 17808c2ecf20Sopenharmony_ci rtlphy->sw_chnl_step = 0; 17818c2ecf20Sopenharmony_ci if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 17828c2ecf20Sopenharmony_ci rtl92ee_phy_sw_chnl_callback(hw); 17838c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, 17848c2ecf20Sopenharmony_ci "sw_chnl_inprogress false schedule workitem current channel %d\n", 17858c2ecf20Sopenharmony_ci rtlphy->current_channel); 17868c2ecf20Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 17878c2ecf20Sopenharmony_ci } else { 17888c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD, 17898c2ecf20Sopenharmony_ci "sw_chnl_inprogress false driver sleep or unload\n"); 17908c2ecf20Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 17918c2ecf20Sopenharmony_ci } 17928c2ecf20Sopenharmony_ci return 1; 17938c2ecf20Sopenharmony_ci} 17948c2ecf20Sopenharmony_ci 17958c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 17968c2ecf20Sopenharmony_ci u8 channel, u8 *stage, u8 *step, 17978c2ecf20Sopenharmony_ci u32 *delay) 17988c2ecf20Sopenharmony_ci{ 17998c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 18008c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 18018c2ecf20Sopenharmony_ci struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; 18028c2ecf20Sopenharmony_ci u32 precommoncmdcnt; 18038c2ecf20Sopenharmony_ci struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; 18048c2ecf20Sopenharmony_ci u32 postcommoncmdcnt; 18058c2ecf20Sopenharmony_ci struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; 18068c2ecf20Sopenharmony_ci u32 rfdependcmdcnt; 18078c2ecf20Sopenharmony_ci struct swchnlcmd *currentcmd = NULL; 18088c2ecf20Sopenharmony_ci u8 rfpath; 18098c2ecf20Sopenharmony_ci u8 num_total_rfpath = rtlphy->num_total_rfpath; 18108c2ecf20Sopenharmony_ci 18118c2ecf20Sopenharmony_ci precommoncmdcnt = 0; 18128c2ecf20Sopenharmony_ci _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 18138c2ecf20Sopenharmony_ci MAX_PRECMD_CNT, 18148c2ecf20Sopenharmony_ci CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); 18158c2ecf20Sopenharmony_ci _rtl92ee_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 18168c2ecf20Sopenharmony_ci MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); 18178c2ecf20Sopenharmony_ci 18188c2ecf20Sopenharmony_ci postcommoncmdcnt = 0; 18198c2ecf20Sopenharmony_ci 18208c2ecf20Sopenharmony_ci _rtl92ee_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, 18218c2ecf20Sopenharmony_ci MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); 18228c2ecf20Sopenharmony_ci 18238c2ecf20Sopenharmony_ci rfdependcmdcnt = 0; 18248c2ecf20Sopenharmony_ci 18258c2ecf20Sopenharmony_ci WARN_ONCE((channel < 1 || channel > 14), 18268c2ecf20Sopenharmony_ci "rtl8192ee: illegal channel for Zebra: %d\n", channel); 18278c2ecf20Sopenharmony_ci 18288c2ecf20Sopenharmony_ci _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 18298c2ecf20Sopenharmony_ci MAX_RFDEPENDCMD_CNT, 18308c2ecf20Sopenharmony_ci CMDID_RF_WRITEREG, 18318c2ecf20Sopenharmony_ci RF_CHNLBW, channel, 10); 18328c2ecf20Sopenharmony_ci 18338c2ecf20Sopenharmony_ci _rtl92ee_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 18348c2ecf20Sopenharmony_ci MAX_RFDEPENDCMD_CNT, CMDID_END, 18358c2ecf20Sopenharmony_ci 0, 0, 0); 18368c2ecf20Sopenharmony_ci 18378c2ecf20Sopenharmony_ci do { 18388c2ecf20Sopenharmony_ci switch (*stage) { 18398c2ecf20Sopenharmony_ci case 0: 18408c2ecf20Sopenharmony_ci currentcmd = &precommoncmd[*step]; 18418c2ecf20Sopenharmony_ci break; 18428c2ecf20Sopenharmony_ci case 1: 18438c2ecf20Sopenharmony_ci currentcmd = &rfdependcmd[*step]; 18448c2ecf20Sopenharmony_ci break; 18458c2ecf20Sopenharmony_ci case 2: 18468c2ecf20Sopenharmony_ci currentcmd = &postcommoncmd[*step]; 18478c2ecf20Sopenharmony_ci break; 18488c2ecf20Sopenharmony_ci default: 18498c2ecf20Sopenharmony_ci pr_err("Invalid 'stage' = %d, Check it!\n", 18508c2ecf20Sopenharmony_ci *stage); 18518c2ecf20Sopenharmony_ci return true; 18528c2ecf20Sopenharmony_ci } 18538c2ecf20Sopenharmony_ci 18548c2ecf20Sopenharmony_ci if (currentcmd->cmdid == CMDID_END) { 18558c2ecf20Sopenharmony_ci if ((*stage) == 2) 18568c2ecf20Sopenharmony_ci return true; 18578c2ecf20Sopenharmony_ci (*stage)++; 18588c2ecf20Sopenharmony_ci (*step) = 0; 18598c2ecf20Sopenharmony_ci continue; 18608c2ecf20Sopenharmony_ci } 18618c2ecf20Sopenharmony_ci 18628c2ecf20Sopenharmony_ci switch (currentcmd->cmdid) { 18638c2ecf20Sopenharmony_ci case CMDID_SET_TXPOWEROWER_LEVEL: 18648c2ecf20Sopenharmony_ci rtl92ee_phy_set_txpower_level(hw, channel); 18658c2ecf20Sopenharmony_ci break; 18668c2ecf20Sopenharmony_ci case CMDID_WRITEPORT_ULONG: 18678c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, currentcmd->para1, 18688c2ecf20Sopenharmony_ci currentcmd->para2); 18698c2ecf20Sopenharmony_ci break; 18708c2ecf20Sopenharmony_ci case CMDID_WRITEPORT_USHORT: 18718c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, currentcmd->para1, 18728c2ecf20Sopenharmony_ci (u16)currentcmd->para2); 18738c2ecf20Sopenharmony_ci break; 18748c2ecf20Sopenharmony_ci case CMDID_WRITEPORT_UCHAR: 18758c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, currentcmd->para1, 18768c2ecf20Sopenharmony_ci (u8)currentcmd->para2); 18778c2ecf20Sopenharmony_ci break; 18788c2ecf20Sopenharmony_ci case CMDID_RF_WRITEREG: 18798c2ecf20Sopenharmony_ci for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { 18808c2ecf20Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath] = 18818c2ecf20Sopenharmony_ci ((rtlphy->rfreg_chnlval[rfpath] & 18828c2ecf20Sopenharmony_ci 0xfffff00) | currentcmd->para2); 18838c2ecf20Sopenharmony_ci 18848c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, (enum radio_path)rfpath, 18858c2ecf20Sopenharmony_ci currentcmd->para1, 18868c2ecf20Sopenharmony_ci 0x3ff, 18878c2ecf20Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath]); 18888c2ecf20Sopenharmony_ci } 18898c2ecf20Sopenharmony_ci break; 18908c2ecf20Sopenharmony_ci default: 18918c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 18928c2ecf20Sopenharmony_ci "switch case %#x not processed\n", 18938c2ecf20Sopenharmony_ci currentcmd->cmdid); 18948c2ecf20Sopenharmony_ci break; 18958c2ecf20Sopenharmony_ci } 18968c2ecf20Sopenharmony_ci 18978c2ecf20Sopenharmony_ci break; 18988c2ecf20Sopenharmony_ci } while (true); 18998c2ecf20Sopenharmony_ci 19008c2ecf20Sopenharmony_ci (*delay) = currentcmd->msdelay; 19018c2ecf20Sopenharmony_ci (*step)++; 19028c2ecf20Sopenharmony_ci return false; 19038c2ecf20Sopenharmony_ci} 19048c2ecf20Sopenharmony_ci 19058c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, 19068c2ecf20Sopenharmony_ci u32 cmdtableidx, u32 cmdtablesz, 19078c2ecf20Sopenharmony_ci enum swchnlcmd_id cmdid, 19088c2ecf20Sopenharmony_ci u32 para1, u32 para2, u32 msdelay) 19098c2ecf20Sopenharmony_ci{ 19108c2ecf20Sopenharmony_ci struct swchnlcmd *pcmd; 19118c2ecf20Sopenharmony_ci 19128c2ecf20Sopenharmony_ci if (cmdtable == NULL) { 19138c2ecf20Sopenharmony_ci WARN_ONCE(true, "rtl8192ee: cmdtable cannot be NULL.\n"); 19148c2ecf20Sopenharmony_ci return false; 19158c2ecf20Sopenharmony_ci } 19168c2ecf20Sopenharmony_ci 19178c2ecf20Sopenharmony_ci if (cmdtableidx >= cmdtablesz) 19188c2ecf20Sopenharmony_ci return false; 19198c2ecf20Sopenharmony_ci 19208c2ecf20Sopenharmony_ci pcmd = cmdtable + cmdtableidx; 19218c2ecf20Sopenharmony_ci pcmd->cmdid = cmdid; 19228c2ecf20Sopenharmony_ci pcmd->para1 = para1; 19238c2ecf20Sopenharmony_ci pcmd->para2 = para2; 19248c2ecf20Sopenharmony_ci pcmd->msdelay = msdelay; 19258c2ecf20Sopenharmony_ci return true; 19268c2ecf20Sopenharmony_ci} 19278c2ecf20Sopenharmony_ci 19288c2ecf20Sopenharmony_cistatic u8 _rtl92ee_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) 19298c2ecf20Sopenharmony_ci{ 19308c2ecf20Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c; 19318c2ecf20Sopenharmony_ci u8 result = 0x00; 19328c2ecf20Sopenharmony_ci /* path-A IQK setting */ 19338c2ecf20Sopenharmony_ci /* PA/PAD controlled by 0x0 */ 19348c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 19358c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180); 19368c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 19378c2ecf20Sopenharmony_ci 19388c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); 19398c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 19408c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 19418c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 19428c2ecf20Sopenharmony_ci 19438c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82140303); 19448c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160000); 19458c2ecf20Sopenharmony_ci 19468c2ecf20Sopenharmony_ci /*LO calibration setting*/ 19478c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); 19488c2ecf20Sopenharmony_ci 19498c2ecf20Sopenharmony_ci /*One shot, path A LOK & IQK*/ 19508c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); 19518c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 19528c2ecf20Sopenharmony_ci 19538c2ecf20Sopenharmony_ci mdelay(IQK_DELAY_TIME); 19548c2ecf20Sopenharmony_ci 19558c2ecf20Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); 19568c2ecf20Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); 19578c2ecf20Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); 19588c2ecf20Sopenharmony_ci 19598c2ecf20Sopenharmony_ci if (!(reg_eac & BIT(28)) && 19608c2ecf20Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 19618c2ecf20Sopenharmony_ci (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) 19628c2ecf20Sopenharmony_ci result |= 0x01; 19638c2ecf20Sopenharmony_ci else 19648c2ecf20Sopenharmony_ci return result; 19658c2ecf20Sopenharmony_ci 19668c2ecf20Sopenharmony_ci return result; 19678c2ecf20Sopenharmony_ci} 19688c2ecf20Sopenharmony_ci 19698c2ecf20Sopenharmony_cistatic u8 _rtl92ee_phy_path_b_iqk(struct ieee80211_hw *hw) 19708c2ecf20Sopenharmony_ci{ 19718c2ecf20Sopenharmony_ci u32 reg_eac, reg_eb4, reg_ebc; 19728c2ecf20Sopenharmony_ci u8 result = 0x00; 19738c2ecf20Sopenharmony_ci 19748c2ecf20Sopenharmony_ci /* PA/PAD controlled by 0x0 */ 19758c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 19768c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180); 19778c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 19788c2ecf20Sopenharmony_ci 19798c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); 19808c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); 19818c2ecf20Sopenharmony_ci 19828c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 19838c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 19848c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c); 19858c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 19868c2ecf20Sopenharmony_ci 19878c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x821403e2); 19888c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160000); 19898c2ecf20Sopenharmony_ci 19908c2ecf20Sopenharmony_ci /* LO calibration setting */ 19918c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); 19928c2ecf20Sopenharmony_ci 19938c2ecf20Sopenharmony_ci /*One shot, path B LOK & IQK*/ 19948c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); 19958c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 19968c2ecf20Sopenharmony_ci 19978c2ecf20Sopenharmony_ci mdelay(IQK_DELAY_TIME); 19988c2ecf20Sopenharmony_ci 19998c2ecf20Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); 20008c2ecf20Sopenharmony_ci reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); 20018c2ecf20Sopenharmony_ci reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); 20028c2ecf20Sopenharmony_ci 20038c2ecf20Sopenharmony_ci if (!(reg_eac & BIT(31)) && 20048c2ecf20Sopenharmony_ci (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && 20058c2ecf20Sopenharmony_ci (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) 20068c2ecf20Sopenharmony_ci result |= 0x01; 20078c2ecf20Sopenharmony_ci else 20088c2ecf20Sopenharmony_ci return result; 20098c2ecf20Sopenharmony_ci 20108c2ecf20Sopenharmony_ci return result; 20118c2ecf20Sopenharmony_ci} 20128c2ecf20Sopenharmony_ci 20138c2ecf20Sopenharmony_cistatic u8 _rtl92ee_phy_path_a_rx_iqk(struct ieee80211_hw *hw, bool config_pathb) 20148c2ecf20Sopenharmony_ci{ 20158c2ecf20Sopenharmony_ci u32 reg_eac, reg_e94, reg_e9c, reg_ea4 , u32temp; 20168c2ecf20Sopenharmony_ci u8 result = 0x00; 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci /*Get TXIMR Setting*/ 20198c2ecf20Sopenharmony_ci /*Modify RX IQK mode table*/ 20208c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 20218c2ecf20Sopenharmony_ci 20228c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); 20238c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 20248c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); 20258c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b); 20268c2ecf20Sopenharmony_ci 20278c2ecf20Sopenharmony_ci /*PA/PAD control by 0x56, and set = 0x0*/ 20288c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980); 20298c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000); 20308c2ecf20Sopenharmony_ci 20318c2ecf20Sopenharmony_ci /*enter IQK mode*/ 20328c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 20338c2ecf20Sopenharmony_ci 20348c2ecf20Sopenharmony_ci /*IQK Setting*/ 20358c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); 20368c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 20378c2ecf20Sopenharmony_ci 20388c2ecf20Sopenharmony_ci /*path a IQK setting*/ 20398c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); 20408c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 20418c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 20428c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 20438c2ecf20Sopenharmony_ci 20448c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f); 20458c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x68160c1f); 20468c2ecf20Sopenharmony_ci 20478c2ecf20Sopenharmony_ci /*LO calibration Setting*/ 20488c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); 20498c2ecf20Sopenharmony_ci 20508c2ecf20Sopenharmony_ci /*one shot,path A LOK & iqk*/ 20518c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); 20528c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 20538c2ecf20Sopenharmony_ci 20548c2ecf20Sopenharmony_ci mdelay(IQK_DELAY_TIME); 20558c2ecf20Sopenharmony_ci 20568c2ecf20Sopenharmony_ci /* Check failed */ 20578c2ecf20Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 20588c2ecf20Sopenharmony_ci reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); 20598c2ecf20Sopenharmony_ci reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); 20608c2ecf20Sopenharmony_ci 20618c2ecf20Sopenharmony_ci if (!(reg_eac & BIT(28)) && 20628c2ecf20Sopenharmony_ci (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 20638c2ecf20Sopenharmony_ci (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) { 20648c2ecf20Sopenharmony_ci result |= 0x01; 20658c2ecf20Sopenharmony_ci } else { 20668c2ecf20Sopenharmony_ci /* PA/PAD controlled by 0x0 */ 20678c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 20688c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180); 20698c2ecf20Sopenharmony_ci return result; 20708c2ecf20Sopenharmony_ci } 20718c2ecf20Sopenharmony_ci 20728c2ecf20Sopenharmony_ci u32temp = 0x80007C00 | (reg_e94 & 0x3FF0000) | 20738c2ecf20Sopenharmony_ci ((reg_e9c & 0x3FF0000) >> 16); 20748c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp); 20758c2ecf20Sopenharmony_ci /*RX IQK*/ 20768c2ecf20Sopenharmony_ci /*Modify RX IQK mode table*/ 20778c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 20788c2ecf20Sopenharmony_ci 20798c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); 20808c2ecf20Sopenharmony_ci 20818c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 20828c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); 20838c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa); 20848c2ecf20Sopenharmony_ci 20858c2ecf20Sopenharmony_ci /*PA/PAD control by 0x56, and set = 0x0*/ 20868c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x980); 20878c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x56, RFREG_OFFSET_MASK, 0x51000); 20888c2ecf20Sopenharmony_ci 20898c2ecf20Sopenharmony_ci /*enter IQK mode*/ 20908c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 20918c2ecf20Sopenharmony_ci 20928c2ecf20Sopenharmony_ci /*IQK Setting*/ 20938c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 20948c2ecf20Sopenharmony_ci 20958c2ecf20Sopenharmony_ci /*path a IQK setting*/ 20968c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 20978c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c); 20988c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 20998c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 21008c2ecf20Sopenharmony_ci 21018c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160c1f); 21028c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160c1f); 21038c2ecf20Sopenharmony_ci 21048c2ecf20Sopenharmony_ci /*LO calibration Setting*/ 21058c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891); 21068c2ecf20Sopenharmony_ci /*one shot,path A LOK & iqk*/ 21078c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); 21088c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 21098c2ecf20Sopenharmony_ci 21108c2ecf20Sopenharmony_ci mdelay(IQK_DELAY_TIME); 21118c2ecf20Sopenharmony_ci /*Check failed*/ 21128c2ecf20Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 21138c2ecf20Sopenharmony_ci reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); 21148c2ecf20Sopenharmony_ci 21158c2ecf20Sopenharmony_ci /*PA/PAD controlled by 0x0*/ 21168c2ecf20Sopenharmony_ci /*leave IQK mode*/ 21178c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 21188c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x180); 21198c2ecf20Sopenharmony_ci /*if Tx is OK, check whether Rx is OK*/ 21208c2ecf20Sopenharmony_ci if (!(reg_eac & BIT(27)) && 21218c2ecf20Sopenharmony_ci (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && 21228c2ecf20Sopenharmony_ci (((reg_eac & 0x03FF0000) >> 16) != 0x36)) 21238c2ecf20Sopenharmony_ci result |= 0x02; 21248c2ecf20Sopenharmony_ci 21258c2ecf20Sopenharmony_ci return result; 21268c2ecf20Sopenharmony_ci} 21278c2ecf20Sopenharmony_ci 21288c2ecf20Sopenharmony_cistatic u8 _rtl92ee_phy_path_b_rx_iqk(struct ieee80211_hw *hw, bool config_pathb) 21298c2ecf20Sopenharmony_ci{ 21308c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 21318c2ecf20Sopenharmony_ci u32 reg_eac, reg_eb4, reg_ebc, reg_ecc, reg_ec4, u32temp; 21328c2ecf20Sopenharmony_ci u8 result = 0x00; 21338c2ecf20Sopenharmony_ci 21348c2ecf20Sopenharmony_ci /*Get TXIMR Setting*/ 21358c2ecf20Sopenharmony_ci /*Modify RX IQK mode table*/ 21368c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 21378c2ecf20Sopenharmony_ci 21388c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); 21398c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 21408c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); 21418c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf117b); 21428c2ecf20Sopenharmony_ci 21438c2ecf20Sopenharmony_ci /*PA/PAD all off*/ 21448c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980); 21458c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000); 21468c2ecf20Sopenharmony_ci 21478c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 21488c2ecf20Sopenharmony_ci 21498c2ecf20Sopenharmony_ci /*IQK Setting*/ 21508c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); 21518c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 21528c2ecf20Sopenharmony_ci 21538c2ecf20Sopenharmony_ci /*path a IQK setting*/ 21548c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 21558c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 21568c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x18008c1c); 21578c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 21588c2ecf20Sopenharmony_ci 21598c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f); 21608c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x68160c1f); 21618c2ecf20Sopenharmony_ci 21628c2ecf20Sopenharmony_ci /*LO calibration Setting*/ 21638c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); 21648c2ecf20Sopenharmony_ci 21658c2ecf20Sopenharmony_ci /*one shot,path A LOK & iqk*/ 21668c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); 21678c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 21688c2ecf20Sopenharmony_ci 21698c2ecf20Sopenharmony_ci mdelay(IQK_DELAY_TIME); 21708c2ecf20Sopenharmony_ci 21718c2ecf20Sopenharmony_ci /* Check failed */ 21728c2ecf20Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 21738c2ecf20Sopenharmony_ci reg_eb4 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_B, MASKDWORD); 21748c2ecf20Sopenharmony_ci reg_ebc = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_B, MASKDWORD); 21758c2ecf20Sopenharmony_ci 21768c2ecf20Sopenharmony_ci if (!(reg_eac & BIT(31)) && 21778c2ecf20Sopenharmony_ci (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && 21788c2ecf20Sopenharmony_ci (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) { 21798c2ecf20Sopenharmony_ci result |= 0x01; 21808c2ecf20Sopenharmony_ci } else { 21818c2ecf20Sopenharmony_ci /* PA/PAD controlled by 0x0 */ 21828c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 21838c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180); 21848c2ecf20Sopenharmony_ci return result; 21858c2ecf20Sopenharmony_ci } 21868c2ecf20Sopenharmony_ci 21878c2ecf20Sopenharmony_ci u32temp = 0x80007C00 | (reg_eb4 & 0x3FF0000) | 21888c2ecf20Sopenharmony_ci ((reg_ebc & 0x3FF0000) >> 16); 21898c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32temp); 21908c2ecf20Sopenharmony_ci /*RX IQK*/ 21918c2ecf20Sopenharmony_ci /*Modify RX IQK mode table*/ 21928c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 21938c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); 21948c2ecf20Sopenharmony_ci 21958c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); 21968c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0000f); 21978c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ffa); 21988c2ecf20Sopenharmony_ci 21998c2ecf20Sopenharmony_ci /*PA/PAD all off*/ 22008c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x980); 22018c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x56, RFREG_OFFSET_MASK, 0x51000); 22028c2ecf20Sopenharmony_ci 22038c2ecf20Sopenharmony_ci /*enter IQK mode*/ 22048c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 22058c2ecf20Sopenharmony_ci 22068c2ecf20Sopenharmony_ci /*IQK Setting*/ 22078c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 22088c2ecf20Sopenharmony_ci 22098c2ecf20Sopenharmony_ci /*path b IQK setting*/ 22108c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 22118c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); 22128c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); 22138c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x18008c1c); 22148c2ecf20Sopenharmony_ci 22158c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82160c1f); 22168c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28160c1f); 22178c2ecf20Sopenharmony_ci 22188c2ecf20Sopenharmony_ci /*LO calibration Setting*/ 22198c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a891); 22208c2ecf20Sopenharmony_ci /*one shot,path A LOK & iqk*/ 22218c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xfa000000); 22228c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); 22238c2ecf20Sopenharmony_ci 22248c2ecf20Sopenharmony_ci mdelay(IQK_DELAY_TIME); 22258c2ecf20Sopenharmony_ci /*Check failed*/ 22268c2ecf20Sopenharmony_ci reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); 22278c2ecf20Sopenharmony_ci reg_ec4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_B_2, MASKDWORD); 22288c2ecf20Sopenharmony_ci reg_ecc = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_B_2, MASKDWORD); 22298c2ecf20Sopenharmony_ci /*PA/PAD controlled by 0x0*/ 22308c2ecf20Sopenharmony_ci /*leave IQK mode*/ 22318c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); 22328c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0xdf, RFREG_OFFSET_MASK, 0x180); 22338c2ecf20Sopenharmony_ci /*if Tx is OK, check whether Rx is OK*/ 22348c2ecf20Sopenharmony_ci if (!(reg_eac & BIT(30)) && 22358c2ecf20Sopenharmony_ci (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && 22368c2ecf20Sopenharmony_ci (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) 22378c2ecf20Sopenharmony_ci result |= 0x02; 22388c2ecf20Sopenharmony_ci else 22398c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, "Path B Rx IQK fail!!\n"); 22408c2ecf20Sopenharmony_ci 22418c2ecf20Sopenharmony_ci return result; 22428c2ecf20Sopenharmony_ci} 22438c2ecf20Sopenharmony_ci 22448c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, 22458c2ecf20Sopenharmony_ci bool b_iqk_ok, long result[][8], 22468c2ecf20Sopenharmony_ci u8 final_candidate, 22478c2ecf20Sopenharmony_ci bool btxonly) 22488c2ecf20Sopenharmony_ci{ 22498c2ecf20Sopenharmony_ci u32 oldval_0, x, tx0_a, reg; 22508c2ecf20Sopenharmony_ci long y, tx0_c; 22518c2ecf20Sopenharmony_ci 22528c2ecf20Sopenharmony_ci if (final_candidate == 0xFF) { 22538c2ecf20Sopenharmony_ci return; 22548c2ecf20Sopenharmony_ci } else if (b_iqk_ok) { 22558c2ecf20Sopenharmony_ci oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 22568c2ecf20Sopenharmony_ci MASKDWORD) >> 22) & 0x3FF; 22578c2ecf20Sopenharmony_ci x = result[final_candidate][0]; 22588c2ecf20Sopenharmony_ci if ((x & 0x00000200) != 0) 22598c2ecf20Sopenharmony_ci x = x | 0xFFFFFC00; 22608c2ecf20Sopenharmony_ci tx0_a = (x * oldval_0) >> 8; 22618c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); 22628c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), 22638c2ecf20Sopenharmony_ci ((x * oldval_0 >> 7) & 0x1)); 22648c2ecf20Sopenharmony_ci y = result[final_candidate][1]; 22658c2ecf20Sopenharmony_ci if ((y & 0x00000200) != 0) 22668c2ecf20Sopenharmony_ci y = y | 0xFFFFFC00; 22678c2ecf20Sopenharmony_ci tx0_c = (y * oldval_0) >> 8; 22688c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, 22698c2ecf20Sopenharmony_ci ((tx0_c & 0x3C0) >> 6)); 22708c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, 22718c2ecf20Sopenharmony_ci (tx0_c & 0x3F)); 22728c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), 22738c2ecf20Sopenharmony_ci ((y * oldval_0 >> 7) & 0x1)); 22748c2ecf20Sopenharmony_ci 22758c2ecf20Sopenharmony_ci if (btxonly) 22768c2ecf20Sopenharmony_ci return; 22778c2ecf20Sopenharmony_ci 22788c2ecf20Sopenharmony_ci reg = result[final_candidate][2]; 22798c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); 22808c2ecf20Sopenharmony_ci 22818c2ecf20Sopenharmony_ci reg = result[final_candidate][3] & 0x3F; 22828c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); 22838c2ecf20Sopenharmony_ci 22848c2ecf20Sopenharmony_ci reg = (result[final_candidate][3] >> 6) & 0xF; 22858c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_RXIQEXTANTA, 0xF0000000, reg); 22868c2ecf20Sopenharmony_ci } 22878c2ecf20Sopenharmony_ci} 22888c2ecf20Sopenharmony_ci 22898c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, 22908c2ecf20Sopenharmony_ci bool b_iqk_ok, long result[][8], 22918c2ecf20Sopenharmony_ci u8 final_candidate, 22928c2ecf20Sopenharmony_ci bool btxonly) 22938c2ecf20Sopenharmony_ci{ 22948c2ecf20Sopenharmony_ci u32 oldval_1, x, tx1_a, reg; 22958c2ecf20Sopenharmony_ci long y, tx1_c; 22968c2ecf20Sopenharmony_ci 22978c2ecf20Sopenharmony_ci if (final_candidate == 0xFF) { 22988c2ecf20Sopenharmony_ci return; 22998c2ecf20Sopenharmony_ci } else if (b_iqk_ok) { 23008c2ecf20Sopenharmony_ci oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 23018c2ecf20Sopenharmony_ci MASKDWORD) >> 22) & 0x3FF; 23028c2ecf20Sopenharmony_ci x = result[final_candidate][4]; 23038c2ecf20Sopenharmony_ci if ((x & 0x00000200) != 0) 23048c2ecf20Sopenharmony_ci x = x | 0xFFFFFC00; 23058c2ecf20Sopenharmony_ci tx1_a = (x * oldval_1) >> 8; 23068c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx1_a); 23078c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), 23088c2ecf20Sopenharmony_ci ((x * oldval_1 >> 7) & 0x1)); 23098c2ecf20Sopenharmony_ci y = result[final_candidate][5]; 23108c2ecf20Sopenharmony_ci if ((y & 0x00000200) != 0) 23118c2ecf20Sopenharmony_ci y = y | 0xFFFFFC00; 23128c2ecf20Sopenharmony_ci tx1_c = (y * oldval_1) >> 8; 23138c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, 23148c2ecf20Sopenharmony_ci ((tx1_c & 0x3C0) >> 6)); 23158c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, 23168c2ecf20Sopenharmony_ci (tx1_c & 0x3F)); 23178c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), 23188c2ecf20Sopenharmony_ci ((y * oldval_1 >> 7) & 0x1)); 23198c2ecf20Sopenharmony_ci 23208c2ecf20Sopenharmony_ci if (btxonly) 23218c2ecf20Sopenharmony_ci return; 23228c2ecf20Sopenharmony_ci 23238c2ecf20Sopenharmony_ci reg = result[final_candidate][6]; 23248c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); 23258c2ecf20Sopenharmony_ci 23268c2ecf20Sopenharmony_ci reg = result[final_candidate][7] & 0x3F; 23278c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); 23288c2ecf20Sopenharmony_ci 23298c2ecf20Sopenharmony_ci reg = (result[final_candidate][7] >> 6) & 0xF; 23308c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0xF0000000, reg); 23318c2ecf20Sopenharmony_ci } 23328c2ecf20Sopenharmony_ci} 23338c2ecf20Sopenharmony_ci 23348c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_save_adda_registers(struct ieee80211_hw *hw, 23358c2ecf20Sopenharmony_ci u32 *addareg, u32 *addabackup, 23368c2ecf20Sopenharmony_ci u32 registernum) 23378c2ecf20Sopenharmony_ci{ 23388c2ecf20Sopenharmony_ci u32 i; 23398c2ecf20Sopenharmony_ci 23408c2ecf20Sopenharmony_ci for (i = 0; i < registernum; i++) 23418c2ecf20Sopenharmony_ci addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); 23428c2ecf20Sopenharmony_ci} 23438c2ecf20Sopenharmony_ci 23448c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_save_mac_registers(struct ieee80211_hw *hw, 23458c2ecf20Sopenharmony_ci u32 *macreg, u32 *macbackup) 23468c2ecf20Sopenharmony_ci{ 23478c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 23488c2ecf20Sopenharmony_ci u32 i; 23498c2ecf20Sopenharmony_ci 23508c2ecf20Sopenharmony_ci for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) 23518c2ecf20Sopenharmony_ci macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); 23528c2ecf20Sopenharmony_ci 23538c2ecf20Sopenharmony_ci macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); 23548c2ecf20Sopenharmony_ci} 23558c2ecf20Sopenharmony_ci 23568c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_reload_adda_registers(struct ieee80211_hw *hw, 23578c2ecf20Sopenharmony_ci u32 *addareg, u32 *addabackup, 23588c2ecf20Sopenharmony_ci u32 regiesternum) 23598c2ecf20Sopenharmony_ci{ 23608c2ecf20Sopenharmony_ci u32 i; 23618c2ecf20Sopenharmony_ci 23628c2ecf20Sopenharmony_ci for (i = 0; i < regiesternum; i++) 23638c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); 23648c2ecf20Sopenharmony_ci} 23658c2ecf20Sopenharmony_ci 23668c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_reload_mac_registers(struct ieee80211_hw *hw, 23678c2ecf20Sopenharmony_ci u32 *macreg, u32 *macbackup) 23688c2ecf20Sopenharmony_ci{ 23698c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 23708c2ecf20Sopenharmony_ci u32 i; 23718c2ecf20Sopenharmony_ci 23728c2ecf20Sopenharmony_ci for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) 23738c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, macreg[i], (u8)macbackup[i]); 23748c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); 23758c2ecf20Sopenharmony_ci} 23768c2ecf20Sopenharmony_ci 23778c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_path_adda_on(struct ieee80211_hw *hw, u32 *addareg, 23788c2ecf20Sopenharmony_ci bool is_patha_on, bool is2t) 23798c2ecf20Sopenharmony_ci{ 23808c2ecf20Sopenharmony_ci u32 i; 23818c2ecf20Sopenharmony_ci 23828c2ecf20Sopenharmony_ci for (i = 0; i < IQK_ADDA_REG_NUM; i++) 23838c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, addareg[i], MASKDWORD, 0x0fc01616); 23848c2ecf20Sopenharmony_ci} 23858c2ecf20Sopenharmony_ci 23868c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_mac_setting_calibration(struct ieee80211_hw *hw, 23878c2ecf20Sopenharmony_ci u32 *macreg, u32 *macbackup) 23888c2ecf20Sopenharmony_ci{ 23898c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0x520, 0x00ff0000, 0xff); 23908c2ecf20Sopenharmony_ci} 23918c2ecf20Sopenharmony_ci 23928c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_path_a_standby(struct ieee80211_hw *hw) 23938c2ecf20Sopenharmony_ci{ 23948c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); 23958c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK, 0x10000); 23968c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); 23978c2ecf20Sopenharmony_ci} 23988c2ecf20Sopenharmony_ci 23998c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_simularity_compare(struct ieee80211_hw *hw, 24008c2ecf20Sopenharmony_ci long result[][8], u8 c1, u8 c2) 24018c2ecf20Sopenharmony_ci{ 24028c2ecf20Sopenharmony_ci u32 i, j, diff, simularity_bitmap, bound; 24038c2ecf20Sopenharmony_ci 24048c2ecf20Sopenharmony_ci u8 final_candidate[2] = { 0xFF, 0xFF }; 24058c2ecf20Sopenharmony_ci bool bresult = true/*, is2t = true*/; 24068c2ecf20Sopenharmony_ci s32 tmp1, tmp2; 24078c2ecf20Sopenharmony_ci 24088c2ecf20Sopenharmony_ci bound = 8; 24098c2ecf20Sopenharmony_ci 24108c2ecf20Sopenharmony_ci simularity_bitmap = 0; 24118c2ecf20Sopenharmony_ci 24128c2ecf20Sopenharmony_ci for (i = 0; i < bound; i++) { 24138c2ecf20Sopenharmony_ci if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) { 24148c2ecf20Sopenharmony_ci if ((result[c1][i] & 0x00000200) != 0) 24158c2ecf20Sopenharmony_ci tmp1 = result[c1][i] | 0xFFFFFC00; 24168c2ecf20Sopenharmony_ci else 24178c2ecf20Sopenharmony_ci tmp1 = result[c1][i]; 24188c2ecf20Sopenharmony_ci 24198c2ecf20Sopenharmony_ci if ((result[c2][i] & 0x00000200) != 0) 24208c2ecf20Sopenharmony_ci tmp2 = result[c2][i] | 0xFFFFFC00; 24218c2ecf20Sopenharmony_ci else 24228c2ecf20Sopenharmony_ci tmp2 = result[c2][i]; 24238c2ecf20Sopenharmony_ci } else { 24248c2ecf20Sopenharmony_ci tmp1 = result[c1][i]; 24258c2ecf20Sopenharmony_ci tmp2 = result[c2][i]; 24268c2ecf20Sopenharmony_ci } 24278c2ecf20Sopenharmony_ci 24288c2ecf20Sopenharmony_ci diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); 24298c2ecf20Sopenharmony_ci 24308c2ecf20Sopenharmony_ci if (diff > MAX_TOLERANCE) { 24318c2ecf20Sopenharmony_ci if ((i == 2 || i == 6) && !simularity_bitmap) { 24328c2ecf20Sopenharmony_ci if (result[c1][i] + result[c1][i + 1] == 0) 24338c2ecf20Sopenharmony_ci final_candidate[(i / 4)] = c2; 24348c2ecf20Sopenharmony_ci else if (result[c2][i] + result[c2][i + 1] == 0) 24358c2ecf20Sopenharmony_ci final_candidate[(i / 4)] = c1; 24368c2ecf20Sopenharmony_ci else 24378c2ecf20Sopenharmony_ci simularity_bitmap |= (1 << i); 24388c2ecf20Sopenharmony_ci } else { 24398c2ecf20Sopenharmony_ci simularity_bitmap |= (1 << i); 24408c2ecf20Sopenharmony_ci } 24418c2ecf20Sopenharmony_ci } 24428c2ecf20Sopenharmony_ci } 24438c2ecf20Sopenharmony_ci 24448c2ecf20Sopenharmony_ci if (simularity_bitmap == 0) { 24458c2ecf20Sopenharmony_ci for (i = 0; i < (bound / 4); i++) { 24468c2ecf20Sopenharmony_ci if (final_candidate[i] != 0xFF) { 24478c2ecf20Sopenharmony_ci for (j = i * 4; j < (i + 1) * 4 - 2; j++) 24488c2ecf20Sopenharmony_ci result[3][j] = 24498c2ecf20Sopenharmony_ci result[final_candidate[i]][j]; 24508c2ecf20Sopenharmony_ci bresult = false; 24518c2ecf20Sopenharmony_ci } 24528c2ecf20Sopenharmony_ci } 24538c2ecf20Sopenharmony_ci return bresult; 24548c2ecf20Sopenharmony_ci } 24558c2ecf20Sopenharmony_ci if (!(simularity_bitmap & 0x03)) {/*path A TX OK*/ 24568c2ecf20Sopenharmony_ci for (i = 0; i < 2; i++) 24578c2ecf20Sopenharmony_ci result[3][i] = result[c1][i]; 24588c2ecf20Sopenharmony_ci } 24598c2ecf20Sopenharmony_ci if (!(simularity_bitmap & 0x0c)) {/*path A RX OK*/ 24608c2ecf20Sopenharmony_ci for (i = 2; i < 4; i++) 24618c2ecf20Sopenharmony_ci result[3][i] = result[c1][i]; 24628c2ecf20Sopenharmony_ci } 24638c2ecf20Sopenharmony_ci if (!(simularity_bitmap & 0x30)) {/*path B TX OK*/ 24648c2ecf20Sopenharmony_ci for (i = 4; i < 6; i++) 24658c2ecf20Sopenharmony_ci result[3][i] = result[c1][i]; 24668c2ecf20Sopenharmony_ci } 24678c2ecf20Sopenharmony_ci if (!(simularity_bitmap & 0xc0)) {/*path B RX OK*/ 24688c2ecf20Sopenharmony_ci for (i = 6; i < 8; i++) 24698c2ecf20Sopenharmony_ci result[3][i] = result[c1][i]; 24708c2ecf20Sopenharmony_ci } 24718c2ecf20Sopenharmony_ci return false; 24728c2ecf20Sopenharmony_ci} 24738c2ecf20Sopenharmony_ci 24748c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, 24758c2ecf20Sopenharmony_ci long result[][8], u8 t, bool is2t) 24768c2ecf20Sopenharmony_ci{ 24778c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 24788c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 24798c2ecf20Sopenharmony_ci u32 i; 24808c2ecf20Sopenharmony_ci u8 patha_ok, pathb_ok; 24818c2ecf20Sopenharmony_ci u8 tmp_0xc50 = (u8)rtl_get_bbreg(hw, 0xc50, MASKBYTE0); 24828c2ecf20Sopenharmony_ci u8 tmp_0xc58 = (u8)rtl_get_bbreg(hw, 0xc58, MASKBYTE0); 24838c2ecf20Sopenharmony_ci u32 adda_reg[IQK_ADDA_REG_NUM] = { 24848c2ecf20Sopenharmony_ci 0x85c, 0xe6c, 0xe70, 0xe74, 24858c2ecf20Sopenharmony_ci 0xe78, 0xe7c, 0xe80, 0xe84, 24868c2ecf20Sopenharmony_ci 0xe88, 0xe8c, 0xed0, 0xed4, 24878c2ecf20Sopenharmony_ci 0xed8, 0xedc, 0xee0, 0xeec 24888c2ecf20Sopenharmony_ci }; 24898c2ecf20Sopenharmony_ci u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { 24908c2ecf20Sopenharmony_ci 0x522, 0x550, 0x551, 0x040 24918c2ecf20Sopenharmony_ci }; 24928c2ecf20Sopenharmony_ci u32 iqk_bb_reg[IQK_BB_REG_NUM] = { 24938c2ecf20Sopenharmony_ci ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, 24948c2ecf20Sopenharmony_ci RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c, 24958c2ecf20Sopenharmony_ci 0x870, 0x860, 24968c2ecf20Sopenharmony_ci 0x864, 0x800 24978c2ecf20Sopenharmony_ci }; 24988c2ecf20Sopenharmony_ci const u32 retrycount = 2; 24998c2ecf20Sopenharmony_ci 25008c2ecf20Sopenharmony_ci if (t == 0) { 25018c2ecf20Sopenharmony_ci _rtl92ee_phy_save_adda_registers(hw, adda_reg, 25028c2ecf20Sopenharmony_ci rtlphy->adda_backup, 25038c2ecf20Sopenharmony_ci IQK_ADDA_REG_NUM); 25048c2ecf20Sopenharmony_ci _rtl92ee_phy_save_mac_registers(hw, iqk_mac_reg, 25058c2ecf20Sopenharmony_ci rtlphy->iqk_mac_backup); 25068c2ecf20Sopenharmony_ci _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg, 25078c2ecf20Sopenharmony_ci rtlphy->iqk_bb_backup, 25088c2ecf20Sopenharmony_ci IQK_BB_REG_NUM); 25098c2ecf20Sopenharmony_ci } 25108c2ecf20Sopenharmony_ci 25118c2ecf20Sopenharmony_ci _rtl92ee_phy_path_adda_on(hw, adda_reg, true, is2t); 25128c2ecf20Sopenharmony_ci 25138c2ecf20Sopenharmony_ci /*BB setting*/ 25148c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BIT(24), 0x00); 25158c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKDWORD, 0x03a05600); 25168c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_TRMUXPAR, MASKDWORD, 0x000800e4); 25178c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, MASKDWORD, 0x22208200); 25188c2ecf20Sopenharmony_ci 25198c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(10), 0x01); 25208c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(26), 0x01); 25218c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, BIT(10), 0x01); 25228c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, BIT(10), 0x01); 25238c2ecf20Sopenharmony_ci 25248c2ecf20Sopenharmony_ci _rtl92ee_phy_mac_setting_calibration(hw, iqk_mac_reg, 25258c2ecf20Sopenharmony_ci rtlphy->iqk_mac_backup); 25268c2ecf20Sopenharmony_ci /* Page B init*/ 25278c2ecf20Sopenharmony_ci /* IQ calibration setting*/ 25288c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 25298c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); 25308c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 25318c2ecf20Sopenharmony_ci 25328c2ecf20Sopenharmony_ci for (i = 0 ; i < retrycount ; i++) { 25338c2ecf20Sopenharmony_ci patha_ok = _rtl92ee_phy_path_a_iqk(hw, is2t); 25348c2ecf20Sopenharmony_ci 25358c2ecf20Sopenharmony_ci if (patha_ok == 0x01) { 25368c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 25378c2ecf20Sopenharmony_ci "Path A Tx IQK Success!!\n"); 25388c2ecf20Sopenharmony_ci result[t][0] = (rtl_get_bbreg(hw, 25398c2ecf20Sopenharmony_ci RTX_POWER_BEFORE_IQK_A, 25408c2ecf20Sopenharmony_ci MASKDWORD) & 0x3FF0000) 25418c2ecf20Sopenharmony_ci >> 16; 25428c2ecf20Sopenharmony_ci result[t][1] = (rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, 25438c2ecf20Sopenharmony_ci MASKDWORD) & 0x3FF0000) 25448c2ecf20Sopenharmony_ci >> 16; 25458c2ecf20Sopenharmony_ci break; 25468c2ecf20Sopenharmony_ci } 25478c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 25488c2ecf20Sopenharmony_ci "Path A Tx IQK Fail!!, ret = 0x%x\n", 25498c2ecf20Sopenharmony_ci patha_ok); 25508c2ecf20Sopenharmony_ci } 25518c2ecf20Sopenharmony_ci 25528c2ecf20Sopenharmony_ci for (i = 0 ; i < retrycount ; i++) { 25538c2ecf20Sopenharmony_ci patha_ok = _rtl92ee_phy_path_a_rx_iqk(hw, is2t); 25548c2ecf20Sopenharmony_ci 25558c2ecf20Sopenharmony_ci if (patha_ok == 0x03) { 25568c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 25578c2ecf20Sopenharmony_ci "Path A Rx IQK Success!!\n"); 25588c2ecf20Sopenharmony_ci result[t][2] = (rtl_get_bbreg(hw, 25598c2ecf20Sopenharmony_ci RRX_POWER_BEFORE_IQK_A_2, 25608c2ecf20Sopenharmony_ci MASKDWORD) & 0x3FF0000) 25618c2ecf20Sopenharmony_ci >> 16; 25628c2ecf20Sopenharmony_ci result[t][3] = (rtl_get_bbreg(hw, 25638c2ecf20Sopenharmony_ci RRX_POWER_AFTER_IQK_A_2, 25648c2ecf20Sopenharmony_ci MASKDWORD) & 0x3FF0000) 25658c2ecf20Sopenharmony_ci >> 16; 25668c2ecf20Sopenharmony_ci break; 25678c2ecf20Sopenharmony_ci } 25688c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 25698c2ecf20Sopenharmony_ci "Path A Rx IQK Fail!!, ret = 0x%x\n", 25708c2ecf20Sopenharmony_ci patha_ok); 25718c2ecf20Sopenharmony_ci } 25728c2ecf20Sopenharmony_ci 25738c2ecf20Sopenharmony_ci if (0x00 == patha_ok) 25748c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 25758c2ecf20Sopenharmony_ci "Path A IQK failed!!, ret = 0\n"); 25768c2ecf20Sopenharmony_ci if (is2t) { 25778c2ecf20Sopenharmony_ci _rtl92ee_phy_path_a_standby(hw); 25788c2ecf20Sopenharmony_ci /* Turn Path B ADDA on */ 25798c2ecf20Sopenharmony_ci _rtl92ee_phy_path_adda_on(hw, adda_reg, false, is2t); 25808c2ecf20Sopenharmony_ci 25818c2ecf20Sopenharmony_ci /* IQ calibration setting */ 25828c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); 25838c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); 25848c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); 25858c2ecf20Sopenharmony_ci 25868c2ecf20Sopenharmony_ci for (i = 0 ; i < retrycount ; i++) { 25878c2ecf20Sopenharmony_ci pathb_ok = _rtl92ee_phy_path_b_iqk(hw); 25888c2ecf20Sopenharmony_ci if (pathb_ok == 0x01) { 25898c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 25908c2ecf20Sopenharmony_ci "Path B Tx IQK Success!!\n"); 25918c2ecf20Sopenharmony_ci result[t][4] = (rtl_get_bbreg(hw, 25928c2ecf20Sopenharmony_ci RTX_POWER_BEFORE_IQK_B, 25938c2ecf20Sopenharmony_ci MASKDWORD) & 0x3FF0000) 25948c2ecf20Sopenharmony_ci >> 16; 25958c2ecf20Sopenharmony_ci result[t][5] = (rtl_get_bbreg(hw, 25968c2ecf20Sopenharmony_ci RTX_POWER_AFTER_IQK_B, 25978c2ecf20Sopenharmony_ci MASKDWORD) & 0x3FF0000) 25988c2ecf20Sopenharmony_ci >> 16; 25998c2ecf20Sopenharmony_ci break; 26008c2ecf20Sopenharmony_ci } 26018c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 26028c2ecf20Sopenharmony_ci "Path B Tx IQK Fail!!, ret = 0x%x\n", 26038c2ecf20Sopenharmony_ci pathb_ok); 26048c2ecf20Sopenharmony_ci } 26058c2ecf20Sopenharmony_ci 26068c2ecf20Sopenharmony_ci for (i = 0 ; i < retrycount ; i++) { 26078c2ecf20Sopenharmony_ci pathb_ok = _rtl92ee_phy_path_b_rx_iqk(hw, is2t); 26088c2ecf20Sopenharmony_ci if (pathb_ok == 0x03) { 26098c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 26108c2ecf20Sopenharmony_ci "Path B Rx IQK Success!!\n"); 26118c2ecf20Sopenharmony_ci result[t][6] = (rtl_get_bbreg(hw, 26128c2ecf20Sopenharmony_ci RRX_POWER_BEFORE_IQK_B_2, 26138c2ecf20Sopenharmony_ci MASKDWORD) & 0x3FF0000) 26148c2ecf20Sopenharmony_ci >> 16; 26158c2ecf20Sopenharmony_ci result[t][7] = (rtl_get_bbreg(hw, 26168c2ecf20Sopenharmony_ci RRX_POWER_AFTER_IQK_B_2, 26178c2ecf20Sopenharmony_ci MASKDWORD) & 0x3FF0000) 26188c2ecf20Sopenharmony_ci >> 16; 26198c2ecf20Sopenharmony_ci break; 26208c2ecf20Sopenharmony_ci } 26218c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 26228c2ecf20Sopenharmony_ci "Path B Rx IQK Fail!!, ret = 0x%x\n", 26238c2ecf20Sopenharmony_ci pathb_ok); 26248c2ecf20Sopenharmony_ci } 26258c2ecf20Sopenharmony_ci 26268c2ecf20Sopenharmony_ci if (0x00 == pathb_ok) 26278c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 26288c2ecf20Sopenharmony_ci "Path B IQK failed!!, ret = 0\n"); 26298c2ecf20Sopenharmony_ci } 26308c2ecf20Sopenharmony_ci /* Back to BB mode, load original value */ 26318c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_LOUD, 26328c2ecf20Sopenharmony_ci "IQK:Back to BB mode, load original value!\n"); 26338c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0); 26348c2ecf20Sopenharmony_ci 26358c2ecf20Sopenharmony_ci if (t != 0) { 26368c2ecf20Sopenharmony_ci /* Reload ADDA power saving parameters */ 26378c2ecf20Sopenharmony_ci _rtl92ee_phy_reload_adda_registers(hw, adda_reg, 26388c2ecf20Sopenharmony_ci rtlphy->adda_backup, 26398c2ecf20Sopenharmony_ci IQK_ADDA_REG_NUM); 26408c2ecf20Sopenharmony_ci 26418c2ecf20Sopenharmony_ci /* Reload MAC parameters */ 26428c2ecf20Sopenharmony_ci _rtl92ee_phy_reload_mac_registers(hw, iqk_mac_reg, 26438c2ecf20Sopenharmony_ci rtlphy->iqk_mac_backup); 26448c2ecf20Sopenharmony_ci 26458c2ecf20Sopenharmony_ci _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg, 26468c2ecf20Sopenharmony_ci rtlphy->iqk_bb_backup, 26478c2ecf20Sopenharmony_ci IQK_BB_REG_NUM); 26488c2ecf20Sopenharmony_ci 26498c2ecf20Sopenharmony_ci /* Restore RX initial gain */ 26508c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50); 26518c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_0xc50); 26528c2ecf20Sopenharmony_ci if (is2t) { 26538c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50); 26548c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_0xc58); 26558c2ecf20Sopenharmony_ci } 26568c2ecf20Sopenharmony_ci 26578c2ecf20Sopenharmony_ci /* load 0xe30 IQC default value */ 26588c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x01008c00); 26598c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x01008c00); 26608c2ecf20Sopenharmony_ci } 26618c2ecf20Sopenharmony_ci} 26628c2ecf20Sopenharmony_ci 26638c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) 26648c2ecf20Sopenharmony_ci{ 26658c2ecf20Sopenharmony_ci u8 tmpreg; 26668c2ecf20Sopenharmony_ci u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; 26678c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 26688c2ecf20Sopenharmony_ci 26698c2ecf20Sopenharmony_ci tmpreg = rtl_read_byte(rtlpriv, 0xd03); 26708c2ecf20Sopenharmony_ci 26718c2ecf20Sopenharmony_ci if ((tmpreg & 0x70) != 0) 26728c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); 26738c2ecf20Sopenharmony_ci else 26748c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 26758c2ecf20Sopenharmony_ci 26768c2ecf20Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 26778c2ecf20Sopenharmony_ci rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); 26788c2ecf20Sopenharmony_ci 26798c2ecf20Sopenharmony_ci if (is2t) 26808c2ecf20Sopenharmony_ci rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, 26818c2ecf20Sopenharmony_ci MASK12BITS); 26828c2ecf20Sopenharmony_ci 26838c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, 26848c2ecf20Sopenharmony_ci (rf_a_mode & 0x8FFFF) | 0x10000); 26858c2ecf20Sopenharmony_ci 26868c2ecf20Sopenharmony_ci if (is2t) 26878c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, 26888c2ecf20Sopenharmony_ci (rf_b_mode & 0x8FFFF) | 0x10000); 26898c2ecf20Sopenharmony_ci } 26908c2ecf20Sopenharmony_ci lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); 26918c2ecf20Sopenharmony_ci 26928c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); 26938c2ecf20Sopenharmony_ci 26948c2ecf20Sopenharmony_ci mdelay(100); 26958c2ecf20Sopenharmony_ci 26968c2ecf20Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 26978c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg); 26988c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); 26998c2ecf20Sopenharmony_ci 27008c2ecf20Sopenharmony_ci if (is2t) 27018c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, 27028c2ecf20Sopenharmony_ci rf_b_mode); 27038c2ecf20Sopenharmony_ci } else { 27048c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 27058c2ecf20Sopenharmony_ci } 27068c2ecf20Sopenharmony_ci} 27078c2ecf20Sopenharmony_ci 27088c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, 27098c2ecf20Sopenharmony_ci bool bmain, bool is2t) 27108c2ecf20Sopenharmony_ci{ 27118c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 27128c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 27138c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 27148c2ecf20Sopenharmony_ci 27158c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); 27168c2ecf20Sopenharmony_ci 27178c2ecf20Sopenharmony_ci if (is_hal_stop(rtlhal)) { 27188c2ecf20Sopenharmony_ci u8 u1btmp; 27198c2ecf20Sopenharmony_ci 27208c2ecf20Sopenharmony_ci u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0); 27218c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7)); 27228c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); 27238c2ecf20Sopenharmony_ci } 27248c2ecf20Sopenharmony_ci if (is2t) { 27258c2ecf20Sopenharmony_ci if (bmain) 27268c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 27278c2ecf20Sopenharmony_ci BIT(5) | BIT(6), 0x1); 27288c2ecf20Sopenharmony_ci else 27298c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 27308c2ecf20Sopenharmony_ci BIT(5) | BIT(6), 0x2); 27318c2ecf20Sopenharmony_ci } else { 27328c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0); 27338c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201); 27348c2ecf20Sopenharmony_ci 27358c2ecf20Sopenharmony_ci /* We use the RF definition of MAIN and AUX, 27368c2ecf20Sopenharmony_ci * left antenna and right antenna repectively. 27378c2ecf20Sopenharmony_ci * Default output at AUX. 27388c2ecf20Sopenharmony_ci */ 27398c2ecf20Sopenharmony_ci if (bmain) { 27408c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 27418c2ecf20Sopenharmony_ci BIT(14) | BIT(13) | BIT(12), 0); 27428c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 27438c2ecf20Sopenharmony_ci BIT(5) | BIT(4) | BIT(3), 0); 27448c2ecf20Sopenharmony_ci if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) 27458c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 0); 27468c2ecf20Sopenharmony_ci } else { 27478c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 27488c2ecf20Sopenharmony_ci BIT(14) | BIT(13) | BIT(12), 1); 27498c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 27508c2ecf20Sopenharmony_ci BIT(5) | BIT(4) | BIT(3), 1); 27518c2ecf20Sopenharmony_ci if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) 27528c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCONFIG_RAM64x16, BIT(31), 1); 27538c2ecf20Sopenharmony_ci } 27548c2ecf20Sopenharmony_ci } 27558c2ecf20Sopenharmony_ci} 27568c2ecf20Sopenharmony_ci 27578c2ecf20Sopenharmony_ci#undef IQK_ADDA_REG_NUM 27588c2ecf20Sopenharmony_ci#undef IQK_DELAY_TIME 27598c2ecf20Sopenharmony_ci 27608c2ecf20Sopenharmony_cistatic u8 rtl92ee_get_rightchnlplace_for_iqk(u8 chnl) 27618c2ecf20Sopenharmony_ci{ 27628c2ecf20Sopenharmony_ci u8 channel_all[59] = { 27638c2ecf20Sopenharmony_ci 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 27648c2ecf20Sopenharmony_ci 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 27658c2ecf20Sopenharmony_ci 60, 62, 64, 100, 102, 104, 106, 108, 110, 112, 27668c2ecf20Sopenharmony_ci 114, 116, 118, 120, 122, 124, 126, 128, 130, 27678c2ecf20Sopenharmony_ci 132, 134, 136, 138, 140, 149, 151, 153, 155, 27688c2ecf20Sopenharmony_ci 157, 159, 161, 163, 165 27698c2ecf20Sopenharmony_ci }; 27708c2ecf20Sopenharmony_ci u8 place = chnl; 27718c2ecf20Sopenharmony_ci 27728c2ecf20Sopenharmony_ci if (chnl > 14) { 27738c2ecf20Sopenharmony_ci for (place = 14; place < sizeof(channel_all); place++) { 27748c2ecf20Sopenharmony_ci if (channel_all[place] == chnl) 27758c2ecf20Sopenharmony_ci return place - 13; 27768c2ecf20Sopenharmony_ci } 27778c2ecf20Sopenharmony_ci } 27788c2ecf20Sopenharmony_ci 27798c2ecf20Sopenharmony_ci return 0; 27808c2ecf20Sopenharmony_ci} 27818c2ecf20Sopenharmony_ci 27828c2ecf20Sopenharmony_civoid rtl92ee_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) 27838c2ecf20Sopenharmony_ci{ 27848c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 27858c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 27868c2ecf20Sopenharmony_ci long result[4][8]; 27878c2ecf20Sopenharmony_ci u8 i, final_candidate; 27888c2ecf20Sopenharmony_ci bool b_patha_ok, b_pathb_ok; 27898c2ecf20Sopenharmony_ci long reg_e94, reg_e9c, reg_ea4; 27908c2ecf20Sopenharmony_ci long reg_eb4, reg_ebc, reg_ec4; 27918c2ecf20Sopenharmony_ci bool is12simular, is13simular, is23simular; 27928c2ecf20Sopenharmony_ci u8 idx; 27938c2ecf20Sopenharmony_ci u32 iqk_bb_reg[IQK_BB_REG_NUM] = { 27948c2ecf20Sopenharmony_ci ROFDM0_XARXIQIMBALANCE, 27958c2ecf20Sopenharmony_ci ROFDM0_XBRXIQIMBALANCE, 27968c2ecf20Sopenharmony_ci ROFDM0_ECCATHRESHOLD, 27978c2ecf20Sopenharmony_ci ROFDM0_AGCRSSITABLE, 27988c2ecf20Sopenharmony_ci ROFDM0_XATXIQIMBALANCE, 27998c2ecf20Sopenharmony_ci ROFDM0_XBTXIQIMBALANCE, 28008c2ecf20Sopenharmony_ci ROFDM0_XCTXAFE, 28018c2ecf20Sopenharmony_ci ROFDM0_XDTXAFE, 28028c2ecf20Sopenharmony_ci ROFDM0_RXIQEXTANTA 28038c2ecf20Sopenharmony_ci }; 28048c2ecf20Sopenharmony_ci 28058c2ecf20Sopenharmony_ci if (b_recovery) { 28068c2ecf20Sopenharmony_ci _rtl92ee_phy_reload_adda_registers(hw, iqk_bb_reg, 28078c2ecf20Sopenharmony_ci rtlphy->iqk_bb_backup, 9); 28088c2ecf20Sopenharmony_ci return; 28098c2ecf20Sopenharmony_ci } 28108c2ecf20Sopenharmony_ci 28118c2ecf20Sopenharmony_ci for (i = 0; i < 8; i++) { 28128c2ecf20Sopenharmony_ci result[0][i] = 0; 28138c2ecf20Sopenharmony_ci result[1][i] = 0; 28148c2ecf20Sopenharmony_ci result[2][i] = 0; 28158c2ecf20Sopenharmony_ci 28168c2ecf20Sopenharmony_ci if ((i == 0) || (i == 2) || (i == 4) || (i == 6)) 28178c2ecf20Sopenharmony_ci result[3][i] = 0x100; 28188c2ecf20Sopenharmony_ci else 28198c2ecf20Sopenharmony_ci result[3][i] = 0; 28208c2ecf20Sopenharmony_ci } 28218c2ecf20Sopenharmony_ci final_candidate = 0xff; 28228c2ecf20Sopenharmony_ci b_patha_ok = false; 28238c2ecf20Sopenharmony_ci b_pathb_ok = false; 28248c2ecf20Sopenharmony_ci is12simular = false; 28258c2ecf20Sopenharmony_ci is23simular = false; 28268c2ecf20Sopenharmony_ci is13simular = false; 28278c2ecf20Sopenharmony_ci for (i = 0; i < 3; i++) { 28288c2ecf20Sopenharmony_ci _rtl92ee_phy_iq_calibrate(hw, result, i, true); 28298c2ecf20Sopenharmony_ci if (i == 1) { 28308c2ecf20Sopenharmony_ci is12simular = _rtl92ee_phy_simularity_compare(hw, 28318c2ecf20Sopenharmony_ci result, 28328c2ecf20Sopenharmony_ci 0, 1); 28338c2ecf20Sopenharmony_ci if (is12simular) { 28348c2ecf20Sopenharmony_ci final_candidate = 0; 28358c2ecf20Sopenharmony_ci break; 28368c2ecf20Sopenharmony_ci } 28378c2ecf20Sopenharmony_ci } 28388c2ecf20Sopenharmony_ci 28398c2ecf20Sopenharmony_ci if (i == 2) { 28408c2ecf20Sopenharmony_ci is13simular = _rtl92ee_phy_simularity_compare(hw, 28418c2ecf20Sopenharmony_ci result, 28428c2ecf20Sopenharmony_ci 0, 2); 28438c2ecf20Sopenharmony_ci if (is13simular) { 28448c2ecf20Sopenharmony_ci final_candidate = 0; 28458c2ecf20Sopenharmony_ci break; 28468c2ecf20Sopenharmony_ci } 28478c2ecf20Sopenharmony_ci is23simular = _rtl92ee_phy_simularity_compare(hw, 28488c2ecf20Sopenharmony_ci result, 28498c2ecf20Sopenharmony_ci 1, 2); 28508c2ecf20Sopenharmony_ci if (is23simular) 28518c2ecf20Sopenharmony_ci final_candidate = 1; 28528c2ecf20Sopenharmony_ci else 28538c2ecf20Sopenharmony_ci final_candidate = 3; 28548c2ecf20Sopenharmony_ci } 28558c2ecf20Sopenharmony_ci } 28568c2ecf20Sopenharmony_ci 28578c2ecf20Sopenharmony_ci reg_e94 = result[3][0]; 28588c2ecf20Sopenharmony_ci reg_e9c = result[3][1]; 28598c2ecf20Sopenharmony_ci reg_ea4 = result[3][2]; 28608c2ecf20Sopenharmony_ci reg_eb4 = result[3][4]; 28618c2ecf20Sopenharmony_ci reg_ebc = result[3][5]; 28628c2ecf20Sopenharmony_ci reg_ec4 = result[3][6]; 28638c2ecf20Sopenharmony_ci 28648c2ecf20Sopenharmony_ci if (final_candidate != 0xff) { 28658c2ecf20Sopenharmony_ci reg_e94 = result[final_candidate][0]; 28668c2ecf20Sopenharmony_ci rtlphy->reg_e94 = reg_e94; 28678c2ecf20Sopenharmony_ci reg_e9c = result[final_candidate][1]; 28688c2ecf20Sopenharmony_ci rtlphy->reg_e9c = reg_e9c; 28698c2ecf20Sopenharmony_ci reg_ea4 = result[final_candidate][2]; 28708c2ecf20Sopenharmony_ci reg_eb4 = result[final_candidate][4]; 28718c2ecf20Sopenharmony_ci rtlphy->reg_eb4 = reg_eb4; 28728c2ecf20Sopenharmony_ci reg_ebc = result[final_candidate][5]; 28738c2ecf20Sopenharmony_ci rtlphy->reg_ebc = reg_ebc; 28748c2ecf20Sopenharmony_ci reg_ec4 = result[final_candidate][6]; 28758c2ecf20Sopenharmony_ci b_patha_ok = true; 28768c2ecf20Sopenharmony_ci b_pathb_ok = true; 28778c2ecf20Sopenharmony_ci } else { 28788c2ecf20Sopenharmony_ci rtlphy->reg_e94 = 0x100; 28798c2ecf20Sopenharmony_ci rtlphy->reg_eb4 = 0x100; 28808c2ecf20Sopenharmony_ci rtlphy->reg_e9c = 0x0; 28818c2ecf20Sopenharmony_ci rtlphy->reg_ebc = 0x0; 28828c2ecf20Sopenharmony_ci } 28838c2ecf20Sopenharmony_ci 28848c2ecf20Sopenharmony_ci if (reg_e94 != 0) 28858c2ecf20Sopenharmony_ci _rtl92ee_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, 28868c2ecf20Sopenharmony_ci final_candidate, 28878c2ecf20Sopenharmony_ci (reg_ea4 == 0)); 28888c2ecf20Sopenharmony_ci 28898c2ecf20Sopenharmony_ci _rtl92ee_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result, 28908c2ecf20Sopenharmony_ci final_candidate, 28918c2ecf20Sopenharmony_ci (reg_ec4 == 0)); 28928c2ecf20Sopenharmony_ci 28938c2ecf20Sopenharmony_ci idx = rtl92ee_get_rightchnlplace_for_iqk(rtlphy->current_channel); 28948c2ecf20Sopenharmony_ci 28958c2ecf20Sopenharmony_ci /* To Fix BSOD when final_candidate is 0xff */ 28968c2ecf20Sopenharmony_ci if (final_candidate < 4) { 28978c2ecf20Sopenharmony_ci for (i = 0; i < IQK_MATRIX_REG_NUM; i++) 28988c2ecf20Sopenharmony_ci rtlphy->iqk_matrix[idx].value[0][i] = 28998c2ecf20Sopenharmony_ci result[final_candidate][i]; 29008c2ecf20Sopenharmony_ci 29018c2ecf20Sopenharmony_ci rtlphy->iqk_matrix[idx].iqk_done = true; 29028c2ecf20Sopenharmony_ci } 29038c2ecf20Sopenharmony_ci _rtl92ee_phy_save_adda_registers(hw, iqk_bb_reg, 29048c2ecf20Sopenharmony_ci rtlphy->iqk_bb_backup, 9); 29058c2ecf20Sopenharmony_ci} 29068c2ecf20Sopenharmony_ci 29078c2ecf20Sopenharmony_civoid rtl92ee_phy_lc_calibrate(struct ieee80211_hw *hw) 29088c2ecf20Sopenharmony_ci{ 29098c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 29108c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 29118c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = &rtlpriv->rtlhal; 29128c2ecf20Sopenharmony_ci u32 timeout = 2000, timecount = 0; 29138c2ecf20Sopenharmony_ci 29148c2ecf20Sopenharmony_ci while (rtlpriv->mac80211.act_scanning && timecount < timeout) { 29158c2ecf20Sopenharmony_ci udelay(50); 29168c2ecf20Sopenharmony_ci timecount += 50; 29178c2ecf20Sopenharmony_ci } 29188c2ecf20Sopenharmony_ci 29198c2ecf20Sopenharmony_ci rtlphy->lck_inprogress = true; 29208c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_IQK, 29218c2ecf20Sopenharmony_ci "LCK:Start!!! currentband %x delay %d ms\n", 29228c2ecf20Sopenharmony_ci rtlhal->current_bandtype, timecount); 29238c2ecf20Sopenharmony_ci 29248c2ecf20Sopenharmony_ci _rtl92ee_phy_lc_calibrate(hw, false); 29258c2ecf20Sopenharmony_ci 29268c2ecf20Sopenharmony_ci rtlphy->lck_inprogress = false; 29278c2ecf20Sopenharmony_ci} 29288c2ecf20Sopenharmony_ci 29298c2ecf20Sopenharmony_civoid rtl92ee_phy_ap_calibrate(struct ieee80211_hw *hw, s8 delta) 29308c2ecf20Sopenharmony_ci{ 29318c2ecf20Sopenharmony_ci} 29328c2ecf20Sopenharmony_ci 29338c2ecf20Sopenharmony_civoid rtl92ee_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) 29348c2ecf20Sopenharmony_ci{ 29358c2ecf20Sopenharmony_ci _rtl92ee_phy_set_rfpath_switch(hw, bmain, false); 29368c2ecf20Sopenharmony_ci} 29378c2ecf20Sopenharmony_ci 29388c2ecf20Sopenharmony_cibool rtl92ee_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) 29398c2ecf20Sopenharmony_ci{ 29408c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 29418c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 29428c2ecf20Sopenharmony_ci bool postprocessing = false; 29438c2ecf20Sopenharmony_ci 29448c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 29458c2ecf20Sopenharmony_ci "-->IO Cmd(%#x), set_io_inprogress(%d)\n", 29468c2ecf20Sopenharmony_ci iotype, rtlphy->set_io_inprogress); 29478c2ecf20Sopenharmony_ci do { 29488c2ecf20Sopenharmony_ci switch (iotype) { 29498c2ecf20Sopenharmony_ci case IO_CMD_RESUME_DM_BY_SCAN: 29508c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 29518c2ecf20Sopenharmony_ci "[IO CMD] Resume DM after scan.\n"); 29528c2ecf20Sopenharmony_ci postprocessing = true; 29538c2ecf20Sopenharmony_ci break; 29548c2ecf20Sopenharmony_ci case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 29558c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 29568c2ecf20Sopenharmony_ci "[IO CMD] Pause DM before scan.\n"); 29578c2ecf20Sopenharmony_ci postprocessing = true; 29588c2ecf20Sopenharmony_ci break; 29598c2ecf20Sopenharmony_ci default: 29608c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 29618c2ecf20Sopenharmony_ci "switch case %#x not processed\n", iotype); 29628c2ecf20Sopenharmony_ci break; 29638c2ecf20Sopenharmony_ci } 29648c2ecf20Sopenharmony_ci } while (false); 29658c2ecf20Sopenharmony_ci if (postprocessing && !rtlphy->set_io_inprogress) { 29668c2ecf20Sopenharmony_ci rtlphy->set_io_inprogress = true; 29678c2ecf20Sopenharmony_ci rtlphy->current_io_type = iotype; 29688c2ecf20Sopenharmony_ci } else { 29698c2ecf20Sopenharmony_ci return false; 29708c2ecf20Sopenharmony_ci } 29718c2ecf20Sopenharmony_ci rtl92ee_phy_set_io(hw); 29728c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); 29738c2ecf20Sopenharmony_ci return true; 29748c2ecf20Sopenharmony_ci} 29758c2ecf20Sopenharmony_ci 29768c2ecf20Sopenharmony_cistatic void rtl92ee_phy_set_io(struct ieee80211_hw *hw) 29778c2ecf20Sopenharmony_ci{ 29788c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 29798c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 29808c2ecf20Sopenharmony_ci struct dig_t *dm_dig = &rtlpriv->dm_digtable; 29818c2ecf20Sopenharmony_ci 29828c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 29838c2ecf20Sopenharmony_ci "--->Cmd(%#x), set_io_inprogress(%d)\n", 29848c2ecf20Sopenharmony_ci rtlphy->current_io_type, rtlphy->set_io_inprogress); 29858c2ecf20Sopenharmony_ci switch (rtlphy->current_io_type) { 29868c2ecf20Sopenharmony_ci case IO_CMD_RESUME_DM_BY_SCAN: 29878c2ecf20Sopenharmony_ci rtl92ee_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1); 29888c2ecf20Sopenharmony_ci rtl92ee_dm_write_cck_cca_thres(hw, rtlphy->initgain_backup.cca); 29898c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "no set txpower\n"); 29908c2ecf20Sopenharmony_ci rtl92ee_phy_set_txpower_level(hw, rtlphy->current_channel); 29918c2ecf20Sopenharmony_ci break; 29928c2ecf20Sopenharmony_ci case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 29938c2ecf20Sopenharmony_ci /* 8192eebt */ 29948c2ecf20Sopenharmony_ci rtlphy->initgain_backup.xaagccore1 = dm_dig->cur_igvalue; 29958c2ecf20Sopenharmony_ci rtl92ee_dm_write_dig(hw, 0x17); 29968c2ecf20Sopenharmony_ci rtlphy->initgain_backup.cca = dm_dig->cur_cck_cca_thres; 29978c2ecf20Sopenharmony_ci rtl92ee_dm_write_cck_cca_thres(hw, 0x40); 29988c2ecf20Sopenharmony_ci break; 29998c2ecf20Sopenharmony_ci default: 30008c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 30018c2ecf20Sopenharmony_ci "switch case %#x not processed\n", 30028c2ecf20Sopenharmony_ci rtlphy->current_io_type); 30038c2ecf20Sopenharmony_ci break; 30048c2ecf20Sopenharmony_ci } 30058c2ecf20Sopenharmony_ci rtlphy->set_io_inprogress = false; 30068c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, 30078c2ecf20Sopenharmony_ci "(%#x)\n", rtlphy->current_io_type); 30088c2ecf20Sopenharmony_ci} 30098c2ecf20Sopenharmony_ci 30108c2ecf20Sopenharmony_cistatic void rtl92ee_phy_set_rf_on(struct ieee80211_hw *hw) 30118c2ecf20Sopenharmony_ci{ 30128c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 30138c2ecf20Sopenharmony_ci 30148c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); 30158c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 30168c2ecf20Sopenharmony_ci /*rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);*/ 30178c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 30188c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 30198c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 30208c2ecf20Sopenharmony_ci} 30218c2ecf20Sopenharmony_ci 30228c2ecf20Sopenharmony_cistatic void _rtl92ee_phy_set_rf_sleep(struct ieee80211_hw *hw) 30238c2ecf20Sopenharmony_ci{ 30248c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 30258c2ecf20Sopenharmony_ci 30268c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 30278c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 30288c2ecf20Sopenharmony_ci 30298c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 30308c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); 30318c2ecf20Sopenharmony_ci} 30328c2ecf20Sopenharmony_ci 30338c2ecf20Sopenharmony_cistatic bool _rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw, 30348c2ecf20Sopenharmony_ci enum rf_pwrstate rfpwr_state) 30358c2ecf20Sopenharmony_ci{ 30368c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 30378c2ecf20Sopenharmony_ci struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 30388c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 30398c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 30408c2ecf20Sopenharmony_ci bool bresult = true; 30418c2ecf20Sopenharmony_ci u8 i, queue_id; 30428c2ecf20Sopenharmony_ci struct rtl8192_tx_ring *ring = NULL; 30438c2ecf20Sopenharmony_ci 30448c2ecf20Sopenharmony_ci switch (rfpwr_state) { 30458c2ecf20Sopenharmony_ci case ERFON: 30468c2ecf20Sopenharmony_ci if ((ppsc->rfpwr_state == ERFOFF) && 30478c2ecf20Sopenharmony_ci RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { 30488c2ecf20Sopenharmony_ci bool rtstatus; 30498c2ecf20Sopenharmony_ci u32 initializecount = 0; 30508c2ecf20Sopenharmony_ci 30518c2ecf20Sopenharmony_ci do { 30528c2ecf20Sopenharmony_ci initializecount++; 30538c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 30548c2ecf20Sopenharmony_ci "IPS Set eRf nic enable\n"); 30558c2ecf20Sopenharmony_ci rtstatus = rtl_ps_enable_nic(hw); 30568c2ecf20Sopenharmony_ci } while (!rtstatus && (initializecount < 10)); 30578c2ecf20Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 30588c2ecf20Sopenharmony_ci } else { 30598c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 30608c2ecf20Sopenharmony_ci "Set ERFON sleeping:%d ms\n", 30618c2ecf20Sopenharmony_ci jiffies_to_msecs(jiffies - 30628c2ecf20Sopenharmony_ci ppsc->last_sleep_jiffies)); 30638c2ecf20Sopenharmony_ci ppsc->last_awake_jiffies = jiffies; 30648c2ecf20Sopenharmony_ci rtl92ee_phy_set_rf_on(hw); 30658c2ecf20Sopenharmony_ci } 30668c2ecf20Sopenharmony_ci if (mac->link_state == MAC80211_LINKED) 30678c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK); 30688c2ecf20Sopenharmony_ci else 30698c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); 30708c2ecf20Sopenharmony_ci break; 30718c2ecf20Sopenharmony_ci case ERFOFF: 30728c2ecf20Sopenharmony_ci for (queue_id = 0, i = 0; 30738c2ecf20Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 30748c2ecf20Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 30758c2ecf20Sopenharmony_ci if (queue_id == BEACON_QUEUE || 30768c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue) == 0) { 30778c2ecf20Sopenharmony_ci queue_id++; 30788c2ecf20Sopenharmony_ci continue; 30798c2ecf20Sopenharmony_ci } else { 30808c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 30818c2ecf20Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", 30828c2ecf20Sopenharmony_ci (i + 1), queue_id, 30838c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue)); 30848c2ecf20Sopenharmony_ci 30858c2ecf20Sopenharmony_ci udelay(10); 30868c2ecf20Sopenharmony_ci i++; 30878c2ecf20Sopenharmony_ci } 30888c2ecf20Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 30898c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 30908c2ecf20Sopenharmony_ci "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", 30918c2ecf20Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 30928c2ecf20Sopenharmony_ci queue_id, 30938c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue)); 30948c2ecf20Sopenharmony_ci break; 30958c2ecf20Sopenharmony_ci } 30968c2ecf20Sopenharmony_ci } 30978c2ecf20Sopenharmony_ci 30988c2ecf20Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { 30998c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 31008c2ecf20Sopenharmony_ci "IPS Set eRf nic disable\n"); 31018c2ecf20Sopenharmony_ci rtl_ps_disable_nic(hw); 31028c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 31038c2ecf20Sopenharmony_ci } else { 31048c2ecf20Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { 31058c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 31068c2ecf20Sopenharmony_ci LED_CTL_NO_LINK); 31078c2ecf20Sopenharmony_ci } else { 31088c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 31098c2ecf20Sopenharmony_ci LED_CTL_POWER_OFF); 31108c2ecf20Sopenharmony_ci } 31118c2ecf20Sopenharmony_ci } 31128c2ecf20Sopenharmony_ci break; 31138c2ecf20Sopenharmony_ci case ERFSLEEP: 31148c2ecf20Sopenharmony_ci if (ppsc->rfpwr_state == ERFOFF) 31158c2ecf20Sopenharmony_ci break; 31168c2ecf20Sopenharmony_ci for (queue_id = 0, i = 0; 31178c2ecf20Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 31188c2ecf20Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 31198c2ecf20Sopenharmony_ci if (skb_queue_len(&ring->queue) == 0) { 31208c2ecf20Sopenharmony_ci queue_id++; 31218c2ecf20Sopenharmony_ci continue; 31228c2ecf20Sopenharmony_ci } else { 31238c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 31248c2ecf20Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", 31258c2ecf20Sopenharmony_ci (i + 1), queue_id, 31268c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue)); 31278c2ecf20Sopenharmony_ci udelay(10); 31288c2ecf20Sopenharmony_ci i++; 31298c2ecf20Sopenharmony_ci } 31308c2ecf20Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 31318c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 31328c2ecf20Sopenharmony_ci "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", 31338c2ecf20Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 31348c2ecf20Sopenharmony_ci queue_id, 31358c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue)); 31368c2ecf20Sopenharmony_ci break; 31378c2ecf20Sopenharmony_ci } 31388c2ecf20Sopenharmony_ci } 31398c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 31408c2ecf20Sopenharmony_ci "Set ERFSLEEP awaked:%d ms\n", 31418c2ecf20Sopenharmony_ci jiffies_to_msecs(jiffies - 31428c2ecf20Sopenharmony_ci ppsc->last_awake_jiffies)); 31438c2ecf20Sopenharmony_ci ppsc->last_sleep_jiffies = jiffies; 31448c2ecf20Sopenharmony_ci _rtl92ee_phy_set_rf_sleep(hw); 31458c2ecf20Sopenharmony_ci break; 31468c2ecf20Sopenharmony_ci default: 31478c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD, 31488c2ecf20Sopenharmony_ci "switch case %#x not processed\n", rfpwr_state); 31498c2ecf20Sopenharmony_ci bresult = false; 31508c2ecf20Sopenharmony_ci break; 31518c2ecf20Sopenharmony_ci } 31528c2ecf20Sopenharmony_ci if (bresult) 31538c2ecf20Sopenharmony_ci ppsc->rfpwr_state = rfpwr_state; 31548c2ecf20Sopenharmony_ci return bresult; 31558c2ecf20Sopenharmony_ci} 31568c2ecf20Sopenharmony_ci 31578c2ecf20Sopenharmony_cibool rtl92ee_phy_set_rf_power_state(struct ieee80211_hw *hw, 31588c2ecf20Sopenharmony_ci enum rf_pwrstate rfpwr_state) 31598c2ecf20Sopenharmony_ci{ 31608c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 31618c2ecf20Sopenharmony_ci 31628c2ecf20Sopenharmony_ci bool bresult = false; 31638c2ecf20Sopenharmony_ci 31648c2ecf20Sopenharmony_ci if (rfpwr_state == ppsc->rfpwr_state) 31658c2ecf20Sopenharmony_ci return bresult; 31668c2ecf20Sopenharmony_ci bresult = _rtl92ee_phy_set_rf_power_state(hw, rfpwr_state); 31678c2ecf20Sopenharmony_ci return bresult; 31688c2ecf20Sopenharmony_ci} 3169