162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2014 Realtek Corporation.*/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "../wifi.h" 562306a36Sopenharmony_ci#include "../efuse.h" 662306a36Sopenharmony_ci#include "../base.h" 762306a36Sopenharmony_ci#include "../regd.h" 862306a36Sopenharmony_ci#include "../cam.h" 962306a36Sopenharmony_ci#include "../ps.h" 1062306a36Sopenharmony_ci#include "../pci.h" 1162306a36Sopenharmony_ci#include "reg.h" 1262306a36Sopenharmony_ci#include "def.h" 1362306a36Sopenharmony_ci#include "phy.h" 1462306a36Sopenharmony_ci#include "dm.h" 1562306a36Sopenharmony_ci#include "fw.h" 1662306a36Sopenharmony_ci#include "led.h" 1762306a36Sopenharmony_ci#include "hw.h" 1862306a36Sopenharmony_ci#include "../pwrseqcmd.h" 1962306a36Sopenharmony_ci#include "pwrseq.h" 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci#define LLT_CONFIG 5 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_cistatic void _rtl92ee_set_bcn_ctrl_reg(struct ieee80211_hw *hw, 2462306a36Sopenharmony_ci u8 set_bits, u8 clear_bits) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 2762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2862306a36Sopenharmony_ci 2962306a36Sopenharmony_ci rtlpci->reg_bcn_ctrl_val |= set_bits; 3062306a36Sopenharmony_ci rtlpci->reg_bcn_ctrl_val &= ~clear_bits; 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val); 3362306a36Sopenharmony_ci} 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_cistatic void _rtl92ee_stop_tx_beacon(struct ieee80211_hw *hw) 3662306a36Sopenharmony_ci{ 3762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3862306a36Sopenharmony_ci u8 tmp; 3962306a36Sopenharmony_ci 4062306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); 4162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp & (~BIT(6))); 4262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); 4362306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); 4462306a36Sopenharmony_ci tmp &= ~(BIT(0)); 4562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp); 4662306a36Sopenharmony_ci} 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_cistatic void _rtl92ee_resume_tx_beacon(struct ieee80211_hw *hw) 4962306a36Sopenharmony_ci{ 5062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5162306a36Sopenharmony_ci u8 tmp; 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); 5462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp | BIT(6)); 5562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); 5662306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); 5762306a36Sopenharmony_ci tmp |= BIT(0); 5862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp); 5962306a36Sopenharmony_ci} 6062306a36Sopenharmony_ci 6162306a36Sopenharmony_cistatic void _rtl92ee_enable_bcn_sub_func(struct ieee80211_hw *hw) 6262306a36Sopenharmony_ci{ 6362306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(1)); 6462306a36Sopenharmony_ci} 6562306a36Sopenharmony_ci 6662306a36Sopenharmony_cistatic void _rtl92ee_disable_bcn_sub_func(struct ieee80211_hw *hw) 6762306a36Sopenharmony_ci{ 6862306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, BIT(1), 0); 6962306a36Sopenharmony_ci} 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_cistatic void _rtl92ee_set_fw_clock_on(struct ieee80211_hw *hw, 7262306a36Sopenharmony_ci u8 rpwm_val, bool b_need_turn_off_ckk) 7362306a36Sopenharmony_ci{ 7462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 7662306a36Sopenharmony_ci bool b_support_remote_wake_up; 7762306a36Sopenharmony_ci u32 count = 0, isr_regaddr, content; 7862306a36Sopenharmony_ci bool b_schedule_timer = b_need_turn_off_ckk; 7962306a36Sopenharmony_ci 8062306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HAL_DEF_WOWLAN, 8162306a36Sopenharmony_ci (u8 *)(&b_support_remote_wake_up)); 8262306a36Sopenharmony_ci 8362306a36Sopenharmony_ci if (!rtlhal->fw_ready) 8462306a36Sopenharmony_ci return; 8562306a36Sopenharmony_ci if (!rtlpriv->psc.fw_current_inpsmode) 8662306a36Sopenharmony_ci return; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci while (1) { 8962306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.fw_ps_lock); 9062306a36Sopenharmony_ci if (rtlhal->fw_clk_change_in_progress) { 9162306a36Sopenharmony_ci while (rtlhal->fw_clk_change_in_progress) { 9262306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 9362306a36Sopenharmony_ci count++; 9462306a36Sopenharmony_ci udelay(100); 9562306a36Sopenharmony_ci if (count > 1000) 9662306a36Sopenharmony_ci return; 9762306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.fw_ps_lock); 9862306a36Sopenharmony_ci } 9962306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 10062306a36Sopenharmony_ci } else { 10162306a36Sopenharmony_ci rtlhal->fw_clk_change_in_progress = false; 10262306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 10362306a36Sopenharmony_ci break; 10462306a36Sopenharmony_ci } 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci if (IS_IN_LOW_POWER_STATE_92E(rtlhal->fw_ps_state)) { 10862306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_SET_RPWM, 10962306a36Sopenharmony_ci (u8 *)(&rpwm_val)); 11062306a36Sopenharmony_ci if (FW_PS_IS_ACK(rpwm_val)) { 11162306a36Sopenharmony_ci isr_regaddr = REG_HISR; 11262306a36Sopenharmony_ci content = rtl_read_dword(rtlpriv, isr_regaddr); 11362306a36Sopenharmony_ci while (!(content & IMR_CPWM) && (count < 500)) { 11462306a36Sopenharmony_ci udelay(50); 11562306a36Sopenharmony_ci count++; 11662306a36Sopenharmony_ci content = rtl_read_dword(rtlpriv, isr_regaddr); 11762306a36Sopenharmony_ci } 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci if (content & IMR_CPWM) { 12062306a36Sopenharmony_ci rtl_write_word(rtlpriv, isr_regaddr, 0x0100); 12162306a36Sopenharmony_ci rtlhal->fw_ps_state = FW_PS_STATE_RF_ON_92E; 12262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 12362306a36Sopenharmony_ci "Receive CPWM INT!!! PSState = %X\n", 12462306a36Sopenharmony_ci rtlhal->fw_ps_state); 12562306a36Sopenharmony_ci } 12662306a36Sopenharmony_ci } 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.fw_ps_lock); 12962306a36Sopenharmony_ci rtlhal->fw_clk_change_in_progress = false; 13062306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 13162306a36Sopenharmony_ci if (b_schedule_timer) { 13262306a36Sopenharmony_ci mod_timer(&rtlpriv->works.fw_clockoff_timer, 13362306a36Sopenharmony_ci jiffies + MSECS(10)); 13462306a36Sopenharmony_ci } 13562306a36Sopenharmony_ci } else { 13662306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.fw_ps_lock); 13762306a36Sopenharmony_ci rtlhal->fw_clk_change_in_progress = false; 13862306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 13962306a36Sopenharmony_ci } 14062306a36Sopenharmony_ci} 14162306a36Sopenharmony_ci 14262306a36Sopenharmony_cistatic void _rtl92ee_set_fw_clock_off(struct ieee80211_hw *hw, u8 rpwm_val) 14362306a36Sopenharmony_ci{ 14462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 14662306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 14762306a36Sopenharmony_ci struct rtl8192_tx_ring *ring; 14862306a36Sopenharmony_ci enum rf_pwrstate rtstate; 14962306a36Sopenharmony_ci bool b_schedule_timer = false; 15062306a36Sopenharmony_ci u8 queue; 15162306a36Sopenharmony_ci 15262306a36Sopenharmony_ci if (!rtlhal->fw_ready) 15362306a36Sopenharmony_ci return; 15462306a36Sopenharmony_ci if (!rtlpriv->psc.fw_current_inpsmode) 15562306a36Sopenharmony_ci return; 15662306a36Sopenharmony_ci if (!rtlhal->allow_sw_to_change_hwclc) 15762306a36Sopenharmony_ci return; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, (u8 *)(&rtstate)); 16062306a36Sopenharmony_ci if (rtstate == ERFOFF || rtlpriv->psc.inactive_pwrstate == ERFOFF) 16162306a36Sopenharmony_ci return; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci for (queue = 0; queue < RTL_PCI_MAX_TX_QUEUE_COUNT; queue++) { 16462306a36Sopenharmony_ci ring = &rtlpci->tx_ring[queue]; 16562306a36Sopenharmony_ci if (skb_queue_len(&ring->queue)) { 16662306a36Sopenharmony_ci b_schedule_timer = true; 16762306a36Sopenharmony_ci break; 16862306a36Sopenharmony_ci } 16962306a36Sopenharmony_ci } 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci if (b_schedule_timer) { 17262306a36Sopenharmony_ci mod_timer(&rtlpriv->works.fw_clockoff_timer, 17362306a36Sopenharmony_ci jiffies + MSECS(10)); 17462306a36Sopenharmony_ci return; 17562306a36Sopenharmony_ci } 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci if (FW_PS_STATE(rtlhal->fw_ps_state) != FW_PS_STATE_RF_OFF_LOW_PWR) { 17862306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.fw_ps_lock); 17962306a36Sopenharmony_ci if (!rtlhal->fw_clk_change_in_progress) { 18062306a36Sopenharmony_ci rtlhal->fw_clk_change_in_progress = true; 18162306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 18262306a36Sopenharmony_ci rtlhal->fw_ps_state = FW_PS_STATE(rpwm_val); 18362306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_HISR, 0x0100); 18462306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, 18562306a36Sopenharmony_ci (u8 *)(&rpwm_val)); 18662306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.fw_ps_lock); 18762306a36Sopenharmony_ci rtlhal->fw_clk_change_in_progress = false; 18862306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 18962306a36Sopenharmony_ci } else { 19062306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.fw_ps_lock); 19162306a36Sopenharmony_ci mod_timer(&rtlpriv->works.fw_clockoff_timer, 19262306a36Sopenharmony_ci jiffies + MSECS(10)); 19362306a36Sopenharmony_ci } 19462306a36Sopenharmony_ci } 19562306a36Sopenharmony_ci} 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_cistatic void _rtl92ee_set_fw_ps_rf_on(struct ieee80211_hw *hw) 19862306a36Sopenharmony_ci{ 19962306a36Sopenharmony_ci u8 rpwm_val = 0; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci rpwm_val |= (FW_PS_STATE_RF_OFF_92E | FW_PS_ACK); 20262306a36Sopenharmony_ci _rtl92ee_set_fw_clock_on(hw, rpwm_val, true); 20362306a36Sopenharmony_ci} 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_cistatic void _rtl92ee_set_fw_ps_rf_off_low_power(struct ieee80211_hw *hw) 20662306a36Sopenharmony_ci{ 20762306a36Sopenharmony_ci u8 rpwm_val = 0; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci rpwm_val |= FW_PS_STATE_RF_OFF_LOW_PWR; 21062306a36Sopenharmony_ci _rtl92ee_set_fw_clock_off(hw, rpwm_val); 21162306a36Sopenharmony_ci} 21262306a36Sopenharmony_ci 21362306a36Sopenharmony_civoid rtl92ee_fw_clk_off_timer_callback(unsigned long data) 21462306a36Sopenharmony_ci{ 21562306a36Sopenharmony_ci struct ieee80211_hw *hw = (struct ieee80211_hw *)data; 21662306a36Sopenharmony_ci 21762306a36Sopenharmony_ci _rtl92ee_set_fw_ps_rf_off_low_power(hw); 21862306a36Sopenharmony_ci} 21962306a36Sopenharmony_ci 22062306a36Sopenharmony_cistatic void _rtl92ee_fwlps_leave(struct ieee80211_hw *hw) 22162306a36Sopenharmony_ci{ 22262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 22362306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 22462306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 22562306a36Sopenharmony_ci bool fw_current_inps = false; 22662306a36Sopenharmony_ci u8 rpwm_val = 0, fw_pwrmode = FW_PS_ACTIVE_MODE; 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci if (ppsc->low_power_enable) { 22962306a36Sopenharmony_ci rpwm_val = (FW_PS_STATE_ALL_ON_92E | FW_PS_ACK);/* RF on */ 23062306a36Sopenharmony_ci _rtl92ee_set_fw_clock_on(hw, rpwm_val, false); 23162306a36Sopenharmony_ci rtlhal->allow_sw_to_change_hwclc = false; 23262306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 23362306a36Sopenharmony_ci (u8 *)(&fw_pwrmode)); 23462306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 23562306a36Sopenharmony_ci (u8 *)(&fw_current_inps)); 23662306a36Sopenharmony_ci } else { 23762306a36Sopenharmony_ci rpwm_val = FW_PS_STATE_ALL_ON_92E; /* RF on */ 23862306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, 23962306a36Sopenharmony_ci (u8 *)(&rpwm_val)); 24062306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 24162306a36Sopenharmony_ci (u8 *)(&fw_pwrmode)); 24262306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 24362306a36Sopenharmony_ci (u8 *)(&fw_current_inps)); 24462306a36Sopenharmony_ci } 24562306a36Sopenharmony_ci} 24662306a36Sopenharmony_ci 24762306a36Sopenharmony_cistatic void _rtl92ee_fwlps_enter(struct ieee80211_hw *hw) 24862306a36Sopenharmony_ci{ 24962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 25062306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 25162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 25262306a36Sopenharmony_ci bool fw_current_inps = true; 25362306a36Sopenharmony_ci u8 rpwm_val; 25462306a36Sopenharmony_ci 25562306a36Sopenharmony_ci if (ppsc->low_power_enable) { 25662306a36Sopenharmony_ci rpwm_val = FW_PS_STATE_RF_OFF_LOW_PWR; /* RF off */ 25762306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 25862306a36Sopenharmony_ci (u8 *)(&fw_current_inps)); 25962306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 26062306a36Sopenharmony_ci (u8 *)(&ppsc->fwctrl_psmode)); 26162306a36Sopenharmony_ci rtlhal->allow_sw_to_change_hwclc = true; 26262306a36Sopenharmony_ci _rtl92ee_set_fw_clock_off(hw, rpwm_val); 26362306a36Sopenharmony_ci } else { 26462306a36Sopenharmony_ci rpwm_val = FW_PS_STATE_RF_OFF_92E; /* RF off */ 26562306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 26662306a36Sopenharmony_ci (u8 *)(&fw_current_inps)); 26762306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 26862306a36Sopenharmony_ci (u8 *)(&ppsc->fwctrl_psmode)); 26962306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, 27062306a36Sopenharmony_ci (u8 *)(&rpwm_val)); 27162306a36Sopenharmony_ci } 27262306a36Sopenharmony_ci} 27362306a36Sopenharmony_ci 27462306a36Sopenharmony_civoid rtl92ee_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 27562306a36Sopenharmony_ci{ 27662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 27762306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 27862306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_ci switch (variable) { 28162306a36Sopenharmony_ci case HW_VAR_RCR: 28262306a36Sopenharmony_ci *((u32 *)(val)) = rtlpci->receive_config; 28362306a36Sopenharmony_ci break; 28462306a36Sopenharmony_ci case HW_VAR_RF_STATE: 28562306a36Sopenharmony_ci *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; 28662306a36Sopenharmony_ci break; 28762306a36Sopenharmony_ci case HW_VAR_FWLPS_RF_ON:{ 28862306a36Sopenharmony_ci enum rf_pwrstate rfstate; 28962306a36Sopenharmony_ci u32 val_rcr; 29062306a36Sopenharmony_ci 29162306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, 29262306a36Sopenharmony_ci (u8 *)(&rfstate)); 29362306a36Sopenharmony_ci if (rfstate == ERFOFF) { 29462306a36Sopenharmony_ci *((bool *)(val)) = true; 29562306a36Sopenharmony_ci } else { 29662306a36Sopenharmony_ci val_rcr = rtl_read_dword(rtlpriv, REG_RCR); 29762306a36Sopenharmony_ci val_rcr &= 0x00070000; 29862306a36Sopenharmony_ci if (val_rcr) 29962306a36Sopenharmony_ci *((bool *)(val)) = false; 30062306a36Sopenharmony_ci else 30162306a36Sopenharmony_ci *((bool *)(val)) = true; 30262306a36Sopenharmony_ci } 30362306a36Sopenharmony_ci } 30462306a36Sopenharmony_ci break; 30562306a36Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: 30662306a36Sopenharmony_ci *((bool *)(val)) = ppsc->fw_current_inpsmode; 30762306a36Sopenharmony_ci break; 30862306a36Sopenharmony_ci case HW_VAR_CORRECT_TSF:{ 30962306a36Sopenharmony_ci u64 tsf; 31062306a36Sopenharmony_ci u32 *ptsf_low = (u32 *)&tsf; 31162306a36Sopenharmony_ci u32 *ptsf_high = ((u32 *)&tsf) + 1; 31262306a36Sopenharmony_ci 31362306a36Sopenharmony_ci *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); 31462306a36Sopenharmony_ci *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); 31562306a36Sopenharmony_ci 31662306a36Sopenharmony_ci *((u64 *)(val)) = tsf; 31762306a36Sopenharmony_ci } 31862306a36Sopenharmony_ci break; 31962306a36Sopenharmony_ci case HAL_DEF_WOWLAN: 32062306a36Sopenharmony_ci break; 32162306a36Sopenharmony_ci default: 32262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, 32362306a36Sopenharmony_ci "switch case %#x not processed\n", variable); 32462306a36Sopenharmony_ci break; 32562306a36Sopenharmony_ci } 32662306a36Sopenharmony_ci} 32762306a36Sopenharmony_ci 32862306a36Sopenharmony_cistatic void _rtl92ee_download_rsvd_page(struct ieee80211_hw *hw) 32962306a36Sopenharmony_ci{ 33062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 33162306a36Sopenharmony_ci u8 tmp_regcr, tmp_reg422; 33262306a36Sopenharmony_ci u8 bcnvalid_reg, txbc_reg; 33362306a36Sopenharmony_ci u8 count = 0, dlbcn_count = 0; 33462306a36Sopenharmony_ci bool b_recover = false; 33562306a36Sopenharmony_ci 33662306a36Sopenharmony_ci /*Set REG_CR bit 8. DMA beacon by SW.*/ 33762306a36Sopenharmony_ci tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); 33862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, tmp_regcr | BIT(0)); 33962306a36Sopenharmony_ci 34062306a36Sopenharmony_ci /* Disable Hw protection for a time which revserd for Hw sending beacon. 34162306a36Sopenharmony_ci * Fix download reserved page packet fail 34262306a36Sopenharmony_ci * that access collision with the protection time. 34362306a36Sopenharmony_ci * 2010.05.11. Added by tynli. 34462306a36Sopenharmony_ci */ 34562306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(3)); 34662306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, BIT(4), 0); 34762306a36Sopenharmony_ci 34862306a36Sopenharmony_ci /* Set FWHW_TXQ_CTRL 0x422[6]=0 to 34962306a36Sopenharmony_ci * tell Hw the packet is not a real beacon frame. 35062306a36Sopenharmony_ci */ 35162306a36Sopenharmony_ci tmp_reg422 = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); 35262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422 & (~BIT(6))); 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci if (tmp_reg422 & BIT(6)) 35562306a36Sopenharmony_ci b_recover = true; 35662306a36Sopenharmony_ci 35762306a36Sopenharmony_ci do { 35862306a36Sopenharmony_ci /* Clear beacon valid check bit */ 35962306a36Sopenharmony_ci bcnvalid_reg = rtl_read_byte(rtlpriv, REG_DWBCN0_CTRL + 2); 36062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 2, 36162306a36Sopenharmony_ci bcnvalid_reg | BIT(0)); 36262306a36Sopenharmony_ci 36362306a36Sopenharmony_ci /* download rsvd page */ 36462306a36Sopenharmony_ci rtl92ee_set_fw_rsvdpagepkt(hw, false); 36562306a36Sopenharmony_ci 36662306a36Sopenharmony_ci txbc_reg = rtl_read_byte(rtlpriv, REG_MGQ_TXBD_NUM + 3); 36762306a36Sopenharmony_ci count = 0; 36862306a36Sopenharmony_ci while ((txbc_reg & BIT(4)) && count < 20) { 36962306a36Sopenharmony_ci count++; 37062306a36Sopenharmony_ci udelay(10); 37162306a36Sopenharmony_ci txbc_reg = rtl_read_byte(rtlpriv, REG_MGQ_TXBD_NUM + 3); 37262306a36Sopenharmony_ci } 37362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MGQ_TXBD_NUM + 3, 37462306a36Sopenharmony_ci txbc_reg | BIT(4)); 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci /* check rsvd page download OK. */ 37762306a36Sopenharmony_ci bcnvalid_reg = rtl_read_byte(rtlpriv, REG_DWBCN0_CTRL + 2); 37862306a36Sopenharmony_ci count = 0; 37962306a36Sopenharmony_ci while (!(bcnvalid_reg & BIT(0)) && count < 20) { 38062306a36Sopenharmony_ci count++; 38162306a36Sopenharmony_ci udelay(50); 38262306a36Sopenharmony_ci bcnvalid_reg = rtl_read_byte(rtlpriv, 38362306a36Sopenharmony_ci REG_DWBCN0_CTRL + 2); 38462306a36Sopenharmony_ci } 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci if (bcnvalid_reg & BIT(0)) 38762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 2, BIT(0)); 38862306a36Sopenharmony_ci 38962306a36Sopenharmony_ci dlbcn_count++; 39062306a36Sopenharmony_ci } while (!(bcnvalid_reg & BIT(0)) && dlbcn_count < 5); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci if (!(bcnvalid_reg & BIT(0))) 39362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 39462306a36Sopenharmony_ci "Download RSVD page failed!\n"); 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci /* Enable Bcn */ 39762306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0); 39862306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(4)); 39962306a36Sopenharmony_ci 40062306a36Sopenharmony_ci if (b_recover) 40162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp_reg422); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); 40462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, tmp_regcr & (~BIT(0))); 40562306a36Sopenharmony_ci} 40662306a36Sopenharmony_ci 40762306a36Sopenharmony_civoid rtl92ee_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 40862306a36Sopenharmony_ci{ 40962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 41062306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 41162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 41262306a36Sopenharmony_ci struct rtl_efuse *efuse = rtl_efuse(rtl_priv(hw)); 41362306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 41462306a36Sopenharmony_ci u8 idx; 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_ci switch (variable) { 41762306a36Sopenharmony_ci case HW_VAR_ETHER_ADDR: 41862306a36Sopenharmony_ci for (idx = 0; idx < ETH_ALEN; idx++) 41962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_MACID + idx), val[idx]); 42062306a36Sopenharmony_ci break; 42162306a36Sopenharmony_ci case HW_VAR_BASIC_RATE:{ 42262306a36Sopenharmony_ci u16 b_rate_cfg = ((u16 *)val)[0]; 42362306a36Sopenharmony_ci 42462306a36Sopenharmony_ci b_rate_cfg = b_rate_cfg & 0x15f; 42562306a36Sopenharmony_ci b_rate_cfg |= 0x01; 42662306a36Sopenharmony_ci b_rate_cfg = (b_rate_cfg | 0xd) & (~BIT(1)); 42762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR, b_rate_cfg & 0xff); 42862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 1, (b_rate_cfg >> 8) & 0xff); 42962306a36Sopenharmony_ci break; } 43062306a36Sopenharmony_ci case HW_VAR_BSSID: 43162306a36Sopenharmony_ci for (idx = 0; idx < ETH_ALEN; idx++) 43262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_BSSID + idx), val[idx]); 43362306a36Sopenharmony_ci break; 43462306a36Sopenharmony_ci case HW_VAR_SIFS: 43562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); 43662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); 43962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci if (!mac->ht_enable) 44262306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 0x0e0e); 44362306a36Sopenharmony_ci else 44462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 44562306a36Sopenharmony_ci *((u16 *)val)); 44662306a36Sopenharmony_ci break; 44762306a36Sopenharmony_ci case HW_VAR_SLOT_TIME:{ 44862306a36Sopenharmony_ci u8 e_aci; 44962306a36Sopenharmony_ci 45062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_TRACE, 45162306a36Sopenharmony_ci "HW_VAR_SLOT_TIME %x\n", val[0]); 45262306a36Sopenharmony_ci 45362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SLOT, val[0]); 45462306a36Sopenharmony_ci 45562306a36Sopenharmony_ci for (e_aci = 0; e_aci < AC_MAX; e_aci++) { 45662306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, 45762306a36Sopenharmony_ci (u8 *)(&e_aci)); 45862306a36Sopenharmony_ci } 45962306a36Sopenharmony_ci break; } 46062306a36Sopenharmony_ci case HW_VAR_ACK_PREAMBLE:{ 46162306a36Sopenharmony_ci u8 reg_tmp; 46262306a36Sopenharmony_ci u8 short_preamble = (bool)(*(u8 *)val); 46362306a36Sopenharmony_ci 46462306a36Sopenharmony_ci reg_tmp = (rtlpriv->mac80211.cur_40_prime_sc) << 5; 46562306a36Sopenharmony_ci if (short_preamble) 46662306a36Sopenharmony_ci reg_tmp |= 0x80; 46762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); 46862306a36Sopenharmony_ci rtlpriv->mac80211.short_preamble = short_preamble; 46962306a36Sopenharmony_ci } 47062306a36Sopenharmony_ci break; 47162306a36Sopenharmony_ci case HW_VAR_WPA_CONFIG: 47262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SECCFG, *((u8 *)val)); 47362306a36Sopenharmony_ci break; 47462306a36Sopenharmony_ci case HW_VAR_AMPDU_FACTOR:{ 47562306a36Sopenharmony_ci u8 regtoset_normal[4] = { 0x41, 0xa8, 0x72, 0xb9 }; 47662306a36Sopenharmony_ci u8 fac; 47762306a36Sopenharmony_ci u8 *reg = NULL; 47862306a36Sopenharmony_ci u8 i = 0; 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci reg = regtoset_normal; 48162306a36Sopenharmony_ci 48262306a36Sopenharmony_ci fac = *((u8 *)val); 48362306a36Sopenharmony_ci if (fac <= 3) { 48462306a36Sopenharmony_ci fac = (1 << (fac + 2)); 48562306a36Sopenharmony_ci if (fac > 0xf) 48662306a36Sopenharmony_ci fac = 0xf; 48762306a36Sopenharmony_ci for (i = 0; i < 4; i++) { 48862306a36Sopenharmony_ci if ((reg[i] & 0xf0) > (fac << 4)) 48962306a36Sopenharmony_ci reg[i] = (reg[i] & 0x0f) | 49062306a36Sopenharmony_ci (fac << 4); 49162306a36Sopenharmony_ci if ((reg[i] & 0x0f) > fac) 49262306a36Sopenharmony_ci reg[i] = (reg[i] & 0xf0) | fac; 49362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 49462306a36Sopenharmony_ci (REG_AGGLEN_LMT + i), 49562306a36Sopenharmony_ci reg[i]); 49662306a36Sopenharmony_ci } 49762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 49862306a36Sopenharmony_ci "Set HW_VAR_AMPDU_FACTOR:%#x\n", fac); 49962306a36Sopenharmony_ci } 50062306a36Sopenharmony_ci } 50162306a36Sopenharmony_ci break; 50262306a36Sopenharmony_ci case HW_VAR_AC_PARAM:{ 50362306a36Sopenharmony_ci u8 e_aci = *((u8 *)val); 50462306a36Sopenharmony_ci 50562306a36Sopenharmony_ci if (rtlpci->acm_method != EACMWAY2_SW) 50662306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, 50762306a36Sopenharmony_ci (u8 *)(&e_aci)); 50862306a36Sopenharmony_ci } 50962306a36Sopenharmony_ci break; 51062306a36Sopenharmony_ci case HW_VAR_ACM_CTRL:{ 51162306a36Sopenharmony_ci u8 e_aci = *((u8 *)val); 51262306a36Sopenharmony_ci union aci_aifsn *aifs = (union aci_aifsn *)(&mac->ac[0].aifs); 51362306a36Sopenharmony_ci 51462306a36Sopenharmony_ci u8 acm = aifs->f.acm; 51562306a36Sopenharmony_ci u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_ci if (acm) { 52062306a36Sopenharmony_ci switch (e_aci) { 52162306a36Sopenharmony_ci case AC0_BE: 52262306a36Sopenharmony_ci acm_ctrl |= ACMHW_BEQEN; 52362306a36Sopenharmony_ci break; 52462306a36Sopenharmony_ci case AC2_VI: 52562306a36Sopenharmony_ci acm_ctrl |= ACMHW_VIQEN; 52662306a36Sopenharmony_ci break; 52762306a36Sopenharmony_ci case AC3_VO: 52862306a36Sopenharmony_ci acm_ctrl |= ACMHW_VOQEN; 52962306a36Sopenharmony_ci break; 53062306a36Sopenharmony_ci default: 53162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 53262306a36Sopenharmony_ci "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", 53362306a36Sopenharmony_ci acm); 53462306a36Sopenharmony_ci break; 53562306a36Sopenharmony_ci } 53662306a36Sopenharmony_ci } else { 53762306a36Sopenharmony_ci switch (e_aci) { 53862306a36Sopenharmony_ci case AC0_BE: 53962306a36Sopenharmony_ci acm_ctrl &= (~ACMHW_BEQEN); 54062306a36Sopenharmony_ci break; 54162306a36Sopenharmony_ci case AC2_VI: 54262306a36Sopenharmony_ci acm_ctrl &= (~ACMHW_VIQEN); 54362306a36Sopenharmony_ci break; 54462306a36Sopenharmony_ci case AC3_VO: 54562306a36Sopenharmony_ci acm_ctrl &= (~ACMHW_VOQEN); 54662306a36Sopenharmony_ci break; 54762306a36Sopenharmony_ci default: 54862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, 54962306a36Sopenharmony_ci "switch case %#x not processed\n", 55062306a36Sopenharmony_ci e_aci); 55162306a36Sopenharmony_ci break; 55262306a36Sopenharmony_ci } 55362306a36Sopenharmony_ci } 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, 55662306a36Sopenharmony_ci "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", 55762306a36Sopenharmony_ci acm_ctrl); 55862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); 55962306a36Sopenharmony_ci } 56062306a36Sopenharmony_ci break; 56162306a36Sopenharmony_ci case HW_VAR_RCR:{ 56262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RCR, ((u32 *)(val))[0]); 56362306a36Sopenharmony_ci rtlpci->receive_config = ((u32 *)(val))[0]; 56462306a36Sopenharmony_ci } 56562306a36Sopenharmony_ci break; 56662306a36Sopenharmony_ci case HW_VAR_RETRY_LIMIT:{ 56762306a36Sopenharmony_ci u8 retry_limit = ((u8 *)(val))[0]; 56862306a36Sopenharmony_ci 56962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RETRY_LIMIT, 57062306a36Sopenharmony_ci retry_limit << RETRY_LIMIT_SHORT_SHIFT | 57162306a36Sopenharmony_ci retry_limit << RETRY_LIMIT_LONG_SHIFT); 57262306a36Sopenharmony_ci } 57362306a36Sopenharmony_ci break; 57462306a36Sopenharmony_ci case HW_VAR_DUAL_TSF_RST: 57562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); 57662306a36Sopenharmony_ci break; 57762306a36Sopenharmony_ci case HW_VAR_EFUSE_BYTES: 57862306a36Sopenharmony_ci efuse->efuse_usedbytes = *((u16 *)val); 57962306a36Sopenharmony_ci break; 58062306a36Sopenharmony_ci case HW_VAR_EFUSE_USAGE: 58162306a36Sopenharmony_ci efuse->efuse_usedpercentage = *((u8 *)val); 58262306a36Sopenharmony_ci break; 58362306a36Sopenharmony_ci case HW_VAR_IO_CMD: 58462306a36Sopenharmony_ci rtl92ee_phy_set_io_cmd(hw, (*(enum io_type *)val)); 58562306a36Sopenharmony_ci break; 58662306a36Sopenharmony_ci case HW_VAR_SET_RPWM:{ 58762306a36Sopenharmony_ci u8 rpwm_val; 58862306a36Sopenharmony_ci 58962306a36Sopenharmony_ci rpwm_val = rtl_read_byte(rtlpriv, REG_PCIE_HRPWM); 59062306a36Sopenharmony_ci udelay(1); 59162306a36Sopenharmony_ci 59262306a36Sopenharmony_ci if (rpwm_val & BIT(7)) { 59362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, (*(u8 *)val)); 59462306a36Sopenharmony_ci } else { 59562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PCIE_HRPWM, 59662306a36Sopenharmony_ci ((*(u8 *)val) | BIT(7))); 59762306a36Sopenharmony_ci } 59862306a36Sopenharmony_ci } 59962306a36Sopenharmony_ci break; 60062306a36Sopenharmony_ci case HW_VAR_H2C_FW_PWRMODE: 60162306a36Sopenharmony_ci rtl92ee_set_fw_pwrmode_cmd(hw, (*(u8 *)val)); 60262306a36Sopenharmony_ci break; 60362306a36Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: 60462306a36Sopenharmony_ci ppsc->fw_current_inpsmode = *((bool *)val); 60562306a36Sopenharmony_ci break; 60662306a36Sopenharmony_ci case HW_VAR_RESUME_CLK_ON: 60762306a36Sopenharmony_ci _rtl92ee_set_fw_ps_rf_on(hw); 60862306a36Sopenharmony_ci break; 60962306a36Sopenharmony_ci case HW_VAR_FW_LPS_ACTION:{ 61062306a36Sopenharmony_ci bool b_enter_fwlps = *((bool *)val); 61162306a36Sopenharmony_ci 61262306a36Sopenharmony_ci if (b_enter_fwlps) 61362306a36Sopenharmony_ci _rtl92ee_fwlps_enter(hw); 61462306a36Sopenharmony_ci else 61562306a36Sopenharmony_ci _rtl92ee_fwlps_leave(hw); 61662306a36Sopenharmony_ci } 61762306a36Sopenharmony_ci break; 61862306a36Sopenharmony_ci case HW_VAR_H2C_FW_JOINBSSRPT:{ 61962306a36Sopenharmony_ci u8 mstatus = (*(u8 *)val); 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci if (mstatus == RT_MEDIA_CONNECT) { 62262306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AID, NULL); 62362306a36Sopenharmony_ci _rtl92ee_download_rsvd_page(hw); 62462306a36Sopenharmony_ci } 62562306a36Sopenharmony_ci rtl92ee_set_fw_media_status_rpt_cmd(hw, mstatus); 62662306a36Sopenharmony_ci } 62762306a36Sopenharmony_ci break; 62862306a36Sopenharmony_ci case HW_VAR_H2C_FW_P2P_PS_OFFLOAD: 62962306a36Sopenharmony_ci rtl92ee_set_p2p_ps_offload_cmd(hw, (*(u8 *)val)); 63062306a36Sopenharmony_ci break; 63162306a36Sopenharmony_ci case HW_VAR_AID:{ 63262306a36Sopenharmony_ci u16 u2btmp; 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_ci u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); 63562306a36Sopenharmony_ci u2btmp &= 0xC000; 63662306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, 63762306a36Sopenharmony_ci (u2btmp | mac->assoc_id)); 63862306a36Sopenharmony_ci } 63962306a36Sopenharmony_ci break; 64062306a36Sopenharmony_ci case HW_VAR_CORRECT_TSF:{ 64162306a36Sopenharmony_ci u8 btype_ibss = ((u8 *)(val))[0]; 64262306a36Sopenharmony_ci 64362306a36Sopenharmony_ci if (btype_ibss) 64462306a36Sopenharmony_ci _rtl92ee_stop_tx_beacon(hw); 64562306a36Sopenharmony_ci 64662306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(3)); 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTR, 64962306a36Sopenharmony_ci (u32)(mac->tsf & 0xffffffff)); 65062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTR + 4, 65162306a36Sopenharmony_ci (u32)((mac->tsf >> 32) & 0xffffffff)); 65262306a36Sopenharmony_ci 65362306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0); 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci if (btype_ibss) 65662306a36Sopenharmony_ci _rtl92ee_resume_tx_beacon(hw); 65762306a36Sopenharmony_ci } 65862306a36Sopenharmony_ci break; 65962306a36Sopenharmony_ci case HW_VAR_KEEP_ALIVE: { 66062306a36Sopenharmony_ci u8 array[2]; 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci array[0] = 0xff; 66362306a36Sopenharmony_ci array[1] = *((u8 *)val); 66462306a36Sopenharmony_ci rtl92ee_fill_h2c_cmd(hw, H2C_92E_KEEP_ALIVE_CTRL, 2, array); 66562306a36Sopenharmony_ci } 66662306a36Sopenharmony_ci break; 66762306a36Sopenharmony_ci default: 66862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, 66962306a36Sopenharmony_ci "switch case %#x not processed\n", variable); 67062306a36Sopenharmony_ci break; 67162306a36Sopenharmony_ci } 67262306a36Sopenharmony_ci} 67362306a36Sopenharmony_ci 67462306a36Sopenharmony_cistatic bool _rtl92ee_llt_table_init(struct ieee80211_hw *hw) 67562306a36Sopenharmony_ci{ 67662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 67762306a36Sopenharmony_ci u8 txpktbuf_bndy; 67862306a36Sopenharmony_ci u8 u8tmp, testcnt = 0; 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci txpktbuf_bndy = 0xF7; 68162306a36Sopenharmony_ci 68262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RQPN, 0x80E60808); 68362306a36Sopenharmony_ci 68462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy); 68562306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_TRXFF_BNDY + 2, 0x3d00 - 1); 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DWBCN0_CTRL + 1, txpktbuf_bndy); 68862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DWBCN1_CTRL + 1, txpktbuf_bndy); 68962306a36Sopenharmony_ci 69062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNQ_BDNY, txpktbuf_bndy); 69162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNQ1_BDNY, txpktbuf_bndy); 69262306a36Sopenharmony_ci 69362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MGQ_BDNY, txpktbuf_bndy); 69462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); 69562306a36Sopenharmony_ci 69662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PBP, 0x31); 69762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); 69862306a36Sopenharmony_ci 69962306a36Sopenharmony_ci u8tmp = rtl_read_byte(rtlpriv, REG_AUTO_LLT + 2); 70062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AUTO_LLT + 2, u8tmp | BIT(0)); 70162306a36Sopenharmony_ci 70262306a36Sopenharmony_ci while (u8tmp & BIT(0)) { 70362306a36Sopenharmony_ci u8tmp = rtl_read_byte(rtlpriv, REG_AUTO_LLT + 2); 70462306a36Sopenharmony_ci udelay(10); 70562306a36Sopenharmony_ci testcnt++; 70662306a36Sopenharmony_ci if (testcnt > 10) 70762306a36Sopenharmony_ci break; 70862306a36Sopenharmony_ci } 70962306a36Sopenharmony_ci 71062306a36Sopenharmony_ci return true; 71162306a36Sopenharmony_ci} 71262306a36Sopenharmony_ci 71362306a36Sopenharmony_cistatic void _rtl92ee_gen_refresh_led_state(struct ieee80211_hw *hw) 71462306a36Sopenharmony_ci{ 71562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 71662306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 71762306a36Sopenharmony_ci enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; 71862306a36Sopenharmony_ci 71962306a36Sopenharmony_ci if (rtlpriv->rtlhal.up_first_time) 72062306a36Sopenharmony_ci return; 72162306a36Sopenharmony_ci 72262306a36Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) 72362306a36Sopenharmony_ci rtl92ee_sw_led_on(hw, pin0); 72462306a36Sopenharmony_ci else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) 72562306a36Sopenharmony_ci rtl92ee_sw_led_on(hw, pin0); 72662306a36Sopenharmony_ci else 72762306a36Sopenharmony_ci rtl92ee_sw_led_off(hw, pin0); 72862306a36Sopenharmony_ci} 72962306a36Sopenharmony_ci 73062306a36Sopenharmony_cistatic bool _rtl92ee_init_mac(struct ieee80211_hw *hw) 73162306a36Sopenharmony_ci{ 73262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 73362306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 73462306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 73562306a36Sopenharmony_ci 73662306a36Sopenharmony_ci u8 bytetmp; 73762306a36Sopenharmony_ci u16 wordtmp; 73862306a36Sopenharmony_ci u32 dwordtmp; 73962306a36Sopenharmony_ci 74062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); 74162306a36Sopenharmony_ci 74262306a36Sopenharmony_ci dwordtmp = rtl_read_dword(rtlpriv, REG_SYS_CFG1); 74362306a36Sopenharmony_ci if (dwordtmp & BIT(24)) { 74462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x7c, 0xc3); 74562306a36Sopenharmony_ci } else { 74662306a36Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, 0x16); 74762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x16, bytetmp | BIT(4) | BIT(6)); 74862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x7c, 0x83); 74962306a36Sopenharmony_ci } 75062306a36Sopenharmony_ci /* 1. 40Mhz crystal source*/ 75162306a36Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_AFE_CTRL2); 75262306a36Sopenharmony_ci bytetmp &= 0xfb; 75362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_CTRL2, bytetmp); 75462306a36Sopenharmony_ci 75562306a36Sopenharmony_ci dwordtmp = rtl_read_dword(rtlpriv, REG_AFE_CTRL4); 75662306a36Sopenharmony_ci dwordtmp &= 0xfffffc7f; 75762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_AFE_CTRL4, dwordtmp); 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci /* 2. 92E AFE parameter 76062306a36Sopenharmony_ci * MP chip then check version 76162306a36Sopenharmony_ci */ 76262306a36Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_AFE_CTRL2); 76362306a36Sopenharmony_ci bytetmp &= 0xbf; 76462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_CTRL2, bytetmp); 76562306a36Sopenharmony_ci 76662306a36Sopenharmony_ci dwordtmp = rtl_read_dword(rtlpriv, REG_AFE_CTRL4); 76762306a36Sopenharmony_ci dwordtmp &= 0xffdfffff; 76862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_AFE_CTRL4, dwordtmp); 76962306a36Sopenharmony_ci 77062306a36Sopenharmony_ci /* HW Power on sequence */ 77162306a36Sopenharmony_ci if (!rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, 77262306a36Sopenharmony_ci PWR_INTF_PCI_MSK, 77362306a36Sopenharmony_ci RTL8192E_NIC_ENABLE_FLOW)) { 77462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 77562306a36Sopenharmony_ci "init MAC Fail as rtl_hal_pwrseqcmdparsing\n"); 77662306a36Sopenharmony_ci return false; 77762306a36Sopenharmony_ci } 77862306a36Sopenharmony_ci 77962306a36Sopenharmony_ci /* Release MAC IO register reset */ 78062306a36Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_CR); 78162306a36Sopenharmony_ci bytetmp = 0xff; 78262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR, bytetmp); 78362306a36Sopenharmony_ci mdelay(2); 78462306a36Sopenharmony_ci bytetmp = 0x7f; 78562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, bytetmp); 78662306a36Sopenharmony_ci mdelay(2); 78762306a36Sopenharmony_ci 78862306a36Sopenharmony_ci /* Add for wakeup online */ 78962306a36Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_SYS_CLKR); 79062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_CLKR, bytetmp | BIT(3)); 79162306a36Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_GPIO_MUXCFG + 1); 79262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG + 1, bytetmp & (~BIT(4))); 79362306a36Sopenharmony_ci /* Release MAC IO register reset */ 79462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_CR, 0x2ff); 79562306a36Sopenharmony_ci 79662306a36Sopenharmony_ci if (!rtlhal->mac_func_enable) { 79762306a36Sopenharmony_ci if (!_rtl92ee_llt_table_init(hw)) { 79862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 79962306a36Sopenharmony_ci "LLT table init fail\n"); 80062306a36Sopenharmony_ci return false; 80162306a36Sopenharmony_ci } 80262306a36Sopenharmony_ci } 80362306a36Sopenharmony_ci 80462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); 80562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HISRE, 0xffffffff); 80662306a36Sopenharmony_ci 80762306a36Sopenharmony_ci wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); 80862306a36Sopenharmony_ci wordtmp &= 0xf; 80962306a36Sopenharmony_ci wordtmp |= 0xF5B1; 81062306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); 81162306a36Sopenharmony_ci /* Reported Tx status from HW for rate adaptive.*/ 81262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_ci /* Set RCR register */ 81562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); 81662306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RXFLTMAP2, 0xffff); 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci /* Set TCR register */ 81962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); 82062306a36Sopenharmony_ci 82162306a36Sopenharmony_ci /* Set TX/RX descriptor physical address -- HI part */ 82262306a36Sopenharmony_ci if (!rtlpriv->cfg->mod_params->dma64) 82362306a36Sopenharmony_ci goto dma64_end; 82462306a36Sopenharmony_ci 82562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BCNQ_DESA + 4, 82662306a36Sopenharmony_ci ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) >> 82762306a36Sopenharmony_ci 32); 82862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MGQ_DESA + 4, 82962306a36Sopenharmony_ci (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma >> 32); 83062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_VOQ_DESA + 4, 83162306a36Sopenharmony_ci (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma >> 32); 83262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_VIQ_DESA + 4, 83362306a36Sopenharmony_ci (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma >> 32); 83462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BEQ_DESA + 4, 83562306a36Sopenharmony_ci (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma >> 32); 83662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BKQ_DESA + 4, 83762306a36Sopenharmony_ci (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma >> 32); 83862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HQ0_DESA + 4, 83962306a36Sopenharmony_ci (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma >> 32); 84062306a36Sopenharmony_ci 84162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RX_DESA + 4, 84262306a36Sopenharmony_ci (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma >> 32); 84362306a36Sopenharmony_ci 84462306a36Sopenharmony_cidma64_end: 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci /* Set TX/RX descriptor physical address(from OS API). */ 84762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BCNQ_DESA, 84862306a36Sopenharmony_ci ((u64)rtlpci->tx_ring[BEACON_QUEUE].buffer_desc_dma) & 84962306a36Sopenharmony_ci DMA_BIT_MASK(32)); 85062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MGQ_DESA, 85162306a36Sopenharmony_ci (u64)rtlpci->tx_ring[MGNT_QUEUE].buffer_desc_dma & 85262306a36Sopenharmony_ci DMA_BIT_MASK(32)); 85362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_VOQ_DESA, 85462306a36Sopenharmony_ci (u64)rtlpci->tx_ring[VO_QUEUE].buffer_desc_dma & 85562306a36Sopenharmony_ci DMA_BIT_MASK(32)); 85662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_VIQ_DESA, 85762306a36Sopenharmony_ci (u64)rtlpci->tx_ring[VI_QUEUE].buffer_desc_dma & 85862306a36Sopenharmony_ci DMA_BIT_MASK(32)); 85962306a36Sopenharmony_ci 86062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BEQ_DESA, 86162306a36Sopenharmony_ci (u64)rtlpci->tx_ring[BE_QUEUE].buffer_desc_dma & 86262306a36Sopenharmony_ci DMA_BIT_MASK(32)); 86362306a36Sopenharmony_ci 86462306a36Sopenharmony_ci dwordtmp = rtl_read_dword(rtlpriv, REG_BEQ_DESA); 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BKQ_DESA, 86762306a36Sopenharmony_ci (u64)rtlpci->tx_ring[BK_QUEUE].buffer_desc_dma & 86862306a36Sopenharmony_ci DMA_BIT_MASK(32)); 86962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HQ0_DESA, 87062306a36Sopenharmony_ci (u64)rtlpci->tx_ring[HIGH_QUEUE].buffer_desc_dma & 87162306a36Sopenharmony_ci DMA_BIT_MASK(32)); 87262306a36Sopenharmony_ci 87362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RX_DESA, 87462306a36Sopenharmony_ci (u64)rtlpci->rx_ring[RX_MPDU_QUEUE].dma & 87562306a36Sopenharmony_ci DMA_BIT_MASK(32)); 87662306a36Sopenharmony_ci 87762306a36Sopenharmony_ci /* if we want to support 64 bit DMA, we should set it here, 87862306a36Sopenharmony_ci * but now we do not support 64 bit DMA 87962306a36Sopenharmony_ci */ 88062306a36Sopenharmony_ci 88162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTIMER_HCI, 0x3fffffff); 88262306a36Sopenharmony_ci 88362306a36Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 3); 88462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, bytetmp | 0xF7); 88562306a36Sopenharmony_ci 88662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_INT_MIG, 0); 88762306a36Sopenharmony_ci 88862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_MGQ_TXBD_NUM, 89162306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 89262306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM, 89362306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 89462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_VIQ_TXBD_NUM, 89562306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 89662306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BEQ_TXBD_NUM, 89762306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 89862306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_VOQ_TXBD_NUM, 89962306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 90062306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BKQ_TXBD_NUM, 90162306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 90262306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_HI0Q_TXBD_NUM, 90362306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 90462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_HI1Q_TXBD_NUM, 90562306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 90662306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_HI2Q_TXBD_NUM, 90762306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 90862306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_HI3Q_TXBD_NUM, 90962306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 91062306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_HI4Q_TXBD_NUM, 91162306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 91262306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_HI5Q_TXBD_NUM, 91362306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 91462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_HI6Q_TXBD_NUM, 91562306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 91662306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_HI7Q_TXBD_NUM, 91762306a36Sopenharmony_ci TX_DESC_NUM_92E | ((RTL8192EE_SEG_NUM << 12) & 0x3000)); 91862306a36Sopenharmony_ci /*Rx*/ 91962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RX_RXBD_NUM, 92062306a36Sopenharmony_ci RX_DESC_NUM_92E | 92162306a36Sopenharmony_ci ((RTL8192EE_SEG_NUM << 13) & 0x6000) | 0x8000); 92262306a36Sopenharmony_ci 92362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTIMER_HCI, 0XFFFFFFFF); 92462306a36Sopenharmony_ci 92562306a36Sopenharmony_ci _rtl92ee_gen_refresh_led_state(hw); 92662306a36Sopenharmony_ci return true; 92762306a36Sopenharmony_ci} 92862306a36Sopenharmony_ci 92962306a36Sopenharmony_cistatic void _rtl92ee_hw_configure(struct ieee80211_hw *hw) 93062306a36Sopenharmony_ci{ 93162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 93262306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 93362306a36Sopenharmony_ci u32 reg_rrsr; 93462306a36Sopenharmony_ci 93562306a36Sopenharmony_ci reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; 93662306a36Sopenharmony_ci /* Init value for RRSR. */ 93762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr); 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ci /* ARFB table 9 for 11ac 5G 2SS */ 94062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_ARFR0, 0x00000010); 94162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_ARFR0 + 4, 0x3e0ff000); 94262306a36Sopenharmony_ci 94362306a36Sopenharmony_ci /* ARFB table 10 for 11ac 5G 1SS */ 94462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_ARFR1, 0x00000010); 94562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_ARFR1 + 4, 0x000ff000); 94662306a36Sopenharmony_ci 94762306a36Sopenharmony_ci /* Set SLOT time */ 94862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SLOT, 0x09); 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci /* CF-End setting. */ 95162306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); 95262306a36Sopenharmony_ci 95362306a36Sopenharmony_ci /* Set retry limit */ 95462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RETRY_LIMIT, 0x0707); 95562306a36Sopenharmony_ci 95662306a36Sopenharmony_ci /* BAR settings */ 95762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x0201ffff); 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci /* Set Data / Response auto rate fallack retry count */ 96062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); 96162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); 96262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); 96362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); 96462306a36Sopenharmony_ci 96562306a36Sopenharmony_ci /* Beacon related, for rate adaptive */ 96662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); 96762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci rtlpci->reg_bcn_ctrl_val = 0x1d; 97062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci /* Marked out by Bruce, 2010-09-09. 97362306a36Sopenharmony_ci * This register is configured for the 2nd Beacon (multiple BSSID). 97462306a36Sopenharmony_ci * We shall disable this register if we only support 1 BSSID. 97562306a36Sopenharmony_ci * vivi guess 92d also need this, also 92d now doesnot set this reg 97662306a36Sopenharmony_ci */ 97762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL_1, 0); 97862306a36Sopenharmony_ci 97962306a36Sopenharmony_ci /* TBTT prohibit hold time. Suggested by designer TimChen. */ 98062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); /* 8 ms */ 98162306a36Sopenharmony_ci 98262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PIFS, 0); 98362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); 98462306a36Sopenharmony_ci 98562306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0040); 98662306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_PROT_MODE_CTRL, 0x08ff); 98762306a36Sopenharmony_ci 98862306a36Sopenharmony_ci /* For Rx TP. Suggested by SD1 Richard. Added by tynli. 2010.04.12.*/ 98962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_FAST_EDCA_CTRL, 0x03086666); 99062306a36Sopenharmony_ci 99162306a36Sopenharmony_ci /* ACKTO for IOT issue. */ 99262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); 99362306a36Sopenharmony_ci 99462306a36Sopenharmony_ci /* Set Spec SIFS (used in NAV) */ 99562306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x100a); 99662306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x100a); 99762306a36Sopenharmony_ci 99862306a36Sopenharmony_ci /* Set SIFS for CCK */ 99962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x100a); 100062306a36Sopenharmony_ci 100162306a36Sopenharmony_ci /* Set SIFS for OFDM */ 100262306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x100a); 100362306a36Sopenharmony_ci 100462306a36Sopenharmony_ci /* Note Data sheet don't define */ 100562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x4C7, 0x80); 100662306a36Sopenharmony_ci 100762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RX_PKT_LIMIT, 0x20); 100862306a36Sopenharmony_ci 100962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_MAX_AGGR_NUM, 0x1717); 101062306a36Sopenharmony_ci 101162306a36Sopenharmony_ci /* Set Multicast Address. 2009.01.07. by tynli. */ 101262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); 101362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); 101462306a36Sopenharmony_ci} 101562306a36Sopenharmony_ci 101662306a36Sopenharmony_cistatic void _rtl92ee_enable_aspm_back_door(struct ieee80211_hw *hw) 101762306a36Sopenharmony_ci{ 101862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 101962306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 102062306a36Sopenharmony_ci u32 tmp32 = 0, count = 0; 102162306a36Sopenharmony_ci u8 tmp8 = 0; 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0x78); 102462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x2); 102562306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 102662306a36Sopenharmony_ci count = 0; 102762306a36Sopenharmony_ci while (tmp8 && count < 20) { 102862306a36Sopenharmony_ci udelay(10); 102962306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 103062306a36Sopenharmony_ci count++; 103162306a36Sopenharmony_ci } 103262306a36Sopenharmony_ci 103362306a36Sopenharmony_ci if (0 == tmp8) { 103462306a36Sopenharmony_ci tmp32 = rtl_read_dword(rtlpriv, REG_BACKDOOR_DBI_RDATA); 103562306a36Sopenharmony_ci if ((tmp32 & 0xff00) != 0x2000) { 103662306a36Sopenharmony_ci tmp32 &= 0xffff00ff; 103762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BACKDOOR_DBI_WDATA, 103862306a36Sopenharmony_ci tmp32 | BIT(13)); 103962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0xf078); 104062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x1); 104162306a36Sopenharmony_ci 104262306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, 104362306a36Sopenharmony_ci REG_BACKDOOR_DBI_DATA + 2); 104462306a36Sopenharmony_ci count = 0; 104562306a36Sopenharmony_ci while (tmp8 && count < 20) { 104662306a36Sopenharmony_ci udelay(10); 104762306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, 104862306a36Sopenharmony_ci REG_BACKDOOR_DBI_DATA + 2); 104962306a36Sopenharmony_ci count++; 105062306a36Sopenharmony_ci } 105162306a36Sopenharmony_ci } 105262306a36Sopenharmony_ci } 105362306a36Sopenharmony_ci 105462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0x70c); 105562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x2); 105662306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 105762306a36Sopenharmony_ci count = 0; 105862306a36Sopenharmony_ci while (tmp8 && count < 20) { 105962306a36Sopenharmony_ci udelay(10); 106062306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 106162306a36Sopenharmony_ci count++; 106262306a36Sopenharmony_ci } 106362306a36Sopenharmony_ci if (0 == tmp8) { 106462306a36Sopenharmony_ci tmp32 = rtl_read_dword(rtlpriv, REG_BACKDOOR_DBI_RDATA); 106562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BACKDOOR_DBI_WDATA, 106662306a36Sopenharmony_ci tmp32 | BIT(31)); 106762306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0xf70c); 106862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x1); 106962306a36Sopenharmony_ci } 107062306a36Sopenharmony_ci 107162306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 107262306a36Sopenharmony_ci count = 0; 107362306a36Sopenharmony_ci while (tmp8 && count < 20) { 107462306a36Sopenharmony_ci udelay(10); 107562306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 107662306a36Sopenharmony_ci count++; 107762306a36Sopenharmony_ci } 107862306a36Sopenharmony_ci 107962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0x718); 108062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x2); 108162306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 108262306a36Sopenharmony_ci count = 0; 108362306a36Sopenharmony_ci while (tmp8 && count < 20) { 108462306a36Sopenharmony_ci udelay(10); 108562306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 108662306a36Sopenharmony_ci count++; 108762306a36Sopenharmony_ci } 108862306a36Sopenharmony_ci if (ppsc->support_backdoor || (0 == tmp8)) { 108962306a36Sopenharmony_ci tmp32 = rtl_read_dword(rtlpriv, REG_BACKDOOR_DBI_RDATA); 109062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BACKDOOR_DBI_WDATA, 109162306a36Sopenharmony_ci tmp32 | BIT(11) | BIT(12)); 109262306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BACKDOOR_DBI_DATA, 0xf718); 109362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2, 0x1); 109462306a36Sopenharmony_ci } 109562306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 109662306a36Sopenharmony_ci count = 0; 109762306a36Sopenharmony_ci while (tmp8 && count < 20) { 109862306a36Sopenharmony_ci udelay(10); 109962306a36Sopenharmony_ci tmp8 = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 2); 110062306a36Sopenharmony_ci count++; 110162306a36Sopenharmony_ci } 110262306a36Sopenharmony_ci} 110362306a36Sopenharmony_ci 110462306a36Sopenharmony_civoid rtl92ee_enable_hw_security_config(struct ieee80211_hw *hw) 110562306a36Sopenharmony_ci{ 110662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 110762306a36Sopenharmony_ci u8 sec_reg_value; 110862306a36Sopenharmony_ci u8 tmp; 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, 111162306a36Sopenharmony_ci "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", 111262306a36Sopenharmony_ci rtlpriv->sec.pairwise_enc_algorithm, 111362306a36Sopenharmony_ci rtlpriv->sec.group_enc_algorithm); 111462306a36Sopenharmony_ci 111562306a36Sopenharmony_ci if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { 111662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 111762306a36Sopenharmony_ci "not open hw encryption\n"); 111862306a36Sopenharmony_ci return; 111962306a36Sopenharmony_ci } 112062306a36Sopenharmony_ci 112162306a36Sopenharmony_ci sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; 112262306a36Sopenharmony_ci 112362306a36Sopenharmony_ci if (rtlpriv->sec.use_defaultkey) { 112462306a36Sopenharmony_ci sec_reg_value |= SCR_TXUSEDK; 112562306a36Sopenharmony_ci sec_reg_value |= SCR_RXUSEDK; 112662306a36Sopenharmony_ci } 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); 112962306a36Sopenharmony_ci 113062306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_CR + 1); 113162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, tmp | BIT(1)); 113262306a36Sopenharmony_ci 113362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 113462306a36Sopenharmony_ci "The SECR-value %x\n", sec_reg_value); 113562306a36Sopenharmony_ci 113662306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); 113762306a36Sopenharmony_ci} 113862306a36Sopenharmony_ci 113962306a36Sopenharmony_cistatic bool _rtl8192ee_check_pcie_dma_hang(struct rtl_priv *rtlpriv) 114062306a36Sopenharmony_ci{ 114162306a36Sopenharmony_ci u8 tmp; 114262306a36Sopenharmony_ci 114362306a36Sopenharmony_ci /* write reg 0x350 Bit[26]=1. Enable debug port. */ 114462306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3); 114562306a36Sopenharmony_ci if (!(tmp & BIT(2))) { 114662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3, 114762306a36Sopenharmony_ci tmp | BIT(2)); 114862306a36Sopenharmony_ci mdelay(100); /* Suggested by DD Justin_tsai. */ 114962306a36Sopenharmony_ci } 115062306a36Sopenharmony_ci 115162306a36Sopenharmony_ci /* read reg 0x350 Bit[25] if 1 : RX hang 115262306a36Sopenharmony_ci * read reg 0x350 Bit[24] if 1 : TX hang 115362306a36Sopenharmony_ci */ 115462306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_BACKDOOR_DBI_DATA + 3); 115562306a36Sopenharmony_ci if ((tmp & BIT(0)) || (tmp & BIT(1))) { 115662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 115762306a36Sopenharmony_ci "CheckPcieDMAHang8192EE(): true!!\n"); 115862306a36Sopenharmony_ci return true; 115962306a36Sopenharmony_ci } 116062306a36Sopenharmony_ci return false; 116162306a36Sopenharmony_ci} 116262306a36Sopenharmony_ci 116362306a36Sopenharmony_cistatic void _rtl8192ee_reset_pcie_interface_dma(struct rtl_priv *rtlpriv, 116462306a36Sopenharmony_ci bool mac_power_on) 116562306a36Sopenharmony_ci{ 116662306a36Sopenharmony_ci u8 tmp; 116762306a36Sopenharmony_ci bool release_mac_rx_pause; 116862306a36Sopenharmony_ci u8 backup_pcie_dma_pause; 116962306a36Sopenharmony_ci 117062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 117162306a36Sopenharmony_ci "ResetPcieInterfaceDMA8192EE()\n"); 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_ci /* Revise Note: Follow the document "PCIe RX DMA Hang Reset Flow_v03" 117462306a36Sopenharmony_ci * released by SD1 Alan. 117562306a36Sopenharmony_ci */ 117662306a36Sopenharmony_ci 117762306a36Sopenharmony_ci /* 1. disable register write lock 117862306a36Sopenharmony_ci * write 0x1C bit[1:0] = 2'h0 117962306a36Sopenharmony_ci * write 0xCC bit[2] = 1'b1 118062306a36Sopenharmony_ci */ 118162306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL); 118262306a36Sopenharmony_ci tmp &= ~(BIT(1) | BIT(0)); 118362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, tmp); 118462306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2); 118562306a36Sopenharmony_ci tmp |= BIT(2); 118662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp); 118762306a36Sopenharmony_ci 118862306a36Sopenharmony_ci /* 2. Check and pause TRX DMA 118962306a36Sopenharmony_ci * write 0x284 bit[18] = 1'b1 119062306a36Sopenharmony_ci * write 0x301 = 0xFF 119162306a36Sopenharmony_ci */ 119262306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); 119362306a36Sopenharmony_ci if (tmp & BIT(2)) { 119462306a36Sopenharmony_ci /* Already pause before the function for another reason. */ 119562306a36Sopenharmony_ci release_mac_rx_pause = false; 119662306a36Sopenharmony_ci } else { 119762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, (tmp | BIT(2))); 119862306a36Sopenharmony_ci release_mac_rx_pause = true; 119962306a36Sopenharmony_ci } 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_ci backup_pcie_dma_pause = rtl_read_byte(rtlpriv, REG_PCIE_CTRL_REG + 1); 120262306a36Sopenharmony_ci if (backup_pcie_dma_pause != 0xFF) 120362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFF); 120462306a36Sopenharmony_ci 120562306a36Sopenharmony_ci if (mac_power_on) { 120662306a36Sopenharmony_ci /* 3. reset TRX function 120762306a36Sopenharmony_ci * write 0x100 = 0x00 120862306a36Sopenharmony_ci */ 120962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR, 0); 121062306a36Sopenharmony_ci } 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci /* 4. Reset PCIe DMA 121362306a36Sopenharmony_ci * write 0x003 bit[0] = 0 121462306a36Sopenharmony_ci */ 121562306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 121662306a36Sopenharmony_ci tmp &= ~(BIT(0)); 121762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp); 121862306a36Sopenharmony_ci 121962306a36Sopenharmony_ci /* 5. Enable PCIe DMA 122062306a36Sopenharmony_ci * write 0x003 bit[0] = 1 122162306a36Sopenharmony_ci */ 122262306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 122362306a36Sopenharmony_ci tmp |= BIT(0); 122462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmp); 122562306a36Sopenharmony_ci 122662306a36Sopenharmony_ci if (mac_power_on) { 122762306a36Sopenharmony_ci /* 6. enable TRX function 122862306a36Sopenharmony_ci * write 0x100 = 0xFF 122962306a36Sopenharmony_ci */ 123062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR, 0xFF); 123162306a36Sopenharmony_ci 123262306a36Sopenharmony_ci /* We should init LLT & RQPN and 123362306a36Sopenharmony_ci * prepare Tx/Rx descrptor address later 123462306a36Sopenharmony_ci * because MAC function is reset. 123562306a36Sopenharmony_ci */ 123662306a36Sopenharmony_ci } 123762306a36Sopenharmony_ci 123862306a36Sopenharmony_ci /* 7. Restore PCIe autoload down bit 123962306a36Sopenharmony_ci * write 0xF8 bit[17] = 1'b1 124062306a36Sopenharmony_ci */ 124162306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2); 124262306a36Sopenharmony_ci tmp |= BIT(1); 124362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL + 2, tmp); 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci /* In MAC power on state, BB and RF maybe in ON state, 124662306a36Sopenharmony_ci * if we release TRx DMA here 124762306a36Sopenharmony_ci * it will cause packets to be started to Tx/Rx, 124862306a36Sopenharmony_ci * so we release Tx/Rx DMA later. 124962306a36Sopenharmony_ci */ 125062306a36Sopenharmony_ci if (!mac_power_on) { 125162306a36Sopenharmony_ci /* 8. release TRX DMA 125262306a36Sopenharmony_ci * write 0x284 bit[18] = 1'b0 125362306a36Sopenharmony_ci * write 0x301 = 0x00 125462306a36Sopenharmony_ci */ 125562306a36Sopenharmony_ci if (release_mac_rx_pause) { 125662306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_RXDMA_CONTROL); 125762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXDMA_CONTROL, 125862306a36Sopenharmony_ci (tmp & (~BIT(2)))); 125962306a36Sopenharmony_ci } 126062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 126162306a36Sopenharmony_ci backup_pcie_dma_pause); 126262306a36Sopenharmony_ci } 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_ci /* 9. lock system register 126562306a36Sopenharmony_ci * write 0xCC bit[2] = 1'b0 126662306a36Sopenharmony_ci */ 126762306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, REG_PMC_DBG_CTRL2); 126862306a36Sopenharmony_ci tmp &= ~(BIT(2)); 126962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PMC_DBG_CTRL2, tmp); 127062306a36Sopenharmony_ci} 127162306a36Sopenharmony_ci 127262306a36Sopenharmony_ciint rtl92ee_hw_init(struct ieee80211_hw *hw) 127362306a36Sopenharmony_ci{ 127462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 127562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 127662306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 127762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 127862306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 127962306a36Sopenharmony_ci bool rtstatus = true; 128062306a36Sopenharmony_ci int err = 0; 128162306a36Sopenharmony_ci u8 tmp_u1b, u1byte; 128262306a36Sopenharmony_ci u32 tmp_u4b; 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, " Rtl8192EE hw init\n"); 128562306a36Sopenharmony_ci rtlpriv->rtlhal.being_init_adapter = true; 128662306a36Sopenharmony_ci rtlpriv->intf_ops->disable_aspm(hw); 128762306a36Sopenharmony_ci 128862306a36Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, REG_SYS_CLKR+1); 128962306a36Sopenharmony_ci u1byte = rtl_read_byte(rtlpriv, REG_CR); 129062306a36Sopenharmony_ci if ((tmp_u1b & BIT(3)) && (u1byte != 0 && u1byte != 0xEA)) { 129162306a36Sopenharmony_ci rtlhal->mac_func_enable = true; 129262306a36Sopenharmony_ci } else { 129362306a36Sopenharmony_ci rtlhal->mac_func_enable = false; 129462306a36Sopenharmony_ci rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_92E; 129562306a36Sopenharmony_ci } 129662306a36Sopenharmony_ci 129762306a36Sopenharmony_ci if (_rtl8192ee_check_pcie_dma_hang(rtlpriv)) { 129862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "92ee dma hang!\n"); 129962306a36Sopenharmony_ci _rtl8192ee_reset_pcie_interface_dma(rtlpriv, 130062306a36Sopenharmony_ci rtlhal->mac_func_enable); 130162306a36Sopenharmony_ci rtlhal->mac_func_enable = false; 130262306a36Sopenharmony_ci } 130362306a36Sopenharmony_ci 130462306a36Sopenharmony_ci rtstatus = _rtl92ee_init_mac(hw); 130562306a36Sopenharmony_ci 130662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x577, 0x03); 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci /*for Crystal 40 Mhz setting */ 130962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_CTRL4, 0x2A); 131062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_CTRL4 + 1, 0x00); 131162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_CTRL2, 0x83); 131262306a36Sopenharmony_ci 131362306a36Sopenharmony_ci /*Forced the antenna b to wifi */ 131462306a36Sopenharmony_ci if (rtlpriv->btcoexist.btc_info.btcoexist == 1) { 131562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x64, 0); 131662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x65, 1); 131762306a36Sopenharmony_ci } 131862306a36Sopenharmony_ci if (!rtstatus) { 131962306a36Sopenharmony_ci pr_err("Init MAC failed\n"); 132062306a36Sopenharmony_ci err = 1; 132162306a36Sopenharmony_ci return err; 132262306a36Sopenharmony_ci } 132362306a36Sopenharmony_ci rtlhal->rx_tag = 0; 132462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_PCIE_CTRL_REG, 0x8000); 132562306a36Sopenharmony_ci err = rtl92ee_download_fw(hw, false); 132662306a36Sopenharmony_ci if (err) { 132762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 132862306a36Sopenharmony_ci "Failed to download FW. Init HW without FW now..\n"); 132962306a36Sopenharmony_ci err = 1; 133062306a36Sopenharmony_ci rtlhal->fw_ready = false; 133162306a36Sopenharmony_ci return err; 133262306a36Sopenharmony_ci } 133362306a36Sopenharmony_ci rtlhal->fw_ready = true; 133462306a36Sopenharmony_ci /*fw related variable initialize */ 133562306a36Sopenharmony_ci ppsc->fw_current_inpsmode = false; 133662306a36Sopenharmony_ci rtlhal->fw_ps_state = FW_PS_STATE_ALL_ON_92E; 133762306a36Sopenharmony_ci rtlhal->fw_clk_change_in_progress = false; 133862306a36Sopenharmony_ci rtlhal->allow_sw_to_change_hwclc = false; 133962306a36Sopenharmony_ci rtlhal->last_hmeboxnum = 0; 134062306a36Sopenharmony_ci 134162306a36Sopenharmony_ci rtl92ee_phy_mac_config(hw); 134262306a36Sopenharmony_ci 134362306a36Sopenharmony_ci rtl92ee_phy_bb_config(hw); 134462306a36Sopenharmony_ci 134562306a36Sopenharmony_ci rtl92ee_phy_rf_config(hw); 134662306a36Sopenharmony_ci 134762306a36Sopenharmony_ci rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, RF90_PATH_A, 134862306a36Sopenharmony_ci RF_CHNLBW, RFREG_OFFSET_MASK); 134962306a36Sopenharmony_ci rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, RF90_PATH_B, 135062306a36Sopenharmony_ci RF_CHNLBW, RFREG_OFFSET_MASK); 135162306a36Sopenharmony_ci rtlphy->backup_rf_0x1a = (u32)rtl_get_rfreg(hw, RF90_PATH_A, RF_RX_G1, 135262306a36Sopenharmony_ci RFREG_OFFSET_MASK); 135362306a36Sopenharmony_ci rtlphy->rfreg_chnlval[0] = (rtlphy->rfreg_chnlval[0] & 0xfffff3ff) | 135462306a36Sopenharmony_ci BIT(10) | BIT(11); 135562306a36Sopenharmony_ci 135662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_CHNLBW, RFREG_OFFSET_MASK, 135762306a36Sopenharmony_ci rtlphy->rfreg_chnlval[0]); 135862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, RF_CHNLBW, RFREG_OFFSET_MASK, 135962306a36Sopenharmony_ci rtlphy->rfreg_chnlval[0]); 136062306a36Sopenharmony_ci 136162306a36Sopenharmony_ci /*---- Set CCK and OFDM Block "ON"----*/ 136262306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); 136362306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); 136462306a36Sopenharmony_ci 136562306a36Sopenharmony_ci /* Must set this, 136662306a36Sopenharmony_ci * otherwise the rx sensitivity will be very pool. Maddest 136762306a36Sopenharmony_ci */ 136862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0xB1, RFREG_OFFSET_MASK, 0x54418); 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_ci /*Set Hardware(MAC default setting.)*/ 137162306a36Sopenharmony_ci _rtl92ee_hw_configure(hw); 137262306a36Sopenharmony_ci 137362306a36Sopenharmony_ci rtlhal->mac_func_enable = true; 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_ci rtl_cam_reset_all_entry(hw); 137662306a36Sopenharmony_ci rtl92ee_enable_hw_security_config(hw); 137762306a36Sopenharmony_ci 137862306a36Sopenharmony_ci ppsc->rfpwr_state = ERFON; 137962306a36Sopenharmony_ci 138062306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); 138162306a36Sopenharmony_ci _rtl92ee_enable_aspm_back_door(hw); 138262306a36Sopenharmony_ci rtlpriv->intf_ops->enable_aspm(hw); 138362306a36Sopenharmony_ci 138462306a36Sopenharmony_ci rtl92ee_bt_hw_init(hw); 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_ci rtlpriv->rtlhal.being_init_adapter = false; 138762306a36Sopenharmony_ci 138862306a36Sopenharmony_ci if (ppsc->rfpwr_state == ERFON) { 138962306a36Sopenharmony_ci if (rtlphy->iqk_initialized) { 139062306a36Sopenharmony_ci rtl92ee_phy_iq_calibrate(hw, true); 139162306a36Sopenharmony_ci } else { 139262306a36Sopenharmony_ci rtl92ee_phy_iq_calibrate(hw, false); 139362306a36Sopenharmony_ci rtlphy->iqk_initialized = true; 139462306a36Sopenharmony_ci } 139562306a36Sopenharmony_ci } 139662306a36Sopenharmony_ci 139762306a36Sopenharmony_ci rtlphy->rfpath_rx_enable[0] = true; 139862306a36Sopenharmony_ci if (rtlphy->rf_type == RF_2T2R) 139962306a36Sopenharmony_ci rtlphy->rfpath_rx_enable[1] = true; 140062306a36Sopenharmony_ci 140162306a36Sopenharmony_ci efuse_one_byte_read(hw, 0x1FA, &tmp_u1b); 140262306a36Sopenharmony_ci if (!(tmp_u1b & BIT(0))) { 140362306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0F, 0x05); 140462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "PA BIAS path A\n"); 140562306a36Sopenharmony_ci } 140662306a36Sopenharmony_ci 140762306a36Sopenharmony_ci if ((!(tmp_u1b & BIT(1))) && (rtlphy->rf_type == RF_2T2R)) { 140862306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0F, 0x05); 140962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "PA BIAS path B\n"); 141062306a36Sopenharmony_ci } 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_NAV_UPPER, ((30000 + 127) / 128)); 141362306a36Sopenharmony_ci 141462306a36Sopenharmony_ci /*Fixed LDPC rx hang issue. */ 141562306a36Sopenharmony_ci tmp_u4b = rtl_read_dword(rtlpriv, REG_SYS_SWR_CTRL1); 141662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_SWR_CTRL2, 0x75); 141762306a36Sopenharmony_ci tmp_u4b = (tmp_u4b & 0xfff00fff) | (0x7E << 12); 141862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_SYS_SWR_CTRL1, tmp_u4b); 141962306a36Sopenharmony_ci 142062306a36Sopenharmony_ci rtl92ee_dm_init(hw); 142162306a36Sopenharmony_ci 142262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, 0x4fc, 0); 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 142562306a36Sopenharmony_ci "end of Rtl8192EE hw init %x\n", err); 142662306a36Sopenharmony_ci return 0; 142762306a36Sopenharmony_ci} 142862306a36Sopenharmony_ci 142962306a36Sopenharmony_cistatic enum version_8192e _rtl92ee_read_chip_version(struct ieee80211_hw *hw) 143062306a36Sopenharmony_ci{ 143162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 143262306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 143362306a36Sopenharmony_ci enum version_8192e version; 143462306a36Sopenharmony_ci u32 value32; 143562306a36Sopenharmony_ci 143662306a36Sopenharmony_ci rtlphy->rf_type = RF_2T2R; 143762306a36Sopenharmony_ci 143862306a36Sopenharmony_ci value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG1); 143962306a36Sopenharmony_ci if (value32 & TRP_VAUX_EN) 144062306a36Sopenharmony_ci version = (enum version_8192e)VERSION_TEST_CHIP_2T2R_8192E; 144162306a36Sopenharmony_ci else 144262306a36Sopenharmony_ci version = (enum version_8192e)VERSION_NORMAL_CHIP_2T2R_8192E; 144362306a36Sopenharmony_ci 144462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 144562306a36Sopenharmony_ci "Chip RF Type: %s\n", (rtlphy->rf_type == RF_2T2R) ? 144662306a36Sopenharmony_ci "RF_2T2R" : "RF_1T1R"); 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci return version; 144962306a36Sopenharmony_ci} 145062306a36Sopenharmony_ci 145162306a36Sopenharmony_cistatic int _rtl92ee_set_media_status(struct ieee80211_hw *hw, 145262306a36Sopenharmony_ci enum nl80211_iftype type) 145362306a36Sopenharmony_ci{ 145462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 145562306a36Sopenharmony_ci u8 bt_msr = rtl_read_byte(rtlpriv, MSR) & 0xfc; 145662306a36Sopenharmony_ci enum led_ctl_mode ledaction = LED_CTL_NO_LINK; 145762306a36Sopenharmony_ci u8 mode = MSR_NOLINK; 145862306a36Sopenharmony_ci 145962306a36Sopenharmony_ci switch (type) { 146062306a36Sopenharmony_ci case NL80211_IFTYPE_UNSPECIFIED: 146162306a36Sopenharmony_ci mode = MSR_NOLINK; 146262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 146362306a36Sopenharmony_ci "Set Network type to NO LINK!\n"); 146462306a36Sopenharmony_ci break; 146562306a36Sopenharmony_ci case NL80211_IFTYPE_ADHOC: 146662306a36Sopenharmony_ci case NL80211_IFTYPE_MESH_POINT: 146762306a36Sopenharmony_ci mode = MSR_ADHOC; 146862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 146962306a36Sopenharmony_ci "Set Network type to Ad Hoc!\n"); 147062306a36Sopenharmony_ci break; 147162306a36Sopenharmony_ci case NL80211_IFTYPE_STATION: 147262306a36Sopenharmony_ci mode = MSR_INFRA; 147362306a36Sopenharmony_ci ledaction = LED_CTL_LINK; 147462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 147562306a36Sopenharmony_ci "Set Network type to STA!\n"); 147662306a36Sopenharmony_ci break; 147762306a36Sopenharmony_ci case NL80211_IFTYPE_AP: 147862306a36Sopenharmony_ci mode = MSR_AP; 147962306a36Sopenharmony_ci ledaction = LED_CTL_LINK; 148062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 148162306a36Sopenharmony_ci "Set Network type to AP!\n"); 148262306a36Sopenharmony_ci break; 148362306a36Sopenharmony_ci default: 148462306a36Sopenharmony_ci pr_err("Network type %d not support!\n", type); 148562306a36Sopenharmony_ci return 1; 148662306a36Sopenharmony_ci } 148762306a36Sopenharmony_ci 148862306a36Sopenharmony_ci /* MSR_INFRA == Link in infrastructure network; 148962306a36Sopenharmony_ci * MSR_ADHOC == Link in ad hoc network; 149062306a36Sopenharmony_ci * Therefore, check link state is necessary. 149162306a36Sopenharmony_ci * 149262306a36Sopenharmony_ci * MSR_AP == AP mode; link state is not cared here. 149362306a36Sopenharmony_ci */ 149462306a36Sopenharmony_ci if (mode != MSR_AP && rtlpriv->mac80211.link_state < MAC80211_LINKED) { 149562306a36Sopenharmony_ci mode = MSR_NOLINK; 149662306a36Sopenharmony_ci ledaction = LED_CTL_NO_LINK; 149762306a36Sopenharmony_ci } 149862306a36Sopenharmony_ci 149962306a36Sopenharmony_ci if (mode == MSR_NOLINK || mode == MSR_INFRA) { 150062306a36Sopenharmony_ci _rtl92ee_stop_tx_beacon(hw); 150162306a36Sopenharmony_ci _rtl92ee_enable_bcn_sub_func(hw); 150262306a36Sopenharmony_ci } else if (mode == MSR_ADHOC || mode == MSR_AP) { 150362306a36Sopenharmony_ci _rtl92ee_resume_tx_beacon(hw); 150462306a36Sopenharmony_ci _rtl92ee_disable_bcn_sub_func(hw); 150562306a36Sopenharmony_ci } else { 150662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 150762306a36Sopenharmony_ci "Set HW_VAR_MEDIA_STATUS: No such media status(%x).\n", 150862306a36Sopenharmony_ci mode); 150962306a36Sopenharmony_ci } 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, MSR, bt_msr | mode); 151262306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, ledaction); 151362306a36Sopenharmony_ci if (mode == MSR_AP) 151462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 151562306a36Sopenharmony_ci else 151662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 151762306a36Sopenharmony_ci return 0; 151862306a36Sopenharmony_ci} 151962306a36Sopenharmony_ci 152062306a36Sopenharmony_civoid rtl92ee_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 152162306a36Sopenharmony_ci{ 152262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 152362306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 152462306a36Sopenharmony_ci u32 reg_rcr = rtlpci->receive_config; 152562306a36Sopenharmony_ci 152662306a36Sopenharmony_ci if (rtlpriv->psc.rfpwr_state != ERFON) 152762306a36Sopenharmony_ci return; 152862306a36Sopenharmony_ci 152962306a36Sopenharmony_ci if (check_bssid) { 153062306a36Sopenharmony_ci reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); 153162306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, 153262306a36Sopenharmony_ci (u8 *)(®_rcr)); 153362306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, 0, BIT(4)); 153462306a36Sopenharmony_ci } else { 153562306a36Sopenharmony_ci reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); 153662306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, BIT(4), 0); 153762306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, 153862306a36Sopenharmony_ci (u8 *)(®_rcr)); 153962306a36Sopenharmony_ci } 154062306a36Sopenharmony_ci} 154162306a36Sopenharmony_ci 154262306a36Sopenharmony_ciint rtl92ee_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) 154362306a36Sopenharmony_ci{ 154462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 154562306a36Sopenharmony_ci 154662306a36Sopenharmony_ci if (_rtl92ee_set_media_status(hw, type)) 154762306a36Sopenharmony_ci return -EOPNOTSUPP; 154862306a36Sopenharmony_ci 154962306a36Sopenharmony_ci if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { 155062306a36Sopenharmony_ci if (type != NL80211_IFTYPE_AP && 155162306a36Sopenharmony_ci type != NL80211_IFTYPE_MESH_POINT) 155262306a36Sopenharmony_ci rtl92ee_set_check_bssid(hw, true); 155362306a36Sopenharmony_ci } else { 155462306a36Sopenharmony_ci rtl92ee_set_check_bssid(hw, false); 155562306a36Sopenharmony_ci } 155662306a36Sopenharmony_ci 155762306a36Sopenharmony_ci return 0; 155862306a36Sopenharmony_ci} 155962306a36Sopenharmony_ci 156062306a36Sopenharmony_ci/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ 156162306a36Sopenharmony_civoid rtl92ee_set_qos(struct ieee80211_hw *hw, int aci) 156262306a36Sopenharmony_ci{ 156362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 156462306a36Sopenharmony_ci 156562306a36Sopenharmony_ci rtl92ee_dm_init_edca_turbo(hw); 156662306a36Sopenharmony_ci switch (aci) { 156762306a36Sopenharmony_ci case AC1_BK: 156862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 0xa44f); 156962306a36Sopenharmony_ci break; 157062306a36Sopenharmony_ci case AC0_BE: 157162306a36Sopenharmony_ci /* rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, u4b_ac_param); */ 157262306a36Sopenharmony_ci break; 157362306a36Sopenharmony_ci case AC2_VI: 157462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 0x5e4322); 157562306a36Sopenharmony_ci break; 157662306a36Sopenharmony_ci case AC3_VO: 157762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 0x2f3222); 157862306a36Sopenharmony_ci break; 157962306a36Sopenharmony_ci default: 158062306a36Sopenharmony_ci WARN_ONCE(true, "rtl8192ee: invalid aci: %d !\n", aci); 158162306a36Sopenharmony_ci break; 158262306a36Sopenharmony_ci } 158362306a36Sopenharmony_ci} 158462306a36Sopenharmony_ci 158562306a36Sopenharmony_civoid rtl92ee_enable_interrupt(struct ieee80211_hw *hw) 158662306a36Sopenharmony_ci{ 158762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 158862306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 158962306a36Sopenharmony_ci 159062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); 159162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); 159262306a36Sopenharmony_ci rtlpci->irq_enabled = true; 159362306a36Sopenharmony_ci} 159462306a36Sopenharmony_ci 159562306a36Sopenharmony_civoid rtl92ee_disable_interrupt(struct ieee80211_hw *hw) 159662306a36Sopenharmony_ci{ 159762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 159862306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 159962306a36Sopenharmony_ci 160062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HIMR, IMR_DISABLED); 160162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HIMRE, IMR_DISABLED); 160262306a36Sopenharmony_ci rtlpci->irq_enabled = false; 160362306a36Sopenharmony_ci /*synchronize_irq(rtlpci->pdev->irq);*/ 160462306a36Sopenharmony_ci} 160562306a36Sopenharmony_ci 160662306a36Sopenharmony_cistatic void _rtl92ee_poweroff_adapter(struct ieee80211_hw *hw) 160762306a36Sopenharmony_ci{ 160862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 160962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 161062306a36Sopenharmony_ci u8 u1b_tmp; 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_ci rtlhal->mac_func_enable = false; 161362306a36Sopenharmony_ci 161462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "POWER OFF adapter\n"); 161562306a36Sopenharmony_ci 161662306a36Sopenharmony_ci /* Run LPS WL RFOFF flow */ 161762306a36Sopenharmony_ci rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, 161862306a36Sopenharmony_ci PWR_INTF_PCI_MSK, RTL8192E_NIC_LPS_ENTER_FLOW); 161962306a36Sopenharmony_ci /* turn off RF */ 162062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci /* ==== Reset digital sequence ====== */ 162362306a36Sopenharmony_ci if ((rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(7)) && rtlhal->fw_ready) 162462306a36Sopenharmony_ci rtl92ee_firmware_selfreset(hw); 162562306a36Sopenharmony_ci 162662306a36Sopenharmony_ci /* Reset MCU */ 162762306a36Sopenharmony_ci u1b_tmp = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 162862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, (u1b_tmp & (~BIT(2)))); 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_ci /* reset MCU ready status */ 163162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); 163262306a36Sopenharmony_ci 163362306a36Sopenharmony_ci /* HW card disable configuration. */ 163462306a36Sopenharmony_ci rtl_hal_pwrseqcmdparsing(rtlpriv, PWR_CUT_ALL_MSK, PWR_FAB_ALL_MSK, 163562306a36Sopenharmony_ci PWR_INTF_PCI_MSK, RTL8192E_NIC_DISABLE_FLOW); 163662306a36Sopenharmony_ci 163762306a36Sopenharmony_ci /* Reset MCU IO Wrapper */ 163862306a36Sopenharmony_ci u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); 163962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp & (~BIT(0)))); 164062306a36Sopenharmony_ci u1b_tmp = rtl_read_byte(rtlpriv, REG_RSV_CTRL + 1); 164162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL + 1, (u1b_tmp | BIT(0))); 164262306a36Sopenharmony_ci 164362306a36Sopenharmony_ci /* lock ISO/CLK/Power control register */ 164462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E); 164562306a36Sopenharmony_ci} 164662306a36Sopenharmony_ci 164762306a36Sopenharmony_civoid rtl92ee_card_disable(struct ieee80211_hw *hw) 164862306a36Sopenharmony_ci{ 164962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 165062306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 165162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 165262306a36Sopenharmony_ci enum nl80211_iftype opmode; 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "RTL8192ee card disable\n"); 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 165762306a36Sopenharmony_ci 165862306a36Sopenharmony_ci mac->link_state = MAC80211_NOLINK; 165962306a36Sopenharmony_ci opmode = NL80211_IFTYPE_UNSPECIFIED; 166062306a36Sopenharmony_ci 166162306a36Sopenharmony_ci _rtl92ee_set_media_status(hw, opmode); 166262306a36Sopenharmony_ci 166362306a36Sopenharmony_ci if (rtlpriv->rtlhal.driver_is_goingto_unload || 166462306a36Sopenharmony_ci ppsc->rfoff_reason > RF_CHANGE_BY_PS) 166562306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); 166662306a36Sopenharmony_ci 166762306a36Sopenharmony_ci _rtl92ee_poweroff_adapter(hw); 166862306a36Sopenharmony_ci 166962306a36Sopenharmony_ci /* after power off we should do iqk again */ 167062306a36Sopenharmony_ci if (!rtlpriv->cfg->ops->get_btc_status()) 167162306a36Sopenharmony_ci rtlpriv->phy.iqk_initialized = false; 167262306a36Sopenharmony_ci} 167362306a36Sopenharmony_ci 167462306a36Sopenharmony_civoid rtl92ee_interrupt_recognized(struct ieee80211_hw *hw, 167562306a36Sopenharmony_ci struct rtl_int *intvec) 167662306a36Sopenharmony_ci{ 167762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 167862306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 167962306a36Sopenharmony_ci 168062306a36Sopenharmony_ci intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; 168162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, ISR, intvec->inta); 168262306a36Sopenharmony_ci 168362306a36Sopenharmony_ci intvec->intb = rtl_read_dword(rtlpriv, REG_HISRE) & rtlpci->irq_mask[1]; 168462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HISRE, intvec->intb); 168562306a36Sopenharmony_ci} 168662306a36Sopenharmony_ci 168762306a36Sopenharmony_civoid rtl92ee_set_beacon_related_registers(struct ieee80211_hw *hw) 168862306a36Sopenharmony_ci{ 168962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 169062306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 169162306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 169262306a36Sopenharmony_ci u16 bcn_interval, atim_window; 169362306a36Sopenharmony_ci 169462306a36Sopenharmony_ci bcn_interval = mac->beacon_interval; 169562306a36Sopenharmony_ci atim_window = 2; /*FIX MERGE */ 169662306a36Sopenharmony_ci rtl92ee_disable_interrupt(hw); 169762306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); 169862306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); 169962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); 170062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x18); 170162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x18); 170262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x606, 0x30); 170362306a36Sopenharmony_ci rtlpci->reg_bcn_ctrl_val |= BIT(3); 170462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlpci->reg_bcn_ctrl_val); 170562306a36Sopenharmony_ci} 170662306a36Sopenharmony_ci 170762306a36Sopenharmony_civoid rtl92ee_set_beacon_interval(struct ieee80211_hw *hw) 170862306a36Sopenharmony_ci{ 170962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 171062306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 171162306a36Sopenharmony_ci u16 bcn_interval = mac->beacon_interval; 171262306a36Sopenharmony_ci 171362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, 171462306a36Sopenharmony_ci "beacon_interval:%d\n", bcn_interval); 171562306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); 171662306a36Sopenharmony_ci} 171762306a36Sopenharmony_ci 171862306a36Sopenharmony_civoid rtl92ee_update_interrupt_mask(struct ieee80211_hw *hw, 171962306a36Sopenharmony_ci u32 add_msr, u32 rm_msr) 172062306a36Sopenharmony_ci{ 172162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 172262306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 172362306a36Sopenharmony_ci 172462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, 172562306a36Sopenharmony_ci "add_msr:%x, rm_msr:%x\n", add_msr, rm_msr); 172662306a36Sopenharmony_ci 172762306a36Sopenharmony_ci if (add_msr) 172862306a36Sopenharmony_ci rtlpci->irq_mask[0] |= add_msr; 172962306a36Sopenharmony_ci if (rm_msr) 173062306a36Sopenharmony_ci rtlpci->irq_mask[0] &= (~rm_msr); 173162306a36Sopenharmony_ci rtl92ee_disable_interrupt(hw); 173262306a36Sopenharmony_ci rtl92ee_enable_interrupt(hw); 173362306a36Sopenharmony_ci} 173462306a36Sopenharmony_ci 173562306a36Sopenharmony_cistatic u8 _rtl92ee_get_chnl_group(u8 chnl) 173662306a36Sopenharmony_ci{ 173762306a36Sopenharmony_ci u8 group = 0; 173862306a36Sopenharmony_ci 173962306a36Sopenharmony_ci if (chnl <= 14) { 174062306a36Sopenharmony_ci if (1 <= chnl && chnl <= 2) 174162306a36Sopenharmony_ci group = 0; 174262306a36Sopenharmony_ci else if (3 <= chnl && chnl <= 5) 174362306a36Sopenharmony_ci group = 1; 174462306a36Sopenharmony_ci else if (6 <= chnl && chnl <= 8) 174562306a36Sopenharmony_ci group = 2; 174662306a36Sopenharmony_ci else if (9 <= chnl && chnl <= 11) 174762306a36Sopenharmony_ci group = 3; 174862306a36Sopenharmony_ci else if (12 <= chnl && chnl <= 14) 174962306a36Sopenharmony_ci group = 4; 175062306a36Sopenharmony_ci } else { 175162306a36Sopenharmony_ci if (36 <= chnl && chnl <= 42) 175262306a36Sopenharmony_ci group = 0; 175362306a36Sopenharmony_ci else if (44 <= chnl && chnl <= 48) 175462306a36Sopenharmony_ci group = 1; 175562306a36Sopenharmony_ci else if (50 <= chnl && chnl <= 58) 175662306a36Sopenharmony_ci group = 2; 175762306a36Sopenharmony_ci else if (60 <= chnl && chnl <= 64) 175862306a36Sopenharmony_ci group = 3; 175962306a36Sopenharmony_ci else if (100 <= chnl && chnl <= 106) 176062306a36Sopenharmony_ci group = 4; 176162306a36Sopenharmony_ci else if (108 <= chnl && chnl <= 114) 176262306a36Sopenharmony_ci group = 5; 176362306a36Sopenharmony_ci else if (116 <= chnl && chnl <= 122) 176462306a36Sopenharmony_ci group = 6; 176562306a36Sopenharmony_ci else if (124 <= chnl && chnl <= 130) 176662306a36Sopenharmony_ci group = 7; 176762306a36Sopenharmony_ci else if (132 <= chnl && chnl <= 138) 176862306a36Sopenharmony_ci group = 8; 176962306a36Sopenharmony_ci else if (140 <= chnl && chnl <= 144) 177062306a36Sopenharmony_ci group = 9; 177162306a36Sopenharmony_ci else if (149 <= chnl && chnl <= 155) 177262306a36Sopenharmony_ci group = 10; 177362306a36Sopenharmony_ci else if (157 <= chnl && chnl <= 161) 177462306a36Sopenharmony_ci group = 11; 177562306a36Sopenharmony_ci else if (165 <= chnl && chnl <= 171) 177662306a36Sopenharmony_ci group = 12; 177762306a36Sopenharmony_ci else if (173 <= chnl && chnl <= 177) 177862306a36Sopenharmony_ci group = 13; 177962306a36Sopenharmony_ci } 178062306a36Sopenharmony_ci return group; 178162306a36Sopenharmony_ci} 178262306a36Sopenharmony_ci 178362306a36Sopenharmony_cistatic void _rtl8192ee_read_power_value_fromprom(struct ieee80211_hw *hw, 178462306a36Sopenharmony_ci struct txpower_info_2g *pwr2g, 178562306a36Sopenharmony_ci struct txpower_info_5g *pwr5g, 178662306a36Sopenharmony_ci bool autoload_fail, u8 *hwinfo) 178762306a36Sopenharmony_ci{ 178862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 178962306a36Sopenharmony_ci u32 rf, addr = EEPROM_TX_PWR_INX, group, i = 0; 179062306a36Sopenharmony_ci 179162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 179262306a36Sopenharmony_ci "hal_ReadPowerValueFromPROM92E(): PROMContent[0x%x]=0x%x\n", 179362306a36Sopenharmony_ci (addr + 1), hwinfo[addr + 1]); 179462306a36Sopenharmony_ci if (0xFF == hwinfo[addr+1]) /*YJ,add,120316*/ 179562306a36Sopenharmony_ci autoload_fail = true; 179662306a36Sopenharmony_ci 179762306a36Sopenharmony_ci if (autoload_fail) { 179862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 179962306a36Sopenharmony_ci "auto load fail : Use Default value!\n"); 180062306a36Sopenharmony_ci for (rf = 0 ; rf < MAX_RF_PATH ; rf++) { 180162306a36Sopenharmony_ci /* 2.4G default value */ 180262306a36Sopenharmony_ci for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { 180362306a36Sopenharmony_ci pwr2g->index_cck_base[rf][group] = 0x2D; 180462306a36Sopenharmony_ci pwr2g->index_bw40_base[rf][group] = 0x2D; 180562306a36Sopenharmony_ci } 180662306a36Sopenharmony_ci for (i = 0; i < MAX_TX_COUNT; i++) { 180762306a36Sopenharmony_ci if (i == 0) { 180862306a36Sopenharmony_ci pwr2g->bw20_diff[rf][0] = 0x02; 180962306a36Sopenharmony_ci pwr2g->ofdm_diff[rf][0] = 0x04; 181062306a36Sopenharmony_ci } else { 181162306a36Sopenharmony_ci pwr2g->bw20_diff[rf][i] = 0xFE; 181262306a36Sopenharmony_ci pwr2g->bw40_diff[rf][i] = 0xFE; 181362306a36Sopenharmony_ci pwr2g->cck_diff[rf][i] = 0xFE; 181462306a36Sopenharmony_ci pwr2g->ofdm_diff[rf][i] = 0xFE; 181562306a36Sopenharmony_ci } 181662306a36Sopenharmony_ci } 181762306a36Sopenharmony_ci 181862306a36Sopenharmony_ci /*5G default value*/ 181962306a36Sopenharmony_ci for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++) 182062306a36Sopenharmony_ci pwr5g->index_bw40_base[rf][group] = 0x2A; 182162306a36Sopenharmony_ci 182262306a36Sopenharmony_ci for (i = 0; i < MAX_TX_COUNT; i++) { 182362306a36Sopenharmony_ci if (i == 0) { 182462306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][0] = 0x04; 182562306a36Sopenharmony_ci pwr5g->bw20_diff[rf][0] = 0x00; 182662306a36Sopenharmony_ci pwr5g->bw80_diff[rf][0] = 0xFE; 182762306a36Sopenharmony_ci pwr5g->bw160_diff[rf][0] = 0xFE; 182862306a36Sopenharmony_ci } else { 182962306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][0] = 0xFE; 183062306a36Sopenharmony_ci pwr5g->bw20_diff[rf][0] = 0xFE; 183162306a36Sopenharmony_ci pwr5g->bw40_diff[rf][0] = 0xFE; 183262306a36Sopenharmony_ci pwr5g->bw80_diff[rf][0] = 0xFE; 183362306a36Sopenharmony_ci pwr5g->bw160_diff[rf][0] = 0xFE; 183462306a36Sopenharmony_ci } 183562306a36Sopenharmony_ci } 183662306a36Sopenharmony_ci } 183762306a36Sopenharmony_ci return; 183862306a36Sopenharmony_ci } 183962306a36Sopenharmony_ci 184062306a36Sopenharmony_ci rtl_priv(hw)->efuse.txpwr_fromeprom = true; 184162306a36Sopenharmony_ci 184262306a36Sopenharmony_ci for (rf = 0 ; rf < MAX_RF_PATH ; rf++) { 184362306a36Sopenharmony_ci /*2.4G default value*/ 184462306a36Sopenharmony_ci for (group = 0 ; group < MAX_CHNL_GROUP_24G; group++) { 184562306a36Sopenharmony_ci pwr2g->index_cck_base[rf][group] = hwinfo[addr++]; 184662306a36Sopenharmony_ci if (pwr2g->index_cck_base[rf][group] == 0xFF) 184762306a36Sopenharmony_ci pwr2g->index_cck_base[rf][group] = 0x2D; 184862306a36Sopenharmony_ci } 184962306a36Sopenharmony_ci for (group = 0 ; group < MAX_CHNL_GROUP_24G - 1; group++) { 185062306a36Sopenharmony_ci pwr2g->index_bw40_base[rf][group] = hwinfo[addr++]; 185162306a36Sopenharmony_ci if (pwr2g->index_bw40_base[rf][group] == 0xFF) 185262306a36Sopenharmony_ci pwr2g->index_bw40_base[rf][group] = 0x2D; 185362306a36Sopenharmony_ci } 185462306a36Sopenharmony_ci for (i = 0; i < MAX_TX_COUNT; i++) { 185562306a36Sopenharmony_ci if (i == 0) { 185662306a36Sopenharmony_ci pwr2g->bw40_diff[rf][i] = 0; 185762306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 185862306a36Sopenharmony_ci pwr2g->bw20_diff[rf][i] = 0x02; 185962306a36Sopenharmony_ci } else { 186062306a36Sopenharmony_ci pwr2g->bw20_diff[rf][i] = (hwinfo[addr] 186162306a36Sopenharmony_ci & 0xf0) >> 4; 186262306a36Sopenharmony_ci if (pwr2g->bw20_diff[rf][i] & BIT(3)) 186362306a36Sopenharmony_ci pwr2g->bw20_diff[rf][i] |= 0xF0; 186462306a36Sopenharmony_ci } 186562306a36Sopenharmony_ci 186662306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 186762306a36Sopenharmony_ci pwr2g->ofdm_diff[rf][i] = 0x04; 186862306a36Sopenharmony_ci } else { 186962306a36Sopenharmony_ci pwr2g->ofdm_diff[rf][i] = (hwinfo[addr] 187062306a36Sopenharmony_ci & 0x0f); 187162306a36Sopenharmony_ci if (pwr2g->ofdm_diff[rf][i] & BIT(3)) 187262306a36Sopenharmony_ci pwr2g->ofdm_diff[rf][i] |= 0xF0; 187362306a36Sopenharmony_ci } 187462306a36Sopenharmony_ci pwr2g->cck_diff[rf][i] = 0; 187562306a36Sopenharmony_ci addr++; 187662306a36Sopenharmony_ci } else { 187762306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 187862306a36Sopenharmony_ci pwr2g->bw40_diff[rf][i] = 0xFE; 187962306a36Sopenharmony_ci } else { 188062306a36Sopenharmony_ci pwr2g->bw40_diff[rf][i] = (hwinfo[addr] 188162306a36Sopenharmony_ci & 0xf0) >> 4; 188262306a36Sopenharmony_ci if (pwr2g->bw40_diff[rf][i] & BIT(3)) 188362306a36Sopenharmony_ci pwr2g->bw40_diff[rf][i] |= 0xF0; 188462306a36Sopenharmony_ci } 188562306a36Sopenharmony_ci 188662306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 188762306a36Sopenharmony_ci pwr2g->bw20_diff[rf][i] = 0xFE; 188862306a36Sopenharmony_ci } else { 188962306a36Sopenharmony_ci pwr2g->bw20_diff[rf][i] = (hwinfo[addr] 189062306a36Sopenharmony_ci & 0x0f); 189162306a36Sopenharmony_ci if (pwr2g->bw20_diff[rf][i] & BIT(3)) 189262306a36Sopenharmony_ci pwr2g->bw20_diff[rf][i] |= 0xF0; 189362306a36Sopenharmony_ci } 189462306a36Sopenharmony_ci addr++; 189562306a36Sopenharmony_ci 189662306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 189762306a36Sopenharmony_ci pwr2g->ofdm_diff[rf][i] = 0xFE; 189862306a36Sopenharmony_ci } else { 189962306a36Sopenharmony_ci pwr2g->ofdm_diff[rf][i] = (hwinfo[addr] 190062306a36Sopenharmony_ci & 0xf0) >> 4; 190162306a36Sopenharmony_ci if (pwr2g->ofdm_diff[rf][i] & BIT(3)) 190262306a36Sopenharmony_ci pwr2g->ofdm_diff[rf][i] |= 0xF0; 190362306a36Sopenharmony_ci } 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 190662306a36Sopenharmony_ci pwr2g->cck_diff[rf][i] = 0xFE; 190762306a36Sopenharmony_ci } else { 190862306a36Sopenharmony_ci pwr2g->cck_diff[rf][i] = (hwinfo[addr] 190962306a36Sopenharmony_ci & 0x0f); 191062306a36Sopenharmony_ci if (pwr2g->cck_diff[rf][i] & BIT(3)) 191162306a36Sopenharmony_ci pwr2g->cck_diff[rf][i] |= 0xF0; 191262306a36Sopenharmony_ci } 191362306a36Sopenharmony_ci addr++; 191462306a36Sopenharmony_ci } 191562306a36Sopenharmony_ci } 191662306a36Sopenharmony_ci 191762306a36Sopenharmony_ci /*5G default value*/ 191862306a36Sopenharmony_ci for (group = 0 ; group < MAX_CHNL_GROUP_5G; group++) { 191962306a36Sopenharmony_ci pwr5g->index_bw40_base[rf][group] = hwinfo[addr++]; 192062306a36Sopenharmony_ci if (pwr5g->index_bw40_base[rf][group] == 0xFF) 192162306a36Sopenharmony_ci pwr5g->index_bw40_base[rf][group] = 0xFE; 192262306a36Sopenharmony_ci } 192362306a36Sopenharmony_ci 192462306a36Sopenharmony_ci for (i = 0; i < MAX_TX_COUNT; i++) { 192562306a36Sopenharmony_ci if (i == 0) { 192662306a36Sopenharmony_ci pwr5g->bw40_diff[rf][i] = 0; 192762306a36Sopenharmony_ci 192862306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 192962306a36Sopenharmony_ci pwr5g->bw20_diff[rf][i] = 0; 193062306a36Sopenharmony_ci } else { 193162306a36Sopenharmony_ci pwr5g->bw20_diff[rf][0] = (hwinfo[addr] 193262306a36Sopenharmony_ci & 0xf0) >> 4; 193362306a36Sopenharmony_ci if (pwr5g->bw20_diff[rf][i] & BIT(3)) 193462306a36Sopenharmony_ci pwr5g->bw20_diff[rf][i] |= 0xF0; 193562306a36Sopenharmony_ci } 193662306a36Sopenharmony_ci 193762306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 193862306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][i] = 0x04; 193962306a36Sopenharmony_ci } else { 194062306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][0] = (hwinfo[addr] 194162306a36Sopenharmony_ci & 0x0f); 194262306a36Sopenharmony_ci if (pwr5g->ofdm_diff[rf][i] & BIT(3)) 194362306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][i] |= 0xF0; 194462306a36Sopenharmony_ci } 194562306a36Sopenharmony_ci addr++; 194662306a36Sopenharmony_ci } else { 194762306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 194862306a36Sopenharmony_ci pwr5g->bw40_diff[rf][i] = 0xFE; 194962306a36Sopenharmony_ci } else { 195062306a36Sopenharmony_ci pwr5g->bw40_diff[rf][i] = (hwinfo[addr] 195162306a36Sopenharmony_ci & 0xf0) >> 4; 195262306a36Sopenharmony_ci if (pwr5g->bw40_diff[rf][i] & BIT(3)) 195362306a36Sopenharmony_ci pwr5g->bw40_diff[rf][i] |= 0xF0; 195462306a36Sopenharmony_ci } 195562306a36Sopenharmony_ci 195662306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 195762306a36Sopenharmony_ci pwr5g->bw20_diff[rf][i] = 0xFE; 195862306a36Sopenharmony_ci } else { 195962306a36Sopenharmony_ci pwr5g->bw20_diff[rf][i] = (hwinfo[addr] 196062306a36Sopenharmony_ci & 0x0f); 196162306a36Sopenharmony_ci if (pwr5g->bw20_diff[rf][i] & BIT(3)) 196262306a36Sopenharmony_ci pwr5g->bw20_diff[rf][i] |= 0xF0; 196362306a36Sopenharmony_ci } 196462306a36Sopenharmony_ci addr++; 196562306a36Sopenharmony_ci } 196662306a36Sopenharmony_ci } 196762306a36Sopenharmony_ci 196862306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 196962306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][1] = 0xFE; 197062306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][2] = 0xFE; 197162306a36Sopenharmony_ci } else { 197262306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][1] = (hwinfo[addr] & 0xf0) >> 4; 197362306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][2] = (hwinfo[addr] & 0x0f); 197462306a36Sopenharmony_ci } 197562306a36Sopenharmony_ci addr++; 197662306a36Sopenharmony_ci 197762306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) 197862306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][3] = 0xFE; 197962306a36Sopenharmony_ci else 198062306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][3] = (hwinfo[addr] & 0x0f); 198162306a36Sopenharmony_ci addr++; 198262306a36Sopenharmony_ci 198362306a36Sopenharmony_ci for (i = 1; i < MAX_TX_COUNT; i++) { 198462306a36Sopenharmony_ci if (pwr5g->ofdm_diff[rf][i] == 0xFF) 198562306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][i] = 0xFE; 198662306a36Sopenharmony_ci else if (pwr5g->ofdm_diff[rf][i] & BIT(3)) 198762306a36Sopenharmony_ci pwr5g->ofdm_diff[rf][i] |= 0xF0; 198862306a36Sopenharmony_ci } 198962306a36Sopenharmony_ci 199062306a36Sopenharmony_ci for (i = 0; i < MAX_TX_COUNT; i++) { 199162306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 199262306a36Sopenharmony_ci pwr5g->bw80_diff[rf][i] = 0xFE; 199362306a36Sopenharmony_ci } else { 199462306a36Sopenharmony_ci pwr5g->bw80_diff[rf][i] = (hwinfo[addr] & 0xf0) 199562306a36Sopenharmony_ci >> 4; 199662306a36Sopenharmony_ci if (pwr5g->bw80_diff[rf][i] & BIT(3)) 199762306a36Sopenharmony_ci pwr5g->bw80_diff[rf][i] |= 0xF0; 199862306a36Sopenharmony_ci } 199962306a36Sopenharmony_ci 200062306a36Sopenharmony_ci if (hwinfo[addr] == 0xFF) { 200162306a36Sopenharmony_ci pwr5g->bw160_diff[rf][i] = 0xFE; 200262306a36Sopenharmony_ci } else { 200362306a36Sopenharmony_ci pwr5g->bw160_diff[rf][i] = 200462306a36Sopenharmony_ci (hwinfo[addr] & 0x0f); 200562306a36Sopenharmony_ci if (pwr5g->bw160_diff[rf][i] & BIT(3)) 200662306a36Sopenharmony_ci pwr5g->bw160_diff[rf][i] |= 0xF0; 200762306a36Sopenharmony_ci } 200862306a36Sopenharmony_ci addr++; 200962306a36Sopenharmony_ci } 201062306a36Sopenharmony_ci } 201162306a36Sopenharmony_ci} 201262306a36Sopenharmony_ci 201362306a36Sopenharmony_cistatic void _rtl92ee_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 201462306a36Sopenharmony_ci bool autoload_fail, u8 *hwinfo) 201562306a36Sopenharmony_ci{ 201662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 201762306a36Sopenharmony_ci struct rtl_efuse *efu = rtl_efuse(rtl_priv(hw)); 201862306a36Sopenharmony_ci struct txpower_info_2g pwr2g; 201962306a36Sopenharmony_ci struct txpower_info_5g pwr5g; 202062306a36Sopenharmony_ci u8 rf, idx; 202162306a36Sopenharmony_ci u8 i; 202262306a36Sopenharmony_ci 202362306a36Sopenharmony_ci _rtl8192ee_read_power_value_fromprom(hw, &pwr2g, &pwr5g, 202462306a36Sopenharmony_ci autoload_fail, hwinfo); 202562306a36Sopenharmony_ci 202662306a36Sopenharmony_ci for (rf = 0; rf < MAX_RF_PATH; rf++) { 202762306a36Sopenharmony_ci for (i = 0; i < 14; i++) { 202862306a36Sopenharmony_ci idx = _rtl92ee_get_chnl_group(i + 1); 202962306a36Sopenharmony_ci 203062306a36Sopenharmony_ci if (i == CHANNEL_MAX_NUMBER_2G - 1) { 203162306a36Sopenharmony_ci efu->txpwrlevel_cck[rf][i] = 203262306a36Sopenharmony_ci pwr2g.index_cck_base[rf][5]; 203362306a36Sopenharmony_ci efu->txpwrlevel_ht40_1s[rf][i] = 203462306a36Sopenharmony_ci pwr2g.index_bw40_base[rf][idx]; 203562306a36Sopenharmony_ci } else { 203662306a36Sopenharmony_ci efu->txpwrlevel_cck[rf][i] = 203762306a36Sopenharmony_ci pwr2g.index_cck_base[rf][idx]; 203862306a36Sopenharmony_ci efu->txpwrlevel_ht40_1s[rf][i] = 203962306a36Sopenharmony_ci pwr2g.index_bw40_base[rf][idx]; 204062306a36Sopenharmony_ci } 204162306a36Sopenharmony_ci } 204262306a36Sopenharmony_ci for (i = 0; i < CHANNEL_MAX_NUMBER_5G; i++) { 204362306a36Sopenharmony_ci idx = _rtl92ee_get_chnl_group(channel5g[i]); 204462306a36Sopenharmony_ci efu->txpwr_5g_bw40base[rf][i] = 204562306a36Sopenharmony_ci pwr5g.index_bw40_base[rf][idx]; 204662306a36Sopenharmony_ci } 204762306a36Sopenharmony_ci for (i = 0; i < CHANNEL_MAX_NUMBER_5G_80M; i++) { 204862306a36Sopenharmony_ci u8 upper, lower; 204962306a36Sopenharmony_ci 205062306a36Sopenharmony_ci idx = _rtl92ee_get_chnl_group(channel5g_80m[i]); 205162306a36Sopenharmony_ci upper = pwr5g.index_bw40_base[rf][idx]; 205262306a36Sopenharmony_ci lower = pwr5g.index_bw40_base[rf][idx + 1]; 205362306a36Sopenharmony_ci 205462306a36Sopenharmony_ci efu->txpwr_5g_bw80base[rf][i] = (upper + lower) / 2; 205562306a36Sopenharmony_ci } 205662306a36Sopenharmony_ci for (i = 0; i < MAX_TX_COUNT; i++) { 205762306a36Sopenharmony_ci efu->txpwr_cckdiff[rf][i] = pwr2g.cck_diff[rf][i]; 205862306a36Sopenharmony_ci efu->txpwr_legacyhtdiff[rf][i] = pwr2g.ofdm_diff[rf][i]; 205962306a36Sopenharmony_ci efu->txpwr_ht20diff[rf][i] = pwr2g.bw20_diff[rf][i]; 206062306a36Sopenharmony_ci efu->txpwr_ht40diff[rf][i] = pwr2g.bw40_diff[rf][i]; 206162306a36Sopenharmony_ci 206262306a36Sopenharmony_ci efu->txpwr_5g_ofdmdiff[rf][i] = pwr5g.ofdm_diff[rf][i]; 206362306a36Sopenharmony_ci efu->txpwr_5g_bw20diff[rf][i] = pwr5g.bw20_diff[rf][i]; 206462306a36Sopenharmony_ci efu->txpwr_5g_bw40diff[rf][i] = pwr5g.bw40_diff[rf][i]; 206562306a36Sopenharmony_ci efu->txpwr_5g_bw80diff[rf][i] = pwr5g.bw80_diff[rf][i]; 206662306a36Sopenharmony_ci } 206762306a36Sopenharmony_ci } 206862306a36Sopenharmony_ci 206962306a36Sopenharmony_ci if (!autoload_fail) 207062306a36Sopenharmony_ci efu->eeprom_thermalmeter = hwinfo[EEPROM_THERMAL_METER_92E]; 207162306a36Sopenharmony_ci else 207262306a36Sopenharmony_ci efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; 207362306a36Sopenharmony_ci 207462306a36Sopenharmony_ci if (efu->eeprom_thermalmeter == 0xff || autoload_fail) { 207562306a36Sopenharmony_ci efu->apk_thermalmeterignore = true; 207662306a36Sopenharmony_ci efu->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; 207762306a36Sopenharmony_ci } 207862306a36Sopenharmony_ci 207962306a36Sopenharmony_ci efu->thermalmeter[0] = efu->eeprom_thermalmeter; 208062306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 208162306a36Sopenharmony_ci "thermalmeter = 0x%x\n", efu->eeprom_thermalmeter); 208262306a36Sopenharmony_ci 208362306a36Sopenharmony_ci if (!autoload_fail) { 208462306a36Sopenharmony_ci efu->eeprom_regulatory = hwinfo[EEPROM_RF_BOARD_OPTION_92E] 208562306a36Sopenharmony_ci & 0x07; 208662306a36Sopenharmony_ci if (hwinfo[EEPROM_RF_BOARD_OPTION_92E] == 0xFF) 208762306a36Sopenharmony_ci efu->eeprom_regulatory = 0; 208862306a36Sopenharmony_ci } else { 208962306a36Sopenharmony_ci efu->eeprom_regulatory = 0; 209062306a36Sopenharmony_ci } 209162306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 209262306a36Sopenharmony_ci "eeprom_regulatory = 0x%x\n", efu->eeprom_regulatory); 209362306a36Sopenharmony_ci} 209462306a36Sopenharmony_ci 209562306a36Sopenharmony_cistatic void _rtl92ee_read_adapter_info(struct ieee80211_hw *hw) 209662306a36Sopenharmony_ci{ 209762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 209862306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 209962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 210062306a36Sopenharmony_ci int params[] = {RTL8192E_EEPROM_ID, EEPROM_VID, EEPROM_DID, 210162306a36Sopenharmony_ci EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, 210262306a36Sopenharmony_ci EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, 210362306a36Sopenharmony_ci COUNTRY_CODE_WORLD_WIDE_13}; 210462306a36Sopenharmony_ci u8 *hwinfo; 210562306a36Sopenharmony_ci 210662306a36Sopenharmony_ci hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); 210762306a36Sopenharmony_ci if (!hwinfo) 210862306a36Sopenharmony_ci return; 210962306a36Sopenharmony_ci 211062306a36Sopenharmony_ci if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) 211162306a36Sopenharmony_ci goto exit; 211262306a36Sopenharmony_ci 211362306a36Sopenharmony_ci if (rtlefuse->eeprom_oemid == 0xFF) 211462306a36Sopenharmony_ci rtlefuse->eeprom_oemid = 0; 211562306a36Sopenharmony_ci 211662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 211762306a36Sopenharmony_ci "EEPROM Customer ID: 0x%2x\n", rtlefuse->eeprom_oemid); 211862306a36Sopenharmony_ci /* set channel plan from efuse */ 211962306a36Sopenharmony_ci rtlefuse->channel_plan = rtlefuse->eeprom_channelplan; 212062306a36Sopenharmony_ci /*tx power*/ 212162306a36Sopenharmony_ci _rtl92ee_read_txpower_info_from_hwpg(hw, rtlefuse->autoload_failflag, 212262306a36Sopenharmony_ci hwinfo); 212362306a36Sopenharmony_ci 212462306a36Sopenharmony_ci rtl92ee_read_bt_coexist_info_from_hwpg(hw, rtlefuse->autoload_failflag, 212562306a36Sopenharmony_ci hwinfo); 212662306a36Sopenharmony_ci 212762306a36Sopenharmony_ci /*board type*/ 212862306a36Sopenharmony_ci rtlefuse->board_type = (((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_92E]) 212962306a36Sopenharmony_ci & 0xE0) >> 5); 213062306a36Sopenharmony_ci if ((*(u8 *)&hwinfo[EEPROM_RF_BOARD_OPTION_92E]) == 0xFF) 213162306a36Sopenharmony_ci rtlefuse->board_type = 0; 213262306a36Sopenharmony_ci 213362306a36Sopenharmony_ci if (rtlpriv->btcoexist.btc_info.btcoexist == 1) 213462306a36Sopenharmony_ci rtlefuse->board_type |= BIT(2); /* ODM_BOARD_BT */ 213562306a36Sopenharmony_ci 213662306a36Sopenharmony_ci rtlhal->board_type = rtlefuse->board_type; 213762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 213862306a36Sopenharmony_ci "board_type = 0x%x\n", rtlefuse->board_type); 213962306a36Sopenharmony_ci /*parse xtal*/ 214062306a36Sopenharmony_ci rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_92E]; 214162306a36Sopenharmony_ci if (hwinfo[EEPROM_XTAL_92E] == 0xFF) 214262306a36Sopenharmony_ci rtlefuse->crystalcap = 0x20; 214362306a36Sopenharmony_ci 214462306a36Sopenharmony_ci /*antenna diversity*/ 214562306a36Sopenharmony_ci rtlefuse->antenna_div_type = NO_ANTDIV; 214662306a36Sopenharmony_ci rtlefuse->antenna_div_cfg = 0; 214762306a36Sopenharmony_ci 214862306a36Sopenharmony_ci if (rtlhal->oem_id == RT_CID_DEFAULT) { 214962306a36Sopenharmony_ci switch (rtlefuse->eeprom_oemid) { 215062306a36Sopenharmony_ci case EEPROM_CID_DEFAULT: 215162306a36Sopenharmony_ci if (rtlefuse->eeprom_did == 0x818B) { 215262306a36Sopenharmony_ci if ((rtlefuse->eeprom_svid == 0x10EC) && 215362306a36Sopenharmony_ci (rtlefuse->eeprom_smid == 0x001B)) 215462306a36Sopenharmony_ci rtlhal->oem_id = RT_CID_819X_LENOVO; 215562306a36Sopenharmony_ci } else { 215662306a36Sopenharmony_ci rtlhal->oem_id = RT_CID_DEFAULT; 215762306a36Sopenharmony_ci } 215862306a36Sopenharmony_ci break; 215962306a36Sopenharmony_ci default: 216062306a36Sopenharmony_ci rtlhal->oem_id = RT_CID_DEFAULT; 216162306a36Sopenharmony_ci break; 216262306a36Sopenharmony_ci } 216362306a36Sopenharmony_ci } 216462306a36Sopenharmony_ciexit: 216562306a36Sopenharmony_ci kfree(hwinfo); 216662306a36Sopenharmony_ci} 216762306a36Sopenharmony_ci 216862306a36Sopenharmony_cistatic void _rtl92ee_hal_customized_behavior(struct ieee80211_hw *hw) 216962306a36Sopenharmony_ci{ 217062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 217162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 217262306a36Sopenharmony_ci 217362306a36Sopenharmony_ci rtlpriv->ledctl.led_opendrain = true; 217462306a36Sopenharmony_ci 217562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, 217662306a36Sopenharmony_ci "RT Customized ID: 0x%02X\n", rtlhal->oem_id); 217762306a36Sopenharmony_ci} 217862306a36Sopenharmony_ci 217962306a36Sopenharmony_civoid rtl92ee_read_eeprom_info(struct ieee80211_hw *hw) 218062306a36Sopenharmony_ci{ 218162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 218262306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 218362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 218462306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 218562306a36Sopenharmony_ci u8 tmp_u1b; 218662306a36Sopenharmony_ci 218762306a36Sopenharmony_ci rtlhal->version = _rtl92ee_read_chip_version(hw); 218862306a36Sopenharmony_ci if (get_rf_type(rtlphy) == RF_1T1R) { 218962306a36Sopenharmony_ci rtlpriv->dm.rfpath_rxenable[0] = true; 219062306a36Sopenharmony_ci } else { 219162306a36Sopenharmony_ci rtlpriv->dm.rfpath_rxenable[0] = true; 219262306a36Sopenharmony_ci rtlpriv->dm.rfpath_rxenable[1] = true; 219362306a36Sopenharmony_ci } 219462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "VersionID = 0x%4x\n", 219562306a36Sopenharmony_ci rtlhal->version); 219662306a36Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); 219762306a36Sopenharmony_ci if (tmp_u1b & BIT(4)) { 219862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); 219962306a36Sopenharmony_ci rtlefuse->epromtype = EEPROM_93C46; 220062306a36Sopenharmony_ci } else { 220162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); 220262306a36Sopenharmony_ci rtlefuse->epromtype = EEPROM_BOOT_EFUSE; 220362306a36Sopenharmony_ci } 220462306a36Sopenharmony_ci if (tmp_u1b & BIT(5)) { 220562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); 220662306a36Sopenharmony_ci rtlefuse->autoload_failflag = false; 220762306a36Sopenharmony_ci _rtl92ee_read_adapter_info(hw); 220862306a36Sopenharmony_ci } else { 220962306a36Sopenharmony_ci pr_err("Autoload ERR!!\n"); 221062306a36Sopenharmony_ci } 221162306a36Sopenharmony_ci _rtl92ee_hal_customized_behavior(hw); 221262306a36Sopenharmony_ci 221362306a36Sopenharmony_ci rtlphy->rfpath_rx_enable[0] = true; 221462306a36Sopenharmony_ci if (rtlphy->rf_type == RF_2T2R) 221562306a36Sopenharmony_ci rtlphy->rfpath_rx_enable[1] = true; 221662306a36Sopenharmony_ci} 221762306a36Sopenharmony_ci 221862306a36Sopenharmony_cistatic u8 _rtl92ee_mrate_idx_to_arfr_id(struct ieee80211_hw *hw, u8 rate_index) 221962306a36Sopenharmony_ci{ 222062306a36Sopenharmony_ci u8 ret = 0; 222162306a36Sopenharmony_ci 222262306a36Sopenharmony_ci switch (rate_index) { 222362306a36Sopenharmony_ci case RATR_INX_WIRELESS_NGB: 222462306a36Sopenharmony_ci ret = 0; 222562306a36Sopenharmony_ci break; 222662306a36Sopenharmony_ci case RATR_INX_WIRELESS_N: 222762306a36Sopenharmony_ci case RATR_INX_WIRELESS_NG: 222862306a36Sopenharmony_ci ret = 4; 222962306a36Sopenharmony_ci break; 223062306a36Sopenharmony_ci case RATR_INX_WIRELESS_NB: 223162306a36Sopenharmony_ci ret = 2; 223262306a36Sopenharmony_ci break; 223362306a36Sopenharmony_ci case RATR_INX_WIRELESS_GB: 223462306a36Sopenharmony_ci ret = 6; 223562306a36Sopenharmony_ci break; 223662306a36Sopenharmony_ci case RATR_INX_WIRELESS_G: 223762306a36Sopenharmony_ci ret = 7; 223862306a36Sopenharmony_ci break; 223962306a36Sopenharmony_ci case RATR_INX_WIRELESS_B: 224062306a36Sopenharmony_ci ret = 8; 224162306a36Sopenharmony_ci break; 224262306a36Sopenharmony_ci default: 224362306a36Sopenharmony_ci ret = 0; 224462306a36Sopenharmony_ci break; 224562306a36Sopenharmony_ci } 224662306a36Sopenharmony_ci return ret; 224762306a36Sopenharmony_ci} 224862306a36Sopenharmony_ci 224962306a36Sopenharmony_cistatic void rtl92ee_update_hal_rate_mask(struct ieee80211_hw *hw, 225062306a36Sopenharmony_ci struct ieee80211_sta *sta, 225162306a36Sopenharmony_ci u8 rssi_level, bool update_bw) 225262306a36Sopenharmony_ci{ 225362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 225462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &rtlpriv->phy; 225562306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 225662306a36Sopenharmony_ci struct rtl_sta_info *sta_entry = NULL; 225762306a36Sopenharmony_ci u32 ratr_bitmap; 225862306a36Sopenharmony_ci u8 ratr_index; 225962306a36Sopenharmony_ci u8 curtxbw_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40) 226062306a36Sopenharmony_ci ? 1 : 0; 226162306a36Sopenharmony_ci u8 b_curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 226262306a36Sopenharmony_ci 1 : 0; 226362306a36Sopenharmony_ci u8 b_curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 226462306a36Sopenharmony_ci 1 : 0; 226562306a36Sopenharmony_ci enum wireless_mode wirelessmode = 0; 226662306a36Sopenharmony_ci bool b_shortgi = false; 226762306a36Sopenharmony_ci u8 rate_mask[7] = {0}; 226862306a36Sopenharmony_ci u8 macid = 0; 226962306a36Sopenharmony_ci /*u8 mimo_ps = IEEE80211_SMPS_OFF;*/ 227062306a36Sopenharmony_ci sta_entry = (struct rtl_sta_info *)sta->drv_priv; 227162306a36Sopenharmony_ci wirelessmode = sta_entry->wireless_mode; 227262306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_STATION || 227362306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_MESH_POINT) 227462306a36Sopenharmony_ci curtxbw_40mhz = mac->bw_40; 227562306a36Sopenharmony_ci else if (mac->opmode == NL80211_IFTYPE_AP || 227662306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC) 227762306a36Sopenharmony_ci macid = sta->aid + 1; 227862306a36Sopenharmony_ci 227962306a36Sopenharmony_ci ratr_bitmap = sta->deflink.supp_rates[0]; 228062306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) 228162306a36Sopenharmony_ci ratr_bitmap = 0xfff; 228262306a36Sopenharmony_ci 228362306a36Sopenharmony_ci ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | 228462306a36Sopenharmony_ci sta->deflink.ht_cap.mcs.rx_mask[0] << 12); 228562306a36Sopenharmony_ci 228662306a36Sopenharmony_ci switch (wirelessmode) { 228762306a36Sopenharmony_ci case WIRELESS_MODE_B: 228862306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_B; 228962306a36Sopenharmony_ci if (ratr_bitmap & 0x0000000c) 229062306a36Sopenharmony_ci ratr_bitmap &= 0x0000000d; 229162306a36Sopenharmony_ci else 229262306a36Sopenharmony_ci ratr_bitmap &= 0x0000000f; 229362306a36Sopenharmony_ci break; 229462306a36Sopenharmony_ci case WIRELESS_MODE_G: 229562306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_GB; 229662306a36Sopenharmony_ci 229762306a36Sopenharmony_ci if (rssi_level == 1) 229862306a36Sopenharmony_ci ratr_bitmap &= 0x00000f00; 229962306a36Sopenharmony_ci else if (rssi_level == 2) 230062306a36Sopenharmony_ci ratr_bitmap &= 0x00000ff0; 230162306a36Sopenharmony_ci else 230262306a36Sopenharmony_ci ratr_bitmap &= 0x00000ff5; 230362306a36Sopenharmony_ci break; 230462306a36Sopenharmony_ci case WIRELESS_MODE_N_24G: 230562306a36Sopenharmony_ci if (curtxbw_40mhz) 230662306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 230762306a36Sopenharmony_ci else 230862306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NB; 230962306a36Sopenharmony_ci 231062306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T1R) { 231162306a36Sopenharmony_ci if (curtxbw_40mhz) { 231262306a36Sopenharmony_ci if (rssi_level == 1) 231362306a36Sopenharmony_ci ratr_bitmap &= 0x000f0000; 231462306a36Sopenharmony_ci else if (rssi_level == 2) 231562306a36Sopenharmony_ci ratr_bitmap &= 0x000ff000; 231662306a36Sopenharmony_ci else 231762306a36Sopenharmony_ci ratr_bitmap &= 0x000ff015; 231862306a36Sopenharmony_ci } else { 231962306a36Sopenharmony_ci if (rssi_level == 1) 232062306a36Sopenharmony_ci ratr_bitmap &= 0x000f0000; 232162306a36Sopenharmony_ci else if (rssi_level == 2) 232262306a36Sopenharmony_ci ratr_bitmap &= 0x000ff000; 232362306a36Sopenharmony_ci else 232462306a36Sopenharmony_ci ratr_bitmap &= 0x000ff005; 232562306a36Sopenharmony_ci } 232662306a36Sopenharmony_ci } else { 232762306a36Sopenharmony_ci if (curtxbw_40mhz) { 232862306a36Sopenharmony_ci if (rssi_level == 1) 232962306a36Sopenharmony_ci ratr_bitmap &= 0x0f8f0000; 233062306a36Sopenharmony_ci else if (rssi_level == 2) 233162306a36Sopenharmony_ci ratr_bitmap &= 0x0ffff000; 233262306a36Sopenharmony_ci else 233362306a36Sopenharmony_ci ratr_bitmap &= 0x0ffff015; 233462306a36Sopenharmony_ci } else { 233562306a36Sopenharmony_ci if (rssi_level == 1) 233662306a36Sopenharmony_ci ratr_bitmap &= 0x0f8f0000; 233762306a36Sopenharmony_ci else if (rssi_level == 2) 233862306a36Sopenharmony_ci ratr_bitmap &= 0x0ffff000; 233962306a36Sopenharmony_ci else 234062306a36Sopenharmony_ci ratr_bitmap &= 0x0ffff005; 234162306a36Sopenharmony_ci } 234262306a36Sopenharmony_ci } 234362306a36Sopenharmony_ci 234462306a36Sopenharmony_ci if ((curtxbw_40mhz && b_curshortgi_40mhz) || 234562306a36Sopenharmony_ci (!curtxbw_40mhz && b_curshortgi_20mhz)) { 234662306a36Sopenharmony_ci if (macid == 0) 234762306a36Sopenharmony_ci b_shortgi = true; 234862306a36Sopenharmony_ci else if (macid == 1) 234962306a36Sopenharmony_ci b_shortgi = false; 235062306a36Sopenharmony_ci } 235162306a36Sopenharmony_ci break; 235262306a36Sopenharmony_ci default: 235362306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 235462306a36Sopenharmony_ci 235562306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T1R) 235662306a36Sopenharmony_ci ratr_bitmap &= 0x000ff0ff; 235762306a36Sopenharmony_ci else 235862306a36Sopenharmony_ci ratr_bitmap &= 0x0f8ff0ff; 235962306a36Sopenharmony_ci break; 236062306a36Sopenharmony_ci } 236162306a36Sopenharmony_ci ratr_index = _rtl92ee_mrate_idx_to_arfr_id(hw, ratr_index); 236262306a36Sopenharmony_ci sta_entry->ratr_index = ratr_index; 236362306a36Sopenharmony_ci 236462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, 236562306a36Sopenharmony_ci "ratr_bitmap :%x\n", ratr_bitmap); 236662306a36Sopenharmony_ci *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | 236762306a36Sopenharmony_ci (ratr_index << 28); 236862306a36Sopenharmony_ci rate_mask[0] = macid; 236962306a36Sopenharmony_ci rate_mask[1] = ratr_index | (b_shortgi ? 0x80 : 0x00); 237062306a36Sopenharmony_ci rate_mask[2] = curtxbw_40mhz | ((!update_bw) << 3); 237162306a36Sopenharmony_ci rate_mask[3] = (u8)(ratr_bitmap & 0x000000ff); 237262306a36Sopenharmony_ci rate_mask[4] = (u8)((ratr_bitmap & 0x0000ff00) >> 8); 237362306a36Sopenharmony_ci rate_mask[5] = (u8)((ratr_bitmap & 0x00ff0000) >> 16); 237462306a36Sopenharmony_ci rate_mask[6] = (u8)((ratr_bitmap & 0xff000000) >> 24); 237562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, 237662306a36Sopenharmony_ci "Rate_index:%x, ratr_val:%x, %x:%x:%x:%x:%x:%x:%x\n", 237762306a36Sopenharmony_ci ratr_index, ratr_bitmap, rate_mask[0], rate_mask[1], 237862306a36Sopenharmony_ci rate_mask[2], rate_mask[3], rate_mask[4], 237962306a36Sopenharmony_ci rate_mask[5], rate_mask[6]); 238062306a36Sopenharmony_ci rtl92ee_fill_h2c_cmd(hw, H2C_92E_RA_MASK, 7, rate_mask); 238162306a36Sopenharmony_ci _rtl92ee_set_bcn_ctrl_reg(hw, BIT(3), 0); 238262306a36Sopenharmony_ci} 238362306a36Sopenharmony_ci 238462306a36Sopenharmony_civoid rtl92ee_update_hal_rate_tbl(struct ieee80211_hw *hw, 238562306a36Sopenharmony_ci struct ieee80211_sta *sta, u8 rssi_level, 238662306a36Sopenharmony_ci bool update_bw) 238762306a36Sopenharmony_ci{ 238862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 238962306a36Sopenharmony_ci 239062306a36Sopenharmony_ci if (rtlpriv->dm.useramask) 239162306a36Sopenharmony_ci rtl92ee_update_hal_rate_mask(hw, sta, rssi_level, update_bw); 239262306a36Sopenharmony_ci} 239362306a36Sopenharmony_ci 239462306a36Sopenharmony_civoid rtl92ee_update_channel_access_setting(struct ieee80211_hw *hw) 239562306a36Sopenharmony_ci{ 239662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 239762306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 239862306a36Sopenharmony_ci u16 sifs_timer; 239962306a36Sopenharmony_ci 240062306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, 240162306a36Sopenharmony_ci (u8 *)&mac->slot_time); 240262306a36Sopenharmony_ci if (!mac->ht_enable) 240362306a36Sopenharmony_ci sifs_timer = 0x0a0a; 240462306a36Sopenharmony_ci else 240562306a36Sopenharmony_ci sifs_timer = 0x0e0e; 240662306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); 240762306a36Sopenharmony_ci} 240862306a36Sopenharmony_ci 240962306a36Sopenharmony_cibool rtl92ee_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) 241062306a36Sopenharmony_ci{ 241162306a36Sopenharmony_ci *valid = 1; 241262306a36Sopenharmony_ci return true; 241362306a36Sopenharmony_ci} 241462306a36Sopenharmony_ci 241562306a36Sopenharmony_civoid rtl92ee_set_key(struct ieee80211_hw *hw, u32 key_index, 241662306a36Sopenharmony_ci u8 *p_macaddr, bool is_group, u8 enc_algo, 241762306a36Sopenharmony_ci bool is_wepkey, bool clear_all) 241862306a36Sopenharmony_ci{ 241962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 242062306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 242162306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 242262306a36Sopenharmony_ci u8 *macaddr = p_macaddr; 242362306a36Sopenharmony_ci u32 entry_id = 0; 242462306a36Sopenharmony_ci bool is_pairwise = false; 242562306a36Sopenharmony_ci 242662306a36Sopenharmony_ci static u8 cam_const_addr[4][6] = { 242762306a36Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 242862306a36Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 242962306a36Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, 243062306a36Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} 243162306a36Sopenharmony_ci }; 243262306a36Sopenharmony_ci static u8 cam_const_broad[] = { 243362306a36Sopenharmony_ci 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 243462306a36Sopenharmony_ci }; 243562306a36Sopenharmony_ci 243662306a36Sopenharmony_ci if (clear_all) { 243762306a36Sopenharmony_ci u8 idx = 0; 243862306a36Sopenharmony_ci u8 cam_offset = 0; 243962306a36Sopenharmony_ci u8 clear_number = 5; 244062306a36Sopenharmony_ci 244162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); 244262306a36Sopenharmony_ci 244362306a36Sopenharmony_ci for (idx = 0; idx < clear_number; idx++) { 244462306a36Sopenharmony_ci rtl_cam_mark_invalid(hw, cam_offset + idx); 244562306a36Sopenharmony_ci rtl_cam_empty_entry(hw, cam_offset + idx); 244662306a36Sopenharmony_ci 244762306a36Sopenharmony_ci if (idx < 5) { 244862306a36Sopenharmony_ci memset(rtlpriv->sec.key_buf[idx], 0, 244962306a36Sopenharmony_ci MAX_KEY_LEN); 245062306a36Sopenharmony_ci rtlpriv->sec.key_len[idx] = 0; 245162306a36Sopenharmony_ci } 245262306a36Sopenharmony_ci } 245362306a36Sopenharmony_ci 245462306a36Sopenharmony_ci } else { 245562306a36Sopenharmony_ci switch (enc_algo) { 245662306a36Sopenharmony_ci case WEP40_ENCRYPTION: 245762306a36Sopenharmony_ci enc_algo = CAM_WEP40; 245862306a36Sopenharmony_ci break; 245962306a36Sopenharmony_ci case WEP104_ENCRYPTION: 246062306a36Sopenharmony_ci enc_algo = CAM_WEP104; 246162306a36Sopenharmony_ci break; 246262306a36Sopenharmony_ci case TKIP_ENCRYPTION: 246362306a36Sopenharmony_ci enc_algo = CAM_TKIP; 246462306a36Sopenharmony_ci break; 246562306a36Sopenharmony_ci case AESCCMP_ENCRYPTION: 246662306a36Sopenharmony_ci enc_algo = CAM_AES; 246762306a36Sopenharmony_ci break; 246862306a36Sopenharmony_ci default: 246962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_DMESG, 247062306a36Sopenharmony_ci "switch case %#x not processed\n", enc_algo); 247162306a36Sopenharmony_ci enc_algo = CAM_TKIP; 247262306a36Sopenharmony_ci break; 247362306a36Sopenharmony_ci } 247462306a36Sopenharmony_ci 247562306a36Sopenharmony_ci if (is_wepkey || rtlpriv->sec.use_defaultkey) { 247662306a36Sopenharmony_ci macaddr = cam_const_addr[key_index]; 247762306a36Sopenharmony_ci entry_id = key_index; 247862306a36Sopenharmony_ci } else { 247962306a36Sopenharmony_ci if (is_group) { 248062306a36Sopenharmony_ci macaddr = cam_const_broad; 248162306a36Sopenharmony_ci entry_id = key_index; 248262306a36Sopenharmony_ci } else { 248362306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP || 248462306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_MESH_POINT) { 248562306a36Sopenharmony_ci entry_id = rtl_cam_get_free_entry(hw, 248662306a36Sopenharmony_ci p_macaddr); 248762306a36Sopenharmony_ci if (entry_id >= TOTAL_CAM_ENTRY) { 248862306a36Sopenharmony_ci pr_err("Can not find free hw security cam entry\n"); 248962306a36Sopenharmony_ci return; 249062306a36Sopenharmony_ci } 249162306a36Sopenharmony_ci } else { 249262306a36Sopenharmony_ci entry_id = CAM_PAIRWISE_KEY_POSITION; 249362306a36Sopenharmony_ci } 249462306a36Sopenharmony_ci 249562306a36Sopenharmony_ci key_index = PAIRWISE_KEYIDX; 249662306a36Sopenharmony_ci is_pairwise = true; 249762306a36Sopenharmony_ci } 249862306a36Sopenharmony_ci } 249962306a36Sopenharmony_ci 250062306a36Sopenharmony_ci if (rtlpriv->sec.key_len[key_index] == 0) { 250162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 250262306a36Sopenharmony_ci "delete one entry, entry_id is %d\n", 250362306a36Sopenharmony_ci entry_id); 250462306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP || 250562306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_MESH_POINT) 250662306a36Sopenharmony_ci rtl_cam_del_entry(hw, p_macaddr); 250762306a36Sopenharmony_ci rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); 250862306a36Sopenharmony_ci } else { 250962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 251062306a36Sopenharmony_ci "add one entry\n"); 251162306a36Sopenharmony_ci if (is_pairwise) { 251262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 251362306a36Sopenharmony_ci "set Pairwise key\n"); 251462306a36Sopenharmony_ci 251562306a36Sopenharmony_ci rtl_cam_add_one_entry(hw, macaddr, key_index, 251662306a36Sopenharmony_ci entry_id, enc_algo, 251762306a36Sopenharmony_ci CAM_CONFIG_NO_USEDK, 251862306a36Sopenharmony_ci rtlpriv->sec.key_buf[key_index]); 251962306a36Sopenharmony_ci } else { 252062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 252162306a36Sopenharmony_ci "set group key\n"); 252262306a36Sopenharmony_ci 252362306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) { 252462306a36Sopenharmony_ci rtl_cam_add_one_entry(hw, 252562306a36Sopenharmony_ci rtlefuse->dev_addr, 252662306a36Sopenharmony_ci PAIRWISE_KEYIDX, 252762306a36Sopenharmony_ci CAM_PAIRWISE_KEY_POSITION, 252862306a36Sopenharmony_ci enc_algo, CAM_CONFIG_NO_USEDK, 252962306a36Sopenharmony_ci rtlpriv->sec.key_buf[entry_id]); 253062306a36Sopenharmony_ci } 253162306a36Sopenharmony_ci 253262306a36Sopenharmony_ci rtl_cam_add_one_entry(hw, macaddr, key_index, 253362306a36Sopenharmony_ci entry_id, enc_algo, 253462306a36Sopenharmony_ci CAM_CONFIG_NO_USEDK, 253562306a36Sopenharmony_ci rtlpriv->sec.key_buf[entry_id]); 253662306a36Sopenharmony_ci } 253762306a36Sopenharmony_ci } 253862306a36Sopenharmony_ci } 253962306a36Sopenharmony_ci} 254062306a36Sopenharmony_ci 254162306a36Sopenharmony_civoid rtl92ee_read_bt_coexist_info_from_hwpg(struct ieee80211_hw *hw, 254262306a36Sopenharmony_ci bool auto_load_fail, u8 *hwinfo) 254362306a36Sopenharmony_ci{ 254462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 254562306a36Sopenharmony_ci u8 value; 254662306a36Sopenharmony_ci 254762306a36Sopenharmony_ci if (!auto_load_fail) { 254862306a36Sopenharmony_ci value = hwinfo[EEPROM_RF_BOARD_OPTION_92E]; 254962306a36Sopenharmony_ci if (((value & 0xe0) >> 5) == 0x1) 255062306a36Sopenharmony_ci rtlpriv->btcoexist.btc_info.btcoexist = 1; 255162306a36Sopenharmony_ci else 255262306a36Sopenharmony_ci rtlpriv->btcoexist.btc_info.btcoexist = 0; 255362306a36Sopenharmony_ci 255462306a36Sopenharmony_ci rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8192E; 255562306a36Sopenharmony_ci rtlpriv->btcoexist.btc_info.ant_num = ANT_X2; 255662306a36Sopenharmony_ci } else { 255762306a36Sopenharmony_ci rtlpriv->btcoexist.btc_info.btcoexist = 1; 255862306a36Sopenharmony_ci rtlpriv->btcoexist.btc_info.bt_type = BT_RTL8192E; 255962306a36Sopenharmony_ci rtlpriv->btcoexist.btc_info.ant_num = ANT_X1; 256062306a36Sopenharmony_ci } 256162306a36Sopenharmony_ci} 256262306a36Sopenharmony_ci 256362306a36Sopenharmony_civoid rtl92ee_bt_reg_init(struct ieee80211_hw *hw) 256462306a36Sopenharmony_ci{ 256562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 256662306a36Sopenharmony_ci 256762306a36Sopenharmony_ci /* 0:Low, 1:High, 2:From Efuse. */ 256862306a36Sopenharmony_ci rtlpriv->btcoexist.reg_bt_iso = 2; 256962306a36Sopenharmony_ci /* 0:Idle, 1:None-SCO, 2:SCO, 3:From Counter. */ 257062306a36Sopenharmony_ci rtlpriv->btcoexist.reg_bt_sco = 3; 257162306a36Sopenharmony_ci /* 0:Disable BT control A-MPDU, 1:Enable BT control A-MPDU. */ 257262306a36Sopenharmony_ci rtlpriv->btcoexist.reg_bt_sco = 0; 257362306a36Sopenharmony_ci} 257462306a36Sopenharmony_ci 257562306a36Sopenharmony_civoid rtl92ee_bt_hw_init(struct ieee80211_hw *hw) 257662306a36Sopenharmony_ci{ 257762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 257862306a36Sopenharmony_ci 257962306a36Sopenharmony_ci if (rtlpriv->cfg->ops->get_btc_status()) 258062306a36Sopenharmony_ci rtlpriv->btcoexist.btc_ops->btc_init_hw_config(rtlpriv); 258162306a36Sopenharmony_ci} 258262306a36Sopenharmony_ci 258362306a36Sopenharmony_civoid rtl92ee_suspend(struct ieee80211_hw *hw) 258462306a36Sopenharmony_ci{ 258562306a36Sopenharmony_ci} 258662306a36Sopenharmony_ci 258762306a36Sopenharmony_civoid rtl92ee_resume(struct ieee80211_hw *hw) 258862306a36Sopenharmony_ci{ 258962306a36Sopenharmony_ci} 259062306a36Sopenharmony_ci 259162306a36Sopenharmony_ci/* Turn on AAP (RCR:bit 0) for promicuous mode. */ 259262306a36Sopenharmony_civoid rtl92ee_allow_all_destaddr(struct ieee80211_hw *hw, 259362306a36Sopenharmony_ci bool allow_all_da, bool write_into_reg) 259462306a36Sopenharmony_ci{ 259562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 259662306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 259762306a36Sopenharmony_ci 259862306a36Sopenharmony_ci if (allow_all_da) /* Set BIT0 */ 259962306a36Sopenharmony_ci rtlpci->receive_config |= RCR_AAP; 260062306a36Sopenharmony_ci else /* Clear BIT0 */ 260162306a36Sopenharmony_ci rtlpci->receive_config &= ~RCR_AAP; 260262306a36Sopenharmony_ci 260362306a36Sopenharmony_ci if (write_into_reg) 260462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); 260562306a36Sopenharmony_ci 260662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_TURBO | COMP_INIT, DBG_LOUD, 260762306a36Sopenharmony_ci "receive_config=0x%08X, write_into_reg=%d\n", 260862306a36Sopenharmony_ci rtlpci->receive_config, write_into_reg); 260962306a36Sopenharmony_ci} 2610