162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2012 Realtek Corporation.*/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "../wifi.h" 562306a36Sopenharmony_ci#include "../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 1962306a36Sopenharmony_civoid rtl92se_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 2062306a36Sopenharmony_ci{ 2162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2262306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 2362306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 2462306a36Sopenharmony_ci 2562306a36Sopenharmony_ci switch (variable) { 2662306a36Sopenharmony_ci case HW_VAR_RCR: { 2762306a36Sopenharmony_ci *((u32 *) (val)) = rtlpci->receive_config; 2862306a36Sopenharmony_ci break; 2962306a36Sopenharmony_ci } 3062306a36Sopenharmony_ci case HW_VAR_RF_STATE: { 3162306a36Sopenharmony_ci *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; 3262306a36Sopenharmony_ci break; 3362306a36Sopenharmony_ci } 3462306a36Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: { 3562306a36Sopenharmony_ci *((bool *) (val)) = ppsc->fw_current_inpsmode; 3662306a36Sopenharmony_ci break; 3762306a36Sopenharmony_ci } 3862306a36Sopenharmony_ci case HW_VAR_CORRECT_TSF: { 3962306a36Sopenharmony_ci u64 tsf; 4062306a36Sopenharmony_ci u32 *ptsf_low = (u32 *)&tsf; 4162306a36Sopenharmony_ci u32 *ptsf_high = ((u32 *)&tsf) + 1; 4262306a36Sopenharmony_ci 4362306a36Sopenharmony_ci *ptsf_high = rtl_read_dword(rtlpriv, (TSFR + 4)); 4462306a36Sopenharmony_ci *ptsf_low = rtl_read_dword(rtlpriv, TSFR); 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci *((u64 *) (val)) = tsf; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci break; 4962306a36Sopenharmony_ci } 5062306a36Sopenharmony_ci case HW_VAR_MRC: { 5162306a36Sopenharmony_ci *((bool *)(val)) = rtlpriv->dm.current_mrc_switch; 5262306a36Sopenharmony_ci break; 5362306a36Sopenharmony_ci } 5462306a36Sopenharmony_ci case HAL_DEF_WOWLAN: 5562306a36Sopenharmony_ci break; 5662306a36Sopenharmony_ci default: 5762306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", variable); 5862306a36Sopenharmony_ci break; 5962306a36Sopenharmony_ci } 6062306a36Sopenharmony_ci} 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_civoid rtl92se_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 6362306a36Sopenharmony_ci{ 6462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6562306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 6662306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 6762306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 6862306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 6962306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci switch (variable) { 7262306a36Sopenharmony_ci case HW_VAR_ETHER_ADDR:{ 7362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, IDR0, ((u32 *)(val))[0]); 7462306a36Sopenharmony_ci rtl_write_word(rtlpriv, IDR4, ((u16 *)(val + 4))[0]); 7562306a36Sopenharmony_ci break; 7662306a36Sopenharmony_ci } 7762306a36Sopenharmony_ci case HW_VAR_BASIC_RATE:{ 7862306a36Sopenharmony_ci u16 rate_cfg = ((u16 *) val)[0]; 7962306a36Sopenharmony_ci u8 rate_index = 0; 8062306a36Sopenharmony_ci 8162306a36Sopenharmony_ci if (rtlhal->version == VERSION_8192S_ACUT) 8262306a36Sopenharmony_ci rate_cfg = rate_cfg & 0x150; 8362306a36Sopenharmony_ci else 8462306a36Sopenharmony_ci rate_cfg = rate_cfg & 0x15f; 8562306a36Sopenharmony_ci 8662306a36Sopenharmony_ci rate_cfg |= 0x01; 8762306a36Sopenharmony_ci 8862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RRSR, rate_cfg & 0xff); 8962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RRSR + 1, 9062306a36Sopenharmony_ci (rate_cfg >> 8) & 0xff); 9162306a36Sopenharmony_ci 9262306a36Sopenharmony_ci while (rate_cfg > 0x1) { 9362306a36Sopenharmony_ci rate_cfg = (rate_cfg >> 1); 9462306a36Sopenharmony_ci rate_index++; 9562306a36Sopenharmony_ci } 9662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, INIRTSMCS_SEL, rate_index); 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_ci break; 9962306a36Sopenharmony_ci } 10062306a36Sopenharmony_ci case HW_VAR_BSSID:{ 10162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, BSSIDR, ((u32 *)(val))[0]); 10262306a36Sopenharmony_ci rtl_write_word(rtlpriv, BSSIDR + 4, 10362306a36Sopenharmony_ci ((u16 *)(val + 4))[0]); 10462306a36Sopenharmony_ci break; 10562306a36Sopenharmony_ci } 10662306a36Sopenharmony_ci case HW_VAR_SIFS:{ 10762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SIFS_OFDM, val[0]); 10862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SIFS_OFDM + 1, val[1]); 10962306a36Sopenharmony_ci break; 11062306a36Sopenharmony_ci } 11162306a36Sopenharmony_ci case HW_VAR_SLOT_TIME:{ 11262306a36Sopenharmony_ci u8 e_aci; 11362306a36Sopenharmony_ci 11462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 11562306a36Sopenharmony_ci "HW_VAR_SLOT_TIME %x\n", val[0]); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SLOT_TIME, val[0]); 11862306a36Sopenharmony_ci 11962306a36Sopenharmony_ci for (e_aci = 0; e_aci < AC_MAX; e_aci++) { 12062306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 12162306a36Sopenharmony_ci HW_VAR_AC_PARAM, 12262306a36Sopenharmony_ci (&e_aci)); 12362306a36Sopenharmony_ci } 12462306a36Sopenharmony_ci break; 12562306a36Sopenharmony_ci } 12662306a36Sopenharmony_ci case HW_VAR_ACK_PREAMBLE:{ 12762306a36Sopenharmony_ci u8 reg_tmp; 12862306a36Sopenharmony_ci u8 short_preamble = (bool) (*val); 12962306a36Sopenharmony_ci reg_tmp = (mac->cur_40_prime_sc) << 5; 13062306a36Sopenharmony_ci if (short_preamble) 13162306a36Sopenharmony_ci reg_tmp |= 0x80; 13262306a36Sopenharmony_ci 13362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RRSR + 2, reg_tmp); 13462306a36Sopenharmony_ci break; 13562306a36Sopenharmony_ci } 13662306a36Sopenharmony_ci case HW_VAR_AMPDU_MIN_SPACE:{ 13762306a36Sopenharmony_ci u8 min_spacing_to_set; 13862306a36Sopenharmony_ci u8 sec_min_space; 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci min_spacing_to_set = *val; 14162306a36Sopenharmony_ci if (min_spacing_to_set <= 7) { 14262306a36Sopenharmony_ci if (rtlpriv->sec.pairwise_enc_algorithm == 14362306a36Sopenharmony_ci NO_ENCRYPTION) 14462306a36Sopenharmony_ci sec_min_space = 0; 14562306a36Sopenharmony_ci else 14662306a36Sopenharmony_ci sec_min_space = 1; 14762306a36Sopenharmony_ci 14862306a36Sopenharmony_ci if (min_spacing_to_set < sec_min_space) 14962306a36Sopenharmony_ci min_spacing_to_set = sec_min_space; 15062306a36Sopenharmony_ci if (min_spacing_to_set > 5) 15162306a36Sopenharmony_ci min_spacing_to_set = 5; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci mac->min_space_cfg = 15462306a36Sopenharmony_ci ((mac->min_space_cfg & 0xf8) | 15562306a36Sopenharmony_ci min_spacing_to_set); 15662306a36Sopenharmony_ci 15762306a36Sopenharmony_ci *val = min_spacing_to_set; 15862306a36Sopenharmony_ci 15962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 16062306a36Sopenharmony_ci "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", 16162306a36Sopenharmony_ci mac->min_space_cfg); 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, 16462306a36Sopenharmony_ci mac->min_space_cfg); 16562306a36Sopenharmony_ci } 16662306a36Sopenharmony_ci break; 16762306a36Sopenharmony_ci } 16862306a36Sopenharmony_ci case HW_VAR_SHORTGI_DENSITY:{ 16962306a36Sopenharmony_ci u8 density_to_set; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci density_to_set = *val; 17262306a36Sopenharmony_ci mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; 17362306a36Sopenharmony_ci mac->min_space_cfg |= (density_to_set << 3); 17462306a36Sopenharmony_ci 17562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 17662306a36Sopenharmony_ci "Set HW_VAR_SHORTGI_DENSITY: %#x\n", 17762306a36Sopenharmony_ci mac->min_space_cfg); 17862306a36Sopenharmony_ci 17962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, 18062306a36Sopenharmony_ci mac->min_space_cfg); 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci break; 18362306a36Sopenharmony_ci } 18462306a36Sopenharmony_ci case HW_VAR_AMPDU_FACTOR:{ 18562306a36Sopenharmony_ci u8 factor_toset; 18662306a36Sopenharmony_ci u8 regtoset; 18762306a36Sopenharmony_ci u8 factorlevel[18] = { 18862306a36Sopenharmony_ci 2, 4, 4, 7, 7, 13, 13, 18962306a36Sopenharmony_ci 13, 2, 7, 7, 13, 13, 19062306a36Sopenharmony_ci 15, 15, 15, 15, 0}; 19162306a36Sopenharmony_ci u8 index = 0; 19262306a36Sopenharmony_ci 19362306a36Sopenharmony_ci factor_toset = *val; 19462306a36Sopenharmony_ci if (factor_toset <= 3) { 19562306a36Sopenharmony_ci factor_toset = (1 << (factor_toset + 2)); 19662306a36Sopenharmony_ci if (factor_toset > 0xf) 19762306a36Sopenharmony_ci factor_toset = 0xf; 19862306a36Sopenharmony_ci 19962306a36Sopenharmony_ci for (index = 0; index < 17; index++) { 20062306a36Sopenharmony_ci if (factorlevel[index] > factor_toset) 20162306a36Sopenharmony_ci factorlevel[index] = 20262306a36Sopenharmony_ci factor_toset; 20362306a36Sopenharmony_ci } 20462306a36Sopenharmony_ci 20562306a36Sopenharmony_ci for (index = 0; index < 8; index++) { 20662306a36Sopenharmony_ci regtoset = ((factorlevel[index * 2]) | 20762306a36Sopenharmony_ci (factorlevel[index * 20862306a36Sopenharmony_ci 2 + 1] << 4)); 20962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 21062306a36Sopenharmony_ci AGGLEN_LMT_L + index, 21162306a36Sopenharmony_ci regtoset); 21262306a36Sopenharmony_ci } 21362306a36Sopenharmony_ci 21462306a36Sopenharmony_ci regtoset = ((factorlevel[16]) | 21562306a36Sopenharmony_ci (factorlevel[17] << 4)); 21662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AGGLEN_LMT_H, regtoset); 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 21962306a36Sopenharmony_ci "Set HW_VAR_AMPDU_FACTOR: %#x\n", 22062306a36Sopenharmony_ci factor_toset); 22162306a36Sopenharmony_ci } 22262306a36Sopenharmony_ci break; 22362306a36Sopenharmony_ci } 22462306a36Sopenharmony_ci case HW_VAR_AC_PARAM:{ 22562306a36Sopenharmony_ci u8 e_aci = *val; 22662306a36Sopenharmony_ci rtl92s_dm_init_edca_turbo(hw); 22762306a36Sopenharmony_ci 22862306a36Sopenharmony_ci if (rtlpci->acm_method != EACMWAY2_SW) 22962306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 23062306a36Sopenharmony_ci HW_VAR_ACM_CTRL, 23162306a36Sopenharmony_ci &e_aci); 23262306a36Sopenharmony_ci break; 23362306a36Sopenharmony_ci } 23462306a36Sopenharmony_ci case HW_VAR_ACM_CTRL:{ 23562306a36Sopenharmony_ci u8 e_aci = *val; 23662306a36Sopenharmony_ci union aci_aifsn *p_aci_aifsn = (union aci_aifsn *)(&( 23762306a36Sopenharmony_ci mac->ac[0].aifs)); 23862306a36Sopenharmony_ci u8 acm = p_aci_aifsn->f.acm; 23962306a36Sopenharmony_ci u8 acm_ctrl = rtl_read_byte(rtlpriv, ACMHWCTRL); 24062306a36Sopenharmony_ci 24162306a36Sopenharmony_ci acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 24262306a36Sopenharmony_ci 0x0 : 0x1); 24362306a36Sopenharmony_ci 24462306a36Sopenharmony_ci if (acm) { 24562306a36Sopenharmony_ci switch (e_aci) { 24662306a36Sopenharmony_ci case AC0_BE: 24762306a36Sopenharmony_ci acm_ctrl |= ACMHW_BEQEN; 24862306a36Sopenharmony_ci break; 24962306a36Sopenharmony_ci case AC2_VI: 25062306a36Sopenharmony_ci acm_ctrl |= ACMHW_VIQEN; 25162306a36Sopenharmony_ci break; 25262306a36Sopenharmony_ci case AC3_VO: 25362306a36Sopenharmony_ci acm_ctrl |= ACMHW_VOQEN; 25462306a36Sopenharmony_ci break; 25562306a36Sopenharmony_ci default: 25662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 25762306a36Sopenharmony_ci "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", 25862306a36Sopenharmony_ci acm); 25962306a36Sopenharmony_ci break; 26062306a36Sopenharmony_ci } 26162306a36Sopenharmony_ci } else { 26262306a36Sopenharmony_ci switch (e_aci) { 26362306a36Sopenharmony_ci case AC0_BE: 26462306a36Sopenharmony_ci acm_ctrl &= (~ACMHW_BEQEN); 26562306a36Sopenharmony_ci break; 26662306a36Sopenharmony_ci case AC2_VI: 26762306a36Sopenharmony_ci acm_ctrl &= (~ACMHW_VIQEN); 26862306a36Sopenharmony_ci break; 26962306a36Sopenharmony_ci case AC3_VO: 27062306a36Sopenharmony_ci acm_ctrl &= (~ACMHW_VOQEN); 27162306a36Sopenharmony_ci break; 27262306a36Sopenharmony_ci default: 27362306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", 27462306a36Sopenharmony_ci e_aci); 27562306a36Sopenharmony_ci break; 27662306a36Sopenharmony_ci } 27762306a36Sopenharmony_ci } 27862306a36Sopenharmony_ci 27962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, 28062306a36Sopenharmony_ci "HW_VAR_ACM_CTRL Write 0x%X\n", acm_ctrl); 28162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ACMHWCTRL, acm_ctrl); 28262306a36Sopenharmony_ci break; 28362306a36Sopenharmony_ci } 28462306a36Sopenharmony_ci case HW_VAR_RCR:{ 28562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, RCR, ((u32 *) (val))[0]); 28662306a36Sopenharmony_ci rtlpci->receive_config = ((u32 *) (val))[0]; 28762306a36Sopenharmony_ci break; 28862306a36Sopenharmony_ci } 28962306a36Sopenharmony_ci case HW_VAR_RETRY_LIMIT:{ 29062306a36Sopenharmony_ci u8 retry_limit = val[0]; 29162306a36Sopenharmony_ci 29262306a36Sopenharmony_ci rtl_write_word(rtlpriv, RETRY_LIMIT, 29362306a36Sopenharmony_ci retry_limit << RETRY_LIMIT_SHORT_SHIFT | 29462306a36Sopenharmony_ci retry_limit << RETRY_LIMIT_LONG_SHIFT); 29562306a36Sopenharmony_ci break; 29662306a36Sopenharmony_ci } 29762306a36Sopenharmony_ci case HW_VAR_DUAL_TSF_RST: { 29862306a36Sopenharmony_ci break; 29962306a36Sopenharmony_ci } 30062306a36Sopenharmony_ci case HW_VAR_EFUSE_BYTES: { 30162306a36Sopenharmony_ci rtlefuse->efuse_usedbytes = *((u16 *) val); 30262306a36Sopenharmony_ci break; 30362306a36Sopenharmony_ci } 30462306a36Sopenharmony_ci case HW_VAR_EFUSE_USAGE: { 30562306a36Sopenharmony_ci rtlefuse->efuse_usedpercentage = *val; 30662306a36Sopenharmony_ci break; 30762306a36Sopenharmony_ci } 30862306a36Sopenharmony_ci case HW_VAR_IO_CMD: { 30962306a36Sopenharmony_ci break; 31062306a36Sopenharmony_ci } 31162306a36Sopenharmony_ci case HW_VAR_WPA_CONFIG: { 31262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SECR, *val); 31362306a36Sopenharmony_ci break; 31462306a36Sopenharmony_ci } 31562306a36Sopenharmony_ci case HW_VAR_SET_RPWM:{ 31662306a36Sopenharmony_ci break; 31762306a36Sopenharmony_ci } 31862306a36Sopenharmony_ci case HW_VAR_H2C_FW_PWRMODE:{ 31962306a36Sopenharmony_ci break; 32062306a36Sopenharmony_ci } 32162306a36Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: { 32262306a36Sopenharmony_ci ppsc->fw_current_inpsmode = *((bool *) val); 32362306a36Sopenharmony_ci break; 32462306a36Sopenharmony_ci } 32562306a36Sopenharmony_ci case HW_VAR_H2C_FW_JOINBSSRPT:{ 32662306a36Sopenharmony_ci break; 32762306a36Sopenharmony_ci } 32862306a36Sopenharmony_ci case HW_VAR_AID:{ 32962306a36Sopenharmony_ci break; 33062306a36Sopenharmony_ci } 33162306a36Sopenharmony_ci case HW_VAR_CORRECT_TSF:{ 33262306a36Sopenharmony_ci break; 33362306a36Sopenharmony_ci } 33462306a36Sopenharmony_ci case HW_VAR_MRC: { 33562306a36Sopenharmony_ci bool bmrc_toset = *((bool *)val); 33662306a36Sopenharmony_ci u8 u1bdata = 0; 33762306a36Sopenharmony_ci 33862306a36Sopenharmony_ci if (bmrc_toset) { 33962306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, 34062306a36Sopenharmony_ci MASKBYTE0, 0x33); 34162306a36Sopenharmony_ci u1bdata = (u8)rtl_get_bbreg(hw, 34262306a36Sopenharmony_ci ROFDM1_TRXPATHENABLE, 34362306a36Sopenharmony_ci MASKBYTE0); 34462306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, 34562306a36Sopenharmony_ci MASKBYTE0, 34662306a36Sopenharmony_ci ((u1bdata & 0xf0) | 0x03)); 34762306a36Sopenharmony_ci u1bdata = (u8)rtl_get_bbreg(hw, 34862306a36Sopenharmony_ci ROFDM0_TRXPATHENABLE, 34962306a36Sopenharmony_ci MASKBYTE1); 35062306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, 35162306a36Sopenharmony_ci MASKBYTE1, 35262306a36Sopenharmony_ci (u1bdata | 0x04)); 35362306a36Sopenharmony_ci 35462306a36Sopenharmony_ci /* Update current settings. */ 35562306a36Sopenharmony_ci rtlpriv->dm.current_mrc_switch = bmrc_toset; 35662306a36Sopenharmony_ci } else { 35762306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, 35862306a36Sopenharmony_ci MASKBYTE0, 0x13); 35962306a36Sopenharmony_ci u1bdata = (u8)rtl_get_bbreg(hw, 36062306a36Sopenharmony_ci ROFDM1_TRXPATHENABLE, 36162306a36Sopenharmony_ci MASKBYTE0); 36262306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, 36362306a36Sopenharmony_ci MASKBYTE0, 36462306a36Sopenharmony_ci ((u1bdata & 0xf0) | 0x01)); 36562306a36Sopenharmony_ci u1bdata = (u8)rtl_get_bbreg(hw, 36662306a36Sopenharmony_ci ROFDM0_TRXPATHENABLE, 36762306a36Sopenharmony_ci MASKBYTE1); 36862306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, 36962306a36Sopenharmony_ci MASKBYTE1, (u1bdata & 0xfb)); 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_ci /* Update current settings. */ 37262306a36Sopenharmony_ci rtlpriv->dm.current_mrc_switch = bmrc_toset; 37362306a36Sopenharmony_ci } 37462306a36Sopenharmony_ci 37562306a36Sopenharmony_ci break; 37662306a36Sopenharmony_ci } 37762306a36Sopenharmony_ci case HW_VAR_FW_LPS_ACTION: { 37862306a36Sopenharmony_ci bool enter_fwlps = *((bool *)val); 37962306a36Sopenharmony_ci u8 rpwm_val, fw_pwrmode; 38062306a36Sopenharmony_ci bool fw_current_inps; 38162306a36Sopenharmony_ci 38262306a36Sopenharmony_ci if (enter_fwlps) { 38362306a36Sopenharmony_ci rpwm_val = 0x02; /* RF off */ 38462306a36Sopenharmony_ci fw_current_inps = true; 38562306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 38662306a36Sopenharmony_ci HW_VAR_FW_PSMODE_STATUS, 38762306a36Sopenharmony_ci (u8 *)(&fw_current_inps)); 38862306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 38962306a36Sopenharmony_ci HW_VAR_H2C_FW_PWRMODE, 39062306a36Sopenharmony_ci &ppsc->fwctrl_psmode); 39162306a36Sopenharmony_ci 39262306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, 39362306a36Sopenharmony_ci &rpwm_val); 39462306a36Sopenharmony_ci } else { 39562306a36Sopenharmony_ci rpwm_val = 0x0C; /* RF on */ 39662306a36Sopenharmony_ci fw_pwrmode = FW_PS_ACTIVE_MODE; 39762306a36Sopenharmony_ci fw_current_inps = false; 39862306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SET_RPWM, 39962306a36Sopenharmony_ci &rpwm_val); 40062306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_H2C_FW_PWRMODE, 40162306a36Sopenharmony_ci &fw_pwrmode); 40262306a36Sopenharmony_ci 40362306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 40462306a36Sopenharmony_ci HW_VAR_FW_PSMODE_STATUS, 40562306a36Sopenharmony_ci (u8 *)(&fw_current_inps)); 40662306a36Sopenharmony_ci } 40762306a36Sopenharmony_ci break; } 40862306a36Sopenharmony_ci default: 40962306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", variable); 41062306a36Sopenharmony_ci break; 41162306a36Sopenharmony_ci } 41262306a36Sopenharmony_ci 41362306a36Sopenharmony_ci} 41462306a36Sopenharmony_ci 41562306a36Sopenharmony_civoid rtl92se_enable_hw_security_config(struct ieee80211_hw *hw) 41662306a36Sopenharmony_ci{ 41762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 41862306a36Sopenharmony_ci u8 sec_reg_value = 0x0; 41962306a36Sopenharmony_ci 42062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 42162306a36Sopenharmony_ci "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", 42262306a36Sopenharmony_ci rtlpriv->sec.pairwise_enc_algorithm, 42362306a36Sopenharmony_ci rtlpriv->sec.group_enc_algorithm); 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { 42662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 42762306a36Sopenharmony_ci "not open hw encryption\n"); 42862306a36Sopenharmony_ci return; 42962306a36Sopenharmony_ci } 43062306a36Sopenharmony_ci 43162306a36Sopenharmony_ci sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE; 43262306a36Sopenharmony_ci 43362306a36Sopenharmony_ci if (rtlpriv->sec.use_defaultkey) { 43462306a36Sopenharmony_ci sec_reg_value |= SCR_TXUSEDK; 43562306a36Sopenharmony_ci sec_reg_value |= SCR_RXUSEDK; 43662306a36Sopenharmony_ci } 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", 43962306a36Sopenharmony_ci sec_reg_value); 44062306a36Sopenharmony_ci 44162306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); 44262306a36Sopenharmony_ci 44362306a36Sopenharmony_ci} 44462306a36Sopenharmony_ci 44562306a36Sopenharmony_cistatic u8 _rtl92se_halset_sysclk(struct ieee80211_hw *hw, u8 data) 44662306a36Sopenharmony_ci{ 44762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 44862306a36Sopenharmony_ci u8 waitcount = 100; 44962306a36Sopenharmony_ci bool bresult = false; 45062306a36Sopenharmony_ci u8 tmpvalue; 45162306a36Sopenharmony_ci 45262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SYS_CLKR + 1, data); 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci /* Wait the MAC synchronized. */ 45562306a36Sopenharmony_ci udelay(400); 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_ci /* Check if it is set ready. */ 45862306a36Sopenharmony_ci tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1); 45962306a36Sopenharmony_ci bresult = ((tmpvalue & BIT(7)) == (data & BIT(7))); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci if (!(data & (BIT(6) | BIT(7)))) { 46262306a36Sopenharmony_ci waitcount = 100; 46362306a36Sopenharmony_ci tmpvalue = 0; 46462306a36Sopenharmony_ci 46562306a36Sopenharmony_ci while (1) { 46662306a36Sopenharmony_ci waitcount--; 46762306a36Sopenharmony_ci 46862306a36Sopenharmony_ci tmpvalue = rtl_read_byte(rtlpriv, SYS_CLKR + 1); 46962306a36Sopenharmony_ci if ((tmpvalue & BIT(6))) 47062306a36Sopenharmony_ci break; 47162306a36Sopenharmony_ci 47262306a36Sopenharmony_ci pr_err("wait for BIT(6) return value %x\n", tmpvalue); 47362306a36Sopenharmony_ci if (waitcount == 0) 47462306a36Sopenharmony_ci break; 47562306a36Sopenharmony_ci 47662306a36Sopenharmony_ci udelay(10); 47762306a36Sopenharmony_ci } 47862306a36Sopenharmony_ci 47962306a36Sopenharmony_ci if (waitcount == 0) 48062306a36Sopenharmony_ci bresult = false; 48162306a36Sopenharmony_ci else 48262306a36Sopenharmony_ci bresult = true; 48362306a36Sopenharmony_ci } 48462306a36Sopenharmony_ci 48562306a36Sopenharmony_ci return bresult; 48662306a36Sopenharmony_ci} 48762306a36Sopenharmony_ci 48862306a36Sopenharmony_civoid rtl8192se_gpiobit3_cfg_inputmode(struct ieee80211_hw *hw) 48962306a36Sopenharmony_ci{ 49062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 49162306a36Sopenharmony_ci u8 u1tmp; 49262306a36Sopenharmony_ci 49362306a36Sopenharmony_ci /* The following config GPIO function */ 49462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO)); 49562306a36Sopenharmony_ci u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL); 49662306a36Sopenharmony_ci 49762306a36Sopenharmony_ci /* config GPIO3 to input */ 49862306a36Sopenharmony_ci u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK; 49962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp); 50062306a36Sopenharmony_ci 50162306a36Sopenharmony_ci} 50262306a36Sopenharmony_ci 50362306a36Sopenharmony_cistatic u8 _rtl92se_rf_onoff_detect(struct ieee80211_hw *hw) 50462306a36Sopenharmony_ci{ 50562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 50662306a36Sopenharmony_ci u8 u1tmp; 50762306a36Sopenharmony_ci u8 retval = ERFON; 50862306a36Sopenharmony_ci 50962306a36Sopenharmony_ci /* The following config GPIO function */ 51062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, (GPIOMUX_EN | GPIOSEL_GPIO)); 51162306a36Sopenharmony_ci u1tmp = rtl_read_byte(rtlpriv, GPIO_IO_SEL); 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci /* config GPIO3 to input */ 51462306a36Sopenharmony_ci u1tmp &= HAL_8192S_HW_GPIO_OFF_MASK; 51562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, GPIO_IO_SEL, u1tmp); 51662306a36Sopenharmony_ci 51762306a36Sopenharmony_ci /* On some of the platform, driver cannot read correct 51862306a36Sopenharmony_ci * value without delay between Write_GPIO_SEL and Read_GPIO_IN */ 51962306a36Sopenharmony_ci mdelay(10); 52062306a36Sopenharmony_ci 52162306a36Sopenharmony_ci /* check GPIO3 */ 52262306a36Sopenharmony_ci u1tmp = rtl_read_byte(rtlpriv, GPIO_IN_SE); 52362306a36Sopenharmony_ci retval = (u1tmp & HAL_8192S_HW_GPIO_OFF_BIT) ? ERFON : ERFOFF; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci return retval; 52662306a36Sopenharmony_ci} 52762306a36Sopenharmony_ci 52862306a36Sopenharmony_cistatic void _rtl92se_macconfig_before_fwdownload(struct ieee80211_hw *hw) 52962306a36Sopenharmony_ci{ 53062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 53162306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 53262306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 53362306a36Sopenharmony_ci 53462306a36Sopenharmony_ci u8 i; 53562306a36Sopenharmony_ci u8 tmpu1b; 53662306a36Sopenharmony_ci u16 tmpu2b; 53762306a36Sopenharmony_ci u8 pollingcnt = 20; 53862306a36Sopenharmony_ci 53962306a36Sopenharmony_ci if (rtlpci->first_init) { 54062306a36Sopenharmony_ci /* Reset PCIE Digital */ 54162306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 54262306a36Sopenharmony_ci tmpu1b &= 0xFE; 54362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b); 54462306a36Sopenharmony_ci udelay(1); 54562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b | BIT(0)); 54662306a36Sopenharmony_ci } 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_ci /* Switch to SW IO control */ 54962306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); 55062306a36Sopenharmony_ci if (tmpu1b & BIT(7)) { 55162306a36Sopenharmony_ci tmpu1b &= ~(BIT(6) | BIT(7)); 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_ci /* Set failed, return to prevent hang. */ 55462306a36Sopenharmony_ci if (!_rtl92se_halset_sysclk(hw, tmpu1b)) 55562306a36Sopenharmony_ci return; 55662306a36Sopenharmony_ci } 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0); 55962306a36Sopenharmony_ci udelay(50); 56062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); 56162306a36Sopenharmony_ci udelay(50); 56262306a36Sopenharmony_ci 56362306a36Sopenharmony_ci /* Clear FW RPWM for FW control LPS.*/ 56462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RPWM, 0x0); 56562306a36Sopenharmony_ci 56662306a36Sopenharmony_ci /* Reset MAC-IO and CPU and Core Digital BIT(10)/11/15 */ 56762306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 56862306a36Sopenharmony_ci tmpu1b &= 0x73; 56962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b); 57062306a36Sopenharmony_ci /* wait for BIT 10/11/15 to pull high automatically!! */ 57162306a36Sopenharmony_ci mdelay(1); 57262306a36Sopenharmony_ci 57362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, CMDR, 0); 57462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, TCR, 0); 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */ 57762306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, 0x562); 57862306a36Sopenharmony_ci tmpu1b |= 0x08; 57962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x562, tmpu1b); 58062306a36Sopenharmony_ci tmpu1b &= ~(BIT(3)); 58162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x562, tmpu1b); 58262306a36Sopenharmony_ci 58362306a36Sopenharmony_ci /* Enable AFE clock source */ 58462306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL); 58562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01)); 58662306a36Sopenharmony_ci /* Delay 1.5ms */ 58762306a36Sopenharmony_ci mdelay(2); 58862306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1); 58962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb)); 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_ci /* Enable AFE Macro Block's Bandgap */ 59262306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); 59362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0))); 59462306a36Sopenharmony_ci mdelay(1); 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci /* Enable AFE Mbias */ 59762306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); 59862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02)); 59962306a36Sopenharmony_ci mdelay(1); 60062306a36Sopenharmony_ci 60162306a36Sopenharmony_ci /* Enable LDOA15 block */ 60262306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL); 60362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0))); 60462306a36Sopenharmony_ci 60562306a36Sopenharmony_ci /* Set Digital Vdd to Retention isolation Path. */ 60662306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); 60762306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11))); 60862306a36Sopenharmony_ci 60962306a36Sopenharmony_ci /* For warm reboot NIC disappera bug. */ 61062306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 61162306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13))); 61262306a36Sopenharmony_ci 61362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68); 61462306a36Sopenharmony_ci 61562306a36Sopenharmony_ci /* Enable AFE PLL Macro Block */ 61662306a36Sopenharmony_ci /* We need to delay 100u before enabling PLL. */ 61762306a36Sopenharmony_ci udelay(200); 61862306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL); 61962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4))); 62062306a36Sopenharmony_ci 62162306a36Sopenharmony_ci /* for divider reset */ 62262306a36Sopenharmony_ci udelay(100); 62362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | 62462306a36Sopenharmony_ci BIT(4) | BIT(6))); 62562306a36Sopenharmony_ci udelay(10); 62662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4))); 62762306a36Sopenharmony_ci udelay(10); 62862306a36Sopenharmony_ci 62962306a36Sopenharmony_ci /* Enable MAC 80MHZ clock */ 63062306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1); 63162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0))); 63262306a36Sopenharmony_ci mdelay(1); 63362306a36Sopenharmony_ci 63462306a36Sopenharmony_ci /* Release isolation AFE PLL & MD */ 63562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6); 63662306a36Sopenharmony_ci 63762306a36Sopenharmony_ci /* Enable MAC clock */ 63862306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); 63962306a36Sopenharmony_ci rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11))); 64062306a36Sopenharmony_ci 64162306a36Sopenharmony_ci /* Enable Core digital and enable IOREG R/W */ 64262306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 64362306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11))); 64462306a36Sopenharmony_ci 64562306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 64662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b & ~(BIT(7))); 64762306a36Sopenharmony_ci 64862306a36Sopenharmony_ci /* enable REG_EN */ 64962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15))); 65062306a36Sopenharmony_ci 65162306a36Sopenharmony_ci /* Switch the control path. */ 65262306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); 65362306a36Sopenharmony_ci rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2)))); 65462306a36Sopenharmony_ci 65562306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); 65662306a36Sopenharmony_ci tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6))); 65762306a36Sopenharmony_ci if (!_rtl92se_halset_sysclk(hw, tmpu1b)) 65862306a36Sopenharmony_ci return; /* Set failed, return to prevent hang. */ 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x07FC); 66162306a36Sopenharmony_ci 66262306a36Sopenharmony_ci /* MH We must enable the section of code to prevent load IMEM fail. */ 66362306a36Sopenharmony_ci /* Load MAC register from WMAc temporarily We simulate macreg. */ 66462306a36Sopenharmony_ci /* txt HW will provide MAC txt later */ 66562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x6, 0x30); 66662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x49, 0xf0); 66762306a36Sopenharmony_ci 66862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x4b, 0x81); 66962306a36Sopenharmony_ci 67062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xb5, 0x21); 67162306a36Sopenharmony_ci 67262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xdc, 0xff); 67362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xdd, 0xff); 67462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xde, 0xff); 67562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xdf, 0xff); 67662306a36Sopenharmony_ci 67762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x11a, 0x00); 67862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x11b, 0x00); 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci for (i = 0; i < 32; i++) 68162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, INIMCS_SEL + i, 0x1b); 68262306a36Sopenharmony_ci 68362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x236, 0xff); 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x503, 0x22); 68662306a36Sopenharmony_ci 68762306a36Sopenharmony_ci if (ppsc->support_aspm && !ppsc->support_backdoor) 68862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x560, 0x40); 68962306a36Sopenharmony_ci else 69062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x560, 0x00); 69162306a36Sopenharmony_ci 69262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, DBG_PORT, 0x91); 69362306a36Sopenharmony_ci 69462306a36Sopenharmony_ci /* Set RX Desc Address */ 69562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, RDQDA, rtlpci->rx_ring[RX_MPDU_QUEUE].dma); 69662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, RCDA, rtlpci->rx_ring[RX_CMD_QUEUE].dma); 69762306a36Sopenharmony_ci 69862306a36Sopenharmony_ci /* Set TX Desc Address */ 69962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TBKDA, rtlpci->tx_ring[BK_QUEUE].dma); 70062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TBEDA, rtlpci->tx_ring[BE_QUEUE].dma); 70162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TVIDA, rtlpci->tx_ring[VI_QUEUE].dma); 70262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TVODA, rtlpci->tx_ring[VO_QUEUE].dma); 70362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TBDA, rtlpci->tx_ring[BEACON_QUEUE].dma); 70462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TCDA, rtlpci->tx_ring[TXCMD_QUEUE].dma); 70562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TMDA, rtlpci->tx_ring[MGNT_QUEUE].dma); 70662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, THPDA, rtlpci->tx_ring[HIGH_QUEUE].dma); 70762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, HDA, rtlpci->tx_ring[HCCA_QUEUE].dma); 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x37FC); 71062306a36Sopenharmony_ci 71162306a36Sopenharmony_ci /* To make sure that TxDMA can ready to download FW. */ 71262306a36Sopenharmony_ci /* We should reset TxDMA if IMEM RPT was not ready. */ 71362306a36Sopenharmony_ci do { 71462306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, TCR); 71562306a36Sopenharmony_ci if ((tmpu1b & TXDMA_INIT_VALUE) == TXDMA_INIT_VALUE) 71662306a36Sopenharmony_ci break; 71762306a36Sopenharmony_ci 71862306a36Sopenharmony_ci udelay(5); 71962306a36Sopenharmony_ci } while (pollingcnt--); 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci if (pollingcnt <= 0) { 72262306a36Sopenharmony_ci pr_err("Polling TXDMA_INIT_VALUE timeout!! Current TCR(%#x)\n", 72362306a36Sopenharmony_ci tmpu1b); 72462306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, CMDR); 72562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, CMDR, tmpu1b & (~TXDMA_EN)); 72662306a36Sopenharmony_ci udelay(2); 72762306a36Sopenharmony_ci /* Reset TxDMA */ 72862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, CMDR, tmpu1b | TXDMA_EN); 72962306a36Sopenharmony_ci } 73062306a36Sopenharmony_ci 73162306a36Sopenharmony_ci /* After MACIO reset,we must refresh LED state. */ 73262306a36Sopenharmony_ci if ((ppsc->rfoff_reason == RF_CHANGE_BY_IPS) || 73362306a36Sopenharmony_ci (ppsc->rfoff_reason == 0)) { 73462306a36Sopenharmony_ci enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; 73562306a36Sopenharmony_ci enum rf_pwrstate rfpwr_state_toset; 73662306a36Sopenharmony_ci rfpwr_state_toset = _rtl92se_rf_onoff_detect(hw); 73762306a36Sopenharmony_ci 73862306a36Sopenharmony_ci if (rfpwr_state_toset == ERFON) 73962306a36Sopenharmony_ci rtl92se_sw_led_on(hw, pin0); 74062306a36Sopenharmony_ci } 74162306a36Sopenharmony_ci} 74262306a36Sopenharmony_ci 74362306a36Sopenharmony_cistatic void _rtl92se_macconfig_after_fwdownload(struct ieee80211_hw *hw) 74462306a36Sopenharmony_ci{ 74562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 74662306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 74762306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 74862306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 74962306a36Sopenharmony_ci u8 i; 75062306a36Sopenharmony_ci u16 tmpu2b; 75162306a36Sopenharmony_ci 75262306a36Sopenharmony_ci /* 1. System Configure Register (Offset: 0x0000 - 0x003F) */ 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci /* 2. Command Control Register (Offset: 0x0040 - 0x004F) */ 75562306a36Sopenharmony_ci /* Turn on 0x40 Command register */ 75662306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, (BBRSTN | BB_GLB_RSTN | 75762306a36Sopenharmony_ci SCHEDULE_EN | MACRXEN | MACTXEN | DDMA_EN | FW2HW_EN | 75862306a36Sopenharmony_ci RXDMA_EN | TXDMA_EN | HCI_RXDMA_EN | HCI_TXDMA_EN)); 75962306a36Sopenharmony_ci 76062306a36Sopenharmony_ci /* Set TCR TX DMA pre 2 FULL enable bit */ 76162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TCR, rtl_read_dword(rtlpriv, TCR) | 76262306a36Sopenharmony_ci TXDMAPRE2FULL); 76362306a36Sopenharmony_ci 76462306a36Sopenharmony_ci /* Set RCR */ 76562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config); 76662306a36Sopenharmony_ci 76762306a36Sopenharmony_ci /* 3. MACID Setting Register (Offset: 0x0050 - 0x007F) */ 76862306a36Sopenharmony_ci 76962306a36Sopenharmony_ci /* 4. Timing Control Register (Offset: 0x0080 - 0x009F) */ 77062306a36Sopenharmony_ci /* Set CCK/OFDM SIFS */ 77162306a36Sopenharmony_ci /* CCK SIFS shall always be 10us. */ 77262306a36Sopenharmony_ci rtl_write_word(rtlpriv, SIFS_CCK, 0x0a0a); 77362306a36Sopenharmony_ci rtl_write_word(rtlpriv, SIFS_OFDM, 0x1010); 77462306a36Sopenharmony_ci 77562306a36Sopenharmony_ci /* Set AckTimeout */ 77662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ACK_TIMEOUT, 0x40); 77762306a36Sopenharmony_ci 77862306a36Sopenharmony_ci /* Beacon related */ 77962306a36Sopenharmony_ci rtl_write_word(rtlpriv, BCN_INTERVAL, 100); 78062306a36Sopenharmony_ci rtl_write_word(rtlpriv, ATIMWND, 2); 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci /* 5. FIFO Control Register (Offset: 0x00A0 - 0x015F) */ 78362306a36Sopenharmony_ci /* 5.1 Initialize Number of Reserved Pages in Firmware Queue */ 78462306a36Sopenharmony_ci /* Firmware allocate now, associate with FW internal setting.!!! */ 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_ci /* 5.2 Setting TX/RX page size 0/1/2/3/4=64/128/256/512/1024 */ 78762306a36Sopenharmony_ci /* 5.3 Set driver info, we only accept PHY status now. */ 78862306a36Sopenharmony_ci /* 5.4 Set RXDMA arbitration to control RXDMA/MAC/FW R/W for RXFIFO */ 78962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RXDMA, rtl_read_byte(rtlpriv, RXDMA) | BIT(6)); 79062306a36Sopenharmony_ci 79162306a36Sopenharmony_ci /* 6. Adaptive Control Register (Offset: 0x0160 - 0x01CF) */ 79262306a36Sopenharmony_ci /* Set RRSR to all legacy rate and HT rate 79362306a36Sopenharmony_ci * CCK rate is supported by default. 79462306a36Sopenharmony_ci * CCK rate will be filtered out only when associated 79562306a36Sopenharmony_ci * AP does not support it. 79662306a36Sopenharmony_ci * Only enable ACK rate to OFDM 24M 79762306a36Sopenharmony_ci * Disable RRSR for CCK rate in A-Cut */ 79862306a36Sopenharmony_ci 79962306a36Sopenharmony_ci if (rtlhal->version == VERSION_8192S_ACUT) 80062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RRSR, 0xf0); 80162306a36Sopenharmony_ci else if (rtlhal->version == VERSION_8192S_BCUT) 80262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RRSR, 0xff); 80362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RRSR + 1, 0x01); 80462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RRSR + 2, 0x00); 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci /* A-Cut IC do not support CCK rate. We forbid ARFR to */ 80762306a36Sopenharmony_ci /* fallback to CCK rate */ 80862306a36Sopenharmony_ci for (i = 0; i < 8; i++) { 80962306a36Sopenharmony_ci /*Disable RRSR for CCK rate in A-Cut */ 81062306a36Sopenharmony_ci if (rtlhal->version == VERSION_8192S_ACUT) 81162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, ARFR0 + i * 4, 0x1f0ff0f0); 81262306a36Sopenharmony_ci } 81362306a36Sopenharmony_ci 81462306a36Sopenharmony_ci /* Different rate use different AMPDU size */ 81562306a36Sopenharmony_ci /* MCS32/ MCS15_SG use max AMPDU size 15*2=30K */ 81662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AGGLEN_LMT_H, 0x0f); 81762306a36Sopenharmony_ci /* MCS0/1/2/3 use max AMPDU size 4*2=8K */ 81862306a36Sopenharmony_ci rtl_write_word(rtlpriv, AGGLEN_LMT_L, 0x7442); 81962306a36Sopenharmony_ci /* MCS4/5 use max AMPDU size 8*2=16K 6/7 use 10*2=20K */ 82062306a36Sopenharmony_ci rtl_write_word(rtlpriv, AGGLEN_LMT_L + 2, 0xddd7); 82162306a36Sopenharmony_ci /* MCS8/9 use max AMPDU size 8*2=16K 10/11 use 10*2=20K */ 82262306a36Sopenharmony_ci rtl_write_word(rtlpriv, AGGLEN_LMT_L + 4, 0xd772); 82362306a36Sopenharmony_ci /* MCS12/13/14/15 use max AMPDU size 15*2=30K */ 82462306a36Sopenharmony_ci rtl_write_word(rtlpriv, AGGLEN_LMT_L + 6, 0xfffd); 82562306a36Sopenharmony_ci 82662306a36Sopenharmony_ci /* Set Data / Response auto rate fallack retry count */ 82762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, DARFRC, 0x04010000); 82862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, DARFRC + 4, 0x09070605); 82962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, RARFRC, 0x04010000); 83062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, RARFRC + 4, 0x09070605); 83162306a36Sopenharmony_ci 83262306a36Sopenharmony_ci /* 7. EDCA Setting Register (Offset: 0x01D0 - 0x01FF) */ 83362306a36Sopenharmony_ci /* Set all rate to support SG */ 83462306a36Sopenharmony_ci rtl_write_word(rtlpriv, SG_RATE, 0xFFFF); 83562306a36Sopenharmony_ci 83662306a36Sopenharmony_ci /* 8. WMAC, BA, and CCX related Register (Offset: 0x0200 - 0x023F) */ 83762306a36Sopenharmony_ci /* Set NAV protection length */ 83862306a36Sopenharmony_ci rtl_write_word(rtlpriv, NAV_PROT_LEN, 0x0080); 83962306a36Sopenharmony_ci /* CF-END Threshold */ 84062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, CFEND_TH, 0xFF); 84162306a36Sopenharmony_ci /* Set AMPDU minimum space */ 84262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, 0x07); 84362306a36Sopenharmony_ci /* Set TXOP stall control for several queue/HI/BCN/MGT/ */ 84462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, TXOP_STALL_CTRL, 0x00); 84562306a36Sopenharmony_ci 84662306a36Sopenharmony_ci /* 9. Security Control Register (Offset: 0x0240 - 0x025F) */ 84762306a36Sopenharmony_ci /* 10. Power Save Control Register (Offset: 0x0260 - 0x02DF) */ 84862306a36Sopenharmony_ci /* 11. General Purpose Register (Offset: 0x02E0 - 0x02FF) */ 84962306a36Sopenharmony_ci /* 12. Host Interrupt Status Register (Offset: 0x0300 - 0x030F) */ 85062306a36Sopenharmony_ci /* 13. Test mode and Debug Control Register (Offset: 0x0310 - 0x034F) */ 85162306a36Sopenharmony_ci 85262306a36Sopenharmony_ci /* 14. Set driver info, we only accept PHY status now. */ 85362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RXDRVINFO_SZ, 4); 85462306a36Sopenharmony_ci 85562306a36Sopenharmony_ci /* 15. For EEPROM R/W Workaround */ 85662306a36Sopenharmony_ci /* 16. For EFUSE to share REG_SYS_FUNC_EN with EEPROM!!! */ 85762306a36Sopenharmony_ci tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); 85862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, tmpu2b | BIT(13)); 85962306a36Sopenharmony_ci tmpu2b = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); 86062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, tmpu2b & (~BIT(8))); 86162306a36Sopenharmony_ci 86262306a36Sopenharmony_ci /* 17. For EFUSE */ 86362306a36Sopenharmony_ci /* We may R/W EFUSE in EEPROM mode */ 86462306a36Sopenharmony_ci if (rtlefuse->epromtype == EEPROM_BOOT_EFUSE) { 86562306a36Sopenharmony_ci u8 tempval; 86662306a36Sopenharmony_ci 86762306a36Sopenharmony_ci tempval = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL + 1); 86862306a36Sopenharmony_ci tempval &= 0xFE; 86962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, tempval); 87062306a36Sopenharmony_ci 87162306a36Sopenharmony_ci /* Change Program timing */ 87262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_EFUSE_CTRL + 3, 0x72); 87362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "EFUSE CONFIG OK\n"); 87462306a36Sopenharmony_ci } 87562306a36Sopenharmony_ci 87662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "OK\n"); 87762306a36Sopenharmony_ci 87862306a36Sopenharmony_ci} 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_cistatic void _rtl92se_hw_configure(struct ieee80211_hw *hw) 88162306a36Sopenharmony_ci{ 88262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 88362306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 88462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 88562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 88662306a36Sopenharmony_ci 88762306a36Sopenharmony_ci u8 reg_bw_opmode = 0; 88862306a36Sopenharmony_ci u32 reg_rrsr = 0; 88962306a36Sopenharmony_ci u8 regtmp = 0; 89062306a36Sopenharmony_ci 89162306a36Sopenharmony_ci reg_bw_opmode = BW_OPMODE_20MHZ; 89262306a36Sopenharmony_ci reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; 89362306a36Sopenharmony_ci 89462306a36Sopenharmony_ci regtmp = rtl_read_byte(rtlpriv, INIRTSMCS_SEL); 89562306a36Sopenharmony_ci reg_rrsr = ((reg_rrsr & 0x000fffff) << 8) | regtmp; 89662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, INIRTSMCS_SEL, reg_rrsr); 89762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, BW_OPMODE, reg_bw_opmode); 89862306a36Sopenharmony_ci 89962306a36Sopenharmony_ci /* Set Retry Limit here */ 90062306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RETRY_LIMIT, 90162306a36Sopenharmony_ci (u8 *)(&rtlpci->shortretry_limit)); 90262306a36Sopenharmony_ci 90362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, MLT, 0x8f); 90462306a36Sopenharmony_ci 90562306a36Sopenharmony_ci /* For Min Spacing configuration. */ 90662306a36Sopenharmony_ci switch (rtlphy->rf_type) { 90762306a36Sopenharmony_ci case RF_1T2R: 90862306a36Sopenharmony_ci case RF_1T1R: 90962306a36Sopenharmony_ci rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3); 91062306a36Sopenharmony_ci break; 91162306a36Sopenharmony_ci case RF_2T2R: 91262306a36Sopenharmony_ci case RF_2T2R_GREEN: 91362306a36Sopenharmony_ci rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3); 91462306a36Sopenharmony_ci break; 91562306a36Sopenharmony_ci } 91662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AMPDU_MIN_SPACE, rtlhal->minspace_cfg); 91762306a36Sopenharmony_ci} 91862306a36Sopenharmony_ci 91962306a36Sopenharmony_ciint rtl92se_hw_init(struct ieee80211_hw *hw) 92062306a36Sopenharmony_ci{ 92162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 92262306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 92362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 92462306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 92562306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 92662306a36Sopenharmony_ci u8 tmp_byte = 0; 92762306a36Sopenharmony_ci unsigned long flags; 92862306a36Sopenharmony_ci bool rtstatus = true; 92962306a36Sopenharmony_ci u8 tmp_u1b; 93062306a36Sopenharmony_ci int err = false; 93162306a36Sopenharmony_ci u8 i; 93262306a36Sopenharmony_ci int wdcapra_add[] = { 93362306a36Sopenharmony_ci EDCAPARA_BE, EDCAPARA_BK, 93462306a36Sopenharmony_ci EDCAPARA_VI, EDCAPARA_VO}; 93562306a36Sopenharmony_ci u8 secr_value = 0x0; 93662306a36Sopenharmony_ci 93762306a36Sopenharmony_ci rtlpci->being_init_adapter = true; 93862306a36Sopenharmony_ci 93962306a36Sopenharmony_ci /* As this function can take a very long time (up to 350 ms) 94062306a36Sopenharmony_ci * and can be called with irqs disabled, reenable the irqs 94162306a36Sopenharmony_ci * to let the other devices continue being serviced. 94262306a36Sopenharmony_ci * 94362306a36Sopenharmony_ci * It is safe doing so since our own interrupts will only be enabled 94462306a36Sopenharmony_ci * in a subsequent step. 94562306a36Sopenharmony_ci */ 94662306a36Sopenharmony_ci local_save_flags(flags); 94762306a36Sopenharmony_ci local_irq_enable(); 94862306a36Sopenharmony_ci 94962306a36Sopenharmony_ci rtlpriv->intf_ops->disable_aspm(hw); 95062306a36Sopenharmony_ci 95162306a36Sopenharmony_ci /* 1. MAC Initialize */ 95262306a36Sopenharmony_ci /* Before FW download, we have to set some MAC register */ 95362306a36Sopenharmony_ci _rtl92se_macconfig_before_fwdownload(hw); 95462306a36Sopenharmony_ci 95562306a36Sopenharmony_ci rtlhal->version = (enum version_8192s)((rtl_read_dword(rtlpriv, 95662306a36Sopenharmony_ci PMC_FSM) >> 16) & 0xF); 95762306a36Sopenharmony_ci 95862306a36Sopenharmony_ci rtl8192se_gpiobit3_cfg_inputmode(hw); 95962306a36Sopenharmony_ci 96062306a36Sopenharmony_ci /* 2. download firmware */ 96162306a36Sopenharmony_ci rtstatus = rtl92s_download_fw(hw); 96262306a36Sopenharmony_ci if (!rtstatus) { 96362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 96462306a36Sopenharmony_ci "Failed to download FW. Init HW without FW now... Please copy FW into /lib/firmware/rtlwifi\n"); 96562306a36Sopenharmony_ci err = 1; 96662306a36Sopenharmony_ci goto exit; 96762306a36Sopenharmony_ci } 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci /* After FW download, we have to reset MAC register */ 97062306a36Sopenharmony_ci _rtl92se_macconfig_after_fwdownload(hw); 97162306a36Sopenharmony_ci 97262306a36Sopenharmony_ci /*Retrieve default FW Cmd IO map. */ 97362306a36Sopenharmony_ci rtlhal->fwcmd_iomap = rtl_read_word(rtlpriv, LBUS_MON_ADDR); 97462306a36Sopenharmony_ci rtlhal->fwcmd_ioparam = rtl_read_dword(rtlpriv, LBUS_ADDR_MASK); 97562306a36Sopenharmony_ci 97662306a36Sopenharmony_ci /* 3. Initialize MAC/PHY Config by MACPHY_reg.txt */ 97762306a36Sopenharmony_ci if (!rtl92s_phy_mac_config(hw)) { 97862306a36Sopenharmony_ci pr_err("MAC Config failed\n"); 97962306a36Sopenharmony_ci err = rtstatus; 98062306a36Sopenharmony_ci goto exit; 98162306a36Sopenharmony_ci } 98262306a36Sopenharmony_ci 98362306a36Sopenharmony_ci /* because last function modify RCR, so we update 98462306a36Sopenharmony_ci * rcr var here, or TP will unstable for receive_config 98562306a36Sopenharmony_ci * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx 98662306a36Sopenharmony_ci * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252 98762306a36Sopenharmony_ci */ 98862306a36Sopenharmony_ci rtlpci->receive_config = rtl_read_dword(rtlpriv, RCR); 98962306a36Sopenharmony_ci rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); 99062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, RCR, rtlpci->receive_config); 99162306a36Sopenharmony_ci 99262306a36Sopenharmony_ci /* Make sure BB/RF write OK. We should prevent enter IPS. radio off. */ 99362306a36Sopenharmony_ci /* We must set flag avoid BB/RF config period later!! */ 99462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, CMDR, 0x37FC); 99562306a36Sopenharmony_ci 99662306a36Sopenharmony_ci /* 4. Initialize BB After MAC Config PHY_reg.txt, AGC_Tab.txt */ 99762306a36Sopenharmony_ci if (!rtl92s_phy_bb_config(hw)) { 99862306a36Sopenharmony_ci pr_err("BB Config failed\n"); 99962306a36Sopenharmony_ci err = rtstatus; 100062306a36Sopenharmony_ci goto exit; 100162306a36Sopenharmony_ci } 100262306a36Sopenharmony_ci 100362306a36Sopenharmony_ci /* 5. Initiailze RF RAIO_A.txt RF RAIO_B.txt */ 100462306a36Sopenharmony_ci /* Before initalizing RF. We can not use FW to do RF-R/W. */ 100562306a36Sopenharmony_ci 100662306a36Sopenharmony_ci rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_ci /* Before RF-R/W we must execute the IO from Scott's suggestion. */ 100962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, 0xDB); 101062306a36Sopenharmony_ci if (rtlhal->version == VERSION_8192S_ACUT) 101162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SPS1_CTRL + 3, 0x07); 101262306a36Sopenharmony_ci else 101362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RF_CTRL, 0x07); 101462306a36Sopenharmony_ci 101562306a36Sopenharmony_ci if (!rtl92s_phy_rf_config(hw)) { 101662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "RF Config failed\n"); 101762306a36Sopenharmony_ci err = rtstatus; 101862306a36Sopenharmony_ci goto exit; 101962306a36Sopenharmony_ci } 102062306a36Sopenharmony_ci 102162306a36Sopenharmony_ci /* After read predefined TXT, we must set BB/MAC/RF 102262306a36Sopenharmony_ci * register as our requirement */ 102362306a36Sopenharmony_ci 102462306a36Sopenharmony_ci rtlphy->rfreg_chnlval[0] = rtl92s_phy_query_rf_reg(hw, 102562306a36Sopenharmony_ci (enum radio_path)0, 102662306a36Sopenharmony_ci RF_CHNLBW, 102762306a36Sopenharmony_ci RFREG_OFFSET_MASK); 102862306a36Sopenharmony_ci rtlphy->rfreg_chnlval[1] = rtl92s_phy_query_rf_reg(hw, 102962306a36Sopenharmony_ci (enum radio_path)1, 103062306a36Sopenharmony_ci RF_CHNLBW, 103162306a36Sopenharmony_ci RFREG_OFFSET_MASK); 103262306a36Sopenharmony_ci 103362306a36Sopenharmony_ci /*---- Set CCK and OFDM Block "ON"----*/ 103462306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); 103562306a36Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci /*3 Set Hardware(Do nothing now) */ 103862306a36Sopenharmony_ci _rtl92se_hw_configure(hw); 103962306a36Sopenharmony_ci 104062306a36Sopenharmony_ci /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */ 104162306a36Sopenharmony_ci /* TX power index for different rate set. */ 104262306a36Sopenharmony_ci /* Get original hw reg values */ 104362306a36Sopenharmony_ci rtl92s_phy_get_hw_reg_originalvalue(hw); 104462306a36Sopenharmony_ci /* Write correct tx power index */ 104562306a36Sopenharmony_ci rtl92s_phy_set_txpower(hw, rtlphy->current_channel); 104662306a36Sopenharmony_ci 104762306a36Sopenharmony_ci /* We must set MAC address after firmware download. */ 104862306a36Sopenharmony_ci for (i = 0; i < 6; i++) 104962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); 105062306a36Sopenharmony_ci 105162306a36Sopenharmony_ci /* EEPROM R/W workaround */ 105262306a36Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, MAC_PINMUX_CFG); 105362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, MAC_PINMUX_CFG, tmp_u1b & (~BIT(3))); 105462306a36Sopenharmony_ci 105562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x4d, 0x0); 105662306a36Sopenharmony_ci 105762306a36Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) >= 0x49) { 105862306a36Sopenharmony_ci tmp_byte = rtl_read_byte(rtlpriv, FW_RSVD_PG_CRTL) & (~BIT(4)); 105962306a36Sopenharmony_ci tmp_byte = tmp_byte | BIT(5); 106062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, FW_RSVD_PG_CRTL, tmp_byte); 106162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TXDESC_MSK, 0xFFFFCFFF); 106262306a36Sopenharmony_ci } 106362306a36Sopenharmony_ci 106462306a36Sopenharmony_ci /* We enable high power and RA related mechanism after NIC 106562306a36Sopenharmony_ci * initialized. */ 106662306a36Sopenharmony_ci if (hal_get_firmwareversion(rtlpriv) >= 0x35) { 106762306a36Sopenharmony_ci /* Fw v.53 and later. */ 106862306a36Sopenharmony_ci rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_INIT); 106962306a36Sopenharmony_ci } else if (hal_get_firmwareversion(rtlpriv) == 0x34) { 107062306a36Sopenharmony_ci /* Fw v.52. */ 107162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_INIT); 107262306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 107362306a36Sopenharmony_ci } else { 107462306a36Sopenharmony_ci /* Compatible earlier FW version. */ 107562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_RESET); 107662306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 107762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_ACTIVE); 107862306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 107962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, FW_RA_REFRESH); 108062306a36Sopenharmony_ci rtl92s_phy_chk_fwcmd_iodone(hw); 108162306a36Sopenharmony_ci } 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci /* Add to prevent ASPM bug. */ 108462306a36Sopenharmony_ci /* Always enable hst and NIC clock request. */ 108562306a36Sopenharmony_ci rtl92s_phy_switch_ephy_parameter(hw); 108662306a36Sopenharmony_ci 108762306a36Sopenharmony_ci /* Security related 108862306a36Sopenharmony_ci * 1. Clear all H/W keys. 108962306a36Sopenharmony_ci * 2. Enable H/W encryption/decryption. */ 109062306a36Sopenharmony_ci rtl_cam_reset_all_entry(hw); 109162306a36Sopenharmony_ci secr_value |= SCR_TXENCENABLE; 109262306a36Sopenharmony_ci secr_value |= SCR_RXENCENABLE; 109362306a36Sopenharmony_ci secr_value |= SCR_NOSKMC; 109462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SECR, secr_value); 109562306a36Sopenharmony_ci 109662306a36Sopenharmony_ci for (i = 0; i < 4; i++) 109762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, wdcapra_add[i], 0x5e4322); 109862306a36Sopenharmony_ci 109962306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) { 110062306a36Sopenharmony_ci bool mrc2set = true; 110162306a36Sopenharmony_ci /* Turn on B-Path */ 110262306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC, (u8 *)&mrc2set); 110362306a36Sopenharmony_ci } 110462306a36Sopenharmony_ci 110562306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_ON); 110662306a36Sopenharmony_ci rtl92s_dm_init(hw); 110762306a36Sopenharmony_ciexit: 110862306a36Sopenharmony_ci local_irq_restore(flags); 110962306a36Sopenharmony_ci rtlpci->being_init_adapter = false; 111062306a36Sopenharmony_ci return err; 111162306a36Sopenharmony_ci} 111262306a36Sopenharmony_ci 111362306a36Sopenharmony_civoid rtl92se_set_mac_addr(struct rtl_io *io, const u8 *addr) 111462306a36Sopenharmony_ci{ 111562306a36Sopenharmony_ci /* This is a stub. */ 111662306a36Sopenharmony_ci} 111762306a36Sopenharmony_ci 111862306a36Sopenharmony_civoid rtl92se_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 111962306a36Sopenharmony_ci{ 112062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 112162306a36Sopenharmony_ci u32 reg_rcr; 112262306a36Sopenharmony_ci 112362306a36Sopenharmony_ci if (rtlpriv->psc.rfpwr_state != ERFON) 112462306a36Sopenharmony_ci return; 112562306a36Sopenharmony_ci 112662306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); 112762306a36Sopenharmony_ci 112862306a36Sopenharmony_ci if (check_bssid) { 112962306a36Sopenharmony_ci reg_rcr |= (RCR_CBSSID); 113062306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); 113162306a36Sopenharmony_ci } else if (!check_bssid) { 113262306a36Sopenharmony_ci reg_rcr &= (~RCR_CBSSID); 113362306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); 113462306a36Sopenharmony_ci } 113562306a36Sopenharmony_ci 113662306a36Sopenharmony_ci} 113762306a36Sopenharmony_ci 113862306a36Sopenharmony_cistatic int _rtl92se_set_media_status(struct ieee80211_hw *hw, 113962306a36Sopenharmony_ci enum nl80211_iftype type) 114062306a36Sopenharmony_ci{ 114162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 114262306a36Sopenharmony_ci u8 bt_msr = rtl_read_byte(rtlpriv, MSR); 114362306a36Sopenharmony_ci u32 temp; 114462306a36Sopenharmony_ci bt_msr &= ~MSR_LINK_MASK; 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci switch (type) { 114762306a36Sopenharmony_ci case NL80211_IFTYPE_UNSPECIFIED: 114862306a36Sopenharmony_ci bt_msr |= (MSR_LINK_NONE << MSR_LINK_SHIFT); 114962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 115062306a36Sopenharmony_ci "Set Network type to NO LINK!\n"); 115162306a36Sopenharmony_ci break; 115262306a36Sopenharmony_ci case NL80211_IFTYPE_ADHOC: 115362306a36Sopenharmony_ci bt_msr |= (MSR_LINK_ADHOC << MSR_LINK_SHIFT); 115462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 115562306a36Sopenharmony_ci "Set Network type to Ad Hoc!\n"); 115662306a36Sopenharmony_ci break; 115762306a36Sopenharmony_ci case NL80211_IFTYPE_STATION: 115862306a36Sopenharmony_ci bt_msr |= (MSR_LINK_MANAGED << MSR_LINK_SHIFT); 115962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 116062306a36Sopenharmony_ci "Set Network type to STA!\n"); 116162306a36Sopenharmony_ci break; 116262306a36Sopenharmony_ci case NL80211_IFTYPE_AP: 116362306a36Sopenharmony_ci bt_msr |= (MSR_LINK_MASTER << MSR_LINK_SHIFT); 116462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 116562306a36Sopenharmony_ci "Set Network type to AP!\n"); 116662306a36Sopenharmony_ci break; 116762306a36Sopenharmony_ci default: 116862306a36Sopenharmony_ci pr_err("Network type %d not supported!\n", type); 116962306a36Sopenharmony_ci return 1; 117062306a36Sopenharmony_ci 117162306a36Sopenharmony_ci } 117262306a36Sopenharmony_ci 117362306a36Sopenharmony_ci if (type != NL80211_IFTYPE_AP && 117462306a36Sopenharmony_ci rtlpriv->mac80211.link_state < MAC80211_LINKED) 117562306a36Sopenharmony_ci bt_msr = rtl_read_byte(rtlpriv, MSR) & ~MSR_LINK_MASK; 117662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, MSR, bt_msr); 117762306a36Sopenharmony_ci 117862306a36Sopenharmony_ci temp = rtl_read_dword(rtlpriv, TCR); 117962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TCR, temp & (~BIT(8))); 118062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, TCR, temp | BIT(8)); 118162306a36Sopenharmony_ci 118262306a36Sopenharmony_ci 118362306a36Sopenharmony_ci return 0; 118462306a36Sopenharmony_ci} 118562306a36Sopenharmony_ci 118662306a36Sopenharmony_ci/* HW_VAR_MEDIA_STATUS & HW_VAR_CECHK_BSSID */ 118762306a36Sopenharmony_ciint rtl92se_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) 118862306a36Sopenharmony_ci{ 118962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 119062306a36Sopenharmony_ci 119162306a36Sopenharmony_ci if (_rtl92se_set_media_status(hw, type)) 119262306a36Sopenharmony_ci return -EOPNOTSUPP; 119362306a36Sopenharmony_ci 119462306a36Sopenharmony_ci if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { 119562306a36Sopenharmony_ci if (type != NL80211_IFTYPE_AP) 119662306a36Sopenharmony_ci rtl92se_set_check_bssid(hw, true); 119762306a36Sopenharmony_ci } else { 119862306a36Sopenharmony_ci rtl92se_set_check_bssid(hw, false); 119962306a36Sopenharmony_ci } 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_ci return 0; 120262306a36Sopenharmony_ci} 120362306a36Sopenharmony_ci 120462306a36Sopenharmony_ci/* don't set REG_EDCA_BE_PARAM here because mac80211 will send pkt when scan */ 120562306a36Sopenharmony_civoid rtl92se_set_qos(struct ieee80211_hw *hw, int aci) 120662306a36Sopenharmony_ci{ 120762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 120862306a36Sopenharmony_ci rtl92s_dm_init_edca_turbo(hw); 120962306a36Sopenharmony_ci 121062306a36Sopenharmony_ci switch (aci) { 121162306a36Sopenharmony_ci case AC1_BK: 121262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, EDCAPARA_BK, 0xa44f); 121362306a36Sopenharmony_ci break; 121462306a36Sopenharmony_ci case AC0_BE: 121562306a36Sopenharmony_ci /* rtl_write_dword(rtlpriv, EDCAPARA_BE, u4b_ac_param); */ 121662306a36Sopenharmony_ci break; 121762306a36Sopenharmony_ci case AC2_VI: 121862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, EDCAPARA_VI, 0x5e4322); 121962306a36Sopenharmony_ci break; 122062306a36Sopenharmony_ci case AC3_VO: 122162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, EDCAPARA_VO, 0x2f3222); 122262306a36Sopenharmony_ci break; 122362306a36Sopenharmony_ci default: 122462306a36Sopenharmony_ci WARN_ONCE(true, "rtl8192se: invalid aci: %d !\n", aci); 122562306a36Sopenharmony_ci break; 122662306a36Sopenharmony_ci } 122762306a36Sopenharmony_ci} 122862306a36Sopenharmony_ci 122962306a36Sopenharmony_civoid rtl92se_enable_interrupt(struct ieee80211_hw *hw) 123062306a36Sopenharmony_ci{ 123162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 123262306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 123362306a36Sopenharmony_ci 123462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, INTA_MASK, rtlpci->irq_mask[0]); 123562306a36Sopenharmony_ci /* Support Bit 32-37(Assign as Bit 0-5) interrupt setting now */ 123662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, INTA_MASK + 4, rtlpci->irq_mask[1] & 0x3F); 123762306a36Sopenharmony_ci rtlpci->irq_enabled = true; 123862306a36Sopenharmony_ci} 123962306a36Sopenharmony_ci 124062306a36Sopenharmony_civoid rtl92se_disable_interrupt(struct ieee80211_hw *hw) 124162306a36Sopenharmony_ci{ 124262306a36Sopenharmony_ci struct rtl_priv *rtlpriv; 124362306a36Sopenharmony_ci struct rtl_pci *rtlpci; 124462306a36Sopenharmony_ci 124562306a36Sopenharmony_ci rtlpriv = rtl_priv(hw); 124662306a36Sopenharmony_ci /* if firmware not available, no interrupts */ 124762306a36Sopenharmony_ci if (!rtlpriv || !rtlpriv->max_fw_size) 124862306a36Sopenharmony_ci return; 124962306a36Sopenharmony_ci rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 125062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, INTA_MASK, 0); 125162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, INTA_MASK + 4, 0); 125262306a36Sopenharmony_ci rtlpci->irq_enabled = false; 125362306a36Sopenharmony_ci} 125462306a36Sopenharmony_ci 125562306a36Sopenharmony_cistatic u8 _rtl92s_set_sysclk(struct ieee80211_hw *hw, u8 data) 125662306a36Sopenharmony_ci{ 125762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 125862306a36Sopenharmony_ci u8 waitcnt = 100; 125962306a36Sopenharmony_ci bool result = false; 126062306a36Sopenharmony_ci u8 tmp; 126162306a36Sopenharmony_ci 126262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SYS_CLKR + 1, data); 126362306a36Sopenharmony_ci 126462306a36Sopenharmony_ci /* Wait the MAC synchronized. */ 126562306a36Sopenharmony_ci udelay(400); 126662306a36Sopenharmony_ci 126762306a36Sopenharmony_ci /* Check if it is set ready. */ 126862306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1); 126962306a36Sopenharmony_ci result = ((tmp & BIT(7)) == (data & BIT(7))); 127062306a36Sopenharmony_ci 127162306a36Sopenharmony_ci if (!(data & (BIT(6) | BIT(7)))) { 127262306a36Sopenharmony_ci waitcnt = 100; 127362306a36Sopenharmony_ci tmp = 0; 127462306a36Sopenharmony_ci 127562306a36Sopenharmony_ci while (1) { 127662306a36Sopenharmony_ci waitcnt--; 127762306a36Sopenharmony_ci tmp = rtl_read_byte(rtlpriv, SYS_CLKR + 1); 127862306a36Sopenharmony_ci 127962306a36Sopenharmony_ci if ((tmp & BIT(6))) 128062306a36Sopenharmony_ci break; 128162306a36Sopenharmony_ci 128262306a36Sopenharmony_ci pr_err("wait for BIT(6) return value %x\n", tmp); 128362306a36Sopenharmony_ci 128462306a36Sopenharmony_ci if (waitcnt == 0) 128562306a36Sopenharmony_ci break; 128662306a36Sopenharmony_ci udelay(10); 128762306a36Sopenharmony_ci } 128862306a36Sopenharmony_ci 128962306a36Sopenharmony_ci if (waitcnt == 0) 129062306a36Sopenharmony_ci result = false; 129162306a36Sopenharmony_ci else 129262306a36Sopenharmony_ci result = true; 129362306a36Sopenharmony_ci } 129462306a36Sopenharmony_ci 129562306a36Sopenharmony_ci return result; 129662306a36Sopenharmony_ci} 129762306a36Sopenharmony_ci 129862306a36Sopenharmony_cistatic void _rtl92s_phy_set_rfhalt(struct ieee80211_hw *hw) 129962306a36Sopenharmony_ci{ 130062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 130162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 130262306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 130362306a36Sopenharmony_ci u8 u1btmp; 130462306a36Sopenharmony_ci 130562306a36Sopenharmony_ci if (rtlhal->driver_is_goingto_unload) 130662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x560, 0x0); 130762306a36Sopenharmony_ci 130862306a36Sopenharmony_ci /* Power save for BB/RF */ 130962306a36Sopenharmony_ci u1btmp = rtl_read_byte(rtlpriv, LDOV12D_CTRL); 131062306a36Sopenharmony_ci u1btmp |= BIT(0); 131162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, LDOV12D_CTRL, u1btmp); 131262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SPS1_CTRL, 0x0); 131362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, TXPAUSE, 0xFF); 131462306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x57FC); 131562306a36Sopenharmony_ci udelay(100); 131662306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x77FC); 131762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, PHY_CCA, 0x0); 131862306a36Sopenharmony_ci udelay(10); 131962306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x37FC); 132062306a36Sopenharmony_ci udelay(10); 132162306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x77FC); 132262306a36Sopenharmony_ci udelay(10); 132362306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x57FC); 132462306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x0000); 132562306a36Sopenharmony_ci 132662306a36Sopenharmony_ci if (rtlhal->driver_is_goingto_unload) { 132762306a36Sopenharmony_ci u1btmp = rtl_read_byte(rtlpriv, (REG_SYS_FUNC_EN + 1)); 132862306a36Sopenharmony_ci u1btmp &= ~(BIT(0)); 132962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, u1btmp); 133062306a36Sopenharmony_ci } 133162306a36Sopenharmony_ci 133262306a36Sopenharmony_ci u1btmp = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); 133362306a36Sopenharmony_ci 133462306a36Sopenharmony_ci /* Add description. After switch control path. register 133562306a36Sopenharmony_ci * after page1 will be invisible. We can not do any IO 133662306a36Sopenharmony_ci * for register>0x40. After resume&MACIO reset, we need 133762306a36Sopenharmony_ci * to remember previous reg content. */ 133862306a36Sopenharmony_ci if (u1btmp & BIT(7)) { 133962306a36Sopenharmony_ci u1btmp &= ~(BIT(6) | BIT(7)); 134062306a36Sopenharmony_ci if (!_rtl92s_set_sysclk(hw, u1btmp)) { 134162306a36Sopenharmony_ci pr_err("Switch ctrl path fail\n"); 134262306a36Sopenharmony_ci return; 134362306a36Sopenharmony_ci } 134462306a36Sopenharmony_ci } 134562306a36Sopenharmony_ci 134662306a36Sopenharmony_ci /* Power save for MAC */ 134762306a36Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS && 134862306a36Sopenharmony_ci !rtlhal->driver_is_goingto_unload) { 134962306a36Sopenharmony_ci /* enable LED function */ 135062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x03, 0xF9); 135162306a36Sopenharmony_ci /* SW/HW radio off or halt adapter!! For example S3/S4 */ 135262306a36Sopenharmony_ci } else { 135362306a36Sopenharmony_ci /* LED function disable. Power range is about 8mA now. */ 135462306a36Sopenharmony_ci /* if write 0xF1 disconnect_pci power 135562306a36Sopenharmony_ci * ifconfig wlan0 down power are both high 35:70 */ 135662306a36Sopenharmony_ci /* if write oxF9 disconnect_pci power 135762306a36Sopenharmony_ci * ifconfig wlan0 down power are both low 12:45*/ 135862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x03, 0xF9); 135962306a36Sopenharmony_ci } 136062306a36Sopenharmony_ci 136162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SYS_CLKR + 1, 0x70); 136262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, 0x68); 136362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x00); 136462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); 136562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, 0x0E); 136662306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 136762306a36Sopenharmony_ci 136862306a36Sopenharmony_ci} 136962306a36Sopenharmony_ci 137062306a36Sopenharmony_cistatic void _rtl92se_gen_refreshledstate(struct ieee80211_hw *hw) 137162306a36Sopenharmony_ci{ 137262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 137362306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 137462306a36Sopenharmony_ci enum rtl_led_pin pin0 = rtlpriv->ledctl.sw_led0; 137562306a36Sopenharmony_ci 137662306a36Sopenharmony_ci if (rtlpci->up_first_time) 137762306a36Sopenharmony_ci return; 137862306a36Sopenharmony_ci 137962306a36Sopenharmony_ci if (rtlpriv->psc.rfoff_reason == RF_CHANGE_BY_IPS) 138062306a36Sopenharmony_ci rtl92se_sw_led_on(hw, pin0); 138162306a36Sopenharmony_ci else 138262306a36Sopenharmony_ci rtl92se_sw_led_off(hw, pin0); 138362306a36Sopenharmony_ci} 138462306a36Sopenharmony_ci 138562306a36Sopenharmony_ci 138662306a36Sopenharmony_cistatic void _rtl92se_power_domain_init(struct ieee80211_hw *hw) 138762306a36Sopenharmony_ci{ 138862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 138962306a36Sopenharmony_ci u16 tmpu2b; 139062306a36Sopenharmony_ci u8 tmpu1b; 139162306a36Sopenharmony_ci 139262306a36Sopenharmony_ci rtlpriv->psc.pwrdomain_protect = true; 139362306a36Sopenharmony_ci 139462306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); 139562306a36Sopenharmony_ci if (tmpu1b & BIT(7)) { 139662306a36Sopenharmony_ci tmpu1b &= ~(BIT(6) | BIT(7)); 139762306a36Sopenharmony_ci if (!_rtl92s_set_sysclk(hw, tmpu1b)) { 139862306a36Sopenharmony_ci rtlpriv->psc.pwrdomain_protect = false; 139962306a36Sopenharmony_ci return; 140062306a36Sopenharmony_ci } 140162306a36Sopenharmony_ci } 140262306a36Sopenharmony_ci 140362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL, 0x0); 140462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, LDOA15_CTRL, 0x34); 140562306a36Sopenharmony_ci 140662306a36Sopenharmony_ci /* Reset MAC-IO and CPU and Core Digital BIT10/11/15 */ 140762306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN + 1); 140862306a36Sopenharmony_ci 140962306a36Sopenharmony_ci /* If IPS we need to turn LED on. So we not 141062306a36Sopenharmony_ci * disable BIT 3/7 of reg3. */ 141162306a36Sopenharmony_ci if (rtlpriv->psc.rfoff_reason & (RF_CHANGE_BY_IPS | RF_CHANGE_BY_HW)) 141262306a36Sopenharmony_ci tmpu1b &= 0xFB; 141362306a36Sopenharmony_ci else 141462306a36Sopenharmony_ci tmpu1b &= 0x73; 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, tmpu1b); 141762306a36Sopenharmony_ci /* wait for BIT 10/11/15 to pull high automatically!! */ 141862306a36Sopenharmony_ci mdelay(1); 141962306a36Sopenharmony_ci 142062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, CMDR, 0); 142162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, TCR, 0); 142262306a36Sopenharmony_ci 142362306a36Sopenharmony_ci /* Data sheet not define 0x562!!! Copy from WMAC!!!!! */ 142462306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, 0x562); 142562306a36Sopenharmony_ci tmpu1b |= 0x08; 142662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x562, tmpu1b); 142762306a36Sopenharmony_ci tmpu1b &= ~(BIT(3)); 142862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x562, tmpu1b); 142962306a36Sopenharmony_ci 143062306a36Sopenharmony_ci /* Enable AFE clock source */ 143162306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL); 143262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_XTAL_CTRL, (tmpu1b | 0x01)); 143362306a36Sopenharmony_ci /* Delay 1.5ms */ 143462306a36Sopenharmony_ci udelay(1500); 143562306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_XTAL_CTRL + 1); 143662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_XTAL_CTRL + 1, (tmpu1b & 0xfb)); 143762306a36Sopenharmony_ci 143862306a36Sopenharmony_ci /* Enable AFE Macro Block's Bandgap */ 143962306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); 144062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | BIT(0))); 144162306a36Sopenharmony_ci mdelay(1); 144262306a36Sopenharmony_ci 144362306a36Sopenharmony_ci /* Enable AFE Mbias */ 144462306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_MISC); 144562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_MISC, (tmpu1b | 0x02)); 144662306a36Sopenharmony_ci mdelay(1); 144762306a36Sopenharmony_ci 144862306a36Sopenharmony_ci /* Enable LDOA15 block */ 144962306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, LDOA15_CTRL); 145062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, LDOA15_CTRL, (tmpu1b | BIT(0))); 145162306a36Sopenharmony_ci 145262306a36Sopenharmony_ci /* Set Digital Vdd to Retention isolation Path. */ 145362306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); 145462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, (tmpu2b | BIT(11))); 145562306a36Sopenharmony_ci 145662306a36Sopenharmony_ci 145762306a36Sopenharmony_ci /* For warm reboot NIC disappera bug. */ 145862306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 145962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(13))); 146062306a36Sopenharmony_ci 146162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x68); 146262306a36Sopenharmony_ci 146362306a36Sopenharmony_ci /* Enable AFE PLL Macro Block */ 146462306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL); 146562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL, (tmpu1b | BIT(0) | BIT(4))); 146662306a36Sopenharmony_ci /* Enable MAC 80MHZ clock */ 146762306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, AFE_PLL_CTRL + 1); 146862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, AFE_PLL_CTRL + 1, (tmpu1b | BIT(0))); 146962306a36Sopenharmony_ci mdelay(1); 147062306a36Sopenharmony_ci 147162306a36Sopenharmony_ci /* Release isolation AFE PLL & MD */ 147262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xA6); 147362306a36Sopenharmony_ci 147462306a36Sopenharmony_ci /* Enable MAC clock */ 147562306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); 147662306a36Sopenharmony_ci rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b | BIT(12) | BIT(11))); 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_ci /* Enable Core digital and enable IOREG R/W */ 147962306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 148062306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11))); 148162306a36Sopenharmony_ci /* enable REG_EN */ 148262306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (tmpu2b | BIT(11) | BIT(15))); 148362306a36Sopenharmony_ci 148462306a36Sopenharmony_ci /* Switch the control path. */ 148562306a36Sopenharmony_ci tmpu2b = rtl_read_word(rtlpriv, SYS_CLKR); 148662306a36Sopenharmony_ci rtl_write_word(rtlpriv, SYS_CLKR, (tmpu2b & (~BIT(2)))); 148762306a36Sopenharmony_ci 148862306a36Sopenharmony_ci tmpu1b = rtl_read_byte(rtlpriv, (SYS_CLKR + 1)); 148962306a36Sopenharmony_ci tmpu1b = ((tmpu1b | BIT(7)) & (~BIT(6))); 149062306a36Sopenharmony_ci if (!_rtl92s_set_sysclk(hw, tmpu1b)) { 149162306a36Sopenharmony_ci rtlpriv->psc.pwrdomain_protect = false; 149262306a36Sopenharmony_ci return; 149362306a36Sopenharmony_ci } 149462306a36Sopenharmony_ci 149562306a36Sopenharmony_ci rtl_write_word(rtlpriv, CMDR, 0x37FC); 149662306a36Sopenharmony_ci 149762306a36Sopenharmony_ci /* After MACIO reset,we must refresh LED state. */ 149862306a36Sopenharmony_ci _rtl92se_gen_refreshledstate(hw); 149962306a36Sopenharmony_ci 150062306a36Sopenharmony_ci rtlpriv->psc.pwrdomain_protect = false; 150162306a36Sopenharmony_ci} 150262306a36Sopenharmony_ci 150362306a36Sopenharmony_civoid rtl92se_card_disable(struct ieee80211_hw *hw) 150462306a36Sopenharmony_ci{ 150562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 150662306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 150762306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 150862306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 150962306a36Sopenharmony_ci enum nl80211_iftype opmode; 151062306a36Sopenharmony_ci u8 wait = 30; 151162306a36Sopenharmony_ci 151262306a36Sopenharmony_ci rtlpriv->intf_ops->enable_aspm(hw); 151362306a36Sopenharmony_ci 151462306a36Sopenharmony_ci if (rtlpci->driver_is_goingto_unload || 151562306a36Sopenharmony_ci ppsc->rfoff_reason > RF_CHANGE_BY_PS) 151662306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); 151762306a36Sopenharmony_ci 151862306a36Sopenharmony_ci /* we should chnge GPIO to input mode 151962306a36Sopenharmony_ci * this will drop away current about 25mA*/ 152062306a36Sopenharmony_ci rtl8192se_gpiobit3_cfg_inputmode(hw); 152162306a36Sopenharmony_ci 152262306a36Sopenharmony_ci /* this is very important for ips power save */ 152362306a36Sopenharmony_ci while (wait-- >= 10 && rtlpriv->psc.pwrdomain_protect) { 152462306a36Sopenharmony_ci if (rtlpriv->psc.pwrdomain_protect) 152562306a36Sopenharmony_ci mdelay(20); 152662306a36Sopenharmony_ci else 152762306a36Sopenharmony_ci break; 152862306a36Sopenharmony_ci } 152962306a36Sopenharmony_ci 153062306a36Sopenharmony_ci mac->link_state = MAC80211_NOLINK; 153162306a36Sopenharmony_ci opmode = NL80211_IFTYPE_UNSPECIFIED; 153262306a36Sopenharmony_ci _rtl92se_set_media_status(hw, opmode); 153362306a36Sopenharmony_ci 153462306a36Sopenharmony_ci _rtl92s_phy_set_rfhalt(hw); 153562306a36Sopenharmony_ci udelay(100); 153662306a36Sopenharmony_ci} 153762306a36Sopenharmony_ci 153862306a36Sopenharmony_civoid rtl92se_interrupt_recognized(struct ieee80211_hw *hw, 153962306a36Sopenharmony_ci struct rtl_int *intvec) 154062306a36Sopenharmony_ci{ 154162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 154262306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 154362306a36Sopenharmony_ci 154462306a36Sopenharmony_ci intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; 154562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, ISR, intvec->inta); 154662306a36Sopenharmony_ci 154762306a36Sopenharmony_ci intvec->intb = rtl_read_dword(rtlpriv, ISR + 4) & rtlpci->irq_mask[1]; 154862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, ISR + 4, intvec->intb); 154962306a36Sopenharmony_ci} 155062306a36Sopenharmony_ci 155162306a36Sopenharmony_civoid rtl92se_set_beacon_related_registers(struct ieee80211_hw *hw) 155262306a36Sopenharmony_ci{ 155362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 155462306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 155562306a36Sopenharmony_ci u16 atim_window = 2; 155662306a36Sopenharmony_ci 155762306a36Sopenharmony_ci /* ATIM Window (in unit of TU). */ 155862306a36Sopenharmony_ci rtl_write_word(rtlpriv, ATIMWND, atim_window); 155962306a36Sopenharmony_ci 156062306a36Sopenharmony_ci /* Beacon interval (in unit of TU). */ 156162306a36Sopenharmony_ci rtl_write_word(rtlpriv, BCN_INTERVAL, mac->beacon_interval); 156262306a36Sopenharmony_ci 156362306a36Sopenharmony_ci /* DrvErlyInt (in unit of TU). (Time to send 156462306a36Sopenharmony_ci * interrupt to notify driver to change 156562306a36Sopenharmony_ci * beacon content) */ 156662306a36Sopenharmony_ci rtl_write_word(rtlpriv, BCN_DRV_EARLY_INT, 10 << 4); 156762306a36Sopenharmony_ci 156862306a36Sopenharmony_ci /* BcnDMATIM(in unit of us). Indicates the 156962306a36Sopenharmony_ci * time before TBTT to perform beacon queue DMA */ 157062306a36Sopenharmony_ci rtl_write_word(rtlpriv, BCN_DMATIME, 256); 157162306a36Sopenharmony_ci 157262306a36Sopenharmony_ci /* Force beacon frame transmission even 157362306a36Sopenharmony_ci * after receiving beacon frame from 157462306a36Sopenharmony_ci * other ad hoc STA */ 157562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, BCN_ERR_THRESH, 100); 157662306a36Sopenharmony_ci 157762306a36Sopenharmony_ci /*for beacon changed */ 157862306a36Sopenharmony_ci rtl92s_phy_set_beacon_hwreg(hw, mac->beacon_interval); 157962306a36Sopenharmony_ci} 158062306a36Sopenharmony_ci 158162306a36Sopenharmony_civoid rtl92se_set_beacon_interval(struct ieee80211_hw *hw) 158262306a36Sopenharmony_ci{ 158362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 158462306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 158562306a36Sopenharmony_ci u16 bcn_interval = mac->beacon_interval; 158662306a36Sopenharmony_ci 158762306a36Sopenharmony_ci /* Beacon interval (in unit of TU). */ 158862306a36Sopenharmony_ci rtl_write_word(rtlpriv, BCN_INTERVAL, bcn_interval); 158962306a36Sopenharmony_ci /* 2008.10.24 added by tynli for beacon changed. */ 159062306a36Sopenharmony_ci rtl92s_phy_set_beacon_hwreg(hw, bcn_interval); 159162306a36Sopenharmony_ci} 159262306a36Sopenharmony_ci 159362306a36Sopenharmony_civoid rtl92se_update_interrupt_mask(struct ieee80211_hw *hw, 159462306a36Sopenharmony_ci u32 add_msr, u32 rm_msr) 159562306a36Sopenharmony_ci{ 159662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 159762306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 159862306a36Sopenharmony_ci 159962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", 160062306a36Sopenharmony_ci add_msr, rm_msr); 160162306a36Sopenharmony_ci 160262306a36Sopenharmony_ci if (add_msr) 160362306a36Sopenharmony_ci rtlpci->irq_mask[0] |= add_msr; 160462306a36Sopenharmony_ci 160562306a36Sopenharmony_ci if (rm_msr) 160662306a36Sopenharmony_ci rtlpci->irq_mask[0] &= (~rm_msr); 160762306a36Sopenharmony_ci 160862306a36Sopenharmony_ci rtl92se_disable_interrupt(hw); 160962306a36Sopenharmony_ci rtl92se_enable_interrupt(hw); 161062306a36Sopenharmony_ci} 161162306a36Sopenharmony_ci 161262306a36Sopenharmony_cistatic void _rtl8192se_get_ic_inferiority(struct ieee80211_hw *hw) 161362306a36Sopenharmony_ci{ 161462306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 161562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 161662306a36Sopenharmony_ci u8 efuse_id; 161762306a36Sopenharmony_ci 161862306a36Sopenharmony_ci rtlhal->ic_class = IC_INFERIORITY_A; 161962306a36Sopenharmony_ci 162062306a36Sopenharmony_ci /* Only retrieving while using EFUSE. */ 162162306a36Sopenharmony_ci if ((rtlefuse->epromtype == EEPROM_BOOT_EFUSE) && 162262306a36Sopenharmony_ci !rtlefuse->autoload_failflag) { 162362306a36Sopenharmony_ci efuse_id = efuse_read_1byte(hw, EFUSE_IC_ID_OFFSET); 162462306a36Sopenharmony_ci 162562306a36Sopenharmony_ci if (efuse_id == 0xfe) 162662306a36Sopenharmony_ci rtlhal->ic_class = IC_INFERIORITY_B; 162762306a36Sopenharmony_ci } 162862306a36Sopenharmony_ci} 162962306a36Sopenharmony_ci 163062306a36Sopenharmony_cistatic void _rtl92se_read_adapter_info(struct ieee80211_hw *hw) 163162306a36Sopenharmony_ci{ 163262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 163362306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 163462306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 163562306a36Sopenharmony_ci struct device *dev = &rtl_pcipriv(hw)->dev.pdev->dev; 163662306a36Sopenharmony_ci u16 i, usvalue; 163762306a36Sopenharmony_ci u16 eeprom_id; 163862306a36Sopenharmony_ci u8 tempval; 163962306a36Sopenharmony_ci u8 hwinfo[HWSET_MAX_SIZE_92S]; 164062306a36Sopenharmony_ci u8 rf_path, index; 164162306a36Sopenharmony_ci 164262306a36Sopenharmony_ci switch (rtlefuse->epromtype) { 164362306a36Sopenharmony_ci case EEPROM_BOOT_EFUSE: 164462306a36Sopenharmony_ci rtl_efuse_shadow_map_update(hw); 164562306a36Sopenharmony_ci break; 164662306a36Sopenharmony_ci 164762306a36Sopenharmony_ci case EEPROM_93C46: 164862306a36Sopenharmony_ci pr_err("RTL819X Not boot from eeprom, check it !!\n"); 164962306a36Sopenharmony_ci return; 165062306a36Sopenharmony_ci 165162306a36Sopenharmony_ci default: 165262306a36Sopenharmony_ci dev_warn(dev, "no efuse data\n"); 165362306a36Sopenharmony_ci return; 165462306a36Sopenharmony_ci } 165562306a36Sopenharmony_ci 165662306a36Sopenharmony_ci memcpy(hwinfo, &rtlefuse->efuse_map[EFUSE_INIT_MAP][0], 165762306a36Sopenharmony_ci HWSET_MAX_SIZE_92S); 165862306a36Sopenharmony_ci 165962306a36Sopenharmony_ci RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, "MAP", 166062306a36Sopenharmony_ci hwinfo, HWSET_MAX_SIZE_92S); 166162306a36Sopenharmony_ci 166262306a36Sopenharmony_ci eeprom_id = *((u16 *)&hwinfo[0]); 166362306a36Sopenharmony_ci if (eeprom_id != RTL8190_EEPROM_ID) { 166462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 166562306a36Sopenharmony_ci "EEPROM ID(%#x) is invalid!!\n", eeprom_id); 166662306a36Sopenharmony_ci rtlefuse->autoload_failflag = true; 166762306a36Sopenharmony_ci } else { 166862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); 166962306a36Sopenharmony_ci rtlefuse->autoload_failflag = false; 167062306a36Sopenharmony_ci } 167162306a36Sopenharmony_ci 167262306a36Sopenharmony_ci if (rtlefuse->autoload_failflag) 167362306a36Sopenharmony_ci return; 167462306a36Sopenharmony_ci 167562306a36Sopenharmony_ci _rtl8192se_get_ic_inferiority(hw); 167662306a36Sopenharmony_ci 167762306a36Sopenharmony_ci /* Read IC Version && Channel Plan */ 167862306a36Sopenharmony_ci /* VID, DID SE 0xA-D */ 167962306a36Sopenharmony_ci rtlefuse->eeprom_vid = *(u16 *)&hwinfo[EEPROM_VID]; 168062306a36Sopenharmony_ci rtlefuse->eeprom_did = *(u16 *)&hwinfo[EEPROM_DID]; 168162306a36Sopenharmony_ci rtlefuse->eeprom_svid = *(u16 *)&hwinfo[EEPROM_SVID]; 168262306a36Sopenharmony_ci rtlefuse->eeprom_smid = *(u16 *)&hwinfo[EEPROM_SMID]; 168362306a36Sopenharmony_ci rtlefuse->eeprom_version = *(u16 *)&hwinfo[EEPROM_VERSION]; 168462306a36Sopenharmony_ci 168562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 168662306a36Sopenharmony_ci "EEPROMId = 0x%4x\n", eeprom_id); 168762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 168862306a36Sopenharmony_ci "EEPROM VID = 0x%4x\n", rtlefuse->eeprom_vid); 168962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 169062306a36Sopenharmony_ci "EEPROM DID = 0x%4x\n", rtlefuse->eeprom_did); 169162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 169262306a36Sopenharmony_ci "EEPROM SVID = 0x%4x\n", rtlefuse->eeprom_svid); 169362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 169462306a36Sopenharmony_ci "EEPROM SMID = 0x%4x\n", rtlefuse->eeprom_smid); 169562306a36Sopenharmony_ci 169662306a36Sopenharmony_ci for (i = 0; i < 6; i += 2) { 169762306a36Sopenharmony_ci usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR + i]; 169862306a36Sopenharmony_ci *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; 169962306a36Sopenharmony_ci } 170062306a36Sopenharmony_ci 170162306a36Sopenharmony_ci for (i = 0; i < 6; i++) 170262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, MACIDR0 + i, rtlefuse->dev_addr[i]); 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); 170562306a36Sopenharmony_ci 170662306a36Sopenharmony_ci /* Get Tx Power Level by Channel */ 170762306a36Sopenharmony_ci /* Read Tx power of Channel 1 ~ 14 from EEPROM. */ 170862306a36Sopenharmony_ci /* 92S suupport RF A & B */ 170962306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 171062306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 171162306a36Sopenharmony_ci /* Read CCK RF A & B Tx power */ 171262306a36Sopenharmony_ci rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][i] = 171362306a36Sopenharmony_ci hwinfo[EEPROM_TXPOWERBASE + rf_path * 3 + i]; 171462306a36Sopenharmony_ci 171562306a36Sopenharmony_ci /* Read OFDM RF A & B Tx power for 1T */ 171662306a36Sopenharmony_ci rtlefuse->eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = 171762306a36Sopenharmony_ci hwinfo[EEPROM_TXPOWERBASE + 6 + rf_path * 3 + i]; 171862306a36Sopenharmony_ci 171962306a36Sopenharmony_ci /* Read OFDM RF A & B Tx power for 2T */ 172062306a36Sopenharmony_ci rtlefuse->eprom_chnl_txpwr_ht40_2sdf[rf_path][i] 172162306a36Sopenharmony_ci = hwinfo[EEPROM_TXPOWERBASE + 12 + 172262306a36Sopenharmony_ci rf_path * 3 + i]; 172362306a36Sopenharmony_ci } 172462306a36Sopenharmony_ci } 172562306a36Sopenharmony_ci 172662306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) 172762306a36Sopenharmony_ci for (i = 0; i < 3; i++) 172862306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_EEPROM, 172962306a36Sopenharmony_ci "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", 173062306a36Sopenharmony_ci rf_path, i, 173162306a36Sopenharmony_ci rtlefuse->eeprom_chnlarea_txpwr_cck 173262306a36Sopenharmony_ci [rf_path][i]); 173362306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) 173462306a36Sopenharmony_ci for (i = 0; i < 3; i++) 173562306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_EEPROM, 173662306a36Sopenharmony_ci "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", 173762306a36Sopenharmony_ci rf_path, i, 173862306a36Sopenharmony_ci rtlefuse->eeprom_chnlarea_txpwr_ht40_1s 173962306a36Sopenharmony_ci [rf_path][i]); 174062306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) 174162306a36Sopenharmony_ci for (i = 0; i < 3; i++) 174262306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_EEPROM, 174362306a36Sopenharmony_ci "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", 174462306a36Sopenharmony_ci rf_path, i, 174562306a36Sopenharmony_ci rtlefuse->eprom_chnl_txpwr_ht40_2sdf 174662306a36Sopenharmony_ci [rf_path][i]); 174762306a36Sopenharmony_ci 174862306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 174962306a36Sopenharmony_ci 175062306a36Sopenharmony_ci /* Assign dedicated channel tx power */ 175162306a36Sopenharmony_ci for (i = 0; i < 14; i++) { 175262306a36Sopenharmony_ci /* channel 1~3 use the same Tx Power Level. */ 175362306a36Sopenharmony_ci if (i < 3) 175462306a36Sopenharmony_ci index = 0; 175562306a36Sopenharmony_ci /* Channel 4-8 */ 175662306a36Sopenharmony_ci else if (i < 8) 175762306a36Sopenharmony_ci index = 1; 175862306a36Sopenharmony_ci /* Channel 9-14 */ 175962306a36Sopenharmony_ci else 176062306a36Sopenharmony_ci index = 2; 176162306a36Sopenharmony_ci 176262306a36Sopenharmony_ci /* Record A & B CCK /OFDM - 1T/2T Channel area 176362306a36Sopenharmony_ci * tx power */ 176462306a36Sopenharmony_ci rtlefuse->txpwrlevel_cck[rf_path][i] = 176562306a36Sopenharmony_ci rtlefuse->eeprom_chnlarea_txpwr_cck 176662306a36Sopenharmony_ci [rf_path][index]; 176762306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = 176862306a36Sopenharmony_ci rtlefuse->eeprom_chnlarea_txpwr_ht40_1s 176962306a36Sopenharmony_ci [rf_path][index]; 177062306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 177162306a36Sopenharmony_ci rtlefuse->eprom_chnl_txpwr_ht40_2sdf 177262306a36Sopenharmony_ci [rf_path][index]; 177362306a36Sopenharmony_ci } 177462306a36Sopenharmony_ci 177562306a36Sopenharmony_ci for (i = 0; i < 14; i++) { 177662306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 177762306a36Sopenharmony_ci "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", 177862306a36Sopenharmony_ci rf_path, i, 177962306a36Sopenharmony_ci rtlefuse->txpwrlevel_cck[rf_path][i], 178062306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[rf_path][i], 178162306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); 178262306a36Sopenharmony_ci } 178362306a36Sopenharmony_ci } 178462306a36Sopenharmony_ci 178562306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 178662306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 178762306a36Sopenharmony_ci /* Read Power diff limit. */ 178862306a36Sopenharmony_ci rtlefuse->eeprom_pwrgroup[rf_path][i] = 178962306a36Sopenharmony_ci hwinfo[EEPROM_TXPWRGROUP + rf_path * 3 + i]; 179062306a36Sopenharmony_ci } 179162306a36Sopenharmony_ci } 179262306a36Sopenharmony_ci 179362306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 179462306a36Sopenharmony_ci /* Fill Pwr group */ 179562306a36Sopenharmony_ci for (i = 0; i < 14; i++) { 179662306a36Sopenharmony_ci /* Chanel 1-3 */ 179762306a36Sopenharmony_ci if (i < 3) 179862306a36Sopenharmony_ci index = 0; 179962306a36Sopenharmony_ci /* Channel 4-8 */ 180062306a36Sopenharmony_ci else if (i < 8) 180162306a36Sopenharmony_ci index = 1; 180262306a36Sopenharmony_ci /* Channel 9-13 */ 180362306a36Sopenharmony_ci else 180462306a36Sopenharmony_ci index = 2; 180562306a36Sopenharmony_ci 180662306a36Sopenharmony_ci rtlefuse->pwrgroup_ht20[rf_path][i] = 180762306a36Sopenharmony_ci (rtlefuse->eeprom_pwrgroup[rf_path][index] & 180862306a36Sopenharmony_ci 0xf); 180962306a36Sopenharmony_ci rtlefuse->pwrgroup_ht40[rf_path][i] = 181062306a36Sopenharmony_ci ((rtlefuse->eeprom_pwrgroup[rf_path][index] & 181162306a36Sopenharmony_ci 0xf0) >> 4); 181262306a36Sopenharmony_ci 181362306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 181462306a36Sopenharmony_ci "RF-%d pwrgroup_ht20[%d] = 0x%x\n", 181562306a36Sopenharmony_ci rf_path, i, 181662306a36Sopenharmony_ci rtlefuse->pwrgroup_ht20[rf_path][i]); 181762306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 181862306a36Sopenharmony_ci "RF-%d pwrgroup_ht40[%d] = 0x%x\n", 181962306a36Sopenharmony_ci rf_path, i, 182062306a36Sopenharmony_ci rtlefuse->pwrgroup_ht40[rf_path][i]); 182162306a36Sopenharmony_ci } 182262306a36Sopenharmony_ci } 182362306a36Sopenharmony_ci 182462306a36Sopenharmony_ci for (i = 0; i < 14; i++) { 182562306a36Sopenharmony_ci /* Read tx power difference between HT OFDM 20/40 MHZ */ 182662306a36Sopenharmony_ci /* channel 1-3 */ 182762306a36Sopenharmony_ci if (i < 3) 182862306a36Sopenharmony_ci index = 0; 182962306a36Sopenharmony_ci /* Channel 4-8 */ 183062306a36Sopenharmony_ci else if (i < 8) 183162306a36Sopenharmony_ci index = 1; 183262306a36Sopenharmony_ci /* Channel 9-14 */ 183362306a36Sopenharmony_ci else 183462306a36Sopenharmony_ci index = 2; 183562306a36Sopenharmony_ci 183662306a36Sopenharmony_ci tempval = hwinfo[EEPROM_TX_PWR_HT20_DIFF + index] & 0xff; 183762306a36Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); 183862306a36Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = 183962306a36Sopenharmony_ci ((tempval >> 4) & 0xF); 184062306a36Sopenharmony_ci 184162306a36Sopenharmony_ci /* Read OFDM<->HT tx power diff */ 184262306a36Sopenharmony_ci /* Channel 1-3 */ 184362306a36Sopenharmony_ci if (i < 3) 184462306a36Sopenharmony_ci index = 0; 184562306a36Sopenharmony_ci /* Channel 4-8 */ 184662306a36Sopenharmony_ci else if (i < 8) 184762306a36Sopenharmony_ci index = 0x11; 184862306a36Sopenharmony_ci /* Channel 9-14 */ 184962306a36Sopenharmony_ci else 185062306a36Sopenharmony_ci index = 1; 185162306a36Sopenharmony_ci 185262306a36Sopenharmony_ci tempval = hwinfo[EEPROM_TX_PWR_OFDM_DIFF + index] & 0xff; 185362306a36Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = 185462306a36Sopenharmony_ci (tempval & 0xF); 185562306a36Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = 185662306a36Sopenharmony_ci ((tempval >> 4) & 0xF); 185762306a36Sopenharmony_ci 185862306a36Sopenharmony_ci tempval = hwinfo[TX_PWR_SAFETY_CHK]; 185962306a36Sopenharmony_ci rtlefuse->txpwr_safetyflag = (tempval & 0x01); 186062306a36Sopenharmony_ci } 186162306a36Sopenharmony_ci 186262306a36Sopenharmony_ci rtlefuse->eeprom_regulatory = 0; 186362306a36Sopenharmony_ci if (rtlefuse->eeprom_version >= 2) { 186462306a36Sopenharmony_ci /* BIT(0)~2 */ 186562306a36Sopenharmony_ci if (rtlefuse->eeprom_version >= 4) 186662306a36Sopenharmony_ci rtlefuse->eeprom_regulatory = 186762306a36Sopenharmony_ci (hwinfo[EEPROM_REGULATORY] & 0x7); 186862306a36Sopenharmony_ci else /* BIT(0) */ 186962306a36Sopenharmony_ci rtlefuse->eeprom_regulatory = 187062306a36Sopenharmony_ci (hwinfo[EEPROM_REGULATORY] & 0x1); 187162306a36Sopenharmony_ci } 187262306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 187362306a36Sopenharmony_ci "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 187462306a36Sopenharmony_ci 187562306a36Sopenharmony_ci for (i = 0; i < 14; i++) 187662306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 187762306a36Sopenharmony_ci "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", 187862306a36Sopenharmony_ci i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); 187962306a36Sopenharmony_ci for (i = 0; i < 14; i++) 188062306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 188162306a36Sopenharmony_ci "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", 188262306a36Sopenharmony_ci i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); 188362306a36Sopenharmony_ci for (i = 0; i < 14; i++) 188462306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 188562306a36Sopenharmony_ci "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", 188662306a36Sopenharmony_ci i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); 188762306a36Sopenharmony_ci for (i = 0; i < 14; i++) 188862306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 188962306a36Sopenharmony_ci "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", 189062306a36Sopenharmony_ci i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); 189162306a36Sopenharmony_ci 189262306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 189362306a36Sopenharmony_ci "TxPwrSafetyFlag = %d\n", rtlefuse->txpwr_safetyflag); 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_ci /* Read RF-indication and Tx Power gain 189662306a36Sopenharmony_ci * index diff of legacy to HT OFDM rate. */ 189762306a36Sopenharmony_ci tempval = hwinfo[EEPROM_RFIND_POWERDIFF] & 0xff; 189862306a36Sopenharmony_ci rtlefuse->eeprom_txpowerdiff = tempval; 189962306a36Sopenharmony_ci rtlefuse->legacy_ht_txpowerdiff = 190062306a36Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][0]; 190162306a36Sopenharmony_ci 190262306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 190362306a36Sopenharmony_ci "TxPowerDiff = %#x\n", rtlefuse->eeprom_txpowerdiff); 190462306a36Sopenharmony_ci 190562306a36Sopenharmony_ci /* Get TSSI value for each path. */ 190662306a36Sopenharmony_ci usvalue = *(u16 *)&hwinfo[EEPROM_TSSI_A]; 190762306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_A] = (u8)((usvalue & 0xff00) >> 8); 190862306a36Sopenharmony_ci usvalue = hwinfo[EEPROM_TSSI_B]; 190962306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_B] = (u8)(usvalue & 0xff); 191062306a36Sopenharmony_ci 191162306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, "TSSI_A = 0x%x, TSSI_B = 0x%x\n", 191262306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_A], 191362306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_B]); 191462306a36Sopenharmony_ci 191562306a36Sopenharmony_ci /* Read antenna tx power offset of B/C/D to A from EEPROM */ 191662306a36Sopenharmony_ci /* and read ThermalMeter from EEPROM */ 191762306a36Sopenharmony_ci tempval = hwinfo[EEPROM_THERMALMETER]; 191862306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter = tempval; 191962306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 192062306a36Sopenharmony_ci "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); 192162306a36Sopenharmony_ci 192262306a36Sopenharmony_ci /* ThermalMeter, BIT(0)~3 for RFIC1, BIT(4)~7 for RFIC2 */ 192362306a36Sopenharmony_ci rtlefuse->thermalmeter[0] = (rtlefuse->eeprom_thermalmeter & 0x1f); 192462306a36Sopenharmony_ci rtlefuse->tssi_13dbm = rtlefuse->eeprom_thermalmeter * 100; 192562306a36Sopenharmony_ci 192662306a36Sopenharmony_ci /* Read CrystalCap from EEPROM */ 192762306a36Sopenharmony_ci tempval = hwinfo[EEPROM_CRYSTALCAP] >> 4; 192862306a36Sopenharmony_ci rtlefuse->eeprom_crystalcap = tempval; 192962306a36Sopenharmony_ci /* CrystalCap, BIT(12)~15 */ 193062306a36Sopenharmony_ci rtlefuse->crystalcap = rtlefuse->eeprom_crystalcap; 193162306a36Sopenharmony_ci 193262306a36Sopenharmony_ci /* Read IC Version && Channel Plan */ 193362306a36Sopenharmony_ci /* Version ID, Channel plan */ 193462306a36Sopenharmony_ci rtlefuse->eeprom_channelplan = hwinfo[EEPROM_CHANNELPLAN]; 193562306a36Sopenharmony_ci rtlefuse->txpwr_fromeprom = true; 193662306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 193762306a36Sopenharmony_ci "EEPROM ChannelPlan = 0x%4x\n", rtlefuse->eeprom_channelplan); 193862306a36Sopenharmony_ci 193962306a36Sopenharmony_ci /* Read Customer ID or Board Type!!! */ 194062306a36Sopenharmony_ci tempval = hwinfo[EEPROM_BOARDTYPE]; 194162306a36Sopenharmony_ci /* Change RF type definition */ 194262306a36Sopenharmony_ci if (tempval == 0) 194362306a36Sopenharmony_ci rtlphy->rf_type = RF_2T2R; 194462306a36Sopenharmony_ci else if (tempval == 1) 194562306a36Sopenharmony_ci rtlphy->rf_type = RF_1T2R; 194662306a36Sopenharmony_ci else if (tempval == 2) 194762306a36Sopenharmony_ci rtlphy->rf_type = RF_1T2R; 194862306a36Sopenharmony_ci else if (tempval == 3) 194962306a36Sopenharmony_ci rtlphy->rf_type = RF_1T1R; 195062306a36Sopenharmony_ci 195162306a36Sopenharmony_ci /* 1T2R but 1SS (1x1 receive combining) */ 195262306a36Sopenharmony_ci rtlefuse->b1x1_recvcombine = false; 195362306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) { 195462306a36Sopenharmony_ci tempval = rtl_read_byte(rtlpriv, 0x07); 195562306a36Sopenharmony_ci if (!(tempval & BIT(0))) { 195662306a36Sopenharmony_ci rtlefuse->b1x1_recvcombine = true; 195762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 195862306a36Sopenharmony_ci "RF_TYPE=1T2R but only 1SS\n"); 195962306a36Sopenharmony_ci } 196062306a36Sopenharmony_ci } 196162306a36Sopenharmony_ci rtlefuse->b1ss_support = rtlefuse->b1x1_recvcombine; 196262306a36Sopenharmony_ci rtlefuse->eeprom_oemid = *&hwinfo[EEPROM_CUSTOMID]; 196362306a36Sopenharmony_ci 196462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "EEPROM Customer ID: 0x%2x\n", 196562306a36Sopenharmony_ci rtlefuse->eeprom_oemid); 196662306a36Sopenharmony_ci 196762306a36Sopenharmony_ci /* set channel paln to world wide 13 */ 196862306a36Sopenharmony_ci rtlefuse->channel_plan = COUNTRY_CODE_WORLD_WIDE_13; 196962306a36Sopenharmony_ci} 197062306a36Sopenharmony_ci 197162306a36Sopenharmony_civoid rtl92se_read_eeprom_info(struct ieee80211_hw *hw) 197262306a36Sopenharmony_ci{ 197362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 197462306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 197562306a36Sopenharmony_ci u8 tmp_u1b = 0; 197662306a36Sopenharmony_ci 197762306a36Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, EPROM_CMD); 197862306a36Sopenharmony_ci 197962306a36Sopenharmony_ci if (tmp_u1b & BIT(4)) { 198062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); 198162306a36Sopenharmony_ci rtlefuse->epromtype = EEPROM_93C46; 198262306a36Sopenharmony_ci } else { 198362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); 198462306a36Sopenharmony_ci rtlefuse->epromtype = EEPROM_BOOT_EFUSE; 198562306a36Sopenharmony_ci } 198662306a36Sopenharmony_ci 198762306a36Sopenharmony_ci if (tmp_u1b & BIT(5)) { 198862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); 198962306a36Sopenharmony_ci rtlefuse->autoload_failflag = false; 199062306a36Sopenharmony_ci _rtl92se_read_adapter_info(hw); 199162306a36Sopenharmony_ci } else { 199262306a36Sopenharmony_ci pr_err("Autoload ERR!!\n"); 199362306a36Sopenharmony_ci rtlefuse->autoload_failflag = true; 199462306a36Sopenharmony_ci } 199562306a36Sopenharmony_ci} 199662306a36Sopenharmony_ci 199762306a36Sopenharmony_cistatic void rtl92se_update_hal_rate_table(struct ieee80211_hw *hw, 199862306a36Sopenharmony_ci struct ieee80211_sta *sta) 199962306a36Sopenharmony_ci{ 200062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 200162306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 200262306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 200362306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 200462306a36Sopenharmony_ci u32 ratr_value; 200562306a36Sopenharmony_ci u8 ratr_index = 0; 200662306a36Sopenharmony_ci u8 nmode = mac->ht_enable; 200762306a36Sopenharmony_ci u8 mimo_ps = IEEE80211_SMPS_OFF; 200862306a36Sopenharmony_ci u16 shortgi_rate = 0; 200962306a36Sopenharmony_ci u32 tmp_ratr_value = 0; 201062306a36Sopenharmony_ci u8 curtxbw_40mhz = mac->bw_40; 201162306a36Sopenharmony_ci u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 201262306a36Sopenharmony_ci 1 : 0; 201362306a36Sopenharmony_ci u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 201462306a36Sopenharmony_ci 1 : 0; 201562306a36Sopenharmony_ci enum wireless_mode wirelessmode = mac->mode; 201662306a36Sopenharmony_ci 201762306a36Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_5G) 201862306a36Sopenharmony_ci ratr_value = sta->deflink.supp_rates[1] << 4; 201962306a36Sopenharmony_ci else 202062306a36Sopenharmony_ci ratr_value = sta->deflink.supp_rates[0]; 202162306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) 202262306a36Sopenharmony_ci ratr_value = 0xfff; 202362306a36Sopenharmony_ci ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | 202462306a36Sopenharmony_ci sta->deflink.ht_cap.mcs.rx_mask[0] << 12); 202562306a36Sopenharmony_ci switch (wirelessmode) { 202662306a36Sopenharmony_ci case WIRELESS_MODE_B: 202762306a36Sopenharmony_ci ratr_value &= 0x0000000D; 202862306a36Sopenharmony_ci break; 202962306a36Sopenharmony_ci case WIRELESS_MODE_G: 203062306a36Sopenharmony_ci ratr_value &= 0x00000FF5; 203162306a36Sopenharmony_ci break; 203262306a36Sopenharmony_ci case WIRELESS_MODE_N_24G: 203362306a36Sopenharmony_ci case WIRELESS_MODE_N_5G: 203462306a36Sopenharmony_ci nmode = 1; 203562306a36Sopenharmony_ci if (mimo_ps == IEEE80211_SMPS_STATIC) { 203662306a36Sopenharmony_ci ratr_value &= 0x0007F005; 203762306a36Sopenharmony_ci } else { 203862306a36Sopenharmony_ci u32 ratr_mask; 203962306a36Sopenharmony_ci 204062306a36Sopenharmony_ci if (get_rf_type(rtlphy) == RF_1T2R || 204162306a36Sopenharmony_ci get_rf_type(rtlphy) == RF_1T1R) { 204262306a36Sopenharmony_ci if (curtxbw_40mhz) 204362306a36Sopenharmony_ci ratr_mask = 0x000ff015; 204462306a36Sopenharmony_ci else 204562306a36Sopenharmony_ci ratr_mask = 0x000ff005; 204662306a36Sopenharmony_ci } else { 204762306a36Sopenharmony_ci if (curtxbw_40mhz) 204862306a36Sopenharmony_ci ratr_mask = 0x0f0ff015; 204962306a36Sopenharmony_ci else 205062306a36Sopenharmony_ci ratr_mask = 0x0f0ff005; 205162306a36Sopenharmony_ci } 205262306a36Sopenharmony_ci 205362306a36Sopenharmony_ci ratr_value &= ratr_mask; 205462306a36Sopenharmony_ci } 205562306a36Sopenharmony_ci break; 205662306a36Sopenharmony_ci default: 205762306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) 205862306a36Sopenharmony_ci ratr_value &= 0x000ff0ff; 205962306a36Sopenharmony_ci else 206062306a36Sopenharmony_ci ratr_value &= 0x0f0ff0ff; 206162306a36Sopenharmony_ci 206262306a36Sopenharmony_ci break; 206362306a36Sopenharmony_ci } 206462306a36Sopenharmony_ci 206562306a36Sopenharmony_ci if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT) 206662306a36Sopenharmony_ci ratr_value &= 0x0FFFFFFF; 206762306a36Sopenharmony_ci else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT) 206862306a36Sopenharmony_ci ratr_value &= 0x0FFFFFF0; 206962306a36Sopenharmony_ci 207062306a36Sopenharmony_ci if (nmode && ((curtxbw_40mhz && 207162306a36Sopenharmony_ci curshortgi_40mhz) || (!curtxbw_40mhz && 207262306a36Sopenharmony_ci curshortgi_20mhz))) { 207362306a36Sopenharmony_ci 207462306a36Sopenharmony_ci ratr_value |= 0x10000000; 207562306a36Sopenharmony_ci tmp_ratr_value = (ratr_value >> 12); 207662306a36Sopenharmony_ci 207762306a36Sopenharmony_ci for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { 207862306a36Sopenharmony_ci if ((1 << shortgi_rate) & tmp_ratr_value) 207962306a36Sopenharmony_ci break; 208062306a36Sopenharmony_ci } 208162306a36Sopenharmony_ci 208262306a36Sopenharmony_ci shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | 208362306a36Sopenharmony_ci (shortgi_rate << 4) | (shortgi_rate); 208462306a36Sopenharmony_ci 208562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate); 208662306a36Sopenharmony_ci } 208762306a36Sopenharmony_ci 208862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, ARFR0 + ratr_index * 4, ratr_value); 208962306a36Sopenharmony_ci if (ratr_value & 0xfffff000) 209062306a36Sopenharmony_ci rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_N); 209162306a36Sopenharmony_ci else 209262306a36Sopenharmony_ci rtl92s_phy_set_fw_cmd(hw, FW_CMD_RA_REFRESH_BG); 209362306a36Sopenharmony_ci 209462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", 209562306a36Sopenharmony_ci rtl_read_dword(rtlpriv, ARFR0)); 209662306a36Sopenharmony_ci} 209762306a36Sopenharmony_ci 209862306a36Sopenharmony_cistatic void rtl92se_update_hal_rate_mask(struct ieee80211_hw *hw, 209962306a36Sopenharmony_ci struct ieee80211_sta *sta, 210062306a36Sopenharmony_ci u8 rssi_level, bool update_bw) 210162306a36Sopenharmony_ci{ 210262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 210362306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 210462306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 210562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 210662306a36Sopenharmony_ci struct rtl_sta_info *sta_entry = NULL; 210762306a36Sopenharmony_ci u32 ratr_bitmap; 210862306a36Sopenharmony_ci u8 ratr_index = 0; 210962306a36Sopenharmony_ci u8 curtxbw_40mhz = (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; 211062306a36Sopenharmony_ci u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 211162306a36Sopenharmony_ci 1 : 0; 211262306a36Sopenharmony_ci u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 211362306a36Sopenharmony_ci 1 : 0; 211462306a36Sopenharmony_ci enum wireless_mode wirelessmode = 0; 211562306a36Sopenharmony_ci bool shortgi = false; 211662306a36Sopenharmony_ci u32 ratr_value = 0; 211762306a36Sopenharmony_ci u8 shortgi_rate = 0; 211862306a36Sopenharmony_ci u32 mask = 0; 211962306a36Sopenharmony_ci u32 band = 0; 212062306a36Sopenharmony_ci bool bmulticast = false; 212162306a36Sopenharmony_ci u8 macid = 0; 212262306a36Sopenharmony_ci u8 mimo_ps = IEEE80211_SMPS_OFF; 212362306a36Sopenharmony_ci 212462306a36Sopenharmony_ci sta_entry = (struct rtl_sta_info *) sta->drv_priv; 212562306a36Sopenharmony_ci wirelessmode = sta_entry->wireless_mode; 212662306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_STATION) 212762306a36Sopenharmony_ci curtxbw_40mhz = mac->bw_40; 212862306a36Sopenharmony_ci else if (mac->opmode == NL80211_IFTYPE_AP || 212962306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC) 213062306a36Sopenharmony_ci macid = sta->aid + 1; 213162306a36Sopenharmony_ci 213262306a36Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_5G) 213362306a36Sopenharmony_ci ratr_bitmap = sta->deflink.supp_rates[1] << 4; 213462306a36Sopenharmony_ci else 213562306a36Sopenharmony_ci ratr_bitmap = sta->deflink.supp_rates[0]; 213662306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) 213762306a36Sopenharmony_ci ratr_bitmap = 0xfff; 213862306a36Sopenharmony_ci ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | 213962306a36Sopenharmony_ci sta->deflink.ht_cap.mcs.rx_mask[0] << 12); 214062306a36Sopenharmony_ci switch (wirelessmode) { 214162306a36Sopenharmony_ci case WIRELESS_MODE_B: 214262306a36Sopenharmony_ci band |= WIRELESS_11B; 214362306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_B; 214462306a36Sopenharmony_ci if (ratr_bitmap & 0x0000000c) 214562306a36Sopenharmony_ci ratr_bitmap &= 0x0000000d; 214662306a36Sopenharmony_ci else 214762306a36Sopenharmony_ci ratr_bitmap &= 0x0000000f; 214862306a36Sopenharmony_ci break; 214962306a36Sopenharmony_ci case WIRELESS_MODE_G: 215062306a36Sopenharmony_ci band |= (WIRELESS_11G | WIRELESS_11B); 215162306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_GB; 215262306a36Sopenharmony_ci 215362306a36Sopenharmony_ci if (rssi_level == 1) 215462306a36Sopenharmony_ci ratr_bitmap &= 0x00000f00; 215562306a36Sopenharmony_ci else if (rssi_level == 2) 215662306a36Sopenharmony_ci ratr_bitmap &= 0x00000ff0; 215762306a36Sopenharmony_ci else 215862306a36Sopenharmony_ci ratr_bitmap &= 0x00000ff5; 215962306a36Sopenharmony_ci break; 216062306a36Sopenharmony_ci case WIRELESS_MODE_A: 216162306a36Sopenharmony_ci band |= WIRELESS_11A; 216262306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_A; 216362306a36Sopenharmony_ci ratr_bitmap &= 0x00000ff0; 216462306a36Sopenharmony_ci break; 216562306a36Sopenharmony_ci case WIRELESS_MODE_N_24G: 216662306a36Sopenharmony_ci case WIRELESS_MODE_N_5G: 216762306a36Sopenharmony_ci band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B); 216862306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 216962306a36Sopenharmony_ci 217062306a36Sopenharmony_ci if (mimo_ps == IEEE80211_SMPS_STATIC) { 217162306a36Sopenharmony_ci if (rssi_level == 1) 217262306a36Sopenharmony_ci ratr_bitmap &= 0x00070000; 217362306a36Sopenharmony_ci else if (rssi_level == 2) 217462306a36Sopenharmony_ci ratr_bitmap &= 0x0007f000; 217562306a36Sopenharmony_ci else 217662306a36Sopenharmony_ci ratr_bitmap &= 0x0007f005; 217762306a36Sopenharmony_ci } else { 217862306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R || 217962306a36Sopenharmony_ci rtlphy->rf_type == RF_1T1R) { 218062306a36Sopenharmony_ci if (rssi_level == 1) { 218162306a36Sopenharmony_ci ratr_bitmap &= 0x000f0000; 218262306a36Sopenharmony_ci } else if (rssi_level == 3) { 218362306a36Sopenharmony_ci ratr_bitmap &= 0x000fc000; 218462306a36Sopenharmony_ci } else if (rssi_level == 5) { 218562306a36Sopenharmony_ci ratr_bitmap &= 0x000ff000; 218662306a36Sopenharmony_ci } else { 218762306a36Sopenharmony_ci if (curtxbw_40mhz) 218862306a36Sopenharmony_ci ratr_bitmap &= 0x000ff015; 218962306a36Sopenharmony_ci else 219062306a36Sopenharmony_ci ratr_bitmap &= 0x000ff005; 219162306a36Sopenharmony_ci } 219262306a36Sopenharmony_ci } else { 219362306a36Sopenharmony_ci if (rssi_level == 1) { 219462306a36Sopenharmony_ci ratr_bitmap &= 0x0f8f0000; 219562306a36Sopenharmony_ci } else if (rssi_level == 3) { 219662306a36Sopenharmony_ci ratr_bitmap &= 0x0f8fc000; 219762306a36Sopenharmony_ci } else if (rssi_level == 5) { 219862306a36Sopenharmony_ci ratr_bitmap &= 0x0f8ff000; 219962306a36Sopenharmony_ci } else { 220062306a36Sopenharmony_ci if (curtxbw_40mhz) 220162306a36Sopenharmony_ci ratr_bitmap &= 0x0f8ff015; 220262306a36Sopenharmony_ci else 220362306a36Sopenharmony_ci ratr_bitmap &= 0x0f8ff005; 220462306a36Sopenharmony_ci } 220562306a36Sopenharmony_ci } 220662306a36Sopenharmony_ci } 220762306a36Sopenharmony_ci 220862306a36Sopenharmony_ci if ((curtxbw_40mhz && curshortgi_40mhz) || 220962306a36Sopenharmony_ci (!curtxbw_40mhz && curshortgi_20mhz)) { 221062306a36Sopenharmony_ci if (macid == 0) 221162306a36Sopenharmony_ci shortgi = true; 221262306a36Sopenharmony_ci else if (macid == 1) 221362306a36Sopenharmony_ci shortgi = false; 221462306a36Sopenharmony_ci } 221562306a36Sopenharmony_ci break; 221662306a36Sopenharmony_ci default: 221762306a36Sopenharmony_ci band |= (WIRELESS_11N | WIRELESS_11G | WIRELESS_11B); 221862306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 221962306a36Sopenharmony_ci 222062306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) 222162306a36Sopenharmony_ci ratr_bitmap &= 0x000ff0ff; 222262306a36Sopenharmony_ci else 222362306a36Sopenharmony_ci ratr_bitmap &= 0x0f8ff0ff; 222462306a36Sopenharmony_ci break; 222562306a36Sopenharmony_ci } 222662306a36Sopenharmony_ci sta_entry->ratr_index = ratr_index; 222762306a36Sopenharmony_ci 222862306a36Sopenharmony_ci if (rtlpriv->rtlhal.version >= VERSION_8192S_BCUT) 222962306a36Sopenharmony_ci ratr_bitmap &= 0x0FFFFFFF; 223062306a36Sopenharmony_ci else if (rtlpriv->rtlhal.version == VERSION_8192S_ACUT) 223162306a36Sopenharmony_ci ratr_bitmap &= 0x0FFFFFF0; 223262306a36Sopenharmony_ci 223362306a36Sopenharmony_ci if (shortgi) { 223462306a36Sopenharmony_ci ratr_bitmap |= 0x10000000; 223562306a36Sopenharmony_ci /* Get MAX MCS available. */ 223662306a36Sopenharmony_ci ratr_value = (ratr_bitmap >> 12); 223762306a36Sopenharmony_ci for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { 223862306a36Sopenharmony_ci if ((1 << shortgi_rate) & ratr_value) 223962306a36Sopenharmony_ci break; 224062306a36Sopenharmony_ci } 224162306a36Sopenharmony_ci 224262306a36Sopenharmony_ci shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | 224362306a36Sopenharmony_ci (shortgi_rate << 4) | (shortgi_rate); 224462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, SG_RATE, shortgi_rate); 224562306a36Sopenharmony_ci } 224662306a36Sopenharmony_ci 224762306a36Sopenharmony_ci mask |= (bmulticast ? 1 : 0) << 9 | (macid & 0x1f) << 4 | (band & 0xf); 224862306a36Sopenharmony_ci 224962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_TRACE, "mask = %x, bitmap = %x\n", 225062306a36Sopenharmony_ci mask, ratr_bitmap); 225162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, 0x2c4, ratr_bitmap); 225262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, WFM5, (FW_RA_UPDATE_MASK | (mask << 8))); 225362306a36Sopenharmony_ci 225462306a36Sopenharmony_ci if (macid != 0) 225562306a36Sopenharmony_ci sta_entry->ratr_index = ratr_index; 225662306a36Sopenharmony_ci} 225762306a36Sopenharmony_ci 225862306a36Sopenharmony_civoid rtl92se_update_hal_rate_tbl(struct ieee80211_hw *hw, 225962306a36Sopenharmony_ci struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) 226062306a36Sopenharmony_ci{ 226162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 226262306a36Sopenharmony_ci 226362306a36Sopenharmony_ci if (rtlpriv->dm.useramask) 226462306a36Sopenharmony_ci rtl92se_update_hal_rate_mask(hw, sta, rssi_level, update_bw); 226562306a36Sopenharmony_ci else 226662306a36Sopenharmony_ci rtl92se_update_hal_rate_table(hw, sta); 226762306a36Sopenharmony_ci} 226862306a36Sopenharmony_ci 226962306a36Sopenharmony_civoid rtl92se_update_channel_access_setting(struct ieee80211_hw *hw) 227062306a36Sopenharmony_ci{ 227162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 227262306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 227362306a36Sopenharmony_ci u16 sifs_timer; 227462306a36Sopenharmony_ci 227562306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, 227662306a36Sopenharmony_ci &mac->slot_time); 227762306a36Sopenharmony_ci sifs_timer = 0x0e0e; 227862306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); 227962306a36Sopenharmony_ci 228062306a36Sopenharmony_ci} 228162306a36Sopenharmony_ci 228262306a36Sopenharmony_ci/* this ifunction is for RFKILL, it's different with windows, 228362306a36Sopenharmony_ci * because UI will disable wireless when GPIO Radio Off. 228462306a36Sopenharmony_ci * And here we not check or Disable/Enable ASPM like windows*/ 228562306a36Sopenharmony_cibool rtl92se_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) 228662306a36Sopenharmony_ci{ 228762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 228862306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 228962306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 229062306a36Sopenharmony_ci enum rf_pwrstate rfpwr_toset /*, cur_rfstate */; 229162306a36Sopenharmony_ci unsigned long flag = 0; 229262306a36Sopenharmony_ci bool actuallyset = false; 229362306a36Sopenharmony_ci bool turnonbypowerdomain = false; 229462306a36Sopenharmony_ci 229562306a36Sopenharmony_ci /* just 8191se can check gpio before firstup, 92c/92d have fixed it */ 229662306a36Sopenharmony_ci if (rtlpci->up_first_time || rtlpci->being_init_adapter) 229762306a36Sopenharmony_ci return false; 229862306a36Sopenharmony_ci 229962306a36Sopenharmony_ci if (ppsc->swrf_processing) 230062306a36Sopenharmony_ci return false; 230162306a36Sopenharmony_ci 230262306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 230362306a36Sopenharmony_ci if (ppsc->rfchange_inprogress) { 230462306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 230562306a36Sopenharmony_ci return false; 230662306a36Sopenharmony_ci } else { 230762306a36Sopenharmony_ci ppsc->rfchange_inprogress = true; 230862306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 230962306a36Sopenharmony_ci } 231062306a36Sopenharmony_ci 231162306a36Sopenharmony_ci /* cur_rfstate = ppsc->rfpwr_state;*/ 231262306a36Sopenharmony_ci 231362306a36Sopenharmony_ci /* because after _rtl92s_phy_set_rfhalt, all power 231462306a36Sopenharmony_ci * closed, so we must open some power for GPIO check, 231562306a36Sopenharmony_ci * or we will always check GPIO RFOFF here, 231662306a36Sopenharmony_ci * And we should close power after GPIO check */ 231762306a36Sopenharmony_ci if (RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { 231862306a36Sopenharmony_ci _rtl92se_power_domain_init(hw); 231962306a36Sopenharmony_ci turnonbypowerdomain = true; 232062306a36Sopenharmony_ci } 232162306a36Sopenharmony_ci 232262306a36Sopenharmony_ci rfpwr_toset = _rtl92se_rf_onoff_detect(hw); 232362306a36Sopenharmony_ci 232462306a36Sopenharmony_ci if ((ppsc->hwradiooff) && (rfpwr_toset == ERFON)) { 232562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 232662306a36Sopenharmony_ci "RFKILL-HW Radio ON, RF ON\n"); 232762306a36Sopenharmony_ci 232862306a36Sopenharmony_ci rfpwr_toset = ERFON; 232962306a36Sopenharmony_ci ppsc->hwradiooff = false; 233062306a36Sopenharmony_ci actuallyset = true; 233162306a36Sopenharmony_ci } else if ((!ppsc->hwradiooff) && (rfpwr_toset == ERFOFF)) { 233262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, 233362306a36Sopenharmony_ci DBG_DMESG, "RFKILL-HW Radio OFF, RF OFF\n"); 233462306a36Sopenharmony_ci 233562306a36Sopenharmony_ci rfpwr_toset = ERFOFF; 233662306a36Sopenharmony_ci ppsc->hwradiooff = true; 233762306a36Sopenharmony_ci actuallyset = true; 233862306a36Sopenharmony_ci } 233962306a36Sopenharmony_ci 234062306a36Sopenharmony_ci if (actuallyset) { 234162306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 234262306a36Sopenharmony_ci ppsc->rfchange_inprogress = false; 234362306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 234462306a36Sopenharmony_ci 234562306a36Sopenharmony_ci /* this not include ifconfig wlan0 down case */ 234662306a36Sopenharmony_ci /* } else if (rfpwr_toset == ERFOFF || cur_rfstate == ERFOFF) { */ 234762306a36Sopenharmony_ci } else { 234862306a36Sopenharmony_ci /* because power_domain_init may be happen when 234962306a36Sopenharmony_ci * _rtl92s_phy_set_rfhalt, this will open some powers 235062306a36Sopenharmony_ci * and cause current increasing about 40 mA for ips, 235162306a36Sopenharmony_ci * rfoff and ifconfig down, so we set 235262306a36Sopenharmony_ci * _rtl92s_phy_set_rfhalt again here */ 235362306a36Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC && 235462306a36Sopenharmony_ci turnonbypowerdomain) { 235562306a36Sopenharmony_ci _rtl92s_phy_set_rfhalt(hw); 235662306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 235762306a36Sopenharmony_ci } 235862306a36Sopenharmony_ci 235962306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 236062306a36Sopenharmony_ci ppsc->rfchange_inprogress = false; 236162306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 236262306a36Sopenharmony_ci } 236362306a36Sopenharmony_ci 236462306a36Sopenharmony_ci *valid = 1; 236562306a36Sopenharmony_ci return !ppsc->hwradiooff; 236662306a36Sopenharmony_ci 236762306a36Sopenharmony_ci} 236862306a36Sopenharmony_ci 236962306a36Sopenharmony_ci/* Is_wepkey just used for WEP used as group & pairwise key 237062306a36Sopenharmony_ci * if pairwise is AES ang group is WEP Is_wepkey == false.*/ 237162306a36Sopenharmony_civoid rtl92se_set_key(struct ieee80211_hw *hw, u32 key_index, u8 *p_macaddr, 237262306a36Sopenharmony_ci bool is_group, u8 enc_algo, bool is_wepkey, bool clear_all) 237362306a36Sopenharmony_ci{ 237462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 237562306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 237662306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 237762306a36Sopenharmony_ci u8 *macaddr = p_macaddr; 237862306a36Sopenharmony_ci 237962306a36Sopenharmony_ci u32 entry_id = 0; 238062306a36Sopenharmony_ci bool is_pairwise = false; 238162306a36Sopenharmony_ci 238262306a36Sopenharmony_ci static u8 cam_const_addr[4][6] = { 238362306a36Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 238462306a36Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 238562306a36Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, 238662306a36Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} 238762306a36Sopenharmony_ci }; 238862306a36Sopenharmony_ci static u8 cam_const_broad[] = { 238962306a36Sopenharmony_ci 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 239062306a36Sopenharmony_ci }; 239162306a36Sopenharmony_ci 239262306a36Sopenharmony_ci if (clear_all) { 239362306a36Sopenharmony_ci u8 idx = 0; 239462306a36Sopenharmony_ci u8 cam_offset = 0; 239562306a36Sopenharmony_ci u8 clear_number = 5; 239662306a36Sopenharmony_ci 239762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); 239862306a36Sopenharmony_ci 239962306a36Sopenharmony_ci for (idx = 0; idx < clear_number; idx++) { 240062306a36Sopenharmony_ci rtl_cam_mark_invalid(hw, cam_offset + idx); 240162306a36Sopenharmony_ci rtl_cam_empty_entry(hw, cam_offset + idx); 240262306a36Sopenharmony_ci 240362306a36Sopenharmony_ci if (idx < 5) { 240462306a36Sopenharmony_ci memset(rtlpriv->sec.key_buf[idx], 0, 240562306a36Sopenharmony_ci MAX_KEY_LEN); 240662306a36Sopenharmony_ci rtlpriv->sec.key_len[idx] = 0; 240762306a36Sopenharmony_ci } 240862306a36Sopenharmony_ci } 240962306a36Sopenharmony_ci 241062306a36Sopenharmony_ci } else { 241162306a36Sopenharmony_ci switch (enc_algo) { 241262306a36Sopenharmony_ci case WEP40_ENCRYPTION: 241362306a36Sopenharmony_ci enc_algo = CAM_WEP40; 241462306a36Sopenharmony_ci break; 241562306a36Sopenharmony_ci case WEP104_ENCRYPTION: 241662306a36Sopenharmony_ci enc_algo = CAM_WEP104; 241762306a36Sopenharmony_ci break; 241862306a36Sopenharmony_ci case TKIP_ENCRYPTION: 241962306a36Sopenharmony_ci enc_algo = CAM_TKIP; 242062306a36Sopenharmony_ci break; 242162306a36Sopenharmony_ci case AESCCMP_ENCRYPTION: 242262306a36Sopenharmony_ci enc_algo = CAM_AES; 242362306a36Sopenharmony_ci break; 242462306a36Sopenharmony_ci default: 242562306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", 242662306a36Sopenharmony_ci enc_algo); 242762306a36Sopenharmony_ci enc_algo = CAM_TKIP; 242862306a36Sopenharmony_ci break; 242962306a36Sopenharmony_ci } 243062306a36Sopenharmony_ci 243162306a36Sopenharmony_ci if (is_wepkey || rtlpriv->sec.use_defaultkey) { 243262306a36Sopenharmony_ci macaddr = cam_const_addr[key_index]; 243362306a36Sopenharmony_ci entry_id = key_index; 243462306a36Sopenharmony_ci } else { 243562306a36Sopenharmony_ci if (is_group) { 243662306a36Sopenharmony_ci macaddr = cam_const_broad; 243762306a36Sopenharmony_ci entry_id = key_index; 243862306a36Sopenharmony_ci } else { 243962306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP) { 244062306a36Sopenharmony_ci entry_id = rtl_cam_get_free_entry(hw, 244162306a36Sopenharmony_ci p_macaddr); 244262306a36Sopenharmony_ci if (entry_id >= TOTAL_CAM_ENTRY) { 244362306a36Sopenharmony_ci pr_err("Can not find free hw security cam entry\n"); 244462306a36Sopenharmony_ci return; 244562306a36Sopenharmony_ci } 244662306a36Sopenharmony_ci } else { 244762306a36Sopenharmony_ci entry_id = CAM_PAIRWISE_KEY_POSITION; 244862306a36Sopenharmony_ci } 244962306a36Sopenharmony_ci 245062306a36Sopenharmony_ci key_index = PAIRWISE_KEYIDX; 245162306a36Sopenharmony_ci is_pairwise = true; 245262306a36Sopenharmony_ci } 245362306a36Sopenharmony_ci } 245462306a36Sopenharmony_ci 245562306a36Sopenharmony_ci if (rtlpriv->sec.key_len[key_index] == 0) { 245662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 245762306a36Sopenharmony_ci "delete one entry, entry_id is %d\n", 245862306a36Sopenharmony_ci entry_id); 245962306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP) 246062306a36Sopenharmony_ci rtl_cam_del_entry(hw, p_macaddr); 246162306a36Sopenharmony_ci rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); 246262306a36Sopenharmony_ci } else { 246362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 246462306a36Sopenharmony_ci "add one entry\n"); 246562306a36Sopenharmony_ci if (is_pairwise) { 246662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 246762306a36Sopenharmony_ci "set Pairwise key\n"); 246862306a36Sopenharmony_ci 246962306a36Sopenharmony_ci rtl_cam_add_one_entry(hw, macaddr, key_index, 247062306a36Sopenharmony_ci entry_id, enc_algo, 247162306a36Sopenharmony_ci CAM_CONFIG_NO_USEDK, 247262306a36Sopenharmony_ci rtlpriv->sec.key_buf[key_index]); 247362306a36Sopenharmony_ci } else { 247462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 247562306a36Sopenharmony_ci "set group key\n"); 247662306a36Sopenharmony_ci 247762306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) { 247862306a36Sopenharmony_ci rtl_cam_add_one_entry(hw, 247962306a36Sopenharmony_ci rtlefuse->dev_addr, 248062306a36Sopenharmony_ci PAIRWISE_KEYIDX, 248162306a36Sopenharmony_ci CAM_PAIRWISE_KEY_POSITION, 248262306a36Sopenharmony_ci enc_algo, CAM_CONFIG_NO_USEDK, 248362306a36Sopenharmony_ci rtlpriv->sec.key_buf[entry_id]); 248462306a36Sopenharmony_ci } 248562306a36Sopenharmony_ci 248662306a36Sopenharmony_ci rtl_cam_add_one_entry(hw, macaddr, key_index, 248762306a36Sopenharmony_ci entry_id, enc_algo, 248862306a36Sopenharmony_ci CAM_CONFIG_NO_USEDK, 248962306a36Sopenharmony_ci rtlpriv->sec.key_buf[entry_id]); 249062306a36Sopenharmony_ci } 249162306a36Sopenharmony_ci 249262306a36Sopenharmony_ci } 249362306a36Sopenharmony_ci } 249462306a36Sopenharmony_ci} 249562306a36Sopenharmony_ci 249662306a36Sopenharmony_civoid rtl92se_suspend(struct ieee80211_hw *hw) 249762306a36Sopenharmony_ci{ 249862306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 249962306a36Sopenharmony_ci 250062306a36Sopenharmony_ci rtlpci->up_first_time = true; 250162306a36Sopenharmony_ci} 250262306a36Sopenharmony_ci 250362306a36Sopenharmony_civoid rtl92se_resume(struct ieee80211_hw *hw) 250462306a36Sopenharmony_ci{ 250562306a36Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 250662306a36Sopenharmony_ci u32 val; 250762306a36Sopenharmony_ci 250862306a36Sopenharmony_ci pci_read_config_dword(rtlpci->pdev, 0x40, &val); 250962306a36Sopenharmony_ci if ((val & 0x0000ff00) != 0) 251062306a36Sopenharmony_ci pci_write_config_dword(rtlpci->pdev, 0x40, 251162306a36Sopenharmony_ci val & 0xffff00ff); 251262306a36Sopenharmony_ci} 2513