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 "rf.h" 128c2ecf20Sopenharmony_ci#include "dm.h" 138c2ecf20Sopenharmony_ci#include "fw.h" 148c2ecf20Sopenharmony_ci#include "hw.h" 158c2ecf20Sopenharmony_ci#include "table.h" 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ciu32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) 188c2ecf20Sopenharmony_ci{ 198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 208c2ecf20Sopenharmony_ci u32 returnvalue = 0, originalvalue, bitshift; 218c2ecf20Sopenharmony_ci 228c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", 238c2ecf20Sopenharmony_ci regaddr, bitmask); 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci originalvalue = rtl_read_dword(rtlpriv, regaddr); 268c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 278c2ecf20Sopenharmony_ci returnvalue = (originalvalue & bitmask) >> bitshift; 288c2ecf20Sopenharmony_ci 298c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", 308c2ecf20Sopenharmony_ci bitmask, regaddr, originalvalue); 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_ci return returnvalue; 338c2ecf20Sopenharmony_ci 348c2ecf20Sopenharmony_ci} 358c2ecf20Sopenharmony_ci 368c2ecf20Sopenharmony_civoid rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, 378c2ecf20Sopenharmony_ci u32 data) 388c2ecf20Sopenharmony_ci{ 398c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 408c2ecf20Sopenharmony_ci u32 originalvalue, bitshift; 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 438c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x)\n", 448c2ecf20Sopenharmony_ci regaddr, bitmask, data); 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci if (bitmask != MASKDWORD) { 478c2ecf20Sopenharmony_ci originalvalue = rtl_read_dword(rtlpriv, regaddr); 488c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 498c2ecf20Sopenharmony_ci data = ((originalvalue & (~bitmask)) | (data << bitshift)); 508c2ecf20Sopenharmony_ci } 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, regaddr, data); 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 558c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x)\n", 568c2ecf20Sopenharmony_ci regaddr, bitmask, data); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci} 598c2ecf20Sopenharmony_ci 608c2ecf20Sopenharmony_cistatic u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, 618c2ecf20Sopenharmony_ci enum radio_path rfpath, u32 offset) 628c2ecf20Sopenharmony_ci{ 638c2ecf20Sopenharmony_ci 648c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 658c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 668c2ecf20Sopenharmony_ci struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 678c2ecf20Sopenharmony_ci u32 newoffset; 688c2ecf20Sopenharmony_ci u32 tmplong, tmplong2; 698c2ecf20Sopenharmony_ci u8 rfpi_enable = 0; 708c2ecf20Sopenharmony_ci u32 retvalue = 0; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci offset &= 0x3f; 738c2ecf20Sopenharmony_ci newoffset = offset; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ci tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci if (rfpath == RF90_PATH_A) 788c2ecf20Sopenharmony_ci tmplong2 = tmplong; 798c2ecf20Sopenharmony_ci else 808c2ecf20Sopenharmony_ci tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); 818c2ecf20Sopenharmony_ci 828c2ecf20Sopenharmony_ci tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) | 838c2ecf20Sopenharmony_ci BLSSI_READEDGE; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, 868c2ecf20Sopenharmony_ci tmplong & (~BLSSI_READEDGE)); 878c2ecf20Sopenharmony_ci 888c2ecf20Sopenharmony_ci mdelay(1); 898c2ecf20Sopenharmony_ci 908c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); 918c2ecf20Sopenharmony_ci mdelay(1); 928c2ecf20Sopenharmony_ci 938c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong | 948c2ecf20Sopenharmony_ci BLSSI_READEDGE); 958c2ecf20Sopenharmony_ci mdelay(1); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci if (rfpath == RF90_PATH_A) 988c2ecf20Sopenharmony_ci rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, 998c2ecf20Sopenharmony_ci BIT(8)); 1008c2ecf20Sopenharmony_ci else if (rfpath == RF90_PATH_B) 1018c2ecf20Sopenharmony_ci rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, 1028c2ecf20Sopenharmony_ci BIT(8)); 1038c2ecf20Sopenharmony_ci 1048c2ecf20Sopenharmony_ci if (rfpi_enable) 1058c2ecf20Sopenharmony_ci retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, 1068c2ecf20Sopenharmony_ci BLSSI_READBACK_DATA); 1078c2ecf20Sopenharmony_ci else 1088c2ecf20Sopenharmony_ci retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, 1098c2ecf20Sopenharmony_ci BLSSI_READBACK_DATA); 1108c2ecf20Sopenharmony_ci 1118c2ecf20Sopenharmony_ci retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, 1128c2ecf20Sopenharmony_ci BLSSI_READBACK_DATA); 1138c2ecf20Sopenharmony_ci 1148c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", 1158c2ecf20Sopenharmony_ci rfpath, pphyreg->rf_rb, retvalue); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci return retvalue; 1188c2ecf20Sopenharmony_ci 1198c2ecf20Sopenharmony_ci} 1208c2ecf20Sopenharmony_ci 1218c2ecf20Sopenharmony_cistatic void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw, 1228c2ecf20Sopenharmony_ci enum radio_path rfpath, u32 offset, 1238c2ecf20Sopenharmony_ci u32 data) 1248c2ecf20Sopenharmony_ci{ 1258c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1268c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 1278c2ecf20Sopenharmony_ci struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 1288c2ecf20Sopenharmony_ci u32 data_and_addr = 0; 1298c2ecf20Sopenharmony_ci u32 newoffset; 1308c2ecf20Sopenharmony_ci 1318c2ecf20Sopenharmony_ci offset &= 0x3f; 1328c2ecf20Sopenharmony_ci newoffset = offset; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_ci data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; 1358c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); 1368c2ecf20Sopenharmony_ci 1378c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", 1388c2ecf20Sopenharmony_ci rfpath, pphyreg->rf3wire_offset, data_and_addr); 1398c2ecf20Sopenharmony_ci} 1408c2ecf20Sopenharmony_ci 1418c2ecf20Sopenharmony_ci 1428c2ecf20Sopenharmony_ciu32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, 1438c2ecf20Sopenharmony_ci u32 regaddr, u32 bitmask) 1448c2ecf20Sopenharmony_ci{ 1458c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1468c2ecf20Sopenharmony_ci u32 original_value, readback_value, bitshift; 1478c2ecf20Sopenharmony_ci 1488c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1498c2ecf20Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", 1508c2ecf20Sopenharmony_ci regaddr, rfpath, bitmask); 1518c2ecf20Sopenharmony_ci 1528c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 1538c2ecf20Sopenharmony_ci 1548c2ecf20Sopenharmony_ci original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); 1558c2ecf20Sopenharmony_ci 1568c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 1578c2ecf20Sopenharmony_ci readback_value = (original_value & bitmask) >> bitshift; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 1608c2ecf20Sopenharmony_ci 1618c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1628c2ecf20Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", 1638c2ecf20Sopenharmony_ci regaddr, rfpath, bitmask, original_value); 1648c2ecf20Sopenharmony_ci 1658c2ecf20Sopenharmony_ci return readback_value; 1668c2ecf20Sopenharmony_ci} 1678c2ecf20Sopenharmony_ci 1688c2ecf20Sopenharmony_civoid rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, 1698c2ecf20Sopenharmony_ci u32 regaddr, u32 bitmask, u32 data) 1708c2ecf20Sopenharmony_ci{ 1718c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1728c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 1738c2ecf20Sopenharmony_ci u32 original_value, bitshift; 1748c2ecf20Sopenharmony_ci 1758c2ecf20Sopenharmony_ci if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) 1768c2ecf20Sopenharmony_ci return; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1798c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 1808c2ecf20Sopenharmony_ci regaddr, bitmask, data, rfpath); 1818c2ecf20Sopenharmony_ci 1828c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 1838c2ecf20Sopenharmony_ci 1848c2ecf20Sopenharmony_ci if (bitmask != RFREG_OFFSET_MASK) { 1858c2ecf20Sopenharmony_ci original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, 1868c2ecf20Sopenharmony_ci regaddr); 1878c2ecf20Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 1888c2ecf20Sopenharmony_ci data = ((original_value & (~bitmask)) | (data << bitshift)); 1898c2ecf20Sopenharmony_ci } 1908c2ecf20Sopenharmony_ci 1918c2ecf20Sopenharmony_ci _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data); 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 1948c2ecf20Sopenharmony_ci 1958c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 1968c2ecf20Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 1978c2ecf20Sopenharmony_ci regaddr, bitmask, data, rfpath); 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_ci} 2008c2ecf20Sopenharmony_ci 2018c2ecf20Sopenharmony_civoid rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, 2028c2ecf20Sopenharmony_ci u8 operation) 2038c2ecf20Sopenharmony_ci{ 2048c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 2058c2ecf20Sopenharmony_ci 2068c2ecf20Sopenharmony_ci if (!is_hal_stop(rtlhal)) { 2078c2ecf20Sopenharmony_ci switch (operation) { 2088c2ecf20Sopenharmony_ci case SCAN_OPT_BACKUP: 2098c2ecf20Sopenharmony_ci rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN); 2108c2ecf20Sopenharmony_ci break; 2118c2ecf20Sopenharmony_ci case SCAN_OPT_RESTORE: 2128c2ecf20Sopenharmony_ci rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN); 2138c2ecf20Sopenharmony_ci break; 2148c2ecf20Sopenharmony_ci default: 2158c2ecf20Sopenharmony_ci pr_err("Unknown operation\n"); 2168c2ecf20Sopenharmony_ci break; 2178c2ecf20Sopenharmony_ci } 2188c2ecf20Sopenharmony_ci } 2198c2ecf20Sopenharmony_ci} 2208c2ecf20Sopenharmony_ci 2218c2ecf20Sopenharmony_civoid rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, 2228c2ecf20Sopenharmony_ci enum nl80211_channel_type ch_type) 2238c2ecf20Sopenharmony_ci{ 2248c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2258c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 2268c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 2278c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 2288c2ecf20Sopenharmony_ci u8 reg_bw_opmode; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", 2318c2ecf20Sopenharmony_ci rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? 2328c2ecf20Sopenharmony_ci "20MHz" : "40MHz"); 2338c2ecf20Sopenharmony_ci 2348c2ecf20Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 2358c2ecf20Sopenharmony_ci return; 2368c2ecf20Sopenharmony_ci if (is_hal_stop(rtlhal)) 2378c2ecf20Sopenharmony_ci return; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_ci rtlphy->set_bwmode_inprogress = true; 2408c2ecf20Sopenharmony_ci 2418c2ecf20Sopenharmony_ci reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE); 2428c2ecf20Sopenharmony_ci /* dummy read */ 2438c2ecf20Sopenharmony_ci rtl_read_byte(rtlpriv, RRSR + 2); 2448c2ecf20Sopenharmony_ci 2458c2ecf20Sopenharmony_ci switch (rtlphy->current_chan_bw) { 2468c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 2478c2ecf20Sopenharmony_ci reg_bw_opmode |= BW_OPMODE_20MHZ; 2488c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); 2498c2ecf20Sopenharmony_ci break; 2508c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 2518c2ecf20Sopenharmony_ci reg_bw_opmode &= ~BW_OPMODE_20MHZ; 2528c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); 2538c2ecf20Sopenharmony_ci break; 2548c2ecf20Sopenharmony_ci default: 2558c2ecf20Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 2568c2ecf20Sopenharmony_ci rtlphy->current_chan_bw); 2578c2ecf20Sopenharmony_ci break; 2588c2ecf20Sopenharmony_ci } 2598c2ecf20Sopenharmony_ci 2608c2ecf20Sopenharmony_ci switch (rtlphy->current_chan_bw) { 2618c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 2628c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); 2638c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci if (rtlhal->version >= VERSION_8192S_BCUT) 2668c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58); 2678c2ecf20Sopenharmony_ci break; 2688c2ecf20Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 2698c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); 2708c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); 2718c2ecf20Sopenharmony_ci 2728c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, 2738c2ecf20Sopenharmony_ci (mac->cur_40_prime_sc >> 1)); 2748c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); 2758c2ecf20Sopenharmony_ci 2768c2ecf20Sopenharmony_ci if (rtlhal->version >= VERSION_8192S_BCUT) 2778c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18); 2788c2ecf20Sopenharmony_ci break; 2798c2ecf20Sopenharmony_ci default: 2808c2ecf20Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 2818c2ecf20Sopenharmony_ci rtlphy->current_chan_bw); 2828c2ecf20Sopenharmony_ci break; 2838c2ecf20Sopenharmony_ci } 2848c2ecf20Sopenharmony_ci 2858c2ecf20Sopenharmony_ci rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); 2868c2ecf20Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 2878c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); 2888c2ecf20Sopenharmony_ci} 2898c2ecf20Sopenharmony_ci 2908c2ecf20Sopenharmony_cistatic bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, 2918c2ecf20Sopenharmony_ci u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid, 2928c2ecf20Sopenharmony_ci u32 para1, u32 para2, u32 msdelay) 2938c2ecf20Sopenharmony_ci{ 2948c2ecf20Sopenharmony_ci struct swchnlcmd *pcmd; 2958c2ecf20Sopenharmony_ci 2968c2ecf20Sopenharmony_ci if (cmdtable == NULL) { 2978c2ecf20Sopenharmony_ci WARN_ONCE(true, "rtl8192se: cmdtable cannot be NULL\n"); 2988c2ecf20Sopenharmony_ci return false; 2998c2ecf20Sopenharmony_ci } 3008c2ecf20Sopenharmony_ci 3018c2ecf20Sopenharmony_ci if (cmdtableidx >= cmdtablesz) 3028c2ecf20Sopenharmony_ci return false; 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_ci pcmd = cmdtable + cmdtableidx; 3058c2ecf20Sopenharmony_ci pcmd->cmdid = cmdid; 3068c2ecf20Sopenharmony_ci pcmd->para1 = para1; 3078c2ecf20Sopenharmony_ci pcmd->para2 = para2; 3088c2ecf20Sopenharmony_ci pcmd->msdelay = msdelay; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci return true; 3118c2ecf20Sopenharmony_ci} 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_cistatic bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 3148c2ecf20Sopenharmony_ci u8 channel, u8 *stage, u8 *step, u32 *delay) 3158c2ecf20Sopenharmony_ci{ 3168c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3178c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 3188c2ecf20Sopenharmony_ci struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; 3198c2ecf20Sopenharmony_ci u32 precommoncmdcnt; 3208c2ecf20Sopenharmony_ci struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; 3218c2ecf20Sopenharmony_ci u32 postcommoncmdcnt; 3228c2ecf20Sopenharmony_ci struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; 3238c2ecf20Sopenharmony_ci u32 rfdependcmdcnt; 3248c2ecf20Sopenharmony_ci struct swchnlcmd *currentcmd = NULL; 3258c2ecf20Sopenharmony_ci u8 rfpath; 3268c2ecf20Sopenharmony_ci u8 num_total_rfpath = rtlphy->num_total_rfpath; 3278c2ecf20Sopenharmony_ci 3288c2ecf20Sopenharmony_ci precommoncmdcnt = 0; 3298c2ecf20Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 3308c2ecf20Sopenharmony_ci MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); 3318c2ecf20Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 3328c2ecf20Sopenharmony_ci MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci postcommoncmdcnt = 0; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, 3378c2ecf20Sopenharmony_ci MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); 3388c2ecf20Sopenharmony_ci 3398c2ecf20Sopenharmony_ci rfdependcmdcnt = 0; 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci WARN_ONCE((channel < 1 || channel > 14), 3428c2ecf20Sopenharmony_ci "rtl8192se: invalid channel for Zebra: %d\n", channel); 3438c2ecf20Sopenharmony_ci 3448c2ecf20Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 3458c2ecf20Sopenharmony_ci MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, 3468c2ecf20Sopenharmony_ci RF_CHNLBW, channel, 10); 3478c2ecf20Sopenharmony_ci 3488c2ecf20Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 3498c2ecf20Sopenharmony_ci MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0); 3508c2ecf20Sopenharmony_ci 3518c2ecf20Sopenharmony_ci do { 3528c2ecf20Sopenharmony_ci switch (*stage) { 3538c2ecf20Sopenharmony_ci case 0: 3548c2ecf20Sopenharmony_ci currentcmd = &precommoncmd[*step]; 3558c2ecf20Sopenharmony_ci break; 3568c2ecf20Sopenharmony_ci case 1: 3578c2ecf20Sopenharmony_ci currentcmd = &rfdependcmd[*step]; 3588c2ecf20Sopenharmony_ci break; 3598c2ecf20Sopenharmony_ci case 2: 3608c2ecf20Sopenharmony_ci currentcmd = &postcommoncmd[*step]; 3618c2ecf20Sopenharmony_ci break; 3628c2ecf20Sopenharmony_ci default: 3638c2ecf20Sopenharmony_ci return true; 3648c2ecf20Sopenharmony_ci } 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci if (currentcmd->cmdid == CMDID_END) { 3678c2ecf20Sopenharmony_ci if ((*stage) == 2) { 3688c2ecf20Sopenharmony_ci return true; 3698c2ecf20Sopenharmony_ci } else { 3708c2ecf20Sopenharmony_ci (*stage)++; 3718c2ecf20Sopenharmony_ci (*step) = 0; 3728c2ecf20Sopenharmony_ci continue; 3738c2ecf20Sopenharmony_ci } 3748c2ecf20Sopenharmony_ci } 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci switch (currentcmd->cmdid) { 3778c2ecf20Sopenharmony_ci case CMDID_SET_TXPOWEROWER_LEVEL: 3788c2ecf20Sopenharmony_ci rtl92s_phy_set_txpower(hw, channel); 3798c2ecf20Sopenharmony_ci break; 3808c2ecf20Sopenharmony_ci case CMDID_WRITEPORT_ULONG: 3818c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, currentcmd->para1, 3828c2ecf20Sopenharmony_ci currentcmd->para2); 3838c2ecf20Sopenharmony_ci break; 3848c2ecf20Sopenharmony_ci case CMDID_WRITEPORT_USHORT: 3858c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, currentcmd->para1, 3868c2ecf20Sopenharmony_ci (u16)currentcmd->para2); 3878c2ecf20Sopenharmony_ci break; 3888c2ecf20Sopenharmony_ci case CMDID_WRITEPORT_UCHAR: 3898c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, currentcmd->para1, 3908c2ecf20Sopenharmony_ci (u8)currentcmd->para2); 3918c2ecf20Sopenharmony_ci break; 3928c2ecf20Sopenharmony_ci case CMDID_RF_WRITEREG: 3938c2ecf20Sopenharmony_ci for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { 3948c2ecf20Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath] = 3958c2ecf20Sopenharmony_ci ((rtlphy->rfreg_chnlval[rfpath] & 3968c2ecf20Sopenharmony_ci 0xfffffc00) | currentcmd->para2); 3978c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, (enum radio_path)rfpath, 3988c2ecf20Sopenharmony_ci currentcmd->para1, 3998c2ecf20Sopenharmony_ci RFREG_OFFSET_MASK, 4008c2ecf20Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath]); 4018c2ecf20Sopenharmony_ci } 4028c2ecf20Sopenharmony_ci break; 4038c2ecf20Sopenharmony_ci default: 4048c2ecf20Sopenharmony_ci pr_err("switch case %#x not processed\n", 4058c2ecf20Sopenharmony_ci currentcmd->cmdid); 4068c2ecf20Sopenharmony_ci break; 4078c2ecf20Sopenharmony_ci } 4088c2ecf20Sopenharmony_ci 4098c2ecf20Sopenharmony_ci break; 4108c2ecf20Sopenharmony_ci } while (true); 4118c2ecf20Sopenharmony_ci 4128c2ecf20Sopenharmony_ci (*delay) = currentcmd->msdelay; 4138c2ecf20Sopenharmony_ci (*step)++; 4148c2ecf20Sopenharmony_ci return false; 4158c2ecf20Sopenharmony_ci} 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_ciu8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) 4188c2ecf20Sopenharmony_ci{ 4198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4208c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 4218c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 4228c2ecf20Sopenharmony_ci u32 delay; 4238c2ecf20Sopenharmony_ci bool ret; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n", 4268c2ecf20Sopenharmony_ci rtlphy->current_channel); 4278c2ecf20Sopenharmony_ci 4288c2ecf20Sopenharmony_ci if (rtlphy->sw_chnl_inprogress) 4298c2ecf20Sopenharmony_ci return 0; 4308c2ecf20Sopenharmony_ci 4318c2ecf20Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 4328c2ecf20Sopenharmony_ci return 0; 4338c2ecf20Sopenharmony_ci 4348c2ecf20Sopenharmony_ci if (is_hal_stop(rtlhal)) 4358c2ecf20Sopenharmony_ci return 0; 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_ci rtlphy->sw_chnl_inprogress = true; 4388c2ecf20Sopenharmony_ci rtlphy->sw_chnl_stage = 0; 4398c2ecf20Sopenharmony_ci rtlphy->sw_chnl_step = 0; 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_ci do { 4428c2ecf20Sopenharmony_ci if (!rtlphy->sw_chnl_inprogress) 4438c2ecf20Sopenharmony_ci break; 4448c2ecf20Sopenharmony_ci 4458c2ecf20Sopenharmony_ci ret = _rtl92s_phy_sw_chnl_step_by_step(hw, 4468c2ecf20Sopenharmony_ci rtlphy->current_channel, 4478c2ecf20Sopenharmony_ci &rtlphy->sw_chnl_stage, 4488c2ecf20Sopenharmony_ci &rtlphy->sw_chnl_step, &delay); 4498c2ecf20Sopenharmony_ci if (!ret) { 4508c2ecf20Sopenharmony_ci if (delay > 0) 4518c2ecf20Sopenharmony_ci mdelay(delay); 4528c2ecf20Sopenharmony_ci else 4538c2ecf20Sopenharmony_ci continue; 4548c2ecf20Sopenharmony_ci } else { 4558c2ecf20Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 4568c2ecf20Sopenharmony_ci } 4578c2ecf20Sopenharmony_ci break; 4588c2ecf20Sopenharmony_ci } while (true); 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 4618c2ecf20Sopenharmony_ci 4628c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); 4638c2ecf20Sopenharmony_ci 4648c2ecf20Sopenharmony_ci return 1; 4658c2ecf20Sopenharmony_ci} 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_cistatic void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw) 4688c2ecf20Sopenharmony_ci{ 4698c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4708c2ecf20Sopenharmony_ci u8 u1btmp; 4718c2ecf20Sopenharmony_ci 4728c2ecf20Sopenharmony_ci u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL); 4738c2ecf20Sopenharmony_ci u1btmp |= BIT(0); 4748c2ecf20Sopenharmony_ci 4758c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp); 4768c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0); 4778c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, TXPAUSE, 0xFF); 4788c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x57FC); 4798c2ecf20Sopenharmony_ci udelay(100); 4808c2ecf20Sopenharmony_ci 4818c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x77FC); 4828c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, PHY_CCA, 0x0); 4838c2ecf20Sopenharmony_ci udelay(10); 4848c2ecf20Sopenharmony_ci 4858c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x37FC); 4868c2ecf20Sopenharmony_ci udelay(10); 4878c2ecf20Sopenharmony_ci 4888c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x77FC); 4898c2ecf20Sopenharmony_ci udelay(10); 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x57FC); 4928c2ecf20Sopenharmony_ci 4938c2ecf20Sopenharmony_ci /* we should chnge GPIO to input mode 4948c2ecf20Sopenharmony_ci * this will drop away current about 25mA*/ 4958c2ecf20Sopenharmony_ci rtl8192se_gpiobit3_cfg_inputmode(hw); 4968c2ecf20Sopenharmony_ci} 4978c2ecf20Sopenharmony_ci 4988c2ecf20Sopenharmony_cibool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, 4998c2ecf20Sopenharmony_ci enum rf_pwrstate rfpwr_state) 5008c2ecf20Sopenharmony_ci{ 5018c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5028c2ecf20Sopenharmony_ci struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 5038c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 5048c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 5058c2ecf20Sopenharmony_ci bool bresult = true; 5068c2ecf20Sopenharmony_ci u8 i, queue_id; 5078c2ecf20Sopenharmony_ci struct rtl8192_tx_ring *ring = NULL; 5088c2ecf20Sopenharmony_ci 5098c2ecf20Sopenharmony_ci if (rfpwr_state == ppsc->rfpwr_state) 5108c2ecf20Sopenharmony_ci return false; 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_ci switch (rfpwr_state) { 5138c2ecf20Sopenharmony_ci case ERFON:{ 5148c2ecf20Sopenharmony_ci if ((ppsc->rfpwr_state == ERFOFF) && 5158c2ecf20Sopenharmony_ci RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci bool rtstatus; 5188c2ecf20Sopenharmony_ci u32 initializecount = 0; 5198c2ecf20Sopenharmony_ci do { 5208c2ecf20Sopenharmony_ci initializecount++; 5218c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 5228c2ecf20Sopenharmony_ci "IPS Set eRf nic enable\n"); 5238c2ecf20Sopenharmony_ci rtstatus = rtl_ps_enable_nic(hw); 5248c2ecf20Sopenharmony_ci } while (!rtstatus && (initializecount < 10)); 5258c2ecf20Sopenharmony_ci 5268c2ecf20Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, 5278c2ecf20Sopenharmony_ci RT_RF_OFF_LEVL_HALT_NIC); 5288c2ecf20Sopenharmony_ci } else { 5298c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 5308c2ecf20Sopenharmony_ci "awake, slept:%d ms state_inap:%x\n", 5318c2ecf20Sopenharmony_ci jiffies_to_msecs(jiffies - 5328c2ecf20Sopenharmony_ci ppsc->last_sleep_jiffies), 5338c2ecf20Sopenharmony_ci rtlpriv->psc.state_inap); 5348c2ecf20Sopenharmony_ci ppsc->last_awake_jiffies = jiffies; 5358c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x37FC); 5368c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, TXPAUSE, 0x00); 5378c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, PHY_CCA, 0x3); 5388c2ecf20Sopenharmony_ci } 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci if (mac->link_state == MAC80211_LINKED) 5418c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 5428c2ecf20Sopenharmony_ci LED_CTL_LINK); 5438c2ecf20Sopenharmony_ci else 5448c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 5458c2ecf20Sopenharmony_ci LED_CTL_NO_LINK); 5468c2ecf20Sopenharmony_ci break; 5478c2ecf20Sopenharmony_ci } 5488c2ecf20Sopenharmony_ci case ERFOFF:{ 5498c2ecf20Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { 5508c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 5518c2ecf20Sopenharmony_ci "IPS Set eRf nic disable\n"); 5528c2ecf20Sopenharmony_ci rtl_ps_disable_nic(hw); 5538c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 5548c2ecf20Sopenharmony_ci } else { 5558c2ecf20Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) 5568c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 5578c2ecf20Sopenharmony_ci LED_CTL_NO_LINK); 5588c2ecf20Sopenharmony_ci else 5598c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 5608c2ecf20Sopenharmony_ci LED_CTL_POWER_OFF); 5618c2ecf20Sopenharmony_ci } 5628c2ecf20Sopenharmony_ci break; 5638c2ecf20Sopenharmony_ci } 5648c2ecf20Sopenharmony_ci case ERFSLEEP: 5658c2ecf20Sopenharmony_ci if (ppsc->rfpwr_state == ERFOFF) 5668c2ecf20Sopenharmony_ci return false; 5678c2ecf20Sopenharmony_ci 5688c2ecf20Sopenharmony_ci for (queue_id = 0, i = 0; 5698c2ecf20Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 5708c2ecf20Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 5718c2ecf20Sopenharmony_ci if (skb_queue_len(&ring->queue) == 0 || 5728c2ecf20Sopenharmony_ci queue_id == BEACON_QUEUE) { 5738c2ecf20Sopenharmony_ci queue_id++; 5748c2ecf20Sopenharmony_ci continue; 5758c2ecf20Sopenharmony_ci } else { 5768c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 5778c2ecf20Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n", 5788c2ecf20Sopenharmony_ci i + 1, queue_id, 5798c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue)); 5808c2ecf20Sopenharmony_ci 5818c2ecf20Sopenharmony_ci udelay(10); 5828c2ecf20Sopenharmony_ci i++; 5838c2ecf20Sopenharmony_ci } 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 5868c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 5878c2ecf20Sopenharmony_ci "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", 5888c2ecf20Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 5898c2ecf20Sopenharmony_ci queue_id, 5908c2ecf20Sopenharmony_ci skb_queue_len(&ring->queue)); 5918c2ecf20Sopenharmony_ci break; 5928c2ecf20Sopenharmony_ci } 5938c2ecf20Sopenharmony_ci } 5948c2ecf20Sopenharmony_ci 5958c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 5968c2ecf20Sopenharmony_ci "Set ERFSLEEP awaked:%d ms\n", 5978c2ecf20Sopenharmony_ci jiffies_to_msecs(jiffies - 5988c2ecf20Sopenharmony_ci ppsc->last_awake_jiffies)); 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 6018c2ecf20Sopenharmony_ci "sleep awaked:%d ms state_inap:%x\n", 6028c2ecf20Sopenharmony_ci jiffies_to_msecs(jiffies - 6038c2ecf20Sopenharmony_ci ppsc->last_awake_jiffies), 6048c2ecf20Sopenharmony_ci rtlpriv->psc.state_inap); 6058c2ecf20Sopenharmony_ci ppsc->last_sleep_jiffies = jiffies; 6068c2ecf20Sopenharmony_ci _rtl92se_phy_set_rf_sleep(hw); 6078c2ecf20Sopenharmony_ci break; 6088c2ecf20Sopenharmony_ci default: 6098c2ecf20Sopenharmony_ci pr_err("switch case %#x not processed\n", 6108c2ecf20Sopenharmony_ci rfpwr_state); 6118c2ecf20Sopenharmony_ci bresult = false; 6128c2ecf20Sopenharmony_ci break; 6138c2ecf20Sopenharmony_ci } 6148c2ecf20Sopenharmony_ci 6158c2ecf20Sopenharmony_ci if (bresult) 6168c2ecf20Sopenharmony_ci ppsc->rfpwr_state = rfpwr_state; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci return bresult; 6198c2ecf20Sopenharmony_ci} 6208c2ecf20Sopenharmony_ci 6218c2ecf20Sopenharmony_cistatic bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw, 6228c2ecf20Sopenharmony_ci enum radio_path rfpath) 6238c2ecf20Sopenharmony_ci{ 6248c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 6258c2ecf20Sopenharmony_ci bool rtstatus = true; 6268c2ecf20Sopenharmony_ci u32 tmpval = 0; 6278c2ecf20Sopenharmony_ci 6288c2ecf20Sopenharmony_ci /* If inferiority IC, we have to increase the PA bias current */ 6298c2ecf20Sopenharmony_ci if (rtlhal->ic_class != IC_INFERIORITY_A) { 6308c2ecf20Sopenharmony_ci tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf); 6318c2ecf20Sopenharmony_ci rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1); 6328c2ecf20Sopenharmony_ci } 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci return rtstatus; 6358c2ecf20Sopenharmony_ci} 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_cistatic void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, 6388c2ecf20Sopenharmony_ci u32 reg_addr, u32 bitmask, u32 data) 6398c2ecf20Sopenharmony_ci{ 6408c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6418c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 6428c2ecf20Sopenharmony_ci int index; 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci if (reg_addr == RTXAGC_RATE18_06) 6458c2ecf20Sopenharmony_ci index = 0; 6468c2ecf20Sopenharmony_ci else if (reg_addr == RTXAGC_RATE54_24) 6478c2ecf20Sopenharmony_ci index = 1; 6488c2ecf20Sopenharmony_ci else if (reg_addr == RTXAGC_CCK_MCS32) 6498c2ecf20Sopenharmony_ci index = 6; 6508c2ecf20Sopenharmony_ci else if (reg_addr == RTXAGC_MCS03_MCS00) 6518c2ecf20Sopenharmony_ci index = 2; 6528c2ecf20Sopenharmony_ci else if (reg_addr == RTXAGC_MCS07_MCS04) 6538c2ecf20Sopenharmony_ci index = 3; 6548c2ecf20Sopenharmony_ci else if (reg_addr == RTXAGC_MCS11_MCS08) 6558c2ecf20Sopenharmony_ci index = 4; 6568c2ecf20Sopenharmony_ci else if (reg_addr == RTXAGC_MCS15_MCS12) 6578c2ecf20Sopenharmony_ci index = 5; 6588c2ecf20Sopenharmony_ci else 6598c2ecf20Sopenharmony_ci return; 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_ci rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; 6628c2ecf20Sopenharmony_ci if (index == 5) 6638c2ecf20Sopenharmony_ci rtlphy->pwrgroup_cnt++; 6648c2ecf20Sopenharmony_ci} 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_cistatic void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) 6678c2ecf20Sopenharmony_ci{ 6688c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6698c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 6708c2ecf20Sopenharmony_ci 6718c2ecf20Sopenharmony_ci /*RF Interface Sowrtware Control */ 6728c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; 6738c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; 6748c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; 6758c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; 6768c2ecf20Sopenharmony_ci 6778c2ecf20Sopenharmony_ci /* RF Interface Readback Value */ 6788c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; 6798c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; 6808c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; 6818c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; 6828c2ecf20Sopenharmony_ci 6838c2ecf20Sopenharmony_ci /* RF Interface Output (and Enable) */ 6848c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; 6858c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; 6868c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE; 6878c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE; 6888c2ecf20Sopenharmony_ci 6898c2ecf20Sopenharmony_ci /* RF Interface (Output and) Enable */ 6908c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; 6918c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; 6928c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE; 6938c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE; 6948c2ecf20Sopenharmony_ci 6958c2ecf20Sopenharmony_ci /* Addr of LSSI. Wirte RF register by driver */ 6968c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = 6978c2ecf20Sopenharmony_ci RFPGA0_XA_LSSIPARAMETER; 6988c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = 6998c2ecf20Sopenharmony_ci RFPGA0_XB_LSSIPARAMETER; 7008c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset = 7018c2ecf20Sopenharmony_ci RFPGA0_XC_LSSIPARAMETER; 7028c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset = 7038c2ecf20Sopenharmony_ci RFPGA0_XD_LSSIPARAMETER; 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci /* RF parameter */ 7068c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; 7078c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; 7088c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; 7098c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; 7108c2ecf20Sopenharmony_ci 7118c2ecf20Sopenharmony_ci /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ 7128c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; 7138c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; 7148c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; 7158c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci /* Tranceiver A~D HSSI Parameter-1 */ 7188c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; 7198c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; 7208c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1; 7218c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1; 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci /* Tranceiver A~D HSSI Parameter-2 */ 7248c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; 7258c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; 7268c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2; 7278c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2; 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_ci /* RF switch Control */ 7308c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; 7318c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; 7328c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; 7338c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; 7348c2ecf20Sopenharmony_ci 7358c2ecf20Sopenharmony_ci /* AGC control 1 */ 7368c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; 7378c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; 7388c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; 7398c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci /* AGC control 2 */ 7428c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; 7438c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; 7448c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; 7458c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; 7468c2ecf20Sopenharmony_ci 7478c2ecf20Sopenharmony_ci /* RX AFE control 1 */ 7488c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; 7498c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; 7508c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; 7518c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci /* RX AFE control 1 */ 7548c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; 7558c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; 7568c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; 7578c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_ci /* Tx AFE control 1 */ 7608c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; 7618c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; 7628c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; 7638c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_ci /* Tx AFE control 2 */ 7668c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; 7678c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; 7688c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; 7698c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; 7708c2ecf20Sopenharmony_ci 7718c2ecf20Sopenharmony_ci /* Tranceiver LSSI Readback */ 7728c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; 7738c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; 7748c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; 7758c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; 7768c2ecf20Sopenharmony_ci 7778c2ecf20Sopenharmony_ci /* Tranceiver LSSI Readback PI mode */ 7788c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; 7798c2ecf20Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; 7808c2ecf20Sopenharmony_ci} 7818c2ecf20Sopenharmony_ci 7828c2ecf20Sopenharmony_ci 7838c2ecf20Sopenharmony_cistatic bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype) 7848c2ecf20Sopenharmony_ci{ 7858c2ecf20Sopenharmony_ci int i; 7868c2ecf20Sopenharmony_ci u32 *phy_reg_table; 7878c2ecf20Sopenharmony_ci u32 *agc_table; 7888c2ecf20Sopenharmony_ci u16 phy_reg_len, agc_len; 7898c2ecf20Sopenharmony_ci 7908c2ecf20Sopenharmony_ci agc_len = AGCTAB_ARRAYLENGTH; 7918c2ecf20Sopenharmony_ci agc_table = rtl8192seagctab_array; 7928c2ecf20Sopenharmony_ci /* Default RF_type: 2T2R */ 7938c2ecf20Sopenharmony_ci phy_reg_len = PHY_REG_2T2RARRAYLENGTH; 7948c2ecf20Sopenharmony_ci phy_reg_table = rtl8192sephy_reg_2t2rarray; 7958c2ecf20Sopenharmony_ci 7968c2ecf20Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 7978c2ecf20Sopenharmony_ci for (i = 0; i < phy_reg_len; i = i + 2) { 7988c2ecf20Sopenharmony_ci rtl_addr_delay(phy_reg_table[i]); 7998c2ecf20Sopenharmony_ci 8008c2ecf20Sopenharmony_ci /* Add delay for ECS T20 & LG malow platform, */ 8018c2ecf20Sopenharmony_ci udelay(1); 8028c2ecf20Sopenharmony_ci 8038c2ecf20Sopenharmony_ci rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD, 8048c2ecf20Sopenharmony_ci phy_reg_table[i + 1]); 8058c2ecf20Sopenharmony_ci } 8068c2ecf20Sopenharmony_ci } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { 8078c2ecf20Sopenharmony_ci for (i = 0; i < agc_len; i = i + 2) { 8088c2ecf20Sopenharmony_ci rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD, 8098c2ecf20Sopenharmony_ci agc_table[i + 1]); 8108c2ecf20Sopenharmony_ci 8118c2ecf20Sopenharmony_ci /* Add delay for ECS T20 & LG malow platform */ 8128c2ecf20Sopenharmony_ci udelay(1); 8138c2ecf20Sopenharmony_ci } 8148c2ecf20Sopenharmony_ci } 8158c2ecf20Sopenharmony_ci 8168c2ecf20Sopenharmony_ci return true; 8178c2ecf20Sopenharmony_ci} 8188c2ecf20Sopenharmony_ci 8198c2ecf20Sopenharmony_cistatic bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw, 8208c2ecf20Sopenharmony_ci u8 configtype) 8218c2ecf20Sopenharmony_ci{ 8228c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8238c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 8248c2ecf20Sopenharmony_ci u32 *phy_regarray2xtxr_table; 8258c2ecf20Sopenharmony_ci u16 phy_regarray2xtxr_len; 8268c2ecf20Sopenharmony_ci int i; 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T1R) { 8298c2ecf20Sopenharmony_ci phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray; 8308c2ecf20Sopenharmony_ci phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH; 8318c2ecf20Sopenharmony_ci } else if (rtlphy->rf_type == RF_1T2R) { 8328c2ecf20Sopenharmony_ci phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray; 8338c2ecf20Sopenharmony_ci phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH; 8348c2ecf20Sopenharmony_ci } else { 8358c2ecf20Sopenharmony_ci return false; 8368c2ecf20Sopenharmony_ci } 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 8398c2ecf20Sopenharmony_ci for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) { 8408c2ecf20Sopenharmony_ci rtl_addr_delay(phy_regarray2xtxr_table[i]); 8418c2ecf20Sopenharmony_ci 8428c2ecf20Sopenharmony_ci rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i], 8438c2ecf20Sopenharmony_ci phy_regarray2xtxr_table[i + 1], 8448c2ecf20Sopenharmony_ci phy_regarray2xtxr_table[i + 2]); 8458c2ecf20Sopenharmony_ci } 8468c2ecf20Sopenharmony_ci } 8478c2ecf20Sopenharmony_ci 8488c2ecf20Sopenharmony_ci return true; 8498c2ecf20Sopenharmony_ci} 8508c2ecf20Sopenharmony_ci 8518c2ecf20Sopenharmony_cistatic bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw, 8528c2ecf20Sopenharmony_ci u8 configtype) 8538c2ecf20Sopenharmony_ci{ 8548c2ecf20Sopenharmony_ci int i; 8558c2ecf20Sopenharmony_ci u32 *phy_table_pg; 8568c2ecf20Sopenharmony_ci u16 phy_pg_len; 8578c2ecf20Sopenharmony_ci 8588c2ecf20Sopenharmony_ci phy_pg_len = PHY_REG_ARRAY_PGLENGTH; 8598c2ecf20Sopenharmony_ci phy_table_pg = rtl8192sephy_reg_array_pg; 8608c2ecf20Sopenharmony_ci 8618c2ecf20Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 8628c2ecf20Sopenharmony_ci for (i = 0; i < phy_pg_len; i = i + 3) { 8638c2ecf20Sopenharmony_ci rtl_addr_delay(phy_table_pg[i]); 8648c2ecf20Sopenharmony_ci 8658c2ecf20Sopenharmony_ci _rtl92s_store_pwrindex_diffrate_offset(hw, 8668c2ecf20Sopenharmony_ci phy_table_pg[i], 8678c2ecf20Sopenharmony_ci phy_table_pg[i + 1], 8688c2ecf20Sopenharmony_ci phy_table_pg[i + 2]); 8698c2ecf20Sopenharmony_ci rtl92s_phy_set_bb_reg(hw, phy_table_pg[i], 8708c2ecf20Sopenharmony_ci phy_table_pg[i + 1], 8718c2ecf20Sopenharmony_ci phy_table_pg[i + 2]); 8728c2ecf20Sopenharmony_ci } 8738c2ecf20Sopenharmony_ci } 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ci return true; 8768c2ecf20Sopenharmony_ci} 8778c2ecf20Sopenharmony_ci 8788c2ecf20Sopenharmony_cistatic bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) 8798c2ecf20Sopenharmony_ci{ 8808c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8818c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 8828c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 8838c2ecf20Sopenharmony_ci bool rtstatus = true; 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_ci /* 1. Read PHY_REG.TXT BB INIT!! */ 8868c2ecf20Sopenharmony_ci /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */ 8878c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R || 8888c2ecf20Sopenharmony_ci rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) { 8898c2ecf20Sopenharmony_ci rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG); 8908c2ecf20Sopenharmony_ci 8918c2ecf20Sopenharmony_ci if (rtlphy->rf_type != RF_2T2R && 8928c2ecf20Sopenharmony_ci rtlphy->rf_type != RF_2T2R_GREEN) 8938c2ecf20Sopenharmony_ci /* so we should reconfig BB reg with the right 8948c2ecf20Sopenharmony_ci * PHY parameters. */ 8958c2ecf20Sopenharmony_ci rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw, 8968c2ecf20Sopenharmony_ci BASEBAND_CONFIG_PHY_REG); 8978c2ecf20Sopenharmony_ci } else { 8988c2ecf20Sopenharmony_ci rtstatus = false; 8998c2ecf20Sopenharmony_ci } 9008c2ecf20Sopenharmony_ci 9018c2ecf20Sopenharmony_ci if (!rtstatus) { 9028c2ecf20Sopenharmony_ci pr_err("Write BB Reg Fail!!\n"); 9038c2ecf20Sopenharmony_ci goto phy_bb8190_config_parafile_fail; 9048c2ecf20Sopenharmony_ci } 9058c2ecf20Sopenharmony_ci 9068c2ecf20Sopenharmony_ci /* 2. If EEPROM or EFUSE autoload OK, We must config by 9078c2ecf20Sopenharmony_ci * PHY_REG_PG.txt */ 9088c2ecf20Sopenharmony_ci if (rtlefuse->autoload_failflag == false) { 9098c2ecf20Sopenharmony_ci rtlphy->pwrgroup_cnt = 0; 9108c2ecf20Sopenharmony_ci 9118c2ecf20Sopenharmony_ci rtstatus = _rtl92s_phy_config_bb_with_pg(hw, 9128c2ecf20Sopenharmony_ci BASEBAND_CONFIG_PHY_REG); 9138c2ecf20Sopenharmony_ci } 9148c2ecf20Sopenharmony_ci if (!rtstatus) { 9158c2ecf20Sopenharmony_ci pr_err("_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n"); 9168c2ecf20Sopenharmony_ci goto phy_bb8190_config_parafile_fail; 9178c2ecf20Sopenharmony_ci } 9188c2ecf20Sopenharmony_ci 9198c2ecf20Sopenharmony_ci /* 3. BB AGC table Initialization */ 9208c2ecf20Sopenharmony_ci rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB); 9218c2ecf20Sopenharmony_ci 9228c2ecf20Sopenharmony_ci if (!rtstatus) { 9238c2ecf20Sopenharmony_ci pr_err("%s(): AGC Table Fail\n", __func__); 9248c2ecf20Sopenharmony_ci goto phy_bb8190_config_parafile_fail; 9258c2ecf20Sopenharmony_ci } 9268c2ecf20Sopenharmony_ci 9278c2ecf20Sopenharmony_ci /* Check if the CCK HighPower is turned ON. */ 9288c2ecf20Sopenharmony_ci /* This is used to calculate PWDB. */ 9298c2ecf20Sopenharmony_ci rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw, 9308c2ecf20Sopenharmony_ci RFPGA0_XA_HSSIPARAMETER2, 0x200)); 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ciphy_bb8190_config_parafile_fail: 9338c2ecf20Sopenharmony_ci return rtstatus; 9348c2ecf20Sopenharmony_ci} 9358c2ecf20Sopenharmony_ci 9368c2ecf20Sopenharmony_ciu8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) 9378c2ecf20Sopenharmony_ci{ 9388c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 9398c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 9408c2ecf20Sopenharmony_ci int i; 9418c2ecf20Sopenharmony_ci bool rtstatus = true; 9428c2ecf20Sopenharmony_ci u32 *radio_a_table; 9438c2ecf20Sopenharmony_ci u32 *radio_b_table; 9448c2ecf20Sopenharmony_ci u16 radio_a_tblen, radio_b_tblen; 9458c2ecf20Sopenharmony_ci 9468c2ecf20Sopenharmony_ci radio_a_tblen = RADIOA_1T_ARRAYLENGTH; 9478c2ecf20Sopenharmony_ci radio_a_table = rtl8192seradioa_1t_array; 9488c2ecf20Sopenharmony_ci 9498c2ecf20Sopenharmony_ci /* Using Green mode array table for RF_2T2R_GREEN */ 9508c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_2T2R_GREEN) { 9518c2ecf20Sopenharmony_ci radio_b_table = rtl8192seradiob_gm_array; 9528c2ecf20Sopenharmony_ci radio_b_tblen = RADIOB_GM_ARRAYLENGTH; 9538c2ecf20Sopenharmony_ci } else { 9548c2ecf20Sopenharmony_ci radio_b_table = rtl8192seradiob_array; 9558c2ecf20Sopenharmony_ci radio_b_tblen = RADIOB_ARRAYLENGTH; 9568c2ecf20Sopenharmony_ci } 9578c2ecf20Sopenharmony_ci 9588c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); 9598c2ecf20Sopenharmony_ci rtstatus = true; 9608c2ecf20Sopenharmony_ci 9618c2ecf20Sopenharmony_ci switch (rfpath) { 9628c2ecf20Sopenharmony_ci case RF90_PATH_A: 9638c2ecf20Sopenharmony_ci for (i = 0; i < radio_a_tblen; i = i + 2) { 9648c2ecf20Sopenharmony_ci rtl_rfreg_delay(hw, rfpath, radio_a_table[i], 9658c2ecf20Sopenharmony_ci MASK20BITS, radio_a_table[i + 1]); 9668c2ecf20Sopenharmony_ci 9678c2ecf20Sopenharmony_ci } 9688c2ecf20Sopenharmony_ci 9698c2ecf20Sopenharmony_ci /* PA Bias current for inferiority IC */ 9708c2ecf20Sopenharmony_ci _rtl92s_phy_config_rfpa_bias_current(hw, rfpath); 9718c2ecf20Sopenharmony_ci break; 9728c2ecf20Sopenharmony_ci case RF90_PATH_B: 9738c2ecf20Sopenharmony_ci for (i = 0; i < radio_b_tblen; i = i + 2) { 9748c2ecf20Sopenharmony_ci rtl_rfreg_delay(hw, rfpath, radio_b_table[i], 9758c2ecf20Sopenharmony_ci MASK20BITS, radio_b_table[i + 1]); 9768c2ecf20Sopenharmony_ci } 9778c2ecf20Sopenharmony_ci break; 9788c2ecf20Sopenharmony_ci case RF90_PATH_C: 9798c2ecf20Sopenharmony_ci ; 9808c2ecf20Sopenharmony_ci break; 9818c2ecf20Sopenharmony_ci case RF90_PATH_D: 9828c2ecf20Sopenharmony_ci ; 9838c2ecf20Sopenharmony_ci break; 9848c2ecf20Sopenharmony_ci default: 9858c2ecf20Sopenharmony_ci break; 9868c2ecf20Sopenharmony_ci } 9878c2ecf20Sopenharmony_ci 9888c2ecf20Sopenharmony_ci return rtstatus; 9898c2ecf20Sopenharmony_ci} 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_ci 9928c2ecf20Sopenharmony_cibool rtl92s_phy_mac_config(struct ieee80211_hw *hw) 9938c2ecf20Sopenharmony_ci{ 9948c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 9958c2ecf20Sopenharmony_ci u32 i; 9968c2ecf20Sopenharmony_ci u32 arraylength; 9978c2ecf20Sopenharmony_ci u32 *ptrarray; 9988c2ecf20Sopenharmony_ci 9998c2ecf20Sopenharmony_ci arraylength = MAC_2T_ARRAYLENGTH; 10008c2ecf20Sopenharmony_ci ptrarray = rtl8192semac_2t_array; 10018c2ecf20Sopenharmony_ci 10028c2ecf20Sopenharmony_ci for (i = 0; i < arraylength; i = i + 2) 10038c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]); 10048c2ecf20Sopenharmony_ci 10058c2ecf20Sopenharmony_ci return true; 10068c2ecf20Sopenharmony_ci} 10078c2ecf20Sopenharmony_ci 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_cibool rtl92s_phy_bb_config(struct ieee80211_hw *hw) 10108c2ecf20Sopenharmony_ci{ 10118c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10128c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 10138c2ecf20Sopenharmony_ci bool rtstatus = true; 10148c2ecf20Sopenharmony_ci u8 pathmap, index, rf_num = 0; 10158c2ecf20Sopenharmony_ci u8 path1, path2; 10168c2ecf20Sopenharmony_ci 10178c2ecf20Sopenharmony_ci _rtl92s_phy_init_register_definition(hw); 10188c2ecf20Sopenharmony_ci 10198c2ecf20Sopenharmony_ci /* Config BB and AGC */ 10208c2ecf20Sopenharmony_ci rtstatus = _rtl92s_phy_bb_config_parafile(hw); 10218c2ecf20Sopenharmony_ci 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_ci /* Check BB/RF confiuration setting. */ 10248c2ecf20Sopenharmony_ci /* We only need to configure RF which is turned on. */ 10258c2ecf20Sopenharmony_ci path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf)); 10268c2ecf20Sopenharmony_ci mdelay(10); 10278c2ecf20Sopenharmony_ci path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf)); 10288c2ecf20Sopenharmony_ci pathmap = path1 | path2; 10298c2ecf20Sopenharmony_ci 10308c2ecf20Sopenharmony_ci rtlphy->rf_pathmap = pathmap; 10318c2ecf20Sopenharmony_ci for (index = 0; index < 4; index++) { 10328c2ecf20Sopenharmony_ci if ((pathmap >> index) & 0x1) 10338c2ecf20Sopenharmony_ci rf_num++; 10348c2ecf20Sopenharmony_ci } 10358c2ecf20Sopenharmony_ci 10368c2ecf20Sopenharmony_ci if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) || 10378c2ecf20Sopenharmony_ci (rtlphy->rf_type == RF_1T2R && rf_num != 2) || 10388c2ecf20Sopenharmony_ci (rtlphy->rf_type == RF_2T2R && rf_num != 2) || 10398c2ecf20Sopenharmony_ci (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) { 10408c2ecf20Sopenharmony_ci pr_err("RF_Type(%x) does not match RF_Num(%x)!!\n", 10418c2ecf20Sopenharmony_ci rtlphy->rf_type, rf_num); 10428c2ecf20Sopenharmony_ci pr_err("path1 0x%x, path2 0x%x, pathmap 0x%x\n", 10438c2ecf20Sopenharmony_ci path1, path2, pathmap); 10448c2ecf20Sopenharmony_ci } 10458c2ecf20Sopenharmony_ci 10468c2ecf20Sopenharmony_ci return rtstatus; 10478c2ecf20Sopenharmony_ci} 10488c2ecf20Sopenharmony_ci 10498c2ecf20Sopenharmony_cibool rtl92s_phy_rf_config(struct ieee80211_hw *hw) 10508c2ecf20Sopenharmony_ci{ 10518c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10528c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 10538c2ecf20Sopenharmony_ci 10548c2ecf20Sopenharmony_ci /* Initialize general global value */ 10558c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T1R) 10568c2ecf20Sopenharmony_ci rtlphy->num_total_rfpath = 1; 10578c2ecf20Sopenharmony_ci else 10588c2ecf20Sopenharmony_ci rtlphy->num_total_rfpath = 2; 10598c2ecf20Sopenharmony_ci 10608c2ecf20Sopenharmony_ci /* Config BB and RF */ 10618c2ecf20Sopenharmony_ci return rtl92s_phy_rf6052_config(hw); 10628c2ecf20Sopenharmony_ci} 10638c2ecf20Sopenharmony_ci 10648c2ecf20Sopenharmony_civoid rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) 10658c2ecf20Sopenharmony_ci{ 10668c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10678c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 10688c2ecf20Sopenharmony_ci 10698c2ecf20Sopenharmony_ci /* read rx initial gain */ 10708c2ecf20Sopenharmony_ci rtlphy->default_initialgain[0] = rtl_get_bbreg(hw, 10718c2ecf20Sopenharmony_ci ROFDM0_XAAGCCORE1, MASKBYTE0); 10728c2ecf20Sopenharmony_ci rtlphy->default_initialgain[1] = rtl_get_bbreg(hw, 10738c2ecf20Sopenharmony_ci ROFDM0_XBAGCCORE1, MASKBYTE0); 10748c2ecf20Sopenharmony_ci rtlphy->default_initialgain[2] = rtl_get_bbreg(hw, 10758c2ecf20Sopenharmony_ci ROFDM0_XCAGCCORE1, MASKBYTE0); 10768c2ecf20Sopenharmony_ci rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, 10778c2ecf20Sopenharmony_ci ROFDM0_XDAGCCORE1, MASKBYTE0); 10788c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 10798c2ecf20Sopenharmony_ci "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", 10808c2ecf20Sopenharmony_ci rtlphy->default_initialgain[0], 10818c2ecf20Sopenharmony_ci rtlphy->default_initialgain[1], 10828c2ecf20Sopenharmony_ci rtlphy->default_initialgain[2], 10838c2ecf20Sopenharmony_ci rtlphy->default_initialgain[3]); 10848c2ecf20Sopenharmony_ci 10858c2ecf20Sopenharmony_ci /* read framesync */ 10868c2ecf20Sopenharmony_ci rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); 10878c2ecf20Sopenharmony_ci rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, 10888c2ecf20Sopenharmony_ci MASKDWORD); 10898c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 10908c2ecf20Sopenharmony_ci "Default framesync (0x%x) = 0x%x\n", 10918c2ecf20Sopenharmony_ci ROFDM0_RXDETECTOR3, rtlphy->framesync); 10928c2ecf20Sopenharmony_ci 10938c2ecf20Sopenharmony_ci} 10948c2ecf20Sopenharmony_ci 10958c2ecf20Sopenharmony_cistatic void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel, 10968c2ecf20Sopenharmony_ci u8 *cckpowerlevel, u8 *ofdmpowerlevel) 10978c2ecf20Sopenharmony_ci{ 10988c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10998c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 11008c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 11018c2ecf20Sopenharmony_ci u8 index = (channel - 1); 11028c2ecf20Sopenharmony_ci 11038c2ecf20Sopenharmony_ci /* 1. CCK */ 11048c2ecf20Sopenharmony_ci /* RF-A */ 11058c2ecf20Sopenharmony_ci cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index]; 11068c2ecf20Sopenharmony_ci /* RF-B */ 11078c2ecf20Sopenharmony_ci cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index]; 11088c2ecf20Sopenharmony_ci 11098c2ecf20Sopenharmony_ci /* 2. OFDM for 1T or 2T */ 11108c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) { 11118c2ecf20Sopenharmony_ci /* Read HT 40 OFDM TX power */ 11128c2ecf20Sopenharmony_ci ofdmpowerlevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index]; 11138c2ecf20Sopenharmony_ci ofdmpowerlevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index]; 11148c2ecf20Sopenharmony_ci } else if (rtlphy->rf_type == RF_2T2R) { 11158c2ecf20Sopenharmony_ci /* Read HT 40 OFDM TX power */ 11168c2ecf20Sopenharmony_ci ofdmpowerlevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index]; 11178c2ecf20Sopenharmony_ci ofdmpowerlevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index]; 11188c2ecf20Sopenharmony_ci } else { 11198c2ecf20Sopenharmony_ci ofdmpowerlevel[0] = 0; 11208c2ecf20Sopenharmony_ci ofdmpowerlevel[1] = 0; 11218c2ecf20Sopenharmony_ci } 11228c2ecf20Sopenharmony_ci} 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_cistatic void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw, 11258c2ecf20Sopenharmony_ci u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel) 11268c2ecf20Sopenharmony_ci{ 11278c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11288c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 11298c2ecf20Sopenharmony_ci 11308c2ecf20Sopenharmony_ci rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; 11318c2ecf20Sopenharmony_ci rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; 11328c2ecf20Sopenharmony_ci} 11338c2ecf20Sopenharmony_ci 11348c2ecf20Sopenharmony_civoid rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel) 11358c2ecf20Sopenharmony_ci{ 11368c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11378c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 11388c2ecf20Sopenharmony_ci /* [0]:RF-A, [1]:RF-B */ 11398c2ecf20Sopenharmony_ci u8 cckpowerlevel[2], ofdmpowerlevel[2]; 11408c2ecf20Sopenharmony_ci 11418c2ecf20Sopenharmony_ci if (!rtlefuse->txpwr_fromeprom) 11428c2ecf20Sopenharmony_ci return; 11438c2ecf20Sopenharmony_ci 11448c2ecf20Sopenharmony_ci /* Mainly we use RF-A Tx Power to write the Tx Power registers, 11458c2ecf20Sopenharmony_ci * but the RF-B Tx Power must be calculated by the antenna diff. 11468c2ecf20Sopenharmony_ci * So we have to rewrite Antenna gain offset register here. 11478c2ecf20Sopenharmony_ci * Please refer to BB register 0x80c 11488c2ecf20Sopenharmony_ci * 1. For CCK. 11498c2ecf20Sopenharmony_ci * 2. For OFDM 1T or 2T */ 11508c2ecf20Sopenharmony_ci _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0], 11518c2ecf20Sopenharmony_ci &ofdmpowerlevel[0]); 11528c2ecf20Sopenharmony_ci 11538c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 11548c2ecf20Sopenharmony_ci "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", 11558c2ecf20Sopenharmony_ci channel, cckpowerlevel[0], cckpowerlevel[1], 11568c2ecf20Sopenharmony_ci ofdmpowerlevel[0], ofdmpowerlevel[1]); 11578c2ecf20Sopenharmony_ci 11588c2ecf20Sopenharmony_ci _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0], 11598c2ecf20Sopenharmony_ci &ofdmpowerlevel[0]); 11608c2ecf20Sopenharmony_ci 11618c2ecf20Sopenharmony_ci rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]); 11628c2ecf20Sopenharmony_ci rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerlevel[0], channel); 11638c2ecf20Sopenharmony_ci 11648c2ecf20Sopenharmony_ci} 11658c2ecf20Sopenharmony_ci 11668c2ecf20Sopenharmony_civoid rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw) 11678c2ecf20Sopenharmony_ci{ 11688c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11698c2ecf20Sopenharmony_ci u16 pollingcnt = 10000; 11708c2ecf20Sopenharmony_ci u32 tmpvalue; 11718c2ecf20Sopenharmony_ci 11728c2ecf20Sopenharmony_ci /* Make sure that CMD IO has be accepted by FW. */ 11738c2ecf20Sopenharmony_ci do { 11748c2ecf20Sopenharmony_ci udelay(10); 11758c2ecf20Sopenharmony_ci 11768c2ecf20Sopenharmony_ci tmpvalue = rtl_read_dword(rtlpriv, WFM5); 11778c2ecf20Sopenharmony_ci if (tmpvalue == 0) 11788c2ecf20Sopenharmony_ci break; 11798c2ecf20Sopenharmony_ci } while (--pollingcnt); 11808c2ecf20Sopenharmony_ci 11818c2ecf20Sopenharmony_ci if (pollingcnt == 0) 11828c2ecf20Sopenharmony_ci pr_err("Set FW Cmd fail!!\n"); 11838c2ecf20Sopenharmony_ci} 11848c2ecf20Sopenharmony_ci 11858c2ecf20Sopenharmony_ci 11868c2ecf20Sopenharmony_cistatic void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) 11878c2ecf20Sopenharmony_ci{ 11888c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11898c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 11908c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 11918c2ecf20Sopenharmony_ci u32 input, current_aid = 0; 11928c2ecf20Sopenharmony_ci 11938c2ecf20Sopenharmony_ci if (is_hal_stop(rtlhal)) 11948c2ecf20Sopenharmony_ci return; 11958c2ecf20Sopenharmony_ci 11968c2ecf20Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) < 0x34) 11978c2ecf20Sopenharmony_ci goto skip; 11988c2ecf20Sopenharmony_ci /* We re-map RA related CMD IO to combinational ones */ 11998c2ecf20Sopenharmony_ci /* if FW version is v.52 or later. */ 12008c2ecf20Sopenharmony_ci switch (rtlhal->current_fwcmd_io) { 12018c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_N: 12028c2ecf20Sopenharmony_ci rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB; 12038c2ecf20Sopenharmony_ci break; 12048c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_BG: 12058c2ecf20Sopenharmony_ci rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB; 12068c2ecf20Sopenharmony_ci break; 12078c2ecf20Sopenharmony_ci default: 12088c2ecf20Sopenharmony_ci break; 12098c2ecf20Sopenharmony_ci } 12108c2ecf20Sopenharmony_ci 12118c2ecf20Sopenharmony_ciskip: 12128c2ecf20Sopenharmony_ci switch (rtlhal->current_fwcmd_io) { 12138c2ecf20Sopenharmony_ci case FW_CMD_RA_RESET: 12148c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n"); 12158c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); 12168c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12178c2ecf20Sopenharmony_ci break; 12188c2ecf20Sopenharmony_ci case FW_CMD_RA_ACTIVE: 12198c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n"); 12208c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); 12218c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12228c2ecf20Sopenharmony_ci break; 12238c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_N: 12248c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n"); 12258c2ecf20Sopenharmony_ci input = FW_RA_REFRESH; 12268c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, input); 12278c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12288c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK); 12298c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12308c2ecf20Sopenharmony_ci break; 12318c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_BG: 12328c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, 12338c2ecf20Sopenharmony_ci "FW_CMD_RA_REFRESH_BG\n"); 12348c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); 12358c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12368c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK); 12378c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12388c2ecf20Sopenharmony_ci break; 12398c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_N_COMB: 12408c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, 12418c2ecf20Sopenharmony_ci "FW_CMD_RA_REFRESH_N_COMB\n"); 12428c2ecf20Sopenharmony_ci input = FW_RA_IOT_N_COMB; 12438c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, input); 12448c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12458c2ecf20Sopenharmony_ci break; 12468c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_BG_COMB: 12478c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, 12488c2ecf20Sopenharmony_ci "FW_CMD_RA_REFRESH_BG_COMB\n"); 12498c2ecf20Sopenharmony_ci input = FW_RA_IOT_BG_COMB; 12508c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, input); 12518c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12528c2ecf20Sopenharmony_ci break; 12538c2ecf20Sopenharmony_ci case FW_CMD_IQK_ENABLE: 12548c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n"); 12558c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE); 12568c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12578c2ecf20Sopenharmony_ci break; 12588c2ecf20Sopenharmony_ci case FW_CMD_PAUSE_DM_BY_SCAN: 12598c2ecf20Sopenharmony_ci /* Lower initial gain */ 12608c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17); 12618c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17); 12628c2ecf20Sopenharmony_ci /* CCA threshold */ 12638c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40); 12648c2ecf20Sopenharmony_ci break; 12658c2ecf20Sopenharmony_ci case FW_CMD_RESUME_DM_BY_SCAN: 12668c2ecf20Sopenharmony_ci /* CCA threshold */ 12678c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); 12688c2ecf20Sopenharmony_ci rtl92s_phy_set_txpower(hw, rtlphy->current_channel); 12698c2ecf20Sopenharmony_ci break; 12708c2ecf20Sopenharmony_ci case FW_CMD_HIGH_PWR_DISABLE: 12718c2ecf20Sopenharmony_ci if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) 12728c2ecf20Sopenharmony_ci break; 12738c2ecf20Sopenharmony_ci 12748c2ecf20Sopenharmony_ci /* Lower initial gain */ 12758c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17); 12768c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17); 12778c2ecf20Sopenharmony_ci /* CCA threshold */ 12788c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40); 12798c2ecf20Sopenharmony_ci break; 12808c2ecf20Sopenharmony_ci case FW_CMD_HIGH_PWR_ENABLE: 12818c2ecf20Sopenharmony_ci if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || 12828c2ecf20Sopenharmony_ci rtlpriv->dm.dynamic_txpower_enable) 12838c2ecf20Sopenharmony_ci break; 12848c2ecf20Sopenharmony_ci 12858c2ecf20Sopenharmony_ci /* CCA threshold */ 12868c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); 12878c2ecf20Sopenharmony_ci break; 12888c2ecf20Sopenharmony_ci case FW_CMD_LPS_ENTER: 12898c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n"); 12908c2ecf20Sopenharmony_ci current_aid = rtlpriv->mac80211.assoc_id; 12918c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER | 12928c2ecf20Sopenharmony_ci ((current_aid | 0xc000) << 8))); 12938c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 12948c2ecf20Sopenharmony_ci /* FW set TXOP disable here, so disable EDCA 12958c2ecf20Sopenharmony_ci * turbo mode until driver leave LPS */ 12968c2ecf20Sopenharmony_ci break; 12978c2ecf20Sopenharmony_ci case FW_CMD_LPS_LEAVE: 12988c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n"); 12998c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE); 13008c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 13018c2ecf20Sopenharmony_ci break; 13028c2ecf20Sopenharmony_ci case FW_CMD_ADD_A2_ENTRY: 13038c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n"); 13048c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY); 13058c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 13068c2ecf20Sopenharmony_ci break; 13078c2ecf20Sopenharmony_ci case FW_CMD_CTRL_DM_BY_DRIVER: 13088c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 13098c2ecf20Sopenharmony_ci "FW_CMD_CTRL_DM_BY_DRIVER\n"); 13108c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER); 13118c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 13128c2ecf20Sopenharmony_ci break; 13138c2ecf20Sopenharmony_ci 13148c2ecf20Sopenharmony_ci default: 13158c2ecf20Sopenharmony_ci break; 13168c2ecf20Sopenharmony_ci } 13178c2ecf20Sopenharmony_ci 13188c2ecf20Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 13198c2ecf20Sopenharmony_ci 13208c2ecf20Sopenharmony_ci /* Clear FW CMD operation flag. */ 13218c2ecf20Sopenharmony_ci rtlhal->set_fwcmd_inprogress = false; 13228c2ecf20Sopenharmony_ci} 13238c2ecf20Sopenharmony_ci 13248c2ecf20Sopenharmony_cibool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) 13258c2ecf20Sopenharmony_ci{ 13268c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13278c2ecf20Sopenharmony_ci struct dig_t *digtable = &rtlpriv->dm_digtable; 13288c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 13298c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 13308c2ecf20Sopenharmony_ci u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv); 13318c2ecf20Sopenharmony_ci u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv); 13328c2ecf20Sopenharmony_ci bool postprocessing = false; 13338c2ecf20Sopenharmony_ci 13348c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 13358c2ecf20Sopenharmony_ci "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", 13368c2ecf20Sopenharmony_ci fw_cmdio, rtlhal->set_fwcmd_inprogress); 13378c2ecf20Sopenharmony_ci 13388c2ecf20Sopenharmony_ci do { 13398c2ecf20Sopenharmony_ci /* We re-map to combined FW CMD ones if firmware version */ 13408c2ecf20Sopenharmony_ci /* is v.53 or later. */ 13418c2ecf20Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) >= 0x35) { 13428c2ecf20Sopenharmony_ci switch (fw_cmdio) { 13438c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_N: 13448c2ecf20Sopenharmony_ci fw_cmdio = FW_CMD_RA_REFRESH_N_COMB; 13458c2ecf20Sopenharmony_ci break; 13468c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_BG: 13478c2ecf20Sopenharmony_ci fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB; 13488c2ecf20Sopenharmony_ci break; 13498c2ecf20Sopenharmony_ci default: 13508c2ecf20Sopenharmony_ci break; 13518c2ecf20Sopenharmony_ci } 13528c2ecf20Sopenharmony_ci } else { 13538c2ecf20Sopenharmony_ci if ((fw_cmdio == FW_CMD_IQK_ENABLE) || 13548c2ecf20Sopenharmony_ci (fw_cmdio == FW_CMD_RA_REFRESH_N) || 13558c2ecf20Sopenharmony_ci (fw_cmdio == FW_CMD_RA_REFRESH_BG)) { 13568c2ecf20Sopenharmony_ci postprocessing = true; 13578c2ecf20Sopenharmony_ci break; 13588c2ecf20Sopenharmony_ci } 13598c2ecf20Sopenharmony_ci } 13608c2ecf20Sopenharmony_ci 13618c2ecf20Sopenharmony_ci /* If firmware version is v.62 or later, 13628c2ecf20Sopenharmony_ci * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */ 13638c2ecf20Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) >= 0x3E) { 13648c2ecf20Sopenharmony_ci if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER) 13658c2ecf20Sopenharmony_ci fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW; 13668c2ecf20Sopenharmony_ci } 13678c2ecf20Sopenharmony_ci 13688c2ecf20Sopenharmony_ci 13698c2ecf20Sopenharmony_ci /* We shall revise all FW Cmd IO into Reg0x364 13708c2ecf20Sopenharmony_ci * DM map table in the future. */ 13718c2ecf20Sopenharmony_ci switch (fw_cmdio) { 13728c2ecf20Sopenharmony_ci case FW_CMD_RA_INIT: 13738c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n"); 13748c2ecf20Sopenharmony_ci fw_cmdmap |= FW_RA_INIT_CTL; 13758c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 13768c2ecf20Sopenharmony_ci /* Clear control flag to sync with FW. */ 13778c2ecf20Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL); 13788c2ecf20Sopenharmony_ci break; 13798c2ecf20Sopenharmony_ci case FW_CMD_DIG_DISABLE: 13808c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 13818c2ecf20Sopenharmony_ci "Set DIG disable!!\n"); 13828c2ecf20Sopenharmony_ci fw_cmdmap &= ~FW_DIG_ENABLE_CTL; 13838c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 13848c2ecf20Sopenharmony_ci break; 13858c2ecf20Sopenharmony_ci case FW_CMD_DIG_ENABLE: 13868c2ecf20Sopenharmony_ci case FW_CMD_DIG_RESUME: 13878c2ecf20Sopenharmony_ci if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) { 13888c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 13898c2ecf20Sopenharmony_ci "Set DIG enable or resume!!\n"); 13908c2ecf20Sopenharmony_ci fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL); 13918c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 13928c2ecf20Sopenharmony_ci } 13938c2ecf20Sopenharmony_ci break; 13948c2ecf20Sopenharmony_ci case FW_CMD_DIG_HALT: 13958c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 13968c2ecf20Sopenharmony_ci "Set DIG halt!!\n"); 13978c2ecf20Sopenharmony_ci fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL); 13988c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 13998c2ecf20Sopenharmony_ci break; 14008c2ecf20Sopenharmony_ci case FW_CMD_TXPWR_TRACK_THERMAL: { 14018c2ecf20Sopenharmony_ci u8 thermalval = 0; 14028c2ecf20Sopenharmony_ci fw_cmdmap |= FW_PWR_TRK_CTL; 14038c2ecf20Sopenharmony_ci 14048c2ecf20Sopenharmony_ci /* Clear FW parameter in terms of thermal parts. */ 14058c2ecf20Sopenharmony_ci fw_param &= FW_PWR_TRK_PARAM_CLR; 14068c2ecf20Sopenharmony_ci 14078c2ecf20Sopenharmony_ci thermalval = rtlpriv->dm.thermalvalue; 14088c2ecf20Sopenharmony_ci fw_param |= ((thermalval << 24) | 14098c2ecf20Sopenharmony_ci (rtlefuse->thermalmeter[0] << 16)); 14108c2ecf20Sopenharmony_ci 14118c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 14128c2ecf20Sopenharmony_ci "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n", 14138c2ecf20Sopenharmony_ci fw_cmdmap, fw_param); 14148c2ecf20Sopenharmony_ci 14158c2ecf20Sopenharmony_ci FW_CMD_PARA_SET(rtlpriv, fw_param); 14168c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 14178c2ecf20Sopenharmony_ci 14188c2ecf20Sopenharmony_ci /* Clear control flag to sync with FW. */ 14198c2ecf20Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL); 14208c2ecf20Sopenharmony_ci } 14218c2ecf20Sopenharmony_ci break; 14228c2ecf20Sopenharmony_ci /* The following FW CMDs are only compatible to 14238c2ecf20Sopenharmony_ci * v.53 or later. */ 14248c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_N_COMB: 14258c2ecf20Sopenharmony_ci fw_cmdmap |= FW_RA_N_CTL; 14268c2ecf20Sopenharmony_ci 14278c2ecf20Sopenharmony_ci /* Clear RA BG mode control. */ 14288c2ecf20Sopenharmony_ci fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL); 14298c2ecf20Sopenharmony_ci 14308c2ecf20Sopenharmony_ci /* Clear FW parameter in terms of RA parts. */ 14318c2ecf20Sopenharmony_ci fw_param &= FW_RA_PARAM_CLR; 14328c2ecf20Sopenharmony_ci 14338c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 14348c2ecf20Sopenharmony_ci "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n", 14358c2ecf20Sopenharmony_ci fw_cmdmap, fw_param); 14368c2ecf20Sopenharmony_ci 14378c2ecf20Sopenharmony_ci FW_CMD_PARA_SET(rtlpriv, fw_param); 14388c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 14398c2ecf20Sopenharmony_ci 14408c2ecf20Sopenharmony_ci /* Clear control flag to sync with FW. */ 14418c2ecf20Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL); 14428c2ecf20Sopenharmony_ci break; 14438c2ecf20Sopenharmony_ci case FW_CMD_RA_REFRESH_BG_COMB: 14448c2ecf20Sopenharmony_ci fw_cmdmap |= FW_RA_BG_CTL; 14458c2ecf20Sopenharmony_ci 14468c2ecf20Sopenharmony_ci /* Clear RA n-mode control. */ 14478c2ecf20Sopenharmony_ci fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL); 14488c2ecf20Sopenharmony_ci /* Clear FW parameter in terms of RA parts. */ 14498c2ecf20Sopenharmony_ci fw_param &= FW_RA_PARAM_CLR; 14508c2ecf20Sopenharmony_ci 14518c2ecf20Sopenharmony_ci FW_CMD_PARA_SET(rtlpriv, fw_param); 14528c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 14538c2ecf20Sopenharmony_ci 14548c2ecf20Sopenharmony_ci /* Clear control flag to sync with FW. */ 14558c2ecf20Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL); 14568c2ecf20Sopenharmony_ci break; 14578c2ecf20Sopenharmony_ci case FW_CMD_IQK_ENABLE: 14588c2ecf20Sopenharmony_ci fw_cmdmap |= FW_IQK_CTL; 14598c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 14608c2ecf20Sopenharmony_ci /* Clear control flag to sync with FW. */ 14618c2ecf20Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL); 14628c2ecf20Sopenharmony_ci break; 14638c2ecf20Sopenharmony_ci /* The following FW CMD is compatible to v.62 or later. */ 14648c2ecf20Sopenharmony_ci case FW_CMD_CTRL_DM_BY_DRIVER_NEW: 14658c2ecf20Sopenharmony_ci fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL; 14668c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 14678c2ecf20Sopenharmony_ci break; 14688c2ecf20Sopenharmony_ci /* The followed FW Cmds needs post-processing later. */ 14698c2ecf20Sopenharmony_ci case FW_CMD_RESUME_DM_BY_SCAN: 14708c2ecf20Sopenharmony_ci fw_cmdmap |= (FW_DIG_ENABLE_CTL | 14718c2ecf20Sopenharmony_ci FW_HIGH_PWR_ENABLE_CTL | 14728c2ecf20Sopenharmony_ci FW_SS_CTL); 14738c2ecf20Sopenharmony_ci 14748c2ecf20Sopenharmony_ci if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE || 14758c2ecf20Sopenharmony_ci !digtable->dig_enable_flag) 14768c2ecf20Sopenharmony_ci fw_cmdmap &= ~FW_DIG_ENABLE_CTL; 14778c2ecf20Sopenharmony_ci 14788c2ecf20Sopenharmony_ci if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || 14798c2ecf20Sopenharmony_ci rtlpriv->dm.dynamic_txpower_enable) 14808c2ecf20Sopenharmony_ci fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; 14818c2ecf20Sopenharmony_ci 14828c2ecf20Sopenharmony_ci if ((digtable->dig_ext_port_stage == 14838c2ecf20Sopenharmony_ci DIG_EXT_PORT_STAGE_0) || 14848c2ecf20Sopenharmony_ci (digtable->dig_ext_port_stage == 14858c2ecf20Sopenharmony_ci DIG_EXT_PORT_STAGE_1)) 14868c2ecf20Sopenharmony_ci fw_cmdmap &= ~FW_DIG_ENABLE_CTL; 14878c2ecf20Sopenharmony_ci 14888c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 14898c2ecf20Sopenharmony_ci postprocessing = true; 14908c2ecf20Sopenharmony_ci break; 14918c2ecf20Sopenharmony_ci case FW_CMD_PAUSE_DM_BY_SCAN: 14928c2ecf20Sopenharmony_ci fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | 14938c2ecf20Sopenharmony_ci FW_HIGH_PWR_ENABLE_CTL | 14948c2ecf20Sopenharmony_ci FW_SS_CTL); 14958c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 14968c2ecf20Sopenharmony_ci postprocessing = true; 14978c2ecf20Sopenharmony_ci break; 14988c2ecf20Sopenharmony_ci case FW_CMD_HIGH_PWR_DISABLE: 14998c2ecf20Sopenharmony_ci fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; 15008c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 15018c2ecf20Sopenharmony_ci postprocessing = true; 15028c2ecf20Sopenharmony_ci break; 15038c2ecf20Sopenharmony_ci case FW_CMD_HIGH_PWR_ENABLE: 15048c2ecf20Sopenharmony_ci if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) && 15058c2ecf20Sopenharmony_ci !rtlpriv->dm.dynamic_txpower_enable) { 15068c2ecf20Sopenharmony_ci fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL | 15078c2ecf20Sopenharmony_ci FW_SS_CTL); 15088c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 15098c2ecf20Sopenharmony_ci postprocessing = true; 15108c2ecf20Sopenharmony_ci } 15118c2ecf20Sopenharmony_ci break; 15128c2ecf20Sopenharmony_ci case FW_CMD_DIG_MODE_FA: 15138c2ecf20Sopenharmony_ci fw_cmdmap |= FW_FA_CTL; 15148c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 15158c2ecf20Sopenharmony_ci break; 15168c2ecf20Sopenharmony_ci case FW_CMD_DIG_MODE_SS: 15178c2ecf20Sopenharmony_ci fw_cmdmap &= ~FW_FA_CTL; 15188c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 15198c2ecf20Sopenharmony_ci break; 15208c2ecf20Sopenharmony_ci case FW_CMD_PAPE_CONTROL: 15218c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 15228c2ecf20Sopenharmony_ci "[FW CMD] Set PAPE Control\n"); 15238c2ecf20Sopenharmony_ci fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW; 15248c2ecf20Sopenharmony_ci 15258c2ecf20Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 15268c2ecf20Sopenharmony_ci break; 15278c2ecf20Sopenharmony_ci default: 15288c2ecf20Sopenharmony_ci /* Pass to original FW CMD processing callback 15298c2ecf20Sopenharmony_ci * routine. */ 15308c2ecf20Sopenharmony_ci postprocessing = true; 15318c2ecf20Sopenharmony_ci break; 15328c2ecf20Sopenharmony_ci } 15338c2ecf20Sopenharmony_ci } while (false); 15348c2ecf20Sopenharmony_ci 15358c2ecf20Sopenharmony_ci /* We shall post processing these FW CMD if 15368c2ecf20Sopenharmony_ci * variable postprocessing is set. 15378c2ecf20Sopenharmony_ci */ 15388c2ecf20Sopenharmony_ci if (postprocessing && !rtlhal->set_fwcmd_inprogress) { 15398c2ecf20Sopenharmony_ci rtlhal->set_fwcmd_inprogress = true; 15408c2ecf20Sopenharmony_ci /* Update current FW Cmd for callback use. */ 15418c2ecf20Sopenharmony_ci rtlhal->current_fwcmd_io = fw_cmdio; 15428c2ecf20Sopenharmony_ci } else { 15438c2ecf20Sopenharmony_ci return false; 15448c2ecf20Sopenharmony_ci } 15458c2ecf20Sopenharmony_ci 15468c2ecf20Sopenharmony_ci _rtl92s_phy_set_fwcmd_io(hw); 15478c2ecf20Sopenharmony_ci return true; 15488c2ecf20Sopenharmony_ci} 15498c2ecf20Sopenharmony_ci 15508c2ecf20Sopenharmony_cistatic void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw) 15518c2ecf20Sopenharmony_ci{ 15528c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 15538c2ecf20Sopenharmony_ci u32 delay = 100; 15548c2ecf20Sopenharmony_ci u8 regu1; 15558c2ecf20Sopenharmony_ci 15568c2ecf20Sopenharmony_ci regu1 = rtl_read_byte(rtlpriv, 0x554); 15578c2ecf20Sopenharmony_ci while ((regu1 & BIT(5)) && (delay > 0)) { 15588c2ecf20Sopenharmony_ci regu1 = rtl_read_byte(rtlpriv, 0x554); 15598c2ecf20Sopenharmony_ci delay--; 15608c2ecf20Sopenharmony_ci /* We delay only 50us to prevent 15618c2ecf20Sopenharmony_ci * being scheduled out. */ 15628c2ecf20Sopenharmony_ci udelay(50); 15638c2ecf20Sopenharmony_ci } 15648c2ecf20Sopenharmony_ci} 15658c2ecf20Sopenharmony_ci 15668c2ecf20Sopenharmony_civoid rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw) 15678c2ecf20Sopenharmony_ci{ 15688c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 15698c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 15708c2ecf20Sopenharmony_ci 15718c2ecf20Sopenharmony_ci /* The way to be capable to switch clock request 15728c2ecf20Sopenharmony_ci * when the PG setting does not support clock request. 15738c2ecf20Sopenharmony_ci * This is the backdoor solution to switch clock 15748c2ecf20Sopenharmony_ci * request before ASPM or D3. */ 15758c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, 0x540, 0x73c11); 15768c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, 0x548, 0x2407c); 15778c2ecf20Sopenharmony_ci 15788c2ecf20Sopenharmony_ci /* Switch EPHY parameter!!!! */ 15798c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, 0x550, 0x1000); 15808c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x554, 0x20); 15818c2ecf20Sopenharmony_ci _rtl92s_phy_check_ephy_switchready(hw); 15828c2ecf20Sopenharmony_ci 15838c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, 0x550, 0xa0eb); 15848c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x554, 0x3e); 15858c2ecf20Sopenharmony_ci _rtl92s_phy_check_ephy_switchready(hw); 15868c2ecf20Sopenharmony_ci 15878c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, 0x550, 0xff80); 15888c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x554, 0x39); 15898c2ecf20Sopenharmony_ci _rtl92s_phy_check_ephy_switchready(hw); 15908c2ecf20Sopenharmony_ci 15918c2ecf20Sopenharmony_ci /* Delay L1 enter time */ 15928c2ecf20Sopenharmony_ci if (ppsc->support_aspm && !ppsc->support_backdoor) 15938c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x560, 0x40); 15948c2ecf20Sopenharmony_ci else 15958c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x560, 0x00); 15968c2ecf20Sopenharmony_ci 15978c2ecf20Sopenharmony_ci} 15988c2ecf20Sopenharmony_ci 15998c2ecf20Sopenharmony_civoid rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval) 16008c2ecf20Sopenharmony_ci{ 16018c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 16028c2ecf20Sopenharmony_ci u32 new_bcn_num = 0; 16038c2ecf20Sopenharmony_ci 16048c2ecf20Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) >= 0x33) { 16058c2ecf20Sopenharmony_ci /* Fw v.51 and later. */ 16068c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | 16078c2ecf20Sopenharmony_ci (beaconinterval << 8)); 16088c2ecf20Sopenharmony_ci } else { 16098c2ecf20Sopenharmony_ci new_bcn_num = beaconinterval * 32 - 64; 16108c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM3 + 4, new_bcn_num); 16118c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, WFM3, 0xB026007C); 16128c2ecf20Sopenharmony_ci } 16138c2ecf20Sopenharmony_ci} 1614