162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2012 Realtek Corporation.*/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "../wifi.h" 562306a36Sopenharmony_ci#include "../pci.h" 662306a36Sopenharmony_ci#include "../ps.h" 762306a36Sopenharmony_ci#include "../core.h" 862306a36Sopenharmony_ci#include "reg.h" 962306a36Sopenharmony_ci#include "def.h" 1062306a36Sopenharmony_ci#include "phy.h" 1162306a36Sopenharmony_ci#include "rf.h" 1262306a36Sopenharmony_ci#include "dm.h" 1362306a36Sopenharmony_ci#include "fw.h" 1462306a36Sopenharmony_ci#include "hw.h" 1562306a36Sopenharmony_ci#include "table.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ciu32 rtl92s_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) 1862306a36Sopenharmony_ci{ 1962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2062306a36Sopenharmony_ci u32 returnvalue = 0, originalvalue, bitshift; 2162306a36Sopenharmony_ci 2262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", 2362306a36Sopenharmony_ci regaddr, bitmask); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci originalvalue = rtl_read_dword(rtlpriv, regaddr); 2662306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 2762306a36Sopenharmony_ci returnvalue = (originalvalue & bitmask) >> bitshift; 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "BBR MASK=0x%x Addr[0x%x]=0x%x\n", 3062306a36Sopenharmony_ci bitmask, regaddr, originalvalue); 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci return returnvalue; 3362306a36Sopenharmony_ci 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_civoid rtl92s_phy_set_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask, 3762306a36Sopenharmony_ci u32 data) 3862306a36Sopenharmony_ci{ 3962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4062306a36Sopenharmony_ci u32 originalvalue, bitshift; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 4362306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x)\n", 4462306a36Sopenharmony_ci regaddr, bitmask, data); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci if (bitmask != MASKDWORD) { 4762306a36Sopenharmony_ci originalvalue = rtl_read_dword(rtlpriv, regaddr); 4862306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 4962306a36Sopenharmony_ci data = ((originalvalue & (~bitmask)) | (data << bitshift)); 5062306a36Sopenharmony_ci } 5162306a36Sopenharmony_ci 5262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, regaddr, data); 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 5562306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x)\n", 5662306a36Sopenharmony_ci regaddr, bitmask, data); 5762306a36Sopenharmony_ci 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic u32 _rtl92s_phy_rf_serial_read(struct ieee80211_hw *hw, 6162306a36Sopenharmony_ci enum radio_path rfpath, u32 offset) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 6662306a36Sopenharmony_ci struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 6762306a36Sopenharmony_ci u32 newoffset; 6862306a36Sopenharmony_ci u32 tmplong, tmplong2; 6962306a36Sopenharmony_ci u8 rfpi_enable = 0; 7062306a36Sopenharmony_ci u32 retvalue = 0; 7162306a36Sopenharmony_ci 7262306a36Sopenharmony_ci offset &= 0x3f; 7362306a36Sopenharmony_ci newoffset = offset; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); 7662306a36Sopenharmony_ci 7762306a36Sopenharmony_ci if (rfpath == RF90_PATH_A) 7862306a36Sopenharmony_ci tmplong2 = tmplong; 7962306a36Sopenharmony_ci else 8062306a36Sopenharmony_ci tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci tmplong2 = (tmplong2 & (~BLSSI_READADDRESS)) | (newoffset << 23) | 8362306a36Sopenharmony_ci BLSSI_READEDGE; 8462306a36Sopenharmony_ci 8562306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, 8662306a36Sopenharmony_ci tmplong & (~BLSSI_READEDGE)); 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci mdelay(1); 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); 9162306a36Sopenharmony_ci mdelay(1); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, tmplong | 9462306a36Sopenharmony_ci BLSSI_READEDGE); 9562306a36Sopenharmony_ci mdelay(1); 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci if (rfpath == RF90_PATH_A) 9862306a36Sopenharmony_ci rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, 9962306a36Sopenharmony_ci BIT(8)); 10062306a36Sopenharmony_ci else if (rfpath == RF90_PATH_B) 10162306a36Sopenharmony_ci rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, 10262306a36Sopenharmony_ci BIT(8)); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci if (rfpi_enable) 10562306a36Sopenharmony_ci retvalue = rtl_get_bbreg(hw, pphyreg->rf_rbpi, 10662306a36Sopenharmony_ci BLSSI_READBACK_DATA); 10762306a36Sopenharmony_ci else 10862306a36Sopenharmony_ci retvalue = rtl_get_bbreg(hw, pphyreg->rf_rb, 10962306a36Sopenharmony_ci BLSSI_READBACK_DATA); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", 11262306a36Sopenharmony_ci rfpath, pphyreg->rf_rb, retvalue); 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci return retvalue; 11562306a36Sopenharmony_ci 11662306a36Sopenharmony_ci} 11762306a36Sopenharmony_ci 11862306a36Sopenharmony_cistatic void _rtl92s_phy_rf_serial_write(struct ieee80211_hw *hw, 11962306a36Sopenharmony_ci enum radio_path rfpath, u32 offset, 12062306a36Sopenharmony_ci u32 data) 12162306a36Sopenharmony_ci{ 12262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 12362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 12462306a36Sopenharmony_ci struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 12562306a36Sopenharmony_ci u32 data_and_addr = 0; 12662306a36Sopenharmony_ci u32 newoffset; 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci offset &= 0x3f; 12962306a36Sopenharmony_ci newoffset = offset; 13062306a36Sopenharmony_ci 13162306a36Sopenharmony_ci data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; 13262306a36Sopenharmony_ci rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); 13362306a36Sopenharmony_ci 13462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", 13562306a36Sopenharmony_ci rfpath, pphyreg->rf3wire_offset, data_and_addr); 13662306a36Sopenharmony_ci} 13762306a36Sopenharmony_ci 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ciu32 rtl92s_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, 14062306a36Sopenharmony_ci u32 regaddr, u32 bitmask) 14162306a36Sopenharmony_ci{ 14262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14362306a36Sopenharmony_ci u32 original_value, readback_value, bitshift; 14462306a36Sopenharmony_ci 14562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 14662306a36Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", 14762306a36Sopenharmony_ci regaddr, rfpath, bitmask); 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 15062306a36Sopenharmony_ci 15162306a36Sopenharmony_ci original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, regaddr); 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 15462306a36Sopenharmony_ci readback_value = (original_value & bitmask) >> bitshift; 15562306a36Sopenharmony_ci 15662306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 15962306a36Sopenharmony_ci "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", 16062306a36Sopenharmony_ci regaddr, rfpath, bitmask, original_value); 16162306a36Sopenharmony_ci 16262306a36Sopenharmony_ci return readback_value; 16362306a36Sopenharmony_ci} 16462306a36Sopenharmony_ci 16562306a36Sopenharmony_civoid rtl92s_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, 16662306a36Sopenharmony_ci u32 regaddr, u32 bitmask, u32 data) 16762306a36Sopenharmony_ci{ 16862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 16962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 17062306a36Sopenharmony_ci u32 original_value, bitshift; 17162306a36Sopenharmony_ci 17262306a36Sopenharmony_ci if (!((rtlphy->rf_pathmap >> rfpath) & 0x1)) 17362306a36Sopenharmony_ci return; 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 17662306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 17762306a36Sopenharmony_ci regaddr, bitmask, data, rfpath); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_lock); 18062306a36Sopenharmony_ci 18162306a36Sopenharmony_ci if (bitmask != RFREG_OFFSET_MASK) { 18262306a36Sopenharmony_ci original_value = _rtl92s_phy_rf_serial_read(hw, rfpath, 18362306a36Sopenharmony_ci regaddr); 18462306a36Sopenharmony_ci bitshift = calculate_bit_shift(bitmask); 18562306a36Sopenharmony_ci data = ((original_value & (~bitmask)) | (data << bitshift)); 18662306a36Sopenharmony_ci } 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci _rtl92s_phy_rf_serial_write(hw, rfpath, regaddr, data); 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_lock); 19162306a36Sopenharmony_ci 19262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE, 19362306a36Sopenharmony_ci "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 19462306a36Sopenharmony_ci regaddr, bitmask, data, rfpath); 19562306a36Sopenharmony_ci 19662306a36Sopenharmony_ci} 19762306a36Sopenharmony_ci 19862306a36Sopenharmony_civoid rtl92s_phy_scan_operation_backup(struct ieee80211_hw *hw, 19962306a36Sopenharmony_ci u8 operation) 20062306a36Sopenharmony_ci{ 20162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 20262306a36Sopenharmony_ci 20362306a36Sopenharmony_ci if (!is_hal_stop(rtlhal)) { 20462306a36Sopenharmony_ci switch (operation) { 20562306a36Sopenharmony_ci case SCAN_OPT_BACKUP: 20662306a36Sopenharmony_ci rtl92s_phy_set_fw_cmd(hw, FW_CMD_PAUSE_DM_BY_SCAN); 20762306a36Sopenharmony_ci break; 20862306a36Sopenharmony_ci case SCAN_OPT_RESTORE: 20962306a36Sopenharmony_ci rtl92s_phy_set_fw_cmd(hw, FW_CMD_RESUME_DM_BY_SCAN); 21062306a36Sopenharmony_ci break; 21162306a36Sopenharmony_ci default: 21262306a36Sopenharmony_ci pr_err("Unknown operation\n"); 21362306a36Sopenharmony_ci break; 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci} 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_civoid rtl92s_phy_set_bw_mode(struct ieee80211_hw *hw, 21962306a36Sopenharmony_ci enum nl80211_channel_type ch_type) 22062306a36Sopenharmony_ci{ 22162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 22262306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 22362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 22462306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 22562306a36Sopenharmony_ci u8 reg_bw_opmode; 22662306a36Sopenharmony_ci 22762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", 22862306a36Sopenharmony_ci rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? 22962306a36Sopenharmony_ci "20MHz" : "40MHz"); 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 23262306a36Sopenharmony_ci return; 23362306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) 23462306a36Sopenharmony_ci return; 23562306a36Sopenharmony_ci 23662306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = true; 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci reg_bw_opmode = rtl_read_byte(rtlpriv, BW_OPMODE); 23962306a36Sopenharmony_ci /* dummy read */ 24062306a36Sopenharmony_ci rtl_read_byte(rtlpriv, RRSR + 2); 24162306a36Sopenharmony_ci 24262306a36Sopenharmony_ci switch (rtlphy->current_chan_bw) { 24362306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 24462306a36Sopenharmony_ci reg_bw_opmode |= BW_OPMODE_20MHZ; 24562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); 24662306a36Sopenharmony_ci break; 24762306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 24862306a36Sopenharmony_ci reg_bw_opmode &= ~BW_OPMODE_20MHZ; 24962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); 25062306a36Sopenharmony_ci break; 25162306a36Sopenharmony_ci default: 25262306a36Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 25362306a36Sopenharmony_ci rtlphy->current_chan_bw); 25462306a36Sopenharmony_ci break; 25562306a36Sopenharmony_ci } 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci switch (rtlphy->current_chan_bw) { 25862306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20: 25962306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); 26062306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci if (rtlhal->version >= VERSION_8192S_BCUT) 26362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x58); 26462306a36Sopenharmony_ci break; 26562306a36Sopenharmony_ci case HT_CHANNEL_WIDTH_20_40: 26662306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); 26762306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); 26862306a36Sopenharmony_ci 26962306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, 27062306a36Sopenharmony_ci (mac->cur_40_prime_sc >> 1)); 27162306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci if (rtlhal->version >= VERSION_8192S_BCUT) 27462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RFPGA0_ANALOGPARAMETER2, 0x18); 27562306a36Sopenharmony_ci break; 27662306a36Sopenharmony_ci default: 27762306a36Sopenharmony_ci pr_err("unknown bandwidth: %#X\n", 27862306a36Sopenharmony_ci rtlphy->current_chan_bw); 27962306a36Sopenharmony_ci break; 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci 28262306a36Sopenharmony_ci rtl92s_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); 28362306a36Sopenharmony_ci rtlphy->set_bwmode_inprogress = false; 28462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); 28562306a36Sopenharmony_ci} 28662306a36Sopenharmony_ci 28762306a36Sopenharmony_cistatic bool _rtl92s_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, 28862306a36Sopenharmony_ci u32 cmdtableidx, u32 cmdtablesz, enum swchnlcmd_id cmdid, 28962306a36Sopenharmony_ci u32 para1, u32 para2, u32 msdelay) 29062306a36Sopenharmony_ci{ 29162306a36Sopenharmony_ci struct swchnlcmd *pcmd; 29262306a36Sopenharmony_ci 29362306a36Sopenharmony_ci if (cmdtable == NULL) { 29462306a36Sopenharmony_ci WARN_ONCE(true, "rtl8192se: cmdtable cannot be NULL\n"); 29562306a36Sopenharmony_ci return false; 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci 29862306a36Sopenharmony_ci if (cmdtableidx >= cmdtablesz) 29962306a36Sopenharmony_ci return false; 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci pcmd = cmdtable + cmdtableidx; 30262306a36Sopenharmony_ci pcmd->cmdid = cmdid; 30362306a36Sopenharmony_ci pcmd->para1 = para1; 30462306a36Sopenharmony_ci pcmd->para2 = para2; 30562306a36Sopenharmony_ci pcmd->msdelay = msdelay; 30662306a36Sopenharmony_ci 30762306a36Sopenharmony_ci return true; 30862306a36Sopenharmony_ci} 30962306a36Sopenharmony_ci 31062306a36Sopenharmony_cistatic bool _rtl92s_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 31162306a36Sopenharmony_ci u8 channel, u8 *stage, u8 *step, u32 *delay) 31262306a36Sopenharmony_ci{ 31362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 31462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 31562306a36Sopenharmony_ci struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; 31662306a36Sopenharmony_ci u32 precommoncmdcnt; 31762306a36Sopenharmony_ci struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; 31862306a36Sopenharmony_ci u32 postcommoncmdcnt; 31962306a36Sopenharmony_ci struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; 32062306a36Sopenharmony_ci u32 rfdependcmdcnt; 32162306a36Sopenharmony_ci struct swchnlcmd *currentcmd = NULL; 32262306a36Sopenharmony_ci u8 rfpath; 32362306a36Sopenharmony_ci u8 num_total_rfpath = rtlphy->num_total_rfpath; 32462306a36Sopenharmony_ci 32562306a36Sopenharmony_ci precommoncmdcnt = 0; 32662306a36Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 32762306a36Sopenharmony_ci MAX_PRECMD_CNT, CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); 32862306a36Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 32962306a36Sopenharmony_ci MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); 33062306a36Sopenharmony_ci 33162306a36Sopenharmony_ci postcommoncmdcnt = 0; 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, 33462306a36Sopenharmony_ci MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci rfdependcmdcnt = 0; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci WARN_ONCE((channel < 1 || channel > 14), 33962306a36Sopenharmony_ci "rtl8192se: invalid channel for Zebra: %d\n", channel); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 34262306a36Sopenharmony_ci MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, 34362306a36Sopenharmony_ci RF_CHNLBW, channel, 10); 34462306a36Sopenharmony_ci 34562306a36Sopenharmony_ci _rtl92s_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 34662306a36Sopenharmony_ci MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 0); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci do { 34962306a36Sopenharmony_ci switch (*stage) { 35062306a36Sopenharmony_ci case 0: 35162306a36Sopenharmony_ci currentcmd = &precommoncmd[*step]; 35262306a36Sopenharmony_ci break; 35362306a36Sopenharmony_ci case 1: 35462306a36Sopenharmony_ci currentcmd = &rfdependcmd[*step]; 35562306a36Sopenharmony_ci break; 35662306a36Sopenharmony_ci case 2: 35762306a36Sopenharmony_ci currentcmd = &postcommoncmd[*step]; 35862306a36Sopenharmony_ci break; 35962306a36Sopenharmony_ci default: 36062306a36Sopenharmony_ci return true; 36162306a36Sopenharmony_ci } 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci if (currentcmd->cmdid == CMDID_END) { 36462306a36Sopenharmony_ci if ((*stage) == 2) { 36562306a36Sopenharmony_ci return true; 36662306a36Sopenharmony_ci } else { 36762306a36Sopenharmony_ci (*stage)++; 36862306a36Sopenharmony_ci (*step) = 0; 36962306a36Sopenharmony_ci continue; 37062306a36Sopenharmony_ci } 37162306a36Sopenharmony_ci } 37262306a36Sopenharmony_ci 37362306a36Sopenharmony_ci switch (currentcmd->cmdid) { 37462306a36Sopenharmony_ci case CMDID_SET_TXPOWEROWER_LEVEL: 37562306a36Sopenharmony_ci rtl92s_phy_set_txpower(hw, channel); 37662306a36Sopenharmony_ci break; 37762306a36Sopenharmony_ci case CMDID_WRITEPORT_ULONG: 37862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, currentcmd->para1, 37962306a36Sopenharmony_ci currentcmd->para2); 38062306a36Sopenharmony_ci break; 38162306a36Sopenharmony_ci case CMDID_WRITEPORT_USHORT: 38262306a36Sopenharmony_ci rtl_write_word(rtlpriv, currentcmd->para1, 38362306a36Sopenharmony_ci (u16)currentcmd->para2); 38462306a36Sopenharmony_ci break; 38562306a36Sopenharmony_ci case CMDID_WRITEPORT_UCHAR: 38662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, currentcmd->para1, 38762306a36Sopenharmony_ci (u8)currentcmd->para2); 38862306a36Sopenharmony_ci break; 38962306a36Sopenharmony_ci case CMDID_RF_WRITEREG: 39062306a36Sopenharmony_ci for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { 39162306a36Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath] = 39262306a36Sopenharmony_ci ((rtlphy->rfreg_chnlval[rfpath] & 39362306a36Sopenharmony_ci 0xfffffc00) | currentcmd->para2); 39462306a36Sopenharmony_ci rtl_set_rfreg(hw, (enum radio_path)rfpath, 39562306a36Sopenharmony_ci currentcmd->para1, 39662306a36Sopenharmony_ci RFREG_OFFSET_MASK, 39762306a36Sopenharmony_ci rtlphy->rfreg_chnlval[rfpath]); 39862306a36Sopenharmony_ci } 39962306a36Sopenharmony_ci break; 40062306a36Sopenharmony_ci default: 40162306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", 40262306a36Sopenharmony_ci currentcmd->cmdid); 40362306a36Sopenharmony_ci break; 40462306a36Sopenharmony_ci } 40562306a36Sopenharmony_ci 40662306a36Sopenharmony_ci break; 40762306a36Sopenharmony_ci } while (true); 40862306a36Sopenharmony_ci 40962306a36Sopenharmony_ci (*delay) = currentcmd->msdelay; 41062306a36Sopenharmony_ci (*step)++; 41162306a36Sopenharmony_ci return false; 41262306a36Sopenharmony_ci} 41362306a36Sopenharmony_ci 41462306a36Sopenharmony_ciu8 rtl92s_phy_sw_chnl(struct ieee80211_hw *hw) 41562306a36Sopenharmony_ci{ 41662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 41762306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 41862306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 41962306a36Sopenharmony_ci u32 delay; 42062306a36Sopenharmony_ci bool ret; 42162306a36Sopenharmony_ci 42262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "switch to channel%d\n", 42362306a36Sopenharmony_ci rtlphy->current_channel); 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci if (rtlphy->sw_chnl_inprogress) 42662306a36Sopenharmony_ci return 0; 42762306a36Sopenharmony_ci 42862306a36Sopenharmony_ci if (rtlphy->set_bwmode_inprogress) 42962306a36Sopenharmony_ci return 0; 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) 43262306a36Sopenharmony_ci return 0; 43362306a36Sopenharmony_ci 43462306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = true; 43562306a36Sopenharmony_ci rtlphy->sw_chnl_stage = 0; 43662306a36Sopenharmony_ci rtlphy->sw_chnl_step = 0; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci do { 43962306a36Sopenharmony_ci if (!rtlphy->sw_chnl_inprogress) 44062306a36Sopenharmony_ci break; 44162306a36Sopenharmony_ci 44262306a36Sopenharmony_ci ret = _rtl92s_phy_sw_chnl_step_by_step(hw, 44362306a36Sopenharmony_ci rtlphy->current_channel, 44462306a36Sopenharmony_ci &rtlphy->sw_chnl_stage, 44562306a36Sopenharmony_ci &rtlphy->sw_chnl_step, &delay); 44662306a36Sopenharmony_ci if (!ret) { 44762306a36Sopenharmony_ci if (delay > 0) 44862306a36Sopenharmony_ci mdelay(delay); 44962306a36Sopenharmony_ci else 45062306a36Sopenharmony_ci continue; 45162306a36Sopenharmony_ci } else { 45262306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 45362306a36Sopenharmony_ci } 45462306a36Sopenharmony_ci break; 45562306a36Sopenharmony_ci } while (true); 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci rtlphy->sw_chnl_inprogress = false; 45862306a36Sopenharmony_ci 45962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci return 1; 46262306a36Sopenharmony_ci} 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_cistatic void _rtl92se_phy_set_rf_sleep(struct ieee80211_hw *hw) 46562306a36Sopenharmony_ci{ 46662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 46762306a36Sopenharmony_ci u8 u1btmp; 46862306a36Sopenharmony_ci 46962306a36Sopenharmony_ci u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL); 47062306a36Sopenharmony_ci u1btmp |= BIT(0); 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp); 47362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0); 47462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, TXPAUSE, 0xFF); 47562306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x57FC); 47662306a36Sopenharmony_ci udelay(100); 47762306a36Sopenharmony_ci 47862306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x77FC); 47962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, PHY_CCA, 0x0); 48062306a36Sopenharmony_ci udelay(10); 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x37FC); 48362306a36Sopenharmony_ci udelay(10); 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x77FC); 48662306a36Sopenharmony_ci udelay(10); 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x57FC); 48962306a36Sopenharmony_ci 49062306a36Sopenharmony_ci /* we should chnge GPIO to input mode 49162306a36Sopenharmony_ci * this will drop away current about 25mA*/ 49262306a36Sopenharmony_ci rtl8192se_gpiobit3_cfg_inputmode(hw); 49362306a36Sopenharmony_ci} 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_cibool rtl92s_phy_set_rf_power_state(struct ieee80211_hw *hw, 49662306a36Sopenharmony_ci enum rf_pwrstate rfpwr_state) 49762306a36Sopenharmony_ci{ 49862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 49962306a36Sopenharmony_ci struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 50062306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 50162306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 50262306a36Sopenharmony_ci bool bresult = true; 50362306a36Sopenharmony_ci u8 i, queue_id; 50462306a36Sopenharmony_ci struct rtl8192_tx_ring *ring = NULL; 50562306a36Sopenharmony_ci 50662306a36Sopenharmony_ci if (rfpwr_state == ppsc->rfpwr_state) 50762306a36Sopenharmony_ci return false; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci switch (rfpwr_state) { 51062306a36Sopenharmony_ci case ERFON:{ 51162306a36Sopenharmony_ci if ((ppsc->rfpwr_state == ERFOFF) && 51262306a36Sopenharmony_ci RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci bool rtstatus; 51562306a36Sopenharmony_ci u32 initializecount = 0; 51662306a36Sopenharmony_ci do { 51762306a36Sopenharmony_ci initializecount++; 51862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 51962306a36Sopenharmony_ci "IPS Set eRf nic enable\n"); 52062306a36Sopenharmony_ci rtstatus = rtl_ps_enable_nic(hw); 52162306a36Sopenharmony_ci } while (!rtstatus && (initializecount < 10)); 52262306a36Sopenharmony_ci 52362306a36Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, 52462306a36Sopenharmony_ci RT_RF_OFF_LEVL_HALT_NIC); 52562306a36Sopenharmony_ci } else { 52662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 52762306a36Sopenharmony_ci "awake, slept:%d ms state_inap:%x\n", 52862306a36Sopenharmony_ci jiffies_to_msecs(jiffies - 52962306a36Sopenharmony_ci ppsc->last_sleep_jiffies), 53062306a36Sopenharmony_ci rtlpriv->psc.state_inap); 53162306a36Sopenharmony_ci ppsc->last_awake_jiffies = jiffies; 53262306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x37FC); 53362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, TXPAUSE, 0x00); 53462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, PHY_CCA, 0x3); 53562306a36Sopenharmony_ci } 53662306a36Sopenharmony_ci 53762306a36Sopenharmony_ci if (mac->link_state == MAC80211_LINKED) 53862306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 53962306a36Sopenharmony_ci LED_CTL_LINK); 54062306a36Sopenharmony_ci else 54162306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 54262306a36Sopenharmony_ci LED_CTL_NO_LINK); 54362306a36Sopenharmony_ci break; 54462306a36Sopenharmony_ci } 54562306a36Sopenharmony_ci case ERFOFF:{ 54662306a36Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { 54762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 54862306a36Sopenharmony_ci "IPS Set eRf nic disable\n"); 54962306a36Sopenharmony_ci rtl_ps_disable_nic(hw); 55062306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 55162306a36Sopenharmony_ci } else { 55262306a36Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) 55362306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 55462306a36Sopenharmony_ci LED_CTL_NO_LINK); 55562306a36Sopenharmony_ci else 55662306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, 55762306a36Sopenharmony_ci LED_CTL_POWER_OFF); 55862306a36Sopenharmony_ci } 55962306a36Sopenharmony_ci break; 56062306a36Sopenharmony_ci } 56162306a36Sopenharmony_ci case ERFSLEEP: 56262306a36Sopenharmony_ci if (ppsc->rfpwr_state == ERFOFF) 56362306a36Sopenharmony_ci return false; 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_ci for (queue_id = 0, i = 0; 56662306a36Sopenharmony_ci queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 56762306a36Sopenharmony_ci ring = &pcipriv->dev.tx_ring[queue_id]; 56862306a36Sopenharmony_ci if (skb_queue_len(&ring->queue) == 0 || 56962306a36Sopenharmony_ci queue_id == BEACON_QUEUE) { 57062306a36Sopenharmony_ci queue_id++; 57162306a36Sopenharmony_ci continue; 57262306a36Sopenharmony_ci } else { 57362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 57462306a36Sopenharmony_ci "eRf Off/Sleep: %d times TcbBusyQueue[%d] = %d before doze!\n", 57562306a36Sopenharmony_ci i + 1, queue_id, 57662306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_ci udelay(10); 57962306a36Sopenharmony_ci i++; 58062306a36Sopenharmony_ci } 58162306a36Sopenharmony_ci 58262306a36Sopenharmony_ci if (i >= MAX_DOZE_WAITING_TIMES_9x) { 58362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 58462306a36Sopenharmony_ci "ERFOFF: %d times TcbBusyQueue[%d] = %d !\n", 58562306a36Sopenharmony_ci MAX_DOZE_WAITING_TIMES_9x, 58662306a36Sopenharmony_ci queue_id, 58762306a36Sopenharmony_ci skb_queue_len(&ring->queue)); 58862306a36Sopenharmony_ci break; 58962306a36Sopenharmony_ci } 59062306a36Sopenharmony_ci } 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 59362306a36Sopenharmony_ci "Set ERFSLEEP awaked:%d ms\n", 59462306a36Sopenharmony_ci jiffies_to_msecs(jiffies - 59562306a36Sopenharmony_ci ppsc->last_awake_jiffies)); 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 59862306a36Sopenharmony_ci "sleep awaked:%d ms state_inap:%x\n", 59962306a36Sopenharmony_ci jiffies_to_msecs(jiffies - 60062306a36Sopenharmony_ci ppsc->last_awake_jiffies), 60162306a36Sopenharmony_ci rtlpriv->psc.state_inap); 60262306a36Sopenharmony_ci ppsc->last_sleep_jiffies = jiffies; 60362306a36Sopenharmony_ci _rtl92se_phy_set_rf_sleep(hw); 60462306a36Sopenharmony_ci break; 60562306a36Sopenharmony_ci default: 60662306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", 60762306a36Sopenharmony_ci rfpwr_state); 60862306a36Sopenharmony_ci bresult = false; 60962306a36Sopenharmony_ci break; 61062306a36Sopenharmony_ci } 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci if (bresult) 61362306a36Sopenharmony_ci ppsc->rfpwr_state = rfpwr_state; 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci return bresult; 61662306a36Sopenharmony_ci} 61762306a36Sopenharmony_ci 61862306a36Sopenharmony_cistatic bool _rtl92s_phy_config_rfpa_bias_current(struct ieee80211_hw *hw, 61962306a36Sopenharmony_ci enum radio_path rfpath) 62062306a36Sopenharmony_ci{ 62162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 62262306a36Sopenharmony_ci bool rtstatus = true; 62362306a36Sopenharmony_ci u32 tmpval = 0; 62462306a36Sopenharmony_ci 62562306a36Sopenharmony_ci /* If inferiority IC, we have to increase the PA bias current */ 62662306a36Sopenharmony_ci if (rtlhal->ic_class != IC_INFERIORITY_A) { 62762306a36Sopenharmony_ci tmpval = rtl92s_phy_query_rf_reg(hw, rfpath, RF_IPA, 0xf); 62862306a36Sopenharmony_ci rtl92s_phy_set_rf_reg(hw, rfpath, RF_IPA, 0xf, tmpval + 1); 62962306a36Sopenharmony_ci } 63062306a36Sopenharmony_ci 63162306a36Sopenharmony_ci return rtstatus; 63262306a36Sopenharmony_ci} 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_cistatic void _rtl92s_store_pwrindex_diffrate_offset(struct ieee80211_hw *hw, 63562306a36Sopenharmony_ci u32 reg_addr, u32 bitmask, u32 data) 63662306a36Sopenharmony_ci{ 63762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 63862306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 63962306a36Sopenharmony_ci int index; 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci if (reg_addr == RTXAGC_RATE18_06) 64262306a36Sopenharmony_ci index = 0; 64362306a36Sopenharmony_ci else if (reg_addr == RTXAGC_RATE54_24) 64462306a36Sopenharmony_ci index = 1; 64562306a36Sopenharmony_ci else if (reg_addr == RTXAGC_CCK_MCS32) 64662306a36Sopenharmony_ci index = 6; 64762306a36Sopenharmony_ci else if (reg_addr == RTXAGC_MCS03_MCS00) 64862306a36Sopenharmony_ci index = 2; 64962306a36Sopenharmony_ci else if (reg_addr == RTXAGC_MCS07_MCS04) 65062306a36Sopenharmony_ci index = 3; 65162306a36Sopenharmony_ci else if (reg_addr == RTXAGC_MCS11_MCS08) 65262306a36Sopenharmony_ci index = 4; 65362306a36Sopenharmony_ci else if (reg_addr == RTXAGC_MCS15_MCS12) 65462306a36Sopenharmony_ci index = 5; 65562306a36Sopenharmony_ci else 65662306a36Sopenharmony_ci return; 65762306a36Sopenharmony_ci 65862306a36Sopenharmony_ci rtlphy->mcs_offset[rtlphy->pwrgroup_cnt][index] = data; 65962306a36Sopenharmony_ci if (index == 5) 66062306a36Sopenharmony_ci rtlphy->pwrgroup_cnt++; 66162306a36Sopenharmony_ci} 66262306a36Sopenharmony_ci 66362306a36Sopenharmony_cistatic void _rtl92s_phy_init_register_definition(struct ieee80211_hw *hw) 66462306a36Sopenharmony_ci{ 66562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 66662306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci /*RF Interface Sowrtware Control */ 66962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; 67062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; 67162306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; 67262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_ci /* RF Interface Readback Value */ 67562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; 67662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; 67762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; 67862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci /* RF Interface Output (and Enable) */ 68162306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; 68262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; 68362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfo = RFPGA0_XC_RFINTERFACEOE; 68462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfo = RFPGA0_XD_RFINTERFACEOE; 68562306a36Sopenharmony_ci 68662306a36Sopenharmony_ci /* RF Interface (Output and) Enable */ 68762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; 68862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; 68962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfintfe = RFPGA0_XC_RFINTERFACEOE; 69062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfintfe = RFPGA0_XD_RFINTERFACEOE; 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ci /* Addr of LSSI. Wirte RF register by driver */ 69362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = 69462306a36Sopenharmony_ci RFPGA0_XA_LSSIPARAMETER; 69562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = 69662306a36Sopenharmony_ci RFPGA0_XB_LSSIPARAMETER; 69762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rf3wire_offset = 69862306a36Sopenharmony_ci RFPGA0_XC_LSSIPARAMETER; 69962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rf3wire_offset = 70062306a36Sopenharmony_ci RFPGA0_XD_LSSIPARAMETER; 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci /* RF parameter */ 70362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = RFPGA0_XAB_RFPARAMETER; 70462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = RFPGA0_XAB_RFPARAMETER; 70562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = RFPGA0_XCD_RFPARAMETER; 70662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = RFPGA0_XCD_RFPARAMETER; 70762306a36Sopenharmony_ci 70862306a36Sopenharmony_ci /* Tx AGC Gain Stage (same for all path. Should we remove this?) */ 70962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; 71062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; 71162306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; 71262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; 71362306a36Sopenharmony_ci 71462306a36Sopenharmony_ci /* Tranceiver A~D HSSI Parameter-1 */ 71562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; 71662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; 71762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para1 = RFPGA0_XC_HSSIPARAMETER1; 71862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para1 = RFPGA0_XD_HSSIPARAMETER1; 71962306a36Sopenharmony_ci 72062306a36Sopenharmony_ci /* Tranceiver A~D HSSI Parameter-2 */ 72162306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; 72262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; 72362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfhssi_para2 = RFPGA0_XC_HSSIPARAMETER2; 72462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfhssi_para2 = RFPGA0_XD_HSSIPARAMETER2; 72562306a36Sopenharmony_ci 72662306a36Sopenharmony_ci /* RF switch Control */ 72762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; 72862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfsw_ctrl = RFPGA0_XAB_SWITCHCONTROL; 72962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; 73062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfsw_ctrl = RFPGA0_XCD_SWITCHCONTROL; 73162306a36Sopenharmony_ci 73262306a36Sopenharmony_ci /* AGC control 1 */ 73362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; 73462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; 73562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; 73662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci /* AGC control 2 */ 73962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; 74062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; 74162306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; 74262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_ci /* RX AFE control 1 */ 74562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbal = ROFDM0_XARXIQIMBALANCE; 74662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbal = ROFDM0_XBRXIQIMBALANCE; 74762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbal = ROFDM0_XCRXIQIMBALANCE; 74862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbal = ROFDM0_XDRXIQIMBALANCE; 74962306a36Sopenharmony_ci 75062306a36Sopenharmony_ci /* RX AFE control 1 */ 75162306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; 75262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; 75362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; 75462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; 75562306a36Sopenharmony_ci 75662306a36Sopenharmony_ci /* Tx AFE control 1 */ 75762306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbal = ROFDM0_XATXIQIMBALANCE; 75862306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbal = ROFDM0_XBTXIQIMBALANCE; 75962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbal = ROFDM0_XCTXIQIMBALANCE; 76062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbal = ROFDM0_XDTXIQIMBALANCE; 76162306a36Sopenharmony_ci 76262306a36Sopenharmony_ci /* Tx AFE control 2 */ 76362306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; 76462306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; 76562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; 76662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; 76762306a36Sopenharmony_ci 76862306a36Sopenharmony_ci /* Tranceiver LSSI Readback */ 76962306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RFPGA0_XA_LSSIREADBACK; 77062306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RFPGA0_XB_LSSIREADBACK; 77162306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_C].rf_rb = RFPGA0_XC_LSSIREADBACK; 77262306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_D].rf_rb = RFPGA0_XD_LSSIREADBACK; 77362306a36Sopenharmony_ci 77462306a36Sopenharmony_ci /* Tranceiver LSSI Readback PI mode */ 77562306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = TRANSCEIVERA_HSPI_READBACK; 77662306a36Sopenharmony_ci rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = TRANSCEIVERB_HSPI_READBACK; 77762306a36Sopenharmony_ci} 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci 78062306a36Sopenharmony_cistatic bool _rtl92s_phy_config_bb(struct ieee80211_hw *hw, u8 configtype) 78162306a36Sopenharmony_ci{ 78262306a36Sopenharmony_ci int i; 78362306a36Sopenharmony_ci u32 *phy_reg_table; 78462306a36Sopenharmony_ci u32 *agc_table; 78562306a36Sopenharmony_ci u16 phy_reg_len, agc_len; 78662306a36Sopenharmony_ci 78762306a36Sopenharmony_ci agc_len = AGCTAB_ARRAYLENGTH; 78862306a36Sopenharmony_ci agc_table = rtl8192seagctab_array; 78962306a36Sopenharmony_ci /* Default RF_type: 2T2R */ 79062306a36Sopenharmony_ci phy_reg_len = PHY_REG_2T2RARRAYLENGTH; 79162306a36Sopenharmony_ci phy_reg_table = rtl8192sephy_reg_2t2rarray; 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 79462306a36Sopenharmony_ci for (i = 0; i < phy_reg_len; i = i + 2) { 79562306a36Sopenharmony_ci rtl_addr_delay(phy_reg_table[i]); 79662306a36Sopenharmony_ci 79762306a36Sopenharmony_ci /* Add delay for ECS T20 & LG malow platform, */ 79862306a36Sopenharmony_ci udelay(1); 79962306a36Sopenharmony_ci 80062306a36Sopenharmony_ci rtl92s_phy_set_bb_reg(hw, phy_reg_table[i], MASKDWORD, 80162306a36Sopenharmony_ci phy_reg_table[i + 1]); 80262306a36Sopenharmony_ci } 80362306a36Sopenharmony_ci } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { 80462306a36Sopenharmony_ci for (i = 0; i < agc_len; i = i + 2) { 80562306a36Sopenharmony_ci rtl92s_phy_set_bb_reg(hw, agc_table[i], MASKDWORD, 80662306a36Sopenharmony_ci agc_table[i + 1]); 80762306a36Sopenharmony_ci 80862306a36Sopenharmony_ci /* Add delay for ECS T20 & LG malow platform */ 80962306a36Sopenharmony_ci udelay(1); 81062306a36Sopenharmony_ci } 81162306a36Sopenharmony_ci } 81262306a36Sopenharmony_ci 81362306a36Sopenharmony_ci return true; 81462306a36Sopenharmony_ci} 81562306a36Sopenharmony_ci 81662306a36Sopenharmony_cistatic bool _rtl92s_phy_set_bb_to_diff_rf(struct ieee80211_hw *hw, 81762306a36Sopenharmony_ci u8 configtype) 81862306a36Sopenharmony_ci{ 81962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 82062306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 82162306a36Sopenharmony_ci u32 *phy_regarray2xtxr_table; 82262306a36Sopenharmony_ci u16 phy_regarray2xtxr_len; 82362306a36Sopenharmony_ci int i; 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T1R) { 82662306a36Sopenharmony_ci phy_regarray2xtxr_table = rtl8192sephy_changeto_1t1rarray; 82762306a36Sopenharmony_ci phy_regarray2xtxr_len = PHY_CHANGETO_1T1RARRAYLENGTH; 82862306a36Sopenharmony_ci } else if (rtlphy->rf_type == RF_1T2R) { 82962306a36Sopenharmony_ci phy_regarray2xtxr_table = rtl8192sephy_changeto_1t2rarray; 83062306a36Sopenharmony_ci phy_regarray2xtxr_len = PHY_CHANGETO_1T2RARRAYLENGTH; 83162306a36Sopenharmony_ci } else { 83262306a36Sopenharmony_ci return false; 83362306a36Sopenharmony_ci } 83462306a36Sopenharmony_ci 83562306a36Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 83662306a36Sopenharmony_ci for (i = 0; i < phy_regarray2xtxr_len; i = i + 3) { 83762306a36Sopenharmony_ci rtl_addr_delay(phy_regarray2xtxr_table[i]); 83862306a36Sopenharmony_ci 83962306a36Sopenharmony_ci rtl92s_phy_set_bb_reg(hw, phy_regarray2xtxr_table[i], 84062306a36Sopenharmony_ci phy_regarray2xtxr_table[i + 1], 84162306a36Sopenharmony_ci phy_regarray2xtxr_table[i + 2]); 84262306a36Sopenharmony_ci } 84362306a36Sopenharmony_ci } 84462306a36Sopenharmony_ci 84562306a36Sopenharmony_ci return true; 84662306a36Sopenharmony_ci} 84762306a36Sopenharmony_ci 84862306a36Sopenharmony_cistatic bool _rtl92s_phy_config_bb_with_pg(struct ieee80211_hw *hw, 84962306a36Sopenharmony_ci u8 configtype) 85062306a36Sopenharmony_ci{ 85162306a36Sopenharmony_ci int i; 85262306a36Sopenharmony_ci u32 *phy_table_pg; 85362306a36Sopenharmony_ci u16 phy_pg_len; 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci phy_pg_len = PHY_REG_ARRAY_PGLENGTH; 85662306a36Sopenharmony_ci phy_table_pg = rtl8192sephy_reg_array_pg; 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci if (configtype == BASEBAND_CONFIG_PHY_REG) { 85962306a36Sopenharmony_ci for (i = 0; i < phy_pg_len; i = i + 3) { 86062306a36Sopenharmony_ci rtl_addr_delay(phy_table_pg[i]); 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci _rtl92s_store_pwrindex_diffrate_offset(hw, 86362306a36Sopenharmony_ci phy_table_pg[i], 86462306a36Sopenharmony_ci phy_table_pg[i + 1], 86562306a36Sopenharmony_ci phy_table_pg[i + 2]); 86662306a36Sopenharmony_ci rtl92s_phy_set_bb_reg(hw, phy_table_pg[i], 86762306a36Sopenharmony_ci phy_table_pg[i + 1], 86862306a36Sopenharmony_ci phy_table_pg[i + 2]); 86962306a36Sopenharmony_ci } 87062306a36Sopenharmony_ci } 87162306a36Sopenharmony_ci 87262306a36Sopenharmony_ci return true; 87362306a36Sopenharmony_ci} 87462306a36Sopenharmony_ci 87562306a36Sopenharmony_cistatic bool _rtl92s_phy_bb_config_parafile(struct ieee80211_hw *hw) 87662306a36Sopenharmony_ci{ 87762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 87862306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 87962306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 88062306a36Sopenharmony_ci bool rtstatus = true; 88162306a36Sopenharmony_ci 88262306a36Sopenharmony_ci /* 1. Read PHY_REG.TXT BB INIT!! */ 88362306a36Sopenharmony_ci /* We will separate as 1T1R/1T2R/1T2R_GREEN/2T2R */ 88462306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_2T2R || 88562306a36Sopenharmony_ci rtlphy->rf_type == RF_1T1R || rtlphy->rf_type == RF_2T2R_GREEN) { 88662306a36Sopenharmony_ci rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_PHY_REG); 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ci if (rtlphy->rf_type != RF_2T2R && 88962306a36Sopenharmony_ci rtlphy->rf_type != RF_2T2R_GREEN) 89062306a36Sopenharmony_ci /* so we should reconfig BB reg with the right 89162306a36Sopenharmony_ci * PHY parameters. */ 89262306a36Sopenharmony_ci rtstatus = _rtl92s_phy_set_bb_to_diff_rf(hw, 89362306a36Sopenharmony_ci BASEBAND_CONFIG_PHY_REG); 89462306a36Sopenharmony_ci } else { 89562306a36Sopenharmony_ci rtstatus = false; 89662306a36Sopenharmony_ci } 89762306a36Sopenharmony_ci 89862306a36Sopenharmony_ci if (!rtstatus) { 89962306a36Sopenharmony_ci pr_err("Write BB Reg Fail!!\n"); 90062306a36Sopenharmony_ci goto phy_bb8190_config_parafile_fail; 90162306a36Sopenharmony_ci } 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_ci /* 2. If EEPROM or EFUSE autoload OK, We must config by 90462306a36Sopenharmony_ci * PHY_REG_PG.txt */ 90562306a36Sopenharmony_ci if (rtlefuse->autoload_failflag == false) { 90662306a36Sopenharmony_ci rtlphy->pwrgroup_cnt = 0; 90762306a36Sopenharmony_ci 90862306a36Sopenharmony_ci rtstatus = _rtl92s_phy_config_bb_with_pg(hw, 90962306a36Sopenharmony_ci BASEBAND_CONFIG_PHY_REG); 91062306a36Sopenharmony_ci } 91162306a36Sopenharmony_ci if (!rtstatus) { 91262306a36Sopenharmony_ci pr_err("_rtl92s_phy_bb_config_parafile(): BB_PG Reg Fail!!\n"); 91362306a36Sopenharmony_ci goto phy_bb8190_config_parafile_fail; 91462306a36Sopenharmony_ci } 91562306a36Sopenharmony_ci 91662306a36Sopenharmony_ci /* 3. BB AGC table Initialization */ 91762306a36Sopenharmony_ci rtstatus = _rtl92s_phy_config_bb(hw, BASEBAND_CONFIG_AGC_TAB); 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ci if (!rtstatus) { 92062306a36Sopenharmony_ci pr_err("%s(): AGC Table Fail\n", __func__); 92162306a36Sopenharmony_ci goto phy_bb8190_config_parafile_fail; 92262306a36Sopenharmony_ci } 92362306a36Sopenharmony_ci 92462306a36Sopenharmony_ci /* Check if the CCK HighPower is turned ON. */ 92562306a36Sopenharmony_ci /* This is used to calculate PWDB. */ 92662306a36Sopenharmony_ci rtlphy->cck_high_power = (bool)(rtl92s_phy_query_bb_reg(hw, 92762306a36Sopenharmony_ci RFPGA0_XA_HSSIPARAMETER2, 0x200)); 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_ciphy_bb8190_config_parafile_fail: 93062306a36Sopenharmony_ci return rtstatus; 93162306a36Sopenharmony_ci} 93262306a36Sopenharmony_ci 93362306a36Sopenharmony_ciu8 rtl92s_phy_config_rf(struct ieee80211_hw *hw, enum radio_path rfpath) 93462306a36Sopenharmony_ci{ 93562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 93662306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 93762306a36Sopenharmony_ci int i; 93862306a36Sopenharmony_ci bool rtstatus = true; 93962306a36Sopenharmony_ci u32 *radio_a_table; 94062306a36Sopenharmony_ci u32 *radio_b_table; 94162306a36Sopenharmony_ci u16 radio_a_tblen, radio_b_tblen; 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci radio_a_tblen = RADIOA_1T_ARRAYLENGTH; 94462306a36Sopenharmony_ci radio_a_table = rtl8192seradioa_1t_array; 94562306a36Sopenharmony_ci 94662306a36Sopenharmony_ci /* Using Green mode array table for RF_2T2R_GREEN */ 94762306a36Sopenharmony_ci if (rtlphy->rf_type == RF_2T2R_GREEN) { 94862306a36Sopenharmony_ci radio_b_table = rtl8192seradiob_gm_array; 94962306a36Sopenharmony_ci radio_b_tblen = RADIOB_GM_ARRAYLENGTH; 95062306a36Sopenharmony_ci } else { 95162306a36Sopenharmony_ci radio_b_table = rtl8192seradiob_array; 95262306a36Sopenharmony_ci radio_b_tblen = RADIOB_ARRAYLENGTH; 95362306a36Sopenharmony_ci } 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); 95662306a36Sopenharmony_ci rtstatus = true; 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci switch (rfpath) { 95962306a36Sopenharmony_ci case RF90_PATH_A: 96062306a36Sopenharmony_ci for (i = 0; i < radio_a_tblen; i = i + 2) { 96162306a36Sopenharmony_ci rtl_rfreg_delay(hw, rfpath, radio_a_table[i], 96262306a36Sopenharmony_ci MASK20BITS, radio_a_table[i + 1]); 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_ci } 96562306a36Sopenharmony_ci 96662306a36Sopenharmony_ci /* PA Bias current for inferiority IC */ 96762306a36Sopenharmony_ci _rtl92s_phy_config_rfpa_bias_current(hw, rfpath); 96862306a36Sopenharmony_ci break; 96962306a36Sopenharmony_ci case RF90_PATH_B: 97062306a36Sopenharmony_ci for (i = 0; i < radio_b_tblen; i = i + 2) { 97162306a36Sopenharmony_ci rtl_rfreg_delay(hw, rfpath, radio_b_table[i], 97262306a36Sopenharmony_ci MASK20BITS, radio_b_table[i + 1]); 97362306a36Sopenharmony_ci } 97462306a36Sopenharmony_ci break; 97562306a36Sopenharmony_ci case RF90_PATH_C: 97662306a36Sopenharmony_ci ; 97762306a36Sopenharmony_ci break; 97862306a36Sopenharmony_ci case RF90_PATH_D: 97962306a36Sopenharmony_ci ; 98062306a36Sopenharmony_ci break; 98162306a36Sopenharmony_ci default: 98262306a36Sopenharmony_ci break; 98362306a36Sopenharmony_ci } 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci return rtstatus; 98662306a36Sopenharmony_ci} 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci 98962306a36Sopenharmony_cibool rtl92s_phy_mac_config(struct ieee80211_hw *hw) 99062306a36Sopenharmony_ci{ 99162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 99262306a36Sopenharmony_ci u32 i; 99362306a36Sopenharmony_ci u32 arraylength; 99462306a36Sopenharmony_ci u32 *ptrarray; 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci arraylength = MAC_2T_ARRAYLENGTH; 99762306a36Sopenharmony_ci ptrarray = rtl8192semac_2t_array; 99862306a36Sopenharmony_ci 99962306a36Sopenharmony_ci for (i = 0; i < arraylength; i = i + 2) 100062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]); 100162306a36Sopenharmony_ci 100262306a36Sopenharmony_ci return true; 100362306a36Sopenharmony_ci} 100462306a36Sopenharmony_ci 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_cibool rtl92s_phy_bb_config(struct ieee80211_hw *hw) 100762306a36Sopenharmony_ci{ 100862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 100962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 101062306a36Sopenharmony_ci bool rtstatus; 101162306a36Sopenharmony_ci u8 pathmap, index, rf_num = 0; 101262306a36Sopenharmony_ci u8 path1, path2; 101362306a36Sopenharmony_ci 101462306a36Sopenharmony_ci _rtl92s_phy_init_register_definition(hw); 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_ci /* Config BB and AGC */ 101762306a36Sopenharmony_ci rtstatus = _rtl92s_phy_bb_config_parafile(hw); 101862306a36Sopenharmony_ci 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ci /* Check BB/RF confiuration setting. */ 102162306a36Sopenharmony_ci /* We only need to configure RF which is turned on. */ 102262306a36Sopenharmony_ci path1 = (u8)(rtl92s_phy_query_bb_reg(hw, RFPGA0_TXINFO, 0xf)); 102362306a36Sopenharmony_ci mdelay(10); 102462306a36Sopenharmony_ci path2 = (u8)(rtl92s_phy_query_bb_reg(hw, ROFDM0_TRXPATHENABLE, 0xf)); 102562306a36Sopenharmony_ci pathmap = path1 | path2; 102662306a36Sopenharmony_ci 102762306a36Sopenharmony_ci rtlphy->rf_pathmap = pathmap; 102862306a36Sopenharmony_ci for (index = 0; index < 4; index++) { 102962306a36Sopenharmony_ci if ((pathmap >> index) & 0x1) 103062306a36Sopenharmony_ci rf_num++; 103162306a36Sopenharmony_ci } 103262306a36Sopenharmony_ci 103362306a36Sopenharmony_ci if ((rtlphy->rf_type == RF_1T1R && rf_num != 1) || 103462306a36Sopenharmony_ci (rtlphy->rf_type == RF_1T2R && rf_num != 2) || 103562306a36Sopenharmony_ci (rtlphy->rf_type == RF_2T2R && rf_num != 2) || 103662306a36Sopenharmony_ci (rtlphy->rf_type == RF_2T2R_GREEN && rf_num != 2)) { 103762306a36Sopenharmony_ci pr_err("RF_Type(%x) does not match RF_Num(%x)!!\n", 103862306a36Sopenharmony_ci rtlphy->rf_type, rf_num); 103962306a36Sopenharmony_ci pr_err("path1 0x%x, path2 0x%x, pathmap 0x%x\n", 104062306a36Sopenharmony_ci path1, path2, pathmap); 104162306a36Sopenharmony_ci } 104262306a36Sopenharmony_ci 104362306a36Sopenharmony_ci return rtstatus; 104462306a36Sopenharmony_ci} 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_cibool rtl92s_phy_rf_config(struct ieee80211_hw *hw) 104762306a36Sopenharmony_ci{ 104862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 104962306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_ci /* Initialize general global value */ 105262306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T1R) 105362306a36Sopenharmony_ci rtlphy->num_total_rfpath = 1; 105462306a36Sopenharmony_ci else 105562306a36Sopenharmony_ci rtlphy->num_total_rfpath = 2; 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_ci /* Config BB and RF */ 105862306a36Sopenharmony_ci return rtl92s_phy_rf6052_config(hw); 105962306a36Sopenharmony_ci} 106062306a36Sopenharmony_ci 106162306a36Sopenharmony_civoid rtl92s_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) 106262306a36Sopenharmony_ci{ 106362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 106462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 106562306a36Sopenharmony_ci 106662306a36Sopenharmony_ci /* read rx initial gain */ 106762306a36Sopenharmony_ci rtlphy->default_initialgain[0] = rtl_get_bbreg(hw, 106862306a36Sopenharmony_ci ROFDM0_XAAGCCORE1, MASKBYTE0); 106962306a36Sopenharmony_ci rtlphy->default_initialgain[1] = rtl_get_bbreg(hw, 107062306a36Sopenharmony_ci ROFDM0_XBAGCCORE1, MASKBYTE0); 107162306a36Sopenharmony_ci rtlphy->default_initialgain[2] = rtl_get_bbreg(hw, 107262306a36Sopenharmony_ci ROFDM0_XCAGCCORE1, MASKBYTE0); 107362306a36Sopenharmony_ci rtlphy->default_initialgain[3] = rtl_get_bbreg(hw, 107462306a36Sopenharmony_ci ROFDM0_XDAGCCORE1, MASKBYTE0); 107562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 107662306a36Sopenharmony_ci "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x)\n", 107762306a36Sopenharmony_ci rtlphy->default_initialgain[0], 107862306a36Sopenharmony_ci rtlphy->default_initialgain[1], 107962306a36Sopenharmony_ci rtlphy->default_initialgain[2], 108062306a36Sopenharmony_ci rtlphy->default_initialgain[3]); 108162306a36Sopenharmony_ci 108262306a36Sopenharmony_ci /* read framesync */ 108362306a36Sopenharmony_ci rtlphy->framesync = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); 108462306a36Sopenharmony_ci rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, 108562306a36Sopenharmony_ci MASKDWORD); 108662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 108762306a36Sopenharmony_ci "Default framesync (0x%x) = 0x%x\n", 108862306a36Sopenharmony_ci ROFDM0_RXDETECTOR3, rtlphy->framesync); 108962306a36Sopenharmony_ci 109062306a36Sopenharmony_ci} 109162306a36Sopenharmony_ci 109262306a36Sopenharmony_cistatic void _rtl92s_phy_get_txpower_index(struct ieee80211_hw *hw, u8 channel, 109362306a36Sopenharmony_ci u8 *cckpowerlevel, u8 *ofdmpowerlevel) 109462306a36Sopenharmony_ci{ 109562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 109662306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 109762306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 109862306a36Sopenharmony_ci u8 index = (channel - 1); 109962306a36Sopenharmony_ci 110062306a36Sopenharmony_ci /* 1. CCK */ 110162306a36Sopenharmony_ci /* RF-A */ 110262306a36Sopenharmony_ci cckpowerlevel[0] = rtlefuse->txpwrlevel_cck[0][index]; 110362306a36Sopenharmony_ci /* RF-B */ 110462306a36Sopenharmony_ci cckpowerlevel[1] = rtlefuse->txpwrlevel_cck[1][index]; 110562306a36Sopenharmony_ci 110662306a36Sopenharmony_ci /* 2. OFDM for 1T or 2T */ 110762306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R || rtlphy->rf_type == RF_1T1R) { 110862306a36Sopenharmony_ci /* Read HT 40 OFDM TX power */ 110962306a36Sopenharmony_ci ofdmpowerlevel[0] = rtlefuse->txpwrlevel_ht40_1s[0][index]; 111062306a36Sopenharmony_ci ofdmpowerlevel[1] = rtlefuse->txpwrlevel_ht40_1s[1][index]; 111162306a36Sopenharmony_ci } else if (rtlphy->rf_type == RF_2T2R) { 111262306a36Sopenharmony_ci /* Read HT 40 OFDM TX power */ 111362306a36Sopenharmony_ci ofdmpowerlevel[0] = rtlefuse->txpwrlevel_ht40_2s[0][index]; 111462306a36Sopenharmony_ci ofdmpowerlevel[1] = rtlefuse->txpwrlevel_ht40_2s[1][index]; 111562306a36Sopenharmony_ci } else { 111662306a36Sopenharmony_ci ofdmpowerlevel[0] = 0; 111762306a36Sopenharmony_ci ofdmpowerlevel[1] = 0; 111862306a36Sopenharmony_ci } 111962306a36Sopenharmony_ci} 112062306a36Sopenharmony_ci 112162306a36Sopenharmony_cistatic void _rtl92s_phy_ccxpower_indexcheck(struct ieee80211_hw *hw, 112262306a36Sopenharmony_ci u8 channel, u8 *cckpowerlevel, u8 *ofdmpowerlevel) 112362306a36Sopenharmony_ci{ 112462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 112562306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 112662306a36Sopenharmony_ci 112762306a36Sopenharmony_ci rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; 112862306a36Sopenharmony_ci rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; 112962306a36Sopenharmony_ci} 113062306a36Sopenharmony_ci 113162306a36Sopenharmony_civoid rtl92s_phy_set_txpower(struct ieee80211_hw *hw, u8 channel) 113262306a36Sopenharmony_ci{ 113362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 113462306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 113562306a36Sopenharmony_ci /* [0]:RF-A, [1]:RF-B */ 113662306a36Sopenharmony_ci u8 cckpowerlevel[2], ofdmpowerlevel[2]; 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_ci if (!rtlefuse->txpwr_fromeprom) 113962306a36Sopenharmony_ci return; 114062306a36Sopenharmony_ci 114162306a36Sopenharmony_ci /* Mainly we use RF-A Tx Power to write the Tx Power registers, 114262306a36Sopenharmony_ci * but the RF-B Tx Power must be calculated by the antenna diff. 114362306a36Sopenharmony_ci * So we have to rewrite Antenna gain offset register here. 114462306a36Sopenharmony_ci * Please refer to BB register 0x80c 114562306a36Sopenharmony_ci * 1. For CCK. 114662306a36Sopenharmony_ci * 2. For OFDM 1T or 2T */ 114762306a36Sopenharmony_ci _rtl92s_phy_get_txpower_index(hw, channel, &cckpowerlevel[0], 114862306a36Sopenharmony_ci &ofdmpowerlevel[0]); 114962306a36Sopenharmony_ci 115062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 115162306a36Sopenharmony_ci "Channel-%d, cckPowerLevel (A / B) = 0x%x / 0x%x, ofdmPowerLevel (A / B) = 0x%x / 0x%x\n", 115262306a36Sopenharmony_ci channel, cckpowerlevel[0], cckpowerlevel[1], 115362306a36Sopenharmony_ci ofdmpowerlevel[0], ofdmpowerlevel[1]); 115462306a36Sopenharmony_ci 115562306a36Sopenharmony_ci _rtl92s_phy_ccxpower_indexcheck(hw, channel, &cckpowerlevel[0], 115662306a36Sopenharmony_ci &ofdmpowerlevel[0]); 115762306a36Sopenharmony_ci 115862306a36Sopenharmony_ci rtl92s_phy_rf6052_set_ccktxpower(hw, cckpowerlevel[0]); 115962306a36Sopenharmony_ci rtl92s_phy_rf6052_set_ofdmtxpower(hw, &ofdmpowerlevel[0], channel); 116062306a36Sopenharmony_ci 116162306a36Sopenharmony_ci} 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_civoid rtl92s_phy_chk_fwcmd_iodone(struct ieee80211_hw *hw) 116462306a36Sopenharmony_ci{ 116562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 116662306a36Sopenharmony_ci u16 pollingcnt = 10000; 116762306a36Sopenharmony_ci u32 tmpvalue; 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_ci /* Make sure that CMD IO has be accepted by FW. */ 117062306a36Sopenharmony_ci do { 117162306a36Sopenharmony_ci udelay(10); 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_ci tmpvalue = rtl_read_dword(rtlpriv, WFM5); 117462306a36Sopenharmony_ci if (tmpvalue == 0) 117562306a36Sopenharmony_ci break; 117662306a36Sopenharmony_ci } while (--pollingcnt); 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_ci if (pollingcnt == 0) 117962306a36Sopenharmony_ci pr_err("Set FW Cmd fail!!\n"); 118062306a36Sopenharmony_ci} 118162306a36Sopenharmony_ci 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_cistatic void _rtl92s_phy_set_fwcmd_io(struct ieee80211_hw *hw) 118462306a36Sopenharmony_ci{ 118562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 118662306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 118762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 118862306a36Sopenharmony_ci u32 input, current_aid = 0; 118962306a36Sopenharmony_ci 119062306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) 119162306a36Sopenharmony_ci return; 119262306a36Sopenharmony_ci 119362306a36Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) < 0x34) 119462306a36Sopenharmony_ci goto skip; 119562306a36Sopenharmony_ci /* We re-map RA related CMD IO to combinational ones */ 119662306a36Sopenharmony_ci /* if FW version is v.52 or later. */ 119762306a36Sopenharmony_ci switch (rtlhal->current_fwcmd_io) { 119862306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_N: 119962306a36Sopenharmony_ci rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_N_COMB; 120062306a36Sopenharmony_ci break; 120162306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_BG: 120262306a36Sopenharmony_ci rtlhal->current_fwcmd_io = FW_CMD_RA_REFRESH_BG_COMB; 120362306a36Sopenharmony_ci break; 120462306a36Sopenharmony_ci default: 120562306a36Sopenharmony_ci break; 120662306a36Sopenharmony_ci } 120762306a36Sopenharmony_ci 120862306a36Sopenharmony_ciskip: 120962306a36Sopenharmony_ci switch (rtlhal->current_fwcmd_io) { 121062306a36Sopenharmony_ci case FW_CMD_RA_RESET: 121162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_RESET\n"); 121262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); 121362306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 121462306a36Sopenharmony_ci break; 121562306a36Sopenharmony_ci case FW_CMD_RA_ACTIVE: 121662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_ACTIVE\n"); 121762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); 121862306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 121962306a36Sopenharmony_ci break; 122062306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_N: 122162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_RA_REFRESH_N\n"); 122262306a36Sopenharmony_ci input = FW_RA_REFRESH; 122362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, input); 122462306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 122562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_ENABLE_RSSI_MASK); 122662306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 122762306a36Sopenharmony_ci break; 122862306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_BG: 122962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, 123062306a36Sopenharmony_ci "FW_CMD_RA_REFRESH_BG\n"); 123162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); 123262306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 123362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_DISABLE_RSSI_MASK); 123462306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 123562306a36Sopenharmony_ci break; 123662306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_N_COMB: 123762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, 123862306a36Sopenharmony_ci "FW_CMD_RA_REFRESH_N_COMB\n"); 123962306a36Sopenharmony_ci input = FW_RA_IOT_N_COMB; 124062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, input); 124162306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 124262306a36Sopenharmony_ci break; 124362306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_BG_COMB: 124462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, 124562306a36Sopenharmony_ci "FW_CMD_RA_REFRESH_BG_COMB\n"); 124662306a36Sopenharmony_ci input = FW_RA_IOT_BG_COMB; 124762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, input); 124862306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 124962306a36Sopenharmony_ci break; 125062306a36Sopenharmony_ci case FW_CMD_IQK_ENABLE: 125162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_IQK_ENABLE\n"); 125262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_IQK_ENABLE); 125362306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 125462306a36Sopenharmony_ci break; 125562306a36Sopenharmony_ci case FW_CMD_PAUSE_DM_BY_SCAN: 125662306a36Sopenharmony_ci /* Lower initial gain */ 125762306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17); 125862306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17); 125962306a36Sopenharmony_ci /* CCA threshold */ 126062306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40); 126162306a36Sopenharmony_ci break; 126262306a36Sopenharmony_ci case FW_CMD_RESUME_DM_BY_SCAN: 126362306a36Sopenharmony_ci /* CCA threshold */ 126462306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); 126562306a36Sopenharmony_ci rtl92s_phy_set_txpower(hw, rtlphy->current_channel); 126662306a36Sopenharmony_ci break; 126762306a36Sopenharmony_ci case FW_CMD_HIGH_PWR_DISABLE: 126862306a36Sopenharmony_ci if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) 126962306a36Sopenharmony_ci break; 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ci /* Lower initial gain */ 127262306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, 0x17); 127362306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, 0x17); 127462306a36Sopenharmony_ci /* CCA threshold */ 127562306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0x40); 127662306a36Sopenharmony_ci break; 127762306a36Sopenharmony_ci case FW_CMD_HIGH_PWR_ENABLE: 127862306a36Sopenharmony_ci if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || 127962306a36Sopenharmony_ci rtlpriv->dm.dynamic_txpower_enable) 128062306a36Sopenharmony_ci break; 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci /* CCA threshold */ 128362306a36Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); 128462306a36Sopenharmony_ci break; 128562306a36Sopenharmony_ci case FW_CMD_LPS_ENTER: 128662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_ENTER\n"); 128762306a36Sopenharmony_ci current_aid = rtlpriv->mac80211.assoc_id; 128862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, (FW_LPS_ENTER | 128962306a36Sopenharmony_ci ((current_aid | 0xc000) << 8))); 129062306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 129162306a36Sopenharmony_ci /* FW set TXOP disable here, so disable EDCA 129262306a36Sopenharmony_ci * turbo mode until driver leave LPS */ 129362306a36Sopenharmony_ci break; 129462306a36Sopenharmony_ci case FW_CMD_LPS_LEAVE: 129562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_LPS_LEAVE\n"); 129662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_LPS_LEAVE); 129762306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 129862306a36Sopenharmony_ci break; 129962306a36Sopenharmony_ci case FW_CMD_ADD_A2_ENTRY: 130062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_DMESG, "FW_CMD_ADD_A2_ENTRY\n"); 130162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_ADD_A2_ENTRY); 130262306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 130362306a36Sopenharmony_ci break; 130462306a36Sopenharmony_ci case FW_CMD_CTRL_DM_BY_DRIVER: 130562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 130662306a36Sopenharmony_ci "FW_CMD_CTRL_DM_BY_DRIVER\n"); 130762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_CTRL_DM_BY_DRIVER); 130862306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 130962306a36Sopenharmony_ci break; 131062306a36Sopenharmony_ci 131162306a36Sopenharmony_ci default: 131262306a36Sopenharmony_ci break; 131362306a36Sopenharmony_ci } 131462306a36Sopenharmony_ci 131562306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 131662306a36Sopenharmony_ci 131762306a36Sopenharmony_ci /* Clear FW CMD operation flag. */ 131862306a36Sopenharmony_ci rtlhal->set_fwcmd_inprogress = false; 131962306a36Sopenharmony_ci} 132062306a36Sopenharmony_ci 132162306a36Sopenharmony_cibool rtl92s_phy_set_fw_cmd(struct ieee80211_hw *hw, enum fwcmd_iotype fw_cmdio) 132262306a36Sopenharmony_ci{ 132362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 132462306a36Sopenharmony_ci struct dig_t *digtable = &rtlpriv->dm_digtable; 132562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 132662306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 132762306a36Sopenharmony_ci u32 fw_param = FW_CMD_IO_PARA_QUERY(rtlpriv); 132862306a36Sopenharmony_ci u16 fw_cmdmap = FW_CMD_IO_QUERY(rtlpriv); 132962306a36Sopenharmony_ci bool postprocessing = false; 133062306a36Sopenharmony_ci 133162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 133262306a36Sopenharmony_ci "Set FW Cmd(%#x), set_fwcmd_inprogress(%d)\n", 133362306a36Sopenharmony_ci fw_cmdio, rtlhal->set_fwcmd_inprogress); 133462306a36Sopenharmony_ci 133562306a36Sopenharmony_ci do { 133662306a36Sopenharmony_ci /* We re-map to combined FW CMD ones if firmware version */ 133762306a36Sopenharmony_ci /* is v.53 or later. */ 133862306a36Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) >= 0x35) { 133962306a36Sopenharmony_ci switch (fw_cmdio) { 134062306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_N: 134162306a36Sopenharmony_ci fw_cmdio = FW_CMD_RA_REFRESH_N_COMB; 134262306a36Sopenharmony_ci break; 134362306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_BG: 134462306a36Sopenharmony_ci fw_cmdio = FW_CMD_RA_REFRESH_BG_COMB; 134562306a36Sopenharmony_ci break; 134662306a36Sopenharmony_ci default: 134762306a36Sopenharmony_ci break; 134862306a36Sopenharmony_ci } 134962306a36Sopenharmony_ci } else { 135062306a36Sopenharmony_ci if ((fw_cmdio == FW_CMD_IQK_ENABLE) || 135162306a36Sopenharmony_ci (fw_cmdio == FW_CMD_RA_REFRESH_N) || 135262306a36Sopenharmony_ci (fw_cmdio == FW_CMD_RA_REFRESH_BG)) { 135362306a36Sopenharmony_ci postprocessing = true; 135462306a36Sopenharmony_ci break; 135562306a36Sopenharmony_ci } 135662306a36Sopenharmony_ci } 135762306a36Sopenharmony_ci 135862306a36Sopenharmony_ci /* If firmware version is v.62 or later, 135962306a36Sopenharmony_ci * use FW_CMD_IO_SET for FW_CMD_CTRL_DM_BY_DRIVER */ 136062306a36Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) >= 0x3E) { 136162306a36Sopenharmony_ci if (fw_cmdio == FW_CMD_CTRL_DM_BY_DRIVER) 136262306a36Sopenharmony_ci fw_cmdio = FW_CMD_CTRL_DM_BY_DRIVER_NEW; 136362306a36Sopenharmony_ci } 136462306a36Sopenharmony_ci 136562306a36Sopenharmony_ci 136662306a36Sopenharmony_ci /* We shall revise all FW Cmd IO into Reg0x364 136762306a36Sopenharmony_ci * DM map table in the future. */ 136862306a36Sopenharmony_ci switch (fw_cmdio) { 136962306a36Sopenharmony_ci case FW_CMD_RA_INIT: 137062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, "RA init!!\n"); 137162306a36Sopenharmony_ci fw_cmdmap |= FW_RA_INIT_CTL; 137262306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 137362306a36Sopenharmony_ci /* Clear control flag to sync with FW. */ 137462306a36Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_RA_INIT_CTL); 137562306a36Sopenharmony_ci break; 137662306a36Sopenharmony_ci case FW_CMD_DIG_DISABLE: 137762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 137862306a36Sopenharmony_ci "Set DIG disable!!\n"); 137962306a36Sopenharmony_ci fw_cmdmap &= ~FW_DIG_ENABLE_CTL; 138062306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 138162306a36Sopenharmony_ci break; 138262306a36Sopenharmony_ci case FW_CMD_DIG_ENABLE: 138362306a36Sopenharmony_ci case FW_CMD_DIG_RESUME: 138462306a36Sopenharmony_ci if (!(rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE)) { 138562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 138662306a36Sopenharmony_ci "Set DIG enable or resume!!\n"); 138762306a36Sopenharmony_ci fw_cmdmap |= (FW_DIG_ENABLE_CTL | FW_SS_CTL); 138862306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 138962306a36Sopenharmony_ci } 139062306a36Sopenharmony_ci break; 139162306a36Sopenharmony_ci case FW_CMD_DIG_HALT: 139262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 139362306a36Sopenharmony_ci "Set DIG halt!!\n"); 139462306a36Sopenharmony_ci fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | FW_SS_CTL); 139562306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 139662306a36Sopenharmony_ci break; 139762306a36Sopenharmony_ci case FW_CMD_TXPWR_TRACK_THERMAL: { 139862306a36Sopenharmony_ci u8 thermalval = 0; 139962306a36Sopenharmony_ci fw_cmdmap |= FW_PWR_TRK_CTL; 140062306a36Sopenharmony_ci 140162306a36Sopenharmony_ci /* Clear FW parameter in terms of thermal parts. */ 140262306a36Sopenharmony_ci fw_param &= FW_PWR_TRK_PARAM_CLR; 140362306a36Sopenharmony_ci 140462306a36Sopenharmony_ci thermalval = rtlpriv->dm.thermalvalue; 140562306a36Sopenharmony_ci fw_param |= ((thermalval << 24) | 140662306a36Sopenharmony_ci (rtlefuse->thermalmeter[0] << 16)); 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 140962306a36Sopenharmony_ci "Set TxPwr tracking!! FwCmdMap(%#x), FwParam(%#x)\n", 141062306a36Sopenharmony_ci fw_cmdmap, fw_param); 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci FW_CMD_PARA_SET(rtlpriv, fw_param); 141362306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 141462306a36Sopenharmony_ci 141562306a36Sopenharmony_ci /* Clear control flag to sync with FW. */ 141662306a36Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_PWR_TRK_CTL); 141762306a36Sopenharmony_ci } 141862306a36Sopenharmony_ci break; 141962306a36Sopenharmony_ci /* The following FW CMDs are only compatible to 142062306a36Sopenharmony_ci * v.53 or later. */ 142162306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_N_COMB: 142262306a36Sopenharmony_ci fw_cmdmap |= FW_RA_N_CTL; 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci /* Clear RA BG mode control. */ 142562306a36Sopenharmony_ci fw_cmdmap &= ~(FW_RA_BG_CTL | FW_RA_INIT_CTL); 142662306a36Sopenharmony_ci 142762306a36Sopenharmony_ci /* Clear FW parameter in terms of RA parts. */ 142862306a36Sopenharmony_ci fw_param &= FW_RA_PARAM_CLR; 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 143162306a36Sopenharmony_ci "[FW CMD] [New Version] Set RA/IOT Comb in n mode!! FwCmdMap(%#x), FwParam(%#x)\n", 143262306a36Sopenharmony_ci fw_cmdmap, fw_param); 143362306a36Sopenharmony_ci 143462306a36Sopenharmony_ci FW_CMD_PARA_SET(rtlpriv, fw_param); 143562306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 143662306a36Sopenharmony_ci 143762306a36Sopenharmony_ci /* Clear control flag to sync with FW. */ 143862306a36Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_RA_N_CTL); 143962306a36Sopenharmony_ci break; 144062306a36Sopenharmony_ci case FW_CMD_RA_REFRESH_BG_COMB: 144162306a36Sopenharmony_ci fw_cmdmap |= FW_RA_BG_CTL; 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ci /* Clear RA n-mode control. */ 144462306a36Sopenharmony_ci fw_cmdmap &= ~(FW_RA_N_CTL | FW_RA_INIT_CTL); 144562306a36Sopenharmony_ci /* Clear FW parameter in terms of RA parts. */ 144662306a36Sopenharmony_ci fw_param &= FW_RA_PARAM_CLR; 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci FW_CMD_PARA_SET(rtlpriv, fw_param); 144962306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_ci /* Clear control flag to sync with FW. */ 145262306a36Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_RA_BG_CTL); 145362306a36Sopenharmony_ci break; 145462306a36Sopenharmony_ci case FW_CMD_IQK_ENABLE: 145562306a36Sopenharmony_ci fw_cmdmap |= FW_IQK_CTL; 145662306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 145762306a36Sopenharmony_ci /* Clear control flag to sync with FW. */ 145862306a36Sopenharmony_ci FW_CMD_IO_CLR(rtlpriv, FW_IQK_CTL); 145962306a36Sopenharmony_ci break; 146062306a36Sopenharmony_ci /* The following FW CMD is compatible to v.62 or later. */ 146162306a36Sopenharmony_ci case FW_CMD_CTRL_DM_BY_DRIVER_NEW: 146262306a36Sopenharmony_ci fw_cmdmap |= FW_DRIVER_CTRL_DM_CTL; 146362306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 146462306a36Sopenharmony_ci break; 146562306a36Sopenharmony_ci /* The followed FW Cmds needs post-processing later. */ 146662306a36Sopenharmony_ci case FW_CMD_RESUME_DM_BY_SCAN: 146762306a36Sopenharmony_ci fw_cmdmap |= (FW_DIG_ENABLE_CTL | 146862306a36Sopenharmony_ci FW_HIGH_PWR_ENABLE_CTL | 146962306a36Sopenharmony_ci FW_SS_CTL); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci if (rtlpriv->dm.dm_flag & HAL_DM_DIG_DISABLE || 147262306a36Sopenharmony_ci !digtable->dig_enable_flag) 147362306a36Sopenharmony_ci fw_cmdmap &= ~FW_DIG_ENABLE_CTL; 147462306a36Sopenharmony_ci 147562306a36Sopenharmony_ci if ((rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) || 147662306a36Sopenharmony_ci rtlpriv->dm.dynamic_txpower_enable) 147762306a36Sopenharmony_ci fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; 147862306a36Sopenharmony_ci 147962306a36Sopenharmony_ci if ((digtable->dig_ext_port_stage == 148062306a36Sopenharmony_ci DIG_EXT_PORT_STAGE_0) || 148162306a36Sopenharmony_ci (digtable->dig_ext_port_stage == 148262306a36Sopenharmony_ci DIG_EXT_PORT_STAGE_1)) 148362306a36Sopenharmony_ci fw_cmdmap &= ~FW_DIG_ENABLE_CTL; 148462306a36Sopenharmony_ci 148562306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 148662306a36Sopenharmony_ci postprocessing = true; 148762306a36Sopenharmony_ci break; 148862306a36Sopenharmony_ci case FW_CMD_PAUSE_DM_BY_SCAN: 148962306a36Sopenharmony_ci fw_cmdmap &= ~(FW_DIG_ENABLE_CTL | 149062306a36Sopenharmony_ci FW_HIGH_PWR_ENABLE_CTL | 149162306a36Sopenharmony_ci FW_SS_CTL); 149262306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 149362306a36Sopenharmony_ci postprocessing = true; 149462306a36Sopenharmony_ci break; 149562306a36Sopenharmony_ci case FW_CMD_HIGH_PWR_DISABLE: 149662306a36Sopenharmony_ci fw_cmdmap &= ~FW_HIGH_PWR_ENABLE_CTL; 149762306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 149862306a36Sopenharmony_ci postprocessing = true; 149962306a36Sopenharmony_ci break; 150062306a36Sopenharmony_ci case FW_CMD_HIGH_PWR_ENABLE: 150162306a36Sopenharmony_ci if (!(rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) && 150262306a36Sopenharmony_ci !rtlpriv->dm.dynamic_txpower_enable) { 150362306a36Sopenharmony_ci fw_cmdmap |= (FW_HIGH_PWR_ENABLE_CTL | 150462306a36Sopenharmony_ci FW_SS_CTL); 150562306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 150662306a36Sopenharmony_ci postprocessing = true; 150762306a36Sopenharmony_ci } 150862306a36Sopenharmony_ci break; 150962306a36Sopenharmony_ci case FW_CMD_DIG_MODE_FA: 151062306a36Sopenharmony_ci fw_cmdmap |= FW_FA_CTL; 151162306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 151262306a36Sopenharmony_ci break; 151362306a36Sopenharmony_ci case FW_CMD_DIG_MODE_SS: 151462306a36Sopenharmony_ci fw_cmdmap &= ~FW_FA_CTL; 151562306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 151662306a36Sopenharmony_ci break; 151762306a36Sopenharmony_ci case FW_CMD_PAPE_CONTROL: 151862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_CMD, DBG_LOUD, 151962306a36Sopenharmony_ci "[FW CMD] Set PAPE Control\n"); 152062306a36Sopenharmony_ci fw_cmdmap &= ~FW_PAPE_CTL_BY_SW_HW; 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci FW_CMD_IO_SET(rtlpriv, fw_cmdmap); 152362306a36Sopenharmony_ci break; 152462306a36Sopenharmony_ci default: 152562306a36Sopenharmony_ci /* Pass to original FW CMD processing callback 152662306a36Sopenharmony_ci * routine. */ 152762306a36Sopenharmony_ci postprocessing = true; 152862306a36Sopenharmony_ci break; 152962306a36Sopenharmony_ci } 153062306a36Sopenharmony_ci } while (false); 153162306a36Sopenharmony_ci 153262306a36Sopenharmony_ci /* We shall post processing these FW CMD if 153362306a36Sopenharmony_ci * variable postprocessing is set. 153462306a36Sopenharmony_ci */ 153562306a36Sopenharmony_ci if (postprocessing && !rtlhal->set_fwcmd_inprogress) { 153662306a36Sopenharmony_ci rtlhal->set_fwcmd_inprogress = true; 153762306a36Sopenharmony_ci /* Update current FW Cmd for callback use. */ 153862306a36Sopenharmony_ci rtlhal->current_fwcmd_io = fw_cmdio; 153962306a36Sopenharmony_ci } else { 154062306a36Sopenharmony_ci return false; 154162306a36Sopenharmony_ci } 154262306a36Sopenharmony_ci 154362306a36Sopenharmony_ci _rtl92s_phy_set_fwcmd_io(hw); 154462306a36Sopenharmony_ci return true; 154562306a36Sopenharmony_ci} 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_cistatic void _rtl92s_phy_check_ephy_switchready(struct ieee80211_hw *hw) 154862306a36Sopenharmony_ci{ 154962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 155062306a36Sopenharmony_ci u32 delay = 100; 155162306a36Sopenharmony_ci u8 regu1; 155262306a36Sopenharmony_ci 155362306a36Sopenharmony_ci regu1 = rtl_read_byte(rtlpriv, 0x554); 155462306a36Sopenharmony_ci while ((regu1 & BIT(5)) && (delay > 0)) { 155562306a36Sopenharmony_ci regu1 = rtl_read_byte(rtlpriv, 0x554); 155662306a36Sopenharmony_ci delay--; 155762306a36Sopenharmony_ci /* We delay only 50us to prevent 155862306a36Sopenharmony_ci * being scheduled out. */ 155962306a36Sopenharmony_ci udelay(50); 156062306a36Sopenharmony_ci } 156162306a36Sopenharmony_ci} 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_civoid rtl92s_phy_switch_ephy_parameter(struct ieee80211_hw *hw) 156462306a36Sopenharmony_ci{ 156562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 156662306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 156762306a36Sopenharmony_ci 156862306a36Sopenharmony_ci /* The way to be capable to switch clock request 156962306a36Sopenharmony_ci * when the PG setting does not support clock request. 157062306a36Sopenharmony_ci * This is the backdoor solution to switch clock 157162306a36Sopenharmony_ci * request before ASPM or D3. */ 157262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, 0x540, 0x73c11); 157362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, 0x548, 0x2407c); 157462306a36Sopenharmony_ci 157562306a36Sopenharmony_ci /* Switch EPHY parameter!!!! */ 157662306a36Sopenharmony_ci rtl_write_word(rtlpriv, 0x550, 0x1000); 157762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x554, 0x20); 157862306a36Sopenharmony_ci _rtl92s_phy_check_ephy_switchready(hw); 157962306a36Sopenharmony_ci 158062306a36Sopenharmony_ci rtl_write_word(rtlpriv, 0x550, 0xa0eb); 158162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x554, 0x3e); 158262306a36Sopenharmony_ci _rtl92s_phy_check_ephy_switchready(hw); 158362306a36Sopenharmony_ci 158462306a36Sopenharmony_ci rtl_write_word(rtlpriv, 0x550, 0xff80); 158562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x554, 0x39); 158662306a36Sopenharmony_ci _rtl92s_phy_check_ephy_switchready(hw); 158762306a36Sopenharmony_ci 158862306a36Sopenharmony_ci /* Delay L1 enter time */ 158962306a36Sopenharmony_ci if (ppsc->support_aspm && !ppsc->support_backdoor) 159062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x560, 0x40); 159162306a36Sopenharmony_ci else 159262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x560, 0x00); 159362306a36Sopenharmony_ci 159462306a36Sopenharmony_ci} 159562306a36Sopenharmony_ci 159662306a36Sopenharmony_civoid rtl92s_phy_set_beacon_hwreg(struct ieee80211_hw *hw, u16 beaconinterval) 159762306a36Sopenharmony_ci{ 159862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 159962306a36Sopenharmony_ci u32 new_bcn_num = 0; 160062306a36Sopenharmony_ci 160162306a36Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) >= 0x33) { 160262306a36Sopenharmony_ci /* Fw v.51 and later. */ 160362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, 0xF1000000 | 160462306a36Sopenharmony_ci (beaconinterval << 8)); 160562306a36Sopenharmony_ci } else { 160662306a36Sopenharmony_ci new_bcn_num = beaconinterval * 32 - 64; 160762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM3 + 4, new_bcn_num); 160862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM3, 0xB026007C); 160962306a36Sopenharmony_ci } 161062306a36Sopenharmony_ci} 1611