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