18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 2009-2012 Realtek Corporation.*/ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "../wifi.h" 58c2ecf20Sopenharmony_ci#include "../pci.h" 68c2ecf20Sopenharmony_ci#include "../ps.h" 78c2ecf20Sopenharmony_ci#include "../core.h" 88c2ecf20Sopenharmony_ci#include "reg.h" 98c2ecf20Sopenharmony_ci#include "def.h" 108c2ecf20Sopenharmony_ci#include "hw.h" 118c2ecf20Sopenharmony_ci#include "phy.h" 128c2ecf20Sopenharmony_ci#include "../rtl8192c/phy_common.h" 138c2ecf20Sopenharmony_ci#include "rf.h" 148c2ecf20Sopenharmony_ci#include "dm.h" 158c2ecf20Sopenharmony_ci#include "../rtl8192c/dm_common.h" 168c2ecf20Sopenharmony_ci#include "../rtl8192c/fw_common.h" 178c2ecf20Sopenharmony_ci#include "table.h" 188c2ecf20Sopenharmony_ci 198c2ecf20Sopenharmony_cistatic bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ciu32 rtl92c_phy_query_rf_reg(struct ieee80211_hw *hw, 228c2ecf20Sopenharmony_ci enum radio_path rfpath, u32 regaddr, u32 bitmask) 238c2ecf20Sopenharmony_ci{ 248c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 258c2ecf20Sopenharmony_ci u32 original_value, readback_value, bitshift; 268c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 298c2ecf20Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", 308c2ecf20Sopenharmony_ci regaddr, rfpath, bitmask); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci if (rtlphy->rf_mode != RF_OP_BY_FW) { 358c2ecf20Sopenharmony_ci original_value = _rtl92c_phy_rf_serial_read(hw, 368c2ecf20Sopenharmony_ci rfpath, regaddr); 378c2ecf20Sopenharmony_ci } else { 388c2ecf20Sopenharmony_ci original_value = _rtl92c_phy_fw_rf_serial_read(hw, 398c2ecf20Sopenharmony_ci rfpath, regaddr); 408c2ecf20Sopenharmony_ci } 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 438c2ecf20Sopenharmony_ci readback_value = (original_value & bitmask) >> bitshift; 448c2ecf20Sopenharmony_ci 458c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 488c2ecf20Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", 498c2ecf20Sopenharmony_ci regaddr, rfpath, bitmask, original_value); 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci return readback_value; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_cibool rtl92c_phy_mac_config(struct ieee80211_hw *hw) 558c2ecf20Sopenharmony_ci{ 568c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 578c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 588c2ecf20Sopenharmony_ci bool is92c = IS_92C_SERIAL(rtlhal->version); 598c2ecf20Sopenharmony_ci bool rtstatus = _rtl92c_phy_config_mac_with_headerfile(hw); 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci if (is92c) 628c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x14, 0x71); 638c2ecf20Sopenharmony_ci else 648c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x04CA, 0x0A); 658c2ecf20Sopenharmony_ci return rtstatus; 668c2ecf20Sopenharmony_ci} 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_cibool rtl92c_phy_bb_config(struct ieee80211_hw *hw) 698c2ecf20Sopenharmony_ci{ 708c2ecf20Sopenharmony_ci bool rtstatus = true; 718c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 728c2ecf20Sopenharmony_ci u16 regval; 738c2ecf20Sopenharmony_ci u32 regvaldw; 748c2ecf20Sopenharmony_ci u8 reg_hwparafile = 1; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ci _rtl92c_phy_init_bb_rf_register_definition(hw); 778c2ecf20Sopenharmony_ci regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 788c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, 798c2ecf20Sopenharmony_ci regval | BIT(13) | BIT(0) | BIT(1)); 808c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x83); 818c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL + 1, 0xdb); 828c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB); 838c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 848c2ecf20Sopenharmony_ci FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE | 858c2ecf20Sopenharmony_ci FEN_BB_GLB_RSTN | FEN_BBRSTB); 868c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); 878c2ecf20Sopenharmony_ci regvaldw = rtl_read_dword(rtlpriv, REG_LEDCFG0); 888c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_LEDCFG0, regvaldw | BIT(23)); 898c2ecf20Sopenharmony_ci if (reg_hwparafile == 1) 908c2ecf20Sopenharmony_ci rtstatus = _rtl92c_phy_bb8192c_config_parafile(hw); 918c2ecf20Sopenharmony_ci return rtstatus; 928c2ecf20Sopenharmony_ci} 938c2ecf20Sopenharmony_ci 948c2ecf20Sopenharmony_civoid rtl92ce_phy_set_rf_reg(struct ieee80211_hw *hw, 958c2ecf20Sopenharmony_ci enum radio_path rfpath, 968c2ecf20Sopenharmony_ci u32 regaddr, u32 bitmask, u32 data) 978c2ecf20Sopenharmony_ci{ 988c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 998c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 1008c2ecf20Sopenharmony_ci u32 original_value, bitshift; 1018c2ecf20Sopenharmony_ci 1028c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1038c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 1048c2ecf20Sopenharmony_ci regaddr, bitmask, data, rfpath); 1058c2ecf20Sopenharmony_ci 1068c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci if (rtlphy->rf_mode != RF_OP_BY_FW) { 1098c2ecf20Sopenharmony_ci if (bitmask != RFREG_OFFSET_MASK) { 1108c2ecf20Sopenharmony_ci original_value = _rtl92c_phy_rf_serial_read(hw, 1118c2ecf20Sopenharmony_ci rfpath, 1128c2ecf20Sopenharmony_ci regaddr); 1138c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 1148c2ecf20Sopenharmony_ci data = 1158c2ecf20Sopenharmony_ci ((original_value & (~bitmask)) | 1168c2ecf20Sopenharmony_ci (data << bitshift)); 1178c2ecf20Sopenharmony_ci } 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci _rtl92c_phy_rf_serial_write(hw, rfpath, regaddr, data); 1208c2ecf20Sopenharmony_ci } else { 1218c2ecf20Sopenharmony_ci if (bitmask != RFREG_OFFSET_MASK) { 1228c2ecf20Sopenharmony_ci original_value = _rtl92c_phy_fw_rf_serial_read(hw, 1238c2ecf20Sopenharmony_ci rfpath, 1248c2ecf20Sopenharmony_ci regaddr); 1258c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 1268c2ecf20Sopenharmony_ci data = 1278c2ecf20Sopenharmony_ci ((original_value & (~bitmask)) | 1288c2ecf20Sopenharmony_ci (data << bitshift)); 1298c2ecf20Sopenharmony_ci } 1308c2ecf20Sopenharmony_ci _rtl92c_phy_fw_rf_serial_write(hw, rfpath, regaddr, data); 1318c2ecf20Sopenharmony_ci } 1328c2ecf20Sopenharmony_ci 1338c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 1348c2ecf20Sopenharmony_ci 1358c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1368c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 1378c2ecf20Sopenharmony_ci regaddr, bitmask, data, rfpath); 1388c2ecf20Sopenharmony_ci} 1398c2ecf20Sopenharmony_ci 1408c2ecf20Sopenharmony_cistatic bool _rtl92c_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) 1418c2ecf20Sopenharmony_ci{ 1428c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1438c2ecf20Sopenharmony_ci u32 i; 1448c2ecf20Sopenharmony_ci u32 arraylength; 1458c2ecf20Sopenharmony_ci u32 *ptrarray; 1468c2ecf20Sopenharmony_ci 1478c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl819XMACPHY_Array\n"); 1488c2ecf20Sopenharmony_ci arraylength = MAC_2T_ARRAYLENGTH; 1498c2ecf20Sopenharmony_ci ptrarray = RTL8192CEMAC_2T_ARRAY; 1508c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Img:RTL8192CEMAC_2T_ARRAY\n"); 1518c2ecf20Sopenharmony_ci for (i = 0; i < arraylength; i = i + 2) 1528c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); 1538c2ecf20Sopenharmony_ci return true; 1548c2ecf20Sopenharmony_ci} 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_cibool _rtl92ce_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, 1578c2ecf20Sopenharmony_ci u8 configtype) 1588c2ecf20Sopenharmony_ci{ 1598c2ecf20Sopenharmony_ci int i; 1608c2ecf20Sopenharmony_ci u32 *phy_regarray_table; 1618c2ecf20Sopenharmony_ci u32 *agctab_array_table; 1628c2ecf20Sopenharmony_ci u16 phy_reg_arraylen, agctab_arraylen; 1638c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1648c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1658c2ecf20Sopenharmony_ci 1668c2ecf20Sopenharmony_ci if (IS_92C_SERIAL(rtlhal->version)) { 1678c2ecf20Sopenharmony_ci agctab_arraylen = AGCTAB_2TARRAYLENGTH; 1688c2ecf20Sopenharmony_ci agctab_array_table = RTL8192CEAGCTAB_2TARRAY; 1698c2ecf20Sopenharmony_ci phy_reg_arraylen = PHY_REG_2TARRAY_LENGTH; 1708c2ecf20Sopenharmony_ci phy_regarray_table = RTL8192CEPHY_REG_2TARRAY; 1718c2ecf20Sopenharmony_ci } else { 1728c2ecf20Sopenharmony_ci agctab_arraylen = AGCTAB_1TARRAYLENGTH; 1738c2ecf20Sopenharmony_ci agctab_array_table = RTL8192CEAGCTAB_1TARRAY; 1748c2ecf20Sopenharmony_ci phy_reg_arraylen = PHY_REG_1TARRAY_LENGTH; 1758c2ecf20Sopenharmony_ci phy_regarray_table = RTL8192CEPHY_REG_1TARRAY; 1768c2ecf20Sopenharmony_ci } 1778c2ecf20Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 1788c2ecf20Sopenharmony_ci for (i = 0; i < phy_reg_arraylen; i = i + 2) { 1798c2ecf20Sopenharmony_ci rtl_addr_delay(phy_regarray_table[i]); 1808c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD, 1818c2ecf20Sopenharmony_ci phy_regarray_table[i + 1]); 1828c2ecf20Sopenharmony_ci udelay(1); 1838c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 1848c2ecf20Sopenharmony_ci "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", 1858c2ecf20Sopenharmony_ci phy_regarray_table[i], 1868c2ecf20Sopenharmony_ci phy_regarray_table[i + 1]); 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { 1898c2ecf20Sopenharmony_ci for (i = 0; i < agctab_arraylen; i = i + 2) { 1908c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD, 1918c2ecf20Sopenharmony_ci agctab_array_table[i + 1]); 1928c2ecf20Sopenharmony_ci udelay(1); 1938c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 1948c2ecf20Sopenharmony_ci "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n", 1958c2ecf20Sopenharmony_ci agctab_array_table[i], 1968c2ecf20Sopenharmony_ci agctab_array_table[i + 1]); 1978c2ecf20Sopenharmony_ci } 1988c2ecf20Sopenharmony_ci } 1998c2ecf20Sopenharmony_ci return true; 2008c2ecf20Sopenharmony_ci} 2018c2ecf20Sopenharmony_ci 2028c2ecf20Sopenharmony_cibool _rtl92ce_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, 2038c2ecf20Sopenharmony_ci u8 configtype) 2048c2ecf20Sopenharmony_ci{ 2058c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2068c2ecf20Sopenharmony_ci int i; 2078c2ecf20Sopenharmony_ci u32 *phy_regarray_table_pg; 2088c2ecf20Sopenharmony_ci u16 phy_regarray_pg_len; 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_ci phy_regarray_pg_len = PHY_REG_ARRAY_PGLENGTH; 2118c2ecf20Sopenharmony_ci phy_regarray_table_pg = RTL8192CEPHY_REG_ARRAY_PG; 2128c2ecf20Sopenharmony_ci 2138c2ecf20Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 2148c2ecf20Sopenharmony_ci for (i = 0; i < phy_regarray_pg_len; i = i + 3) { 2158c2ecf20Sopenharmony_ci rtl_addr_delay(phy_regarray_table_pg[i]); 2168c2ecf20Sopenharmony_ci 2178c2ecf20Sopenharmony_ci _rtl92c_store_pwrindex_diffrate_offset(hw, 2188c2ecf20Sopenharmony_ci phy_regarray_table_pg[i], 2198c2ecf20Sopenharmony_ci phy_regarray_table_pg[i + 1], 2208c2ecf20Sopenharmony_ci phy_regarray_table_pg[i + 2]); 2218c2ecf20Sopenharmony_ci } 2228c2ecf20Sopenharmony_ci } else { 2238c2ecf20Sopenharmony_ci 2248c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE, 2258c2ecf20Sopenharmony_ci "configtype != BaseBand_Config_PHY_REG\n"); 2268c2ecf20Sopenharmony_ci } 2278c2ecf20Sopenharmony_ci return true; 2288c2ecf20Sopenharmony_ci} 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_cibool rtl92c_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, 2318c2ecf20Sopenharmony_ci enum radio_path rfpath) 2328c2ecf20Sopenharmony_ci{ 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci int i; 2358c2ecf20Sopenharmony_ci u32 *radioa_array_table; 2368c2ecf20Sopenharmony_ci u32 *radiob_array_table; 2378c2ecf20Sopenharmony_ci u16 radioa_arraylen, radiob_arraylen; 2388c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2398c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci if (IS_92C_SERIAL(rtlhal->version)) { 2428c2ecf20Sopenharmony_ci radioa_arraylen = RADIOA_2TARRAYLENGTH; 2438c2ecf20Sopenharmony_ci radioa_array_table = RTL8192CERADIOA_2TARRAY; 2448c2ecf20Sopenharmony_ci radiob_arraylen = RADIOB_2TARRAYLENGTH; 2458c2ecf20Sopenharmony_ci radiob_array_table = RTL8192CE_RADIOB_2TARRAY; 2468c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 2478c2ecf20Sopenharmony_ci "Radio_A:RTL8192CERADIOA_2TARRAY\n"); 2488c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 2498c2ecf20Sopenharmony_ci "Radio_B:RTL8192CE_RADIOB_2TARRAY\n"); 2508c2ecf20Sopenharmony_ci } else { 2518c2ecf20Sopenharmony_ci radioa_arraylen = RADIOA_1TARRAYLENGTH; 2528c2ecf20Sopenharmony_ci radioa_array_table = RTL8192CE_RADIOA_1TARRAY; 2538c2ecf20Sopenharmony_ci radiob_arraylen = RADIOB_1TARRAYLENGTH; 2548c2ecf20Sopenharmony_ci radiob_array_table = RTL8192CE_RADIOB_1TARRAY; 2558c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 2568c2ecf20Sopenharmony_ci "Radio_A:RTL8192CE_RADIOA_1TARRAY\n"); 2578c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 2588c2ecf20Sopenharmony_ci "Radio_B:RTL8192CE_RADIOB_1TARRAY\n"); 2598c2ecf20Sopenharmony_ci } 2608c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Radio No %x\n", rfpath); 2618c2ecf20Sopenharmony_ci switch (rfpath) { 2628c2ecf20Sopenharmony_ci case RF90_PATH_A: 2638c2ecf20Sopenharmony_ci for (i = 0; i < radioa_arraylen; i = i + 2) { 2648c2ecf20Sopenharmony_ci rtl_rfreg_delay(hw, rfpath, radioa_array_table[i], 2658c2ecf20Sopenharmony_ci RFREG_OFFSET_MASK, 2668c2ecf20Sopenharmony_ci radioa_array_table[i + 1]); 2678c2ecf20Sopenharmony_ci } 2688c2ecf20Sopenharmony_ci break; 2698c2ecf20Sopenharmony_ci case RF90_PATH_B: 2708c2ecf20Sopenharmony_ci for (i = 0; i < radiob_arraylen; i = i + 2) { 2718c2ecf20Sopenharmony_ci rtl_rfreg_delay(hw, rfpath, radiob_array_table[i], 2728c2ecf20Sopenharmony_ci RFREG_OFFSET_MASK, 2738c2ecf20Sopenharmony_ci radiob_array_table[i + 1]); 2748c2ecf20Sopenharmony_ci } 2758c2ecf20Sopenharmony_ci break; 2768c2ecf20Sopenharmony_ci case RF90_PATH_C: 2778c2ecf20Sopenharmony_ci case RF90_PATH_D: 2788c2ecf20Sopenharmony_ci pr_info("Incorrect rfpath %#x\n", rfpath); 2798c2ecf20Sopenharmony_ci break; 2808c2ecf20Sopenharmony_ci default: 2818c2ecf20Sopenharmony_ci pr_info("switch case %#x not processed\n", rfpath); 2828c2ecf20Sopenharmony_ci break; 2838c2ecf20Sopenharmony_ci } 2848c2ecf20Sopenharmony_ci return true; 2858c2ecf20Sopenharmony_ci} 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_civoid rtl92ce_phy_set_bw_mode_callback(struct ieee80211_hw *hw) 2888c2ecf20Sopenharmony_ci{ 2898c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2908c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 2918c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 2928c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 2938c2ecf20Sopenharmony_ci u8 reg_bw_opmode; 2948c2ecf20Sopenharmony_ci u8 reg_prsr_rsc; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", 2978c2ecf20Sopenharmony_ci rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? 2988c2ecf20Sopenharmony_ci "20MHz" : "40MHz"); 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_ci if (is_hal_stop(rtlhal)) { 3018c2ecf20Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 3028c2ecf20Sopenharmony_ci return; 3038c2ecf20Sopenharmony_ci } 3048c2ecf20Sopenharmony_ci 3058c2ecf20Sopenharmony_ci reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE); 3068c2ecf20Sopenharmony_ci reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci switch (rtlphy->current_chan_bw) { 3098c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 3108c2ecf20Sopenharmony_ci reg_bw_opmode |= BW_OPMODE_20MHZ; 3118c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 3128c2ecf20Sopenharmony_ci break; 3138c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 3148c2ecf20Sopenharmony_ci reg_bw_opmode &= ~BW_OPMODE_20MHZ; 3158c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 3168c2ecf20Sopenharmony_ci reg_prsr_rsc = 3178c2ecf20Sopenharmony_ci (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5); 3188c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc); 3198c2ecf20Sopenharmony_ci break; 3208c2ecf20Sopenharmony_ci default: 3218c2ecf20Sopenharmony_ci pr_info("unknown bandwidth: %#X\n", rtlphy->current_chan_bw); 3228c2ecf20Sopenharmony_ci break; 3238c2ecf20Sopenharmony_ci } 3248c2ecf20Sopenharmony_ci 3258c2ecf20Sopenharmony_ci switch (rtlphy->current_chan_bw) { 3268c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 3278c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); 3288c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); 3298c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1); 3308c2ecf20Sopenharmony_ci break; 3318c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 3328c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); 3338c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); 3348c2ecf20Sopenharmony_ci 3358c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, 3368c2ecf20Sopenharmony_ci (mac->cur_40_prime_sc >> 1)); 3378c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); 3388c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0); 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), 3418c2ecf20Sopenharmony_ci (mac->cur_40_prime_sc == 3428c2ecf20Sopenharmony_ci HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); 3438c2ecf20Sopenharmony_ci break; 3448c2ecf20Sopenharmony_ci default: 3458c2ecf20Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 3468c2ecf20Sopenharmony_ci rtlphy->current_chan_bw); 3478c2ecf20Sopenharmony_ci break; 3488c2ecf20Sopenharmony_ci } 3498c2ecf20Sopenharmony_ci rtl92ce_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); 3508c2ecf20Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 3518c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); 3528c2ecf20Sopenharmony_ci} 3538c2ecf20Sopenharmony_ci 3548c2ecf20Sopenharmony_civoid _rtl92ce_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) 3558c2ecf20Sopenharmony_ci{ 3568c2ecf20Sopenharmony_ci u8 tmpreg; 3578c2ecf20Sopenharmony_ci u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; 3588c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci tmpreg = rtl_read_byte(rtlpriv, 0xd03); 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci if ((tmpreg & 0x70) != 0) 3638c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F); 3648c2ecf20Sopenharmony_ci else 3658c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 3668c2ecf20Sopenharmony_ci 3678c2ecf20Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 3688c2ecf20Sopenharmony_ci rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS); 3698c2ecf20Sopenharmony_ci 3708c2ecf20Sopenharmony_ci if (is2t) 3718c2ecf20Sopenharmony_ci rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00, 3728c2ecf20Sopenharmony_ci MASK12BITS); 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, 3758c2ecf20Sopenharmony_ci (rf_a_mode & 0x8FFFF) | 0x10000); 3768c2ecf20Sopenharmony_ci 3778c2ecf20Sopenharmony_ci if (is2t) 3788c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, 3798c2ecf20Sopenharmony_ci (rf_b_mode & 0x8FFFF) | 0x10000); 3808c2ecf20Sopenharmony_ci } 3818c2ecf20Sopenharmony_ci lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS); 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000); 3848c2ecf20Sopenharmony_ci 3858c2ecf20Sopenharmony_ci mdelay(100); 3868c2ecf20Sopenharmony_ci 3878c2ecf20Sopenharmony_ci if ((tmpreg & 0x70) != 0) { 3888c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0xd03, tmpreg); 3898c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode); 3908c2ecf20Sopenharmony_ci 3918c2ecf20Sopenharmony_ci if (is2t) 3928c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS, 3938c2ecf20Sopenharmony_ci rf_b_mode); 3948c2ecf20Sopenharmony_ci } else { 3958c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 3968c2ecf20Sopenharmony_ci } 3978c2ecf20Sopenharmony_ci} 3988c2ecf20Sopenharmony_ci 3998c2ecf20Sopenharmony_cistatic void _rtl92ce_phy_set_rf_sleep(struct ieee80211_hw *hw) 4008c2ecf20Sopenharmony_ci{ 4018c2ecf20Sopenharmony_ci u32 u4b_tmp; 4028c2ecf20Sopenharmony_ci u8 delay = 5; 4038c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4048c2ecf20Sopenharmony_ci 4058c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 4068c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 4078c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 4088c2ecf20Sopenharmony_ci u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); 4098c2ecf20Sopenharmony_ci while (u4b_tmp != 0 && delay > 0) { 4108c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); 4118c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 4128c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 4138c2ecf20Sopenharmony_ci u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); 4148c2ecf20Sopenharmony_ci delay--; 4158c2ecf20Sopenharmony_ci } 4168c2ecf20Sopenharmony_ci if (delay == 0) { 4178c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); 4188c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 4198c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 4208c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 4218c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, 4228c2ecf20Sopenharmony_ci "Switch RF timeout !!!\n"); 4238c2ecf20Sopenharmony_ci return; 4248c2ecf20Sopenharmony_ci } 4258c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 4268c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); 4278c2ecf20Sopenharmony_ci} 4288c2ecf20Sopenharmony_ci 4298c2ecf20Sopenharmony_cistatic bool _rtl92ce_phy_set_rf_power_state(struct ieee80211_hw *hw, 4308c2ecf20Sopenharmony_ci enum rf_pwrstate rfpwr_state) 4318c2ecf20Sopenharmony_ci{ 4328c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4338c2ecf20Sopenharmony_ci struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 4348c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 4358c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 4368c2ecf20Sopenharmony_ci bool bresult = true; 4378c2ecf20Sopenharmony_ci u8 i, queue_id; 4388c2ecf20Sopenharmony_ci struct rtl8192_tx_ring *ring = NULL; 4398c2ecf20Sopenharmony_ci 4408c2ecf20Sopenharmony_ci switch (rfpwr_state) { 4418c2ecf20Sopenharmony_ci case ERFON:{ 4428c2ecf20Sopenharmony_ci if ((ppsc->rfpwr_state == ERFOFF) && 4438c2ecf20Sopenharmony_ci RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { 4448c2ecf20Sopenharmony_ci bool rtstatus; 4458c2ecf20Sopenharmony_ci u32 initializecount = 0; 4468c2ecf20Sopenharmony_ci 4478c2ecf20Sopenharmony_ci do { 4488c2ecf20Sopenharmony_ci initializecount++; 4498c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 4508c2ecf20Sopenharmony_ci "IPS Set eRf nic enable\n"); 4518c2ecf20Sopenharmony_ci rtstatus = rtl_ps_enable_nic(hw); 4528c2ecf20Sopenharmony_ci } while (!rtstatus && (initializecount < 10)); 4538c2ecf20Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, 4548c2ecf20Sopenharmony_ci RT_RF_OFF_LEVL_HALT_NIC); 4558c2ecf20Sopenharmony_ci } else { 4568c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 4578c2ecf20Sopenharmony_ci "Set ERFON slept:%d ms\n", 4588c2ecf20Sopenharmony_ci jiffies_to_msecs(jiffies - 4598c2ecf20Sopenharmony_ci ppsc->last_sleep_jiffies)); 4608c2ecf20Sopenharmony_ci ppsc->last_awake_jiffies = jiffies; 4618c2ecf20Sopenharmony_ci rtl92ce_phy_set_rf_on(hw); 4628c2ecf20Sopenharmony_ci } 4638c2ecf20Sopenharmony_ci if (mac->link_state == MAC80211_LINKED) { 4648c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 4658c2ecf20Sopenharmony_ci LED_CTL_LINK); 4668c2ecf20Sopenharmony_ci } else { 4678c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 4688c2ecf20Sopenharmony_ci LED_CTL_NO_LINK); 4698c2ecf20Sopenharmony_ci } 4708c2ecf20Sopenharmony_ci break; 4718c2ecf20Sopenharmony_ci } 4728c2ecf20Sopenharmony_ci case ERFOFF:{ 4738c2ecf20Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { 4748c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 4758c2ecf20Sopenharmony_ci "IPS Set eRf nic disable\n"); 4768c2ecf20Sopenharmony_ci rtl_ps_disable_nic(hw); 4778c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 4788c2ecf20Sopenharmony_ci } else { 4798c2ecf20Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { 4808c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 4818c2ecf20Sopenharmony_ci LED_CTL_NO_LINK); 4828c2ecf20Sopenharmony_ci } else { 4838c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 4848c2ecf20Sopenharmony_ci LED_CTL_POWER_OFF); 4858c2ecf20Sopenharmony_ci } 4868c2ecf20Sopenharmony_ci } 4878c2ecf20Sopenharmony_ci break; 4888c2ecf20Sopenharmony_ci } 4898c2ecf20Sopenharmony_ci case ERFSLEEP:{ 4908c2ecf20Sopenharmony_ci if (ppsc->rfpwr_state == ERFOFF) 4918c2ecf20Sopenharmony_ci break; 4928c2ecf20Sopenharmony_ci for (queue_id = 0, i = 0; 4938c2ecf20Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 4948c2ecf20Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 4958c2ecf20Sopenharmony_ci if (queue_id == BEACON_QUEUE || 4968c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue) == 0) { 4978c2ecf20Sopenharmony_ci queue_id++; 4988c2ecf20Sopenharmony_ci continue; 4998c2ecf20Sopenharmony_ci } else { 5008c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 5018c2ecf20Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", 5028c2ecf20Sopenharmony_ci i + 1, queue_id, 5038c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue)); 5048c2ecf20Sopenharmony_ci 5058c2ecf20Sopenharmony_ci udelay(10); 5068c2ecf20Sopenharmony_ci i++; 5078c2ecf20Sopenharmony_ci } 5088c2ecf20Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 5098c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 5108c2ecf20Sopenharmony_ci "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", 5118c2ecf20Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 5128c2ecf20Sopenharmony_ci queue_id, 5138c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue)); 5148c2ecf20Sopenharmony_ci break; 5158c2ecf20Sopenharmony_ci } 5168c2ecf20Sopenharmony_ci } 5178c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 5188c2ecf20Sopenharmony_ci "Set ERFSLEEP awaked:%d ms\n", 5198c2ecf20Sopenharmony_ci jiffies_to_msecs(jiffies - 5208c2ecf20Sopenharmony_ci ppsc->last_awake_jiffies)); 5218c2ecf20Sopenharmony_ci ppsc->last_sleep_jiffies = jiffies; 5228c2ecf20Sopenharmony_ci _rtl92ce_phy_set_rf_sleep(hw); 5238c2ecf20Sopenharmony_ci break; 5248c2ecf20Sopenharmony_ci } 5258c2ecf20Sopenharmony_ci default: 5268c2ecf20Sopenharmony_ci pr_err("switch case %#x not processed\n", 5278c2ecf20Sopenharmony_ci rfpwr_state); 5288c2ecf20Sopenharmony_ci bresult = false; 5298c2ecf20Sopenharmony_ci break; 5308c2ecf20Sopenharmony_ci } 5318c2ecf20Sopenharmony_ci if (bresult) 5328c2ecf20Sopenharmony_ci ppsc->rfpwr_state = rfpwr_state; 5338c2ecf20Sopenharmony_ci return bresult; 5348c2ecf20Sopenharmony_ci} 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_cibool rtl92c_phy_set_rf_power_state(struct ieee80211_hw *hw, 5378c2ecf20Sopenharmony_ci enum rf_pwrstate rfpwr_state) 5388c2ecf20Sopenharmony_ci{ 5398c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci bool bresult = false; 5428c2ecf20Sopenharmony_ci 5438c2ecf20Sopenharmony_ci if (rfpwr_state == ppsc->rfpwr_state) 5448c2ecf20Sopenharmony_ci return bresult; 5458c2ecf20Sopenharmony_ci bresult = _rtl92ce_phy_set_rf_power_state(hw, rfpwr_state); 5468c2ecf20Sopenharmony_ci return bresult; 5478c2ecf20Sopenharmony_ci} 548