18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 2009-2012 Realtek Corporation.*/ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "../wifi.h" 58c2ecf20Sopenharmony_ci#include "../efuse.h" 68c2ecf20Sopenharmony_ci#include "../base.h" 78c2ecf20Sopenharmony_ci#include "../regd.h" 88c2ecf20Sopenharmony_ci#include "../cam.h" 98c2ecf20Sopenharmony_ci#include "../ps.h" 108c2ecf20Sopenharmony_ci#include "../pci.h" 118c2ecf20Sopenharmony_ci#include "reg.h" 128c2ecf20Sopenharmony_ci#include "def.h" 138c2ecf20Sopenharmony_ci#include "phy.h" 148c2ecf20Sopenharmony_ci#include "dm.h" 158c2ecf20Sopenharmony_ci#include "fw.h" 168c2ecf20Sopenharmony_ci#include "led.h" 178c2ecf20Sopenharmony_ci#include "sw.h" 188c2ecf20Sopenharmony_ci#include "hw.h" 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ciu32 rtl92de_read_dword_dbi(struct ieee80211_hw *hw, u16 offset, u8 direct) 218c2ecf20Sopenharmony_ci{ 228c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 238c2ecf20Sopenharmony_ci u32 value; 248c2ecf20Sopenharmony_ci 258c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_DBI_CTRL, (offset & 0xFFC)); 268c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DBI_FLAG, BIT(1) | direct); 278c2ecf20Sopenharmony_ci udelay(10); 288c2ecf20Sopenharmony_ci value = rtl_read_dword(rtlpriv, REG_DBI_RDATA); 298c2ecf20Sopenharmony_ci return value; 308c2ecf20Sopenharmony_ci} 318c2ecf20Sopenharmony_ci 328c2ecf20Sopenharmony_civoid rtl92de_write_dword_dbi(struct ieee80211_hw *hw, 338c2ecf20Sopenharmony_ci u16 offset, u32 value, u8 direct) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_DBI_CTRL, ((offset & 0xFFC) | 0xF000)); 388c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DBI_WDATA, value); 398c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DBI_FLAG, BIT(0) | direct); 408c2ecf20Sopenharmony_ci} 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_cistatic void _rtl92de_set_bcn_ctrl_reg(struct ieee80211_hw *hw, 438c2ecf20Sopenharmony_ci u8 set_bits, u8 clear_bits) 448c2ecf20Sopenharmony_ci{ 458c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 468c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci rtlpci->reg_bcn_ctrl_val |= set_bits; 498c2ecf20Sopenharmony_ci rtlpci->reg_bcn_ctrl_val &= ~clear_bits; 508c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8) rtlpci->reg_bcn_ctrl_val); 518c2ecf20Sopenharmony_ci} 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistatic void _rtl92de_stop_tx_beacon(struct ieee80211_hw *hw) 548c2ecf20Sopenharmony_ci{ 558c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 568c2ecf20Sopenharmony_ci u8 tmp1byte; 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); 598c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte & (~BIT(6))); 608c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0xff); 618c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); 628c2ecf20Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); 638c2ecf20Sopenharmony_ci tmp1byte &= ~(BIT(0)); 648c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); 658c2ecf20Sopenharmony_ci} 668c2ecf20Sopenharmony_ci 678c2ecf20Sopenharmony_cistatic void _rtl92de_resume_tx_beacon(struct ieee80211_hw *hw) 688c2ecf20Sopenharmony_ci{ 698c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 708c2ecf20Sopenharmony_ci u8 tmp1byte; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); 738c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, tmp1byte | BIT(6)); 748c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0x0a); 758c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); 768c2ecf20Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); 778c2ecf20Sopenharmony_ci tmp1byte |= BIT(0); 788c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); 798c2ecf20Sopenharmony_ci} 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cistatic void _rtl92de_enable_bcn_sub_func(struct ieee80211_hw *hw) 828c2ecf20Sopenharmony_ci{ 838c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(1)); 848c2ecf20Sopenharmony_ci} 858c2ecf20Sopenharmony_ci 868c2ecf20Sopenharmony_cistatic void _rtl92de_disable_bcn_sub_func(struct ieee80211_hw *hw) 878c2ecf20Sopenharmony_ci{ 888c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, BIT(1), 0); 898c2ecf20Sopenharmony_ci} 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_civoid rtl92de_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 928c2ecf20Sopenharmony_ci{ 938c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 948c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 958c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci switch (variable) { 988c2ecf20Sopenharmony_ci case HW_VAR_RCR: 998c2ecf20Sopenharmony_ci *((u32 *) (val)) = rtlpci->receive_config; 1008c2ecf20Sopenharmony_ci break; 1018c2ecf20Sopenharmony_ci case HW_VAR_RF_STATE: 1028c2ecf20Sopenharmony_ci *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; 1038c2ecf20Sopenharmony_ci break; 1048c2ecf20Sopenharmony_ci case HW_VAR_FWLPS_RF_ON:{ 1058c2ecf20Sopenharmony_ci enum rf_pwrstate rfstate; 1068c2ecf20Sopenharmony_ci u32 val_rcr; 1078c2ecf20Sopenharmony_ci 1088c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, 1098c2ecf20Sopenharmony_ci (u8 *)(&rfstate)); 1108c2ecf20Sopenharmony_ci if (rfstate == ERFOFF) { 1118c2ecf20Sopenharmony_ci *((bool *) (val)) = true; 1128c2ecf20Sopenharmony_ci } else { 1138c2ecf20Sopenharmony_ci val_rcr = rtl_read_dword(rtlpriv, REG_RCR); 1148c2ecf20Sopenharmony_ci val_rcr &= 0x00070000; 1158c2ecf20Sopenharmony_ci if (val_rcr) 1168c2ecf20Sopenharmony_ci *((bool *) (val)) = false; 1178c2ecf20Sopenharmony_ci else 1188c2ecf20Sopenharmony_ci *((bool *) (val)) = true; 1198c2ecf20Sopenharmony_ci } 1208c2ecf20Sopenharmony_ci break; 1218c2ecf20Sopenharmony_ci } 1228c2ecf20Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: 1238c2ecf20Sopenharmony_ci *((bool *) (val)) = ppsc->fw_current_inpsmode; 1248c2ecf20Sopenharmony_ci break; 1258c2ecf20Sopenharmony_ci case HW_VAR_CORRECT_TSF:{ 1268c2ecf20Sopenharmony_ci u64 tsf; 1278c2ecf20Sopenharmony_ci u32 *ptsf_low = (u32 *)&tsf; 1288c2ecf20Sopenharmony_ci u32 *ptsf_high = ((u32 *)&tsf) + 1; 1298c2ecf20Sopenharmony_ci 1308c2ecf20Sopenharmony_ci *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); 1318c2ecf20Sopenharmony_ci *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); 1328c2ecf20Sopenharmony_ci *((u64 *) (val)) = tsf; 1338c2ecf20Sopenharmony_ci break; 1348c2ecf20Sopenharmony_ci } 1358c2ecf20Sopenharmony_ci case HW_VAR_INT_MIGRATION: 1368c2ecf20Sopenharmony_ci *((bool *)(val)) = rtlpriv->dm.interrupt_migration; 1378c2ecf20Sopenharmony_ci break; 1388c2ecf20Sopenharmony_ci case HW_VAR_INT_AC: 1398c2ecf20Sopenharmony_ci *((bool *)(val)) = rtlpriv->dm.disable_tx_int; 1408c2ecf20Sopenharmony_ci break; 1418c2ecf20Sopenharmony_ci case HAL_DEF_WOWLAN: 1428c2ecf20Sopenharmony_ci break; 1438c2ecf20Sopenharmony_ci default: 1448c2ecf20Sopenharmony_ci pr_err("switch case %#x not processed\n", variable); 1458c2ecf20Sopenharmony_ci break; 1468c2ecf20Sopenharmony_ci } 1478c2ecf20Sopenharmony_ci} 1488c2ecf20Sopenharmony_ci 1498c2ecf20Sopenharmony_civoid rtl92de_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 1508c2ecf20Sopenharmony_ci{ 1518c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1528c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 1538c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 1548c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1558c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 1568c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 1578c2ecf20Sopenharmony_ci u8 idx; 1588c2ecf20Sopenharmony_ci 1598c2ecf20Sopenharmony_ci switch (variable) { 1608c2ecf20Sopenharmony_ci case HW_VAR_ETHER_ADDR: 1618c2ecf20Sopenharmony_ci for (idx = 0; idx < ETH_ALEN; idx++) { 1628c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_MACID + idx), 1638c2ecf20Sopenharmony_ci val[idx]); 1648c2ecf20Sopenharmony_ci } 1658c2ecf20Sopenharmony_ci break; 1668c2ecf20Sopenharmony_ci case HW_VAR_BASIC_RATE: { 1678c2ecf20Sopenharmony_ci u16 rate_cfg = ((u16 *) val)[0]; 1688c2ecf20Sopenharmony_ci u8 rate_index = 0; 1698c2ecf20Sopenharmony_ci 1708c2ecf20Sopenharmony_ci rate_cfg = rate_cfg & 0x15f; 1718c2ecf20Sopenharmony_ci if (mac->vendor == PEER_CISCO && 1728c2ecf20Sopenharmony_ci ((rate_cfg & 0x150) == 0)) 1738c2ecf20Sopenharmony_ci rate_cfg |= 0x01; 1748c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); 1758c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 1, 1768c2ecf20Sopenharmony_ci (rate_cfg >> 8) & 0xff); 1778c2ecf20Sopenharmony_ci while (rate_cfg > 0x1) { 1788c2ecf20Sopenharmony_ci rate_cfg = (rate_cfg >> 1); 1798c2ecf20Sopenharmony_ci rate_index++; 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci if (rtlhal->fw_version > 0xe) 1828c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 1838c2ecf20Sopenharmony_ci rate_index); 1848c2ecf20Sopenharmony_ci break; 1858c2ecf20Sopenharmony_ci } 1868c2ecf20Sopenharmony_ci case HW_VAR_BSSID: 1878c2ecf20Sopenharmony_ci for (idx = 0; idx < ETH_ALEN; idx++) { 1888c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_BSSID + idx), 1898c2ecf20Sopenharmony_ci val[idx]); 1908c2ecf20Sopenharmony_ci } 1918c2ecf20Sopenharmony_ci break; 1928c2ecf20Sopenharmony_ci case HW_VAR_SIFS: 1938c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SIFS_CTX + 1, val[0]); 1948c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SIFS_TRX + 1, val[1]); 1958c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); 1968c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); 1978c2ecf20Sopenharmony_ci if (!mac->ht_enable) 1988c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 1998c2ecf20Sopenharmony_ci 0x0e0e); 2008c2ecf20Sopenharmony_ci else 2018c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_RESP_SIFS_OFDM, 2028c2ecf20Sopenharmony_ci *((u16 *) val)); 2038c2ecf20Sopenharmony_ci break; 2048c2ecf20Sopenharmony_ci case HW_VAR_SLOT_TIME: { 2058c2ecf20Sopenharmony_ci u8 e_aci; 2068c2ecf20Sopenharmony_ci 2078c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 2088c2ecf20Sopenharmony_ci "HW_VAR_SLOT_TIME %x\n", val[0]); 2098c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SLOT, val[0]); 2108c2ecf20Sopenharmony_ci for (e_aci = 0; e_aci < AC_MAX; e_aci++) 2118c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 2128c2ecf20Sopenharmony_ci HW_VAR_AC_PARAM, 2138c2ecf20Sopenharmony_ci (&e_aci)); 2148c2ecf20Sopenharmony_ci break; 2158c2ecf20Sopenharmony_ci } 2168c2ecf20Sopenharmony_ci case HW_VAR_ACK_PREAMBLE: { 2178c2ecf20Sopenharmony_ci u8 reg_tmp; 2188c2ecf20Sopenharmony_ci u8 short_preamble = (bool) (*val); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci reg_tmp = (mac->cur_40_prime_sc) << 5; 2218c2ecf20Sopenharmony_ci if (short_preamble) 2228c2ecf20Sopenharmony_ci reg_tmp |= 0x80; 2238c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); 2248c2ecf20Sopenharmony_ci break; 2258c2ecf20Sopenharmony_ci } 2268c2ecf20Sopenharmony_ci case HW_VAR_AMPDU_MIN_SPACE: { 2278c2ecf20Sopenharmony_ci u8 min_spacing_to_set; 2288c2ecf20Sopenharmony_ci u8 sec_min_space; 2298c2ecf20Sopenharmony_ci 2308c2ecf20Sopenharmony_ci min_spacing_to_set = *val; 2318c2ecf20Sopenharmony_ci if (min_spacing_to_set <= 7) { 2328c2ecf20Sopenharmony_ci sec_min_space = 0; 2338c2ecf20Sopenharmony_ci if (min_spacing_to_set < sec_min_space) 2348c2ecf20Sopenharmony_ci min_spacing_to_set = sec_min_space; 2358c2ecf20Sopenharmony_ci mac->min_space_cfg = ((mac->min_space_cfg & 0xf8) | 2368c2ecf20Sopenharmony_ci min_spacing_to_set); 2378c2ecf20Sopenharmony_ci *val = min_spacing_to_set; 2388c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 2398c2ecf20Sopenharmony_ci "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", 2408c2ecf20Sopenharmony_ci mac->min_space_cfg); 2418c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 2428c2ecf20Sopenharmony_ci mac->min_space_cfg); 2438c2ecf20Sopenharmony_ci } 2448c2ecf20Sopenharmony_ci break; 2458c2ecf20Sopenharmony_ci } 2468c2ecf20Sopenharmony_ci case HW_VAR_SHORTGI_DENSITY: { 2478c2ecf20Sopenharmony_ci u8 density_to_set; 2488c2ecf20Sopenharmony_ci 2498c2ecf20Sopenharmony_ci density_to_set = *val; 2508c2ecf20Sopenharmony_ci mac->min_space_cfg = rtlpriv->rtlhal.minspace_cfg; 2518c2ecf20Sopenharmony_ci mac->min_space_cfg |= (density_to_set << 3); 2528c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 2538c2ecf20Sopenharmony_ci "Set HW_VAR_SHORTGI_DENSITY: %#x\n", 2548c2ecf20Sopenharmony_ci mac->min_space_cfg); 2558c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 2568c2ecf20Sopenharmony_ci mac->min_space_cfg); 2578c2ecf20Sopenharmony_ci break; 2588c2ecf20Sopenharmony_ci } 2598c2ecf20Sopenharmony_ci case HW_VAR_AMPDU_FACTOR: { 2608c2ecf20Sopenharmony_ci u8 factor_toset; 2618c2ecf20Sopenharmony_ci u32 regtoset; 2628c2ecf20Sopenharmony_ci u8 *ptmp_byte = NULL; 2638c2ecf20Sopenharmony_ci u8 index; 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci if (rtlhal->macphymode == DUALMAC_DUALPHY) 2668c2ecf20Sopenharmony_ci regtoset = 0xb9726641; 2678c2ecf20Sopenharmony_ci else if (rtlhal->macphymode == DUALMAC_SINGLEPHY) 2688c2ecf20Sopenharmony_ci regtoset = 0x66626641; 2698c2ecf20Sopenharmony_ci else 2708c2ecf20Sopenharmony_ci regtoset = 0xb972a841; 2718c2ecf20Sopenharmony_ci factor_toset = *val; 2728c2ecf20Sopenharmony_ci if (factor_toset <= 3) { 2738c2ecf20Sopenharmony_ci factor_toset = (1 << (factor_toset + 2)); 2748c2ecf20Sopenharmony_ci if (factor_toset > 0xf) 2758c2ecf20Sopenharmony_ci factor_toset = 0xf; 2768c2ecf20Sopenharmony_ci for (index = 0; index < 4; index++) { 2778c2ecf20Sopenharmony_ci ptmp_byte = (u8 *)(®toset) + index; 2788c2ecf20Sopenharmony_ci if ((*ptmp_byte & 0xf0) > 2798c2ecf20Sopenharmony_ci (factor_toset << 4)) 2808c2ecf20Sopenharmony_ci *ptmp_byte = (*ptmp_byte & 0x0f) 2818c2ecf20Sopenharmony_ci | (factor_toset << 4); 2828c2ecf20Sopenharmony_ci if ((*ptmp_byte & 0x0f) > factor_toset) 2838c2ecf20Sopenharmony_ci *ptmp_byte = (*ptmp_byte & 0xf0) 2848c2ecf20Sopenharmony_ci | (factor_toset); 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, regtoset); 2878c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 2888c2ecf20Sopenharmony_ci "Set HW_VAR_AMPDU_FACTOR: %#x\n", 2898c2ecf20Sopenharmony_ci factor_toset); 2908c2ecf20Sopenharmony_ci } 2918c2ecf20Sopenharmony_ci break; 2928c2ecf20Sopenharmony_ci } 2938c2ecf20Sopenharmony_ci case HW_VAR_AC_PARAM: { 2948c2ecf20Sopenharmony_ci u8 e_aci = *val; 2958c2ecf20Sopenharmony_ci rtl92d_dm_init_edca_turbo(hw); 2968c2ecf20Sopenharmony_ci if (rtlpci->acm_method != EACMWAY2_SW) 2978c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ACM_CTRL, 2988c2ecf20Sopenharmony_ci &e_aci); 2998c2ecf20Sopenharmony_ci break; 3008c2ecf20Sopenharmony_ci } 3018c2ecf20Sopenharmony_ci case HW_VAR_ACM_CTRL: { 3028c2ecf20Sopenharmony_ci u8 e_aci = *val; 3038c2ecf20Sopenharmony_ci union aci_aifsn *p_aci_aifsn = 3048c2ecf20Sopenharmony_ci (union aci_aifsn *)(&(mac->ac[0].aifs)); 3058c2ecf20Sopenharmony_ci u8 acm = p_aci_aifsn->f.acm; 3068c2ecf20Sopenharmony_ci u8 acm_ctrl = rtl_read_byte(rtlpriv, REG_ACMHWCTRL); 3078c2ecf20Sopenharmony_ci 3088c2ecf20Sopenharmony_ci acm_ctrl = acm_ctrl | ((rtlpci->acm_method == 2) ? 0x0 : 0x1); 3098c2ecf20Sopenharmony_ci if (acm) { 3108c2ecf20Sopenharmony_ci switch (e_aci) { 3118c2ecf20Sopenharmony_ci case AC0_BE: 3128c2ecf20Sopenharmony_ci acm_ctrl |= ACMHW_BEQEN; 3138c2ecf20Sopenharmony_ci break; 3148c2ecf20Sopenharmony_ci case AC2_VI: 3158c2ecf20Sopenharmony_ci acm_ctrl |= ACMHW_VIQEN; 3168c2ecf20Sopenharmony_ci break; 3178c2ecf20Sopenharmony_ci case AC3_VO: 3188c2ecf20Sopenharmony_ci acm_ctrl |= ACMHW_VOQEN; 3198c2ecf20Sopenharmony_ci break; 3208c2ecf20Sopenharmony_ci default: 3218c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 3228c2ecf20Sopenharmony_ci "HW_VAR_ACM_CTRL acm set failed: eACI is %d\n", 3238c2ecf20Sopenharmony_ci acm); 3248c2ecf20Sopenharmony_ci break; 3258c2ecf20Sopenharmony_ci } 3268c2ecf20Sopenharmony_ci } else { 3278c2ecf20Sopenharmony_ci switch (e_aci) { 3288c2ecf20Sopenharmony_ci case AC0_BE: 3298c2ecf20Sopenharmony_ci acm_ctrl &= (~ACMHW_BEQEN); 3308c2ecf20Sopenharmony_ci break; 3318c2ecf20Sopenharmony_ci case AC2_VI: 3328c2ecf20Sopenharmony_ci acm_ctrl &= (~ACMHW_VIQEN); 3338c2ecf20Sopenharmony_ci break; 3348c2ecf20Sopenharmony_ci case AC3_VO: 3358c2ecf20Sopenharmony_ci acm_ctrl &= (~ACMHW_VOQEN); 3368c2ecf20Sopenharmony_ci break; 3378c2ecf20Sopenharmony_ci default: 3388c2ecf20Sopenharmony_ci pr_err("switch case %#x not processed\n", 3398c2ecf20Sopenharmony_ci e_aci); 3408c2ecf20Sopenharmony_ci break; 3418c2ecf20Sopenharmony_ci } 3428c2ecf20Sopenharmony_ci } 3438c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_QOS, DBG_TRACE, 3448c2ecf20Sopenharmony_ci "SetHwReg8190pci(): [HW_VAR_ACM_CTRL] Write 0x%X\n", 3458c2ecf20Sopenharmony_ci acm_ctrl); 3468c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_ACMHWCTRL, acm_ctrl); 3478c2ecf20Sopenharmony_ci break; 3488c2ecf20Sopenharmony_ci } 3498c2ecf20Sopenharmony_ci case HW_VAR_RCR: 3508c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); 3518c2ecf20Sopenharmony_ci rtlpci->receive_config = ((u32 *) (val))[0]; 3528c2ecf20Sopenharmony_ci break; 3538c2ecf20Sopenharmony_ci case HW_VAR_RETRY_LIMIT: { 3548c2ecf20Sopenharmony_ci u8 retry_limit = val[0]; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_RL, 3578c2ecf20Sopenharmony_ci retry_limit << RETRY_LIMIT_SHORT_SHIFT | 3588c2ecf20Sopenharmony_ci retry_limit << RETRY_LIMIT_LONG_SHIFT); 3598c2ecf20Sopenharmony_ci break; 3608c2ecf20Sopenharmony_ci } 3618c2ecf20Sopenharmony_ci case HW_VAR_DUAL_TSF_RST: 3628c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); 3638c2ecf20Sopenharmony_ci break; 3648c2ecf20Sopenharmony_ci case HW_VAR_EFUSE_BYTES: 3658c2ecf20Sopenharmony_ci rtlefuse->efuse_usedbytes = *((u16 *) val); 3668c2ecf20Sopenharmony_ci break; 3678c2ecf20Sopenharmony_ci case HW_VAR_EFUSE_USAGE: 3688c2ecf20Sopenharmony_ci rtlefuse->efuse_usedpercentage = *val; 3698c2ecf20Sopenharmony_ci break; 3708c2ecf20Sopenharmony_ci case HW_VAR_IO_CMD: 3718c2ecf20Sopenharmony_ci rtl92d_phy_set_io_cmd(hw, (*(enum io_type *)val)); 3728c2ecf20Sopenharmony_ci break; 3738c2ecf20Sopenharmony_ci case HW_VAR_WPA_CONFIG: 3748c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SECCFG, *val); 3758c2ecf20Sopenharmony_ci break; 3768c2ecf20Sopenharmony_ci case HW_VAR_SET_RPWM: 3778c2ecf20Sopenharmony_ci rtl92d_fill_h2c_cmd(hw, H2C_PWRM, 1, (val)); 3788c2ecf20Sopenharmony_ci break; 3798c2ecf20Sopenharmony_ci case HW_VAR_H2C_FW_PWRMODE: 3808c2ecf20Sopenharmony_ci break; 3818c2ecf20Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: 3828c2ecf20Sopenharmony_ci ppsc->fw_current_inpsmode = *((bool *) val); 3838c2ecf20Sopenharmony_ci break; 3848c2ecf20Sopenharmony_ci case HW_VAR_H2C_FW_JOINBSSRPT: { 3858c2ecf20Sopenharmony_ci u8 mstatus = (*val); 3868c2ecf20Sopenharmony_ci u8 tmp_regcr, tmp_reg422; 3878c2ecf20Sopenharmony_ci bool recover = false; 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci if (mstatus == RT_MEDIA_CONNECT) { 3908c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 3918c2ecf20Sopenharmony_ci HW_VAR_AID, NULL); 3928c2ecf20Sopenharmony_ci tmp_regcr = rtl_read_byte(rtlpriv, REG_CR + 1); 3938c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, 3948c2ecf20Sopenharmony_ci (tmp_regcr | BIT(0))); 3958c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(3)); 3968c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0); 3978c2ecf20Sopenharmony_ci tmp_reg422 = rtl_read_byte(rtlpriv, 3988c2ecf20Sopenharmony_ci REG_FWHW_TXQ_CTRL + 2); 3998c2ecf20Sopenharmony_ci if (tmp_reg422 & BIT(6)) 4008c2ecf20Sopenharmony_ci recover = true; 4018c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, 4028c2ecf20Sopenharmony_ci tmp_reg422 & (~BIT(6))); 4038c2ecf20Sopenharmony_ci rtl92d_set_fw_rsvdpagepkt(hw, 0); 4048c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, BIT(3), 0); 4058c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4)); 4068c2ecf20Sopenharmony_ci if (recover) 4078c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 4088c2ecf20Sopenharmony_ci REG_FWHW_TXQ_CTRL + 2, 4098c2ecf20Sopenharmony_ci tmp_reg422); 4108c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, 4118c2ecf20Sopenharmony_ci (tmp_regcr & ~(BIT(0)))); 4128c2ecf20Sopenharmony_ci } 4138c2ecf20Sopenharmony_ci rtl92d_set_fw_joinbss_report_cmd(hw, (*val)); 4148c2ecf20Sopenharmony_ci break; 4158c2ecf20Sopenharmony_ci } 4168c2ecf20Sopenharmony_ci case HW_VAR_AID: { 4178c2ecf20Sopenharmony_ci u16 u2btmp; 4188c2ecf20Sopenharmony_ci u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); 4198c2ecf20Sopenharmony_ci u2btmp &= 0xC000; 4208c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, (u2btmp | 4218c2ecf20Sopenharmony_ci mac->assoc_id)); 4228c2ecf20Sopenharmony_ci break; 4238c2ecf20Sopenharmony_ci } 4248c2ecf20Sopenharmony_ci case HW_VAR_CORRECT_TSF: { 4258c2ecf20Sopenharmony_ci u8 btype_ibss = val[0]; 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci if (btype_ibss) 4288c2ecf20Sopenharmony_ci _rtl92de_stop_tx_beacon(hw); 4298c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(3)); 4308c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTR, 4318c2ecf20Sopenharmony_ci (u32) (mac->tsf & 0xffffffff)); 4328c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTR + 4, 4338c2ecf20Sopenharmony_ci (u32) ((mac->tsf >> 32) & 0xffffffff)); 4348c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, BIT(3), 0); 4358c2ecf20Sopenharmony_ci if (btype_ibss) 4368c2ecf20Sopenharmony_ci _rtl92de_resume_tx_beacon(hw); 4378c2ecf20Sopenharmony_ci 4388c2ecf20Sopenharmony_ci break; 4398c2ecf20Sopenharmony_ci } 4408c2ecf20Sopenharmony_ci case HW_VAR_INT_MIGRATION: { 4418c2ecf20Sopenharmony_ci bool int_migration = *(bool *) (val); 4428c2ecf20Sopenharmony_ci 4438c2ecf20Sopenharmony_ci if (int_migration) { 4448c2ecf20Sopenharmony_ci /* Set interrupt migration timer and 4458c2ecf20Sopenharmony_ci * corresponding Tx/Rx counter. 4468c2ecf20Sopenharmony_ci * timer 25ns*0xfa0=100us for 0xf packets. 4478c2ecf20Sopenharmony_ci * 0x306:Rx, 0x307:Tx */ 4488c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_INT_MIG, 0xfe000fa0); 4498c2ecf20Sopenharmony_ci rtlpriv->dm.interrupt_migration = int_migration; 4508c2ecf20Sopenharmony_ci } else { 4518c2ecf20Sopenharmony_ci /* Reset all interrupt migration settings. */ 4528c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_INT_MIG, 0); 4538c2ecf20Sopenharmony_ci rtlpriv->dm.interrupt_migration = int_migration; 4548c2ecf20Sopenharmony_ci } 4558c2ecf20Sopenharmony_ci break; 4568c2ecf20Sopenharmony_ci } 4578c2ecf20Sopenharmony_ci case HW_VAR_INT_AC: { 4588c2ecf20Sopenharmony_ci bool disable_ac_int = *((bool *) val); 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_ci /* Disable four ACs interrupts. */ 4618c2ecf20Sopenharmony_ci if (disable_ac_int) { 4628c2ecf20Sopenharmony_ci /* Disable VO, VI, BE and BK four AC interrupts 4638c2ecf20Sopenharmony_ci * to gain more efficient CPU utilization. 4648c2ecf20Sopenharmony_ci * When extremely highly Rx OK occurs, 4658c2ecf20Sopenharmony_ci * we will disable Tx interrupts. 4668c2ecf20Sopenharmony_ci */ 4678c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->update_interrupt_mask(hw, 0, 4688c2ecf20Sopenharmony_ci RT_AC_INT_MASKS); 4698c2ecf20Sopenharmony_ci rtlpriv->dm.disable_tx_int = disable_ac_int; 4708c2ecf20Sopenharmony_ci /* Enable four ACs interrupts. */ 4718c2ecf20Sopenharmony_ci } else { 4728c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->update_interrupt_mask(hw, 4738c2ecf20Sopenharmony_ci RT_AC_INT_MASKS, 0); 4748c2ecf20Sopenharmony_ci rtlpriv->dm.disable_tx_int = disable_ac_int; 4758c2ecf20Sopenharmony_ci } 4768c2ecf20Sopenharmony_ci break; 4778c2ecf20Sopenharmony_ci } 4788c2ecf20Sopenharmony_ci default: 4798c2ecf20Sopenharmony_ci pr_err("switch case %#x not processed\n", variable); 4808c2ecf20Sopenharmony_ci break; 4818c2ecf20Sopenharmony_ci } 4828c2ecf20Sopenharmony_ci} 4838c2ecf20Sopenharmony_ci 4848c2ecf20Sopenharmony_cistatic bool _rtl92de_llt_write(struct ieee80211_hw *hw, u32 address, u32 data) 4858c2ecf20Sopenharmony_ci{ 4868c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4878c2ecf20Sopenharmony_ci bool status = true; 4888c2ecf20Sopenharmony_ci long count = 0; 4898c2ecf20Sopenharmony_ci u32 value = _LLT_INIT_ADDR(address) | 4908c2ecf20Sopenharmony_ci _LLT_INIT_DATA(data) | _LLT_OP(_LLT_WRITE_ACCESS); 4918c2ecf20Sopenharmony_ci 4928c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_LLT_INIT, value); 4938c2ecf20Sopenharmony_ci do { 4948c2ecf20Sopenharmony_ci value = rtl_read_dword(rtlpriv, REG_LLT_INIT); 4958c2ecf20Sopenharmony_ci if (_LLT_NO_ACTIVE == _LLT_OP_VALUE(value)) 4968c2ecf20Sopenharmony_ci break; 4978c2ecf20Sopenharmony_ci if (count > POLLING_LLT_THRESHOLD) { 4988c2ecf20Sopenharmony_ci pr_err("Failed to polling write LLT done at address %d!\n", 4998c2ecf20Sopenharmony_ci address); 5008c2ecf20Sopenharmony_ci status = false; 5018c2ecf20Sopenharmony_ci break; 5028c2ecf20Sopenharmony_ci } 5038c2ecf20Sopenharmony_ci } while (++count); 5048c2ecf20Sopenharmony_ci return status; 5058c2ecf20Sopenharmony_ci} 5068c2ecf20Sopenharmony_ci 5078c2ecf20Sopenharmony_cistatic bool _rtl92de_llt_table_init(struct ieee80211_hw *hw) 5088c2ecf20Sopenharmony_ci{ 5098c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5108c2ecf20Sopenharmony_ci unsigned short i; 5118c2ecf20Sopenharmony_ci u8 txpktbuf_bndy; 5128c2ecf20Sopenharmony_ci u8 maxpage; 5138c2ecf20Sopenharmony_ci bool status; 5148c2ecf20Sopenharmony_ci u32 value32; /* High+low page number */ 5158c2ecf20Sopenharmony_ci u8 value8; /* normal page number */ 5168c2ecf20Sopenharmony_ci 5178c2ecf20Sopenharmony_ci if (rtlpriv->rtlhal.macphymode == SINGLEMAC_SINGLEPHY) { 5188c2ecf20Sopenharmony_ci maxpage = 255; 5198c2ecf20Sopenharmony_ci txpktbuf_bndy = 246; 5208c2ecf20Sopenharmony_ci value8 = 0; 5218c2ecf20Sopenharmony_ci value32 = 0x80bf0d29; 5228c2ecf20Sopenharmony_ci } else { 5238c2ecf20Sopenharmony_ci maxpage = 127; 5248c2ecf20Sopenharmony_ci txpktbuf_bndy = 123; 5258c2ecf20Sopenharmony_ci value8 = 0; 5268c2ecf20Sopenharmony_ci value32 = 0x80750005; 5278c2ecf20Sopenharmony_ci } 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_ci /* Set reserved page for each queue */ 5308c2ecf20Sopenharmony_ci /* 11. RQPN 0x200[31:0] = 0x80BD1C1C */ 5318c2ecf20Sopenharmony_ci /* load RQPN */ 5328c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); 5338c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RQPN, value32); 5348c2ecf20Sopenharmony_ci 5358c2ecf20Sopenharmony_ci /* 12. TXRKTBUG_PG_BNDY 0x114[31:0] = 0x27FF00F6 */ 5368c2ecf20Sopenharmony_ci /* TXRKTBUG_PG_BNDY */ 5378c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TRXFF_BNDY, 5388c2ecf20Sopenharmony_ci (rtl_read_word(rtlpriv, REG_TRXFF_BNDY + 2) << 16 | 5398c2ecf20Sopenharmony_ci txpktbuf_bndy)); 5408c2ecf20Sopenharmony_ci 5418c2ecf20Sopenharmony_ci /* 13. TDECTRL[15:8] 0x209[7:0] = 0xF6 */ 5428c2ecf20Sopenharmony_ci /* Beacon Head for TXDMA */ 5438c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TDECTRL + 1, txpktbuf_bndy); 5448c2ecf20Sopenharmony_ci 5458c2ecf20Sopenharmony_ci /* 14. BCNQ_PGBNDY 0x424[7:0] = 0xF6 */ 5468c2ecf20Sopenharmony_ci /* BCNQ_PGBNDY */ 5478c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); 5488c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); 5498c2ecf20Sopenharmony_ci 5508c2ecf20Sopenharmony_ci /* 15. WMAC_LBK_BF_HD 0x45D[7:0] = 0xF6 */ 5518c2ecf20Sopenharmony_ci /* WMAC_LBK_BF_HD */ 5528c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x45D, txpktbuf_bndy); 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_ci /* Set Tx/Rx page size (Tx must be 128 Bytes, */ 5558c2ecf20Sopenharmony_ci /* Rx can be 64,128,256,512,1024 bytes) */ 5568c2ecf20Sopenharmony_ci /* 16. PBP [7:0] = 0x11 */ 5578c2ecf20Sopenharmony_ci /* TRX page size */ 5588c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PBP, 0x11); 5598c2ecf20Sopenharmony_ci 5608c2ecf20Sopenharmony_ci /* 17. DRV_INFO_SZ = 0x04 */ 5618c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RX_DRVINFO_SZ, 0x4); 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_ci /* 18. LLT_table_init(Adapter); */ 5648c2ecf20Sopenharmony_ci for (i = 0; i < (txpktbuf_bndy - 1); i++) { 5658c2ecf20Sopenharmony_ci status = _rtl92de_llt_write(hw, i, i + 1); 5668c2ecf20Sopenharmony_ci if (!status) 5678c2ecf20Sopenharmony_ci return status; 5688c2ecf20Sopenharmony_ci } 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_ci /* end of list */ 5718c2ecf20Sopenharmony_ci status = _rtl92de_llt_write(hw, (txpktbuf_bndy - 1), 0xFF); 5728c2ecf20Sopenharmony_ci if (!status) 5738c2ecf20Sopenharmony_ci return status; 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci /* Make the other pages as ring buffer */ 5768c2ecf20Sopenharmony_ci /* This ring buffer is used as beacon buffer if we */ 5778c2ecf20Sopenharmony_ci /* config this MAC as two MAC transfer. */ 5788c2ecf20Sopenharmony_ci /* Otherwise used as local loopback buffer. */ 5798c2ecf20Sopenharmony_ci for (i = txpktbuf_bndy; i < maxpage; i++) { 5808c2ecf20Sopenharmony_ci status = _rtl92de_llt_write(hw, i, (i + 1)); 5818c2ecf20Sopenharmony_ci if (!status) 5828c2ecf20Sopenharmony_ci return status; 5838c2ecf20Sopenharmony_ci } 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci /* Let last entry point to the start entry of ring buffer */ 5868c2ecf20Sopenharmony_ci status = _rtl92de_llt_write(hw, maxpage, txpktbuf_bndy); 5878c2ecf20Sopenharmony_ci if (!status) 5888c2ecf20Sopenharmony_ci return status; 5898c2ecf20Sopenharmony_ci 5908c2ecf20Sopenharmony_ci return true; 5918c2ecf20Sopenharmony_ci} 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_cistatic void _rtl92de_gen_refresh_led_state(struct ieee80211_hw *hw) 5948c2ecf20Sopenharmony_ci{ 5958c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5968c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 5978c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 5988c2ecf20Sopenharmony_ci struct rtl_led *pled0 = &rtlpriv->ledctl.sw_led0; 5998c2ecf20Sopenharmony_ci 6008c2ecf20Sopenharmony_ci if (rtlpci->up_first_time) 6018c2ecf20Sopenharmony_ci return; 6028c2ecf20Sopenharmony_ci if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) 6038c2ecf20Sopenharmony_ci rtl92de_sw_led_on(hw, pled0); 6048c2ecf20Sopenharmony_ci else if (ppsc->rfoff_reason == RF_CHANGE_BY_INIT) 6058c2ecf20Sopenharmony_ci rtl92de_sw_led_on(hw, pled0); 6068c2ecf20Sopenharmony_ci else 6078c2ecf20Sopenharmony_ci rtl92de_sw_led_off(hw, pled0); 6088c2ecf20Sopenharmony_ci} 6098c2ecf20Sopenharmony_ci 6108c2ecf20Sopenharmony_cistatic bool _rtl92de_init_mac(struct ieee80211_hw *hw) 6118c2ecf20Sopenharmony_ci{ 6128c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6138c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 6148c2ecf20Sopenharmony_ci unsigned char bytetmp; 6158c2ecf20Sopenharmony_ci unsigned short wordtmp; 6168c2ecf20Sopenharmony_ci u16 retry; 6178c2ecf20Sopenharmony_ci 6188c2ecf20Sopenharmony_ci rtl92d_phy_set_poweron(hw); 6198c2ecf20Sopenharmony_ci /* Add for resume sequence of power domain according 6208c2ecf20Sopenharmony_ci * to power document V11. Chapter V.11.... */ 6218c2ecf20Sopenharmony_ci /* 0. RSV_CTRL 0x1C[7:0] = 0x00 */ 6228c2ecf20Sopenharmony_ci /* unlock ISO/CLK/Power control register */ 6238c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x00); 6248c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x05); 6258c2ecf20Sopenharmony_ci 6268c2ecf20Sopenharmony_ci /* 1. AFE_XTAL_CTRL [7:0] = 0x0F enable XTAL */ 6278c2ecf20Sopenharmony_ci /* 2. SPS0_CTRL 0x11[7:0] = 0x2b enable SPS into PWM mode */ 6288c2ecf20Sopenharmony_ci /* 3. delay (1ms) this is not necessary when initially power on */ 6298c2ecf20Sopenharmony_ci 6308c2ecf20Sopenharmony_ci /* C. Resume Sequence */ 6318c2ecf20Sopenharmony_ci /* a. SPS0_CTRL 0x11[7:0] = 0x2b */ 6328c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); 6338c2ecf20Sopenharmony_ci 6348c2ecf20Sopenharmony_ci /* b. AFE_XTAL_CTRL [7:0] = 0x0F */ 6358c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0F); 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_ci /* c. DRV runs power on init flow */ 6388c2ecf20Sopenharmony_ci 6398c2ecf20Sopenharmony_ci /* auto enable WLAN */ 6408c2ecf20Sopenharmony_ci /* 4. APS_FSMCO 0x04[8] = 1; wait till 0x04[8] = 0 */ 6418c2ecf20Sopenharmony_ci /* Power On Reset for MAC Block */ 6428c2ecf20Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1) | BIT(0); 6438c2ecf20Sopenharmony_ci udelay(2); 6448c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, bytetmp); 6458c2ecf20Sopenharmony_ci udelay(2); 6468c2ecf20Sopenharmony_ci 6478c2ecf20Sopenharmony_ci /* 5. Wait while 0x04[8] == 0 goto 2, otherwise goto 1 */ 6488c2ecf20Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); 6498c2ecf20Sopenharmony_ci udelay(50); 6508c2ecf20Sopenharmony_ci retry = 0; 6518c2ecf20Sopenharmony_ci while ((bytetmp & BIT(0)) && retry < 1000) { 6528c2ecf20Sopenharmony_ci retry++; 6538c2ecf20Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_APS_FSMCO + 1); 6548c2ecf20Sopenharmony_ci udelay(50); 6558c2ecf20Sopenharmony_ci } 6568c2ecf20Sopenharmony_ci 6578c2ecf20Sopenharmony_ci /* Enable Radio off, GPIO, and LED function */ 6588c2ecf20Sopenharmony_ci /* 6. APS_FSMCO 0x04[15:0] = 0x0012 when enable HWPDN */ 6598c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x1012); 6608c2ecf20Sopenharmony_ci 6618c2ecf20Sopenharmony_ci /* release RF digital isolation */ 6628c2ecf20Sopenharmony_ci /* 7. SYS_ISO_CTRL 0x01[1] = 0x0; */ 6638c2ecf20Sopenharmony_ci /*Set REG_SYS_ISO_CTRL 0x1=0x82 to prevent wake# problem. */ 6648c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL + 1, 0x82); 6658c2ecf20Sopenharmony_ci udelay(2); 6668c2ecf20Sopenharmony_ci 6678c2ecf20Sopenharmony_ci /* make sure that BB reset OK. */ 6688c2ecf20Sopenharmony_ci /* rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); */ 6698c2ecf20Sopenharmony_ci 6708c2ecf20Sopenharmony_ci /* Disable REG_CR before enable it to assure reset */ 6718c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_CR, 0x0); 6728c2ecf20Sopenharmony_ci 6738c2ecf20Sopenharmony_ci /* Release MAC IO register reset */ 6748c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_CR, 0x2ff); 6758c2ecf20Sopenharmony_ci 6768c2ecf20Sopenharmony_ci /* clear stopping tx/rx dma */ 6778c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0x0); 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci /* rtl_write_word(rtlpriv,REG_CR+2, 0x2); */ 6808c2ecf20Sopenharmony_ci 6818c2ecf20Sopenharmony_ci /* System init */ 6828c2ecf20Sopenharmony_ci /* 18. LLT_table_init(Adapter); */ 6838c2ecf20Sopenharmony_ci if (!_rtl92de_llt_table_init(hw)) 6848c2ecf20Sopenharmony_ci return false; 6858c2ecf20Sopenharmony_ci 6868c2ecf20Sopenharmony_ci /* Clear interrupt and enable interrupt */ 6878c2ecf20Sopenharmony_ci /* 19. HISR 0x124[31:0] = 0xffffffff; */ 6888c2ecf20Sopenharmony_ci /* HISRE 0x12C[7:0] = 0xFF */ 6898c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HISR, 0xffffffff); 6908c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_HISRE, 0xff); 6918c2ecf20Sopenharmony_ci 6928c2ecf20Sopenharmony_ci /* 20. HIMR 0x120[31:0] |= [enable INT mask bit map]; */ 6938c2ecf20Sopenharmony_ci /* 21. HIMRE 0x128[7:0] = [enable INT mask bit map] */ 6948c2ecf20Sopenharmony_ci /* The IMR should be enabled later after all init sequence 6958c2ecf20Sopenharmony_ci * is finished. */ 6968c2ecf20Sopenharmony_ci 6978c2ecf20Sopenharmony_ci /* 22. PCIE configuration space configuration */ 6988c2ecf20Sopenharmony_ci /* 23. Ensure PCIe Device 0x80[15:0] = 0x0143 (ASPM+CLKREQ), */ 6998c2ecf20Sopenharmony_ci /* and PCIe gated clock function is enabled. */ 7008c2ecf20Sopenharmony_ci /* PCIE configuration space will be written after 7018c2ecf20Sopenharmony_ci * all init sequence.(Or by BIOS) */ 7028c2ecf20Sopenharmony_ci 7038c2ecf20Sopenharmony_ci rtl92d_phy_config_maccoexist_rfpage(hw); 7048c2ecf20Sopenharmony_ci 7058c2ecf20Sopenharmony_ci /* THe below section is not related to power document Vxx . */ 7068c2ecf20Sopenharmony_ci /* This is only useful for driver and OS setting. */ 7078c2ecf20Sopenharmony_ci /* -------------------Software Relative Setting---------------------- */ 7088c2ecf20Sopenharmony_ci wordtmp = rtl_read_word(rtlpriv, REG_TRXDMA_CTRL); 7098c2ecf20Sopenharmony_ci wordtmp &= 0xf; 7108c2ecf20Sopenharmony_ci wordtmp |= 0xF771; 7118c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, wordtmp); 7128c2ecf20Sopenharmony_ci 7138c2ecf20Sopenharmony_ci /* Reported Tx status from HW for rate adaptive. */ 7148c2ecf20Sopenharmony_ci /* This should be realtive to power on step 14. But in document V11 */ 7158c2ecf20Sopenharmony_ci /* still not contain the description.!!! */ 7168c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 1, 0x1F); 7178c2ecf20Sopenharmony_ci 7188c2ecf20Sopenharmony_ci /* Set Tx/Rx page size (Tx must be 128 Bytes, 7198c2ecf20Sopenharmony_ci * Rx can be 64,128,256,512,1024 bytes) */ 7208c2ecf20Sopenharmony_ci /* rtl_write_byte(rtlpriv,REG_PBP, 0x11); */ 7218c2ecf20Sopenharmony_ci 7228c2ecf20Sopenharmony_ci /* Set RCR register */ 7238c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RCR, rtlpci->receive_config); 7248c2ecf20Sopenharmony_ci /* rtl_write_byte(rtlpriv,REG_RX_DRVINFO_SZ, 4); */ 7258c2ecf20Sopenharmony_ci 7268c2ecf20Sopenharmony_ci /* Set TCR register */ 7278c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TCR, rtlpci->transmit_config); 7288c2ecf20Sopenharmony_ci 7298c2ecf20Sopenharmony_ci /* disable earlymode */ 7308c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x4d0, 0x0); 7318c2ecf20Sopenharmony_ci 7328c2ecf20Sopenharmony_ci /* Set TX/RX descriptor physical address(from OS API). */ 7338c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BCNQ_DESA, 7348c2ecf20Sopenharmony_ci rtlpci->tx_ring[BEACON_QUEUE].dma); 7358c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MGQ_DESA, rtlpci->tx_ring[MGNT_QUEUE].dma); 7368c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_VOQ_DESA, rtlpci->tx_ring[VO_QUEUE].dma); 7378c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_VIQ_DESA, rtlpci->tx_ring[VI_QUEUE].dma); 7388c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BEQ_DESA, rtlpci->tx_ring[BE_QUEUE].dma); 7398c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BKQ_DESA, rtlpci->tx_ring[BK_QUEUE].dma); 7408c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HQ_DESA, rtlpci->tx_ring[HIGH_QUEUE].dma); 7418c2ecf20Sopenharmony_ci /* Set RX Desc Address */ 7428c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RX_DESA, 7438c2ecf20Sopenharmony_ci rtlpci->rx_ring[RX_MPDU_QUEUE].dma); 7448c2ecf20Sopenharmony_ci 7458c2ecf20Sopenharmony_ci /* if we want to support 64 bit DMA, we should set it here, 7468c2ecf20Sopenharmony_ci * but now we do not support 64 bit DMA*/ 7478c2ecf20Sopenharmony_ci 7488c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 3, 0x33); 7498c2ecf20Sopenharmony_ci 7508c2ecf20Sopenharmony_ci /* Reset interrupt migration setting when initialization */ 7518c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_INT_MIG, 0); 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci /* Reconsider when to do this operation after asking HWSD. */ 7548c2ecf20Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); 7558c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, bytetmp & ~BIT(6)); 7568c2ecf20Sopenharmony_ci do { 7578c2ecf20Sopenharmony_ci retry++; 7588c2ecf20Sopenharmony_ci bytetmp = rtl_read_byte(rtlpriv, REG_APSD_CTRL); 7598c2ecf20Sopenharmony_ci } while ((retry < 200) && !(bytetmp & BIT(7))); 7608c2ecf20Sopenharmony_ci 7618c2ecf20Sopenharmony_ci /* After MACIO reset,we must refresh LED state. */ 7628c2ecf20Sopenharmony_ci _rtl92de_gen_refresh_led_state(hw); 7638c2ecf20Sopenharmony_ci 7648c2ecf20Sopenharmony_ci /* Reset H2C protection register */ 7658c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MCUTST_1, 0x0); 7668c2ecf20Sopenharmony_ci 7678c2ecf20Sopenharmony_ci return true; 7688c2ecf20Sopenharmony_ci} 7698c2ecf20Sopenharmony_ci 7708c2ecf20Sopenharmony_cistatic void _rtl92de_hw_configure(struct ieee80211_hw *hw) 7718c2ecf20Sopenharmony_ci{ 7728c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 7738c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7748c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 7758c2ecf20Sopenharmony_ci u8 reg_bw_opmode = BW_OPMODE_20MHZ; 7768c2ecf20Sopenharmony_ci u32 reg_rrsr; 7778c2ecf20Sopenharmony_ci 7788c2ecf20Sopenharmony_ci reg_rrsr = RATE_ALL_CCK | RATE_ALL_OFDM_AG; 7798c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 0x8); 7808c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode); 7818c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RRSR, reg_rrsr); 7828c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SLOT, 0x09); 7838c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 0x0); 7848c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_FWHW_TXQ_CTRL, 0x1F80); 7858c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_RL, 0x0707); 7868c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_BAR_MODE_CTRL, 0x02012802); 7878c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); 7888c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 0x01000000); 7898c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 0x07060504); 7908c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RARFRC, 0x01000000); 7918c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RARFRC + 4, 0x07060504); 7928c2ecf20Sopenharmony_ci /* Aggregation threshold */ 7938c2ecf20Sopenharmony_ci if (rtlhal->macphymode == DUALMAC_DUALPHY) 7948c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb9726641); 7958c2ecf20Sopenharmony_ci else if (rtlhal->macphymode == DUALMAC_SINGLEPHY) 7968c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0x66626641); 7978c2ecf20Sopenharmony_ci else 7988c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_AGGLEN_LMT, 0xb972a841); 7998c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_ATIMWND, 0x2); 8008c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_MAX_ERR, 0x0a); 8018c2ecf20Sopenharmony_ci rtlpci->reg_bcn_ctrl_val = 0x1f; 8028c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL, rtlpci->reg_bcn_ctrl_val); 8038c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); 8048c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PIFS, 0x1C); 8058c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AGGR_BREAK_TIME, 0x16); 8068c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_NAV_PROT_LEN, 0x0020); 8078c2ecf20Sopenharmony_ci /* For throughput */ 8088c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_FAST_EDCA_CTRL, 0x6666); 8098c2ecf20Sopenharmony_ci /* ACKTO for IOT issue. */ 8108c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_ACKTO, 0x40); 8118c2ecf20Sopenharmony_ci /* Set Spec SIFS (used in NAV) */ 8128c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SPEC_SIFS, 0x1010); 8138c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_MAC_SPEC_SIFS, 0x1010); 8148c2ecf20Sopenharmony_ci /* Set SIFS for CCK */ 8158c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SIFS_CTX, 0x1010); 8168c2ecf20Sopenharmony_ci /* Set SIFS for OFDM */ 8178c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SIFS_TRX, 0x1010); 8188c2ecf20Sopenharmony_ci /* Set Multicast Address. */ 8198c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MAR, 0xffffffff); 8208c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MAR + 4, 0xffffffff); 8218c2ecf20Sopenharmony_ci switch (rtlpriv->phy.rf_type) { 8228c2ecf20Sopenharmony_ci case RF_1T2R: 8238c2ecf20Sopenharmony_ci case RF_1T1R: 8248c2ecf20Sopenharmony_ci rtlhal->minspace_cfg = (MAX_MSS_DENSITY_1T << 3); 8258c2ecf20Sopenharmony_ci break; 8268c2ecf20Sopenharmony_ci case RF_2T2R: 8278c2ecf20Sopenharmony_ci case RF_2T2R_GREEN: 8288c2ecf20Sopenharmony_ci rtlhal->minspace_cfg = (MAX_MSS_DENSITY_2T << 3); 8298c2ecf20Sopenharmony_ci break; 8308c2ecf20Sopenharmony_ci } 8318c2ecf20Sopenharmony_ci} 8328c2ecf20Sopenharmony_ci 8338c2ecf20Sopenharmony_cistatic void _rtl92de_enable_aspm_back_door(struct ieee80211_hw *hw) 8348c2ecf20Sopenharmony_ci{ 8358c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8368c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 8378c2ecf20Sopenharmony_ci 8388c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x34b, 0x93); 8398c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, 0x350, 0x870c); 8408c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x352, 0x1); 8418c2ecf20Sopenharmony_ci if (ppsc->support_backdoor) 8428c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x349, 0x1b); 8438c2ecf20Sopenharmony_ci else 8448c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x349, 0x03); 8458c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, 0x350, 0x2718); 8468c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x352, 0x1); 8478c2ecf20Sopenharmony_ci} 8488c2ecf20Sopenharmony_ci 8498c2ecf20Sopenharmony_civoid rtl92de_enable_hw_security_config(struct ieee80211_hw *hw) 8508c2ecf20Sopenharmony_ci{ 8518c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8528c2ecf20Sopenharmony_ci u8 sec_reg_value; 8538c2ecf20Sopenharmony_ci 8548c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 8558c2ecf20Sopenharmony_ci "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", 8568c2ecf20Sopenharmony_ci rtlpriv->sec.pairwise_enc_algorithm, 8578c2ecf20Sopenharmony_ci rtlpriv->sec.group_enc_algorithm); 8588c2ecf20Sopenharmony_ci if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { 8598c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 8608c2ecf20Sopenharmony_ci "not open hw encryption\n"); 8618c2ecf20Sopenharmony_ci return; 8628c2ecf20Sopenharmony_ci } 8638c2ecf20Sopenharmony_ci sec_reg_value = SCR_TXENCENABLE | SCR_RXENCENABLE; 8648c2ecf20Sopenharmony_ci if (rtlpriv->sec.use_defaultkey) { 8658c2ecf20Sopenharmony_ci sec_reg_value |= SCR_TXUSEDK; 8668c2ecf20Sopenharmony_ci sec_reg_value |= SCR_RXUSEDK; 8678c2ecf20Sopenharmony_ci } 8688c2ecf20Sopenharmony_ci sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); 8698c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); 8708c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, 8718c2ecf20Sopenharmony_ci "The SECR-value %x\n", sec_reg_value); 8728c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); 8738c2ecf20Sopenharmony_ci} 8748c2ecf20Sopenharmony_ci 8758c2ecf20Sopenharmony_ciint rtl92de_hw_init(struct ieee80211_hw *hw) 8768c2ecf20Sopenharmony_ci{ 8778c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8788c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 8798c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 8808c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 8818c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 8828c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 8838c2ecf20Sopenharmony_ci bool rtstatus = true; 8848c2ecf20Sopenharmony_ci u8 tmp_u1b; 8858c2ecf20Sopenharmony_ci int i; 8868c2ecf20Sopenharmony_ci int err; 8878c2ecf20Sopenharmony_ci unsigned long flags; 8888c2ecf20Sopenharmony_ci 8898c2ecf20Sopenharmony_ci rtlpci->being_init_adapter = true; 8908c2ecf20Sopenharmony_ci rtlpci->init_ready = false; 8918c2ecf20Sopenharmony_ci spin_lock_irqsave(&globalmutex_for_power_and_efuse, flags); 8928c2ecf20Sopenharmony_ci /* we should do iqk after disable/enable */ 8938c2ecf20Sopenharmony_ci rtl92d_phy_reset_iqk_result(hw); 8948c2ecf20Sopenharmony_ci /* rtlpriv->intf_ops->disable_aspm(hw); */ 8958c2ecf20Sopenharmony_ci rtstatus = _rtl92de_init_mac(hw); 8968c2ecf20Sopenharmony_ci if (!rtstatus) { 8978c2ecf20Sopenharmony_ci pr_err("Init MAC failed\n"); 8988c2ecf20Sopenharmony_ci err = 1; 8998c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); 9008c2ecf20Sopenharmony_ci return err; 9018c2ecf20Sopenharmony_ci } 9028c2ecf20Sopenharmony_ci err = rtl92d_download_fw(hw); 9038c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&globalmutex_for_power_and_efuse, flags); 9048c2ecf20Sopenharmony_ci if (err) { 9058c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 9068c2ecf20Sopenharmony_ci "Failed to download FW. Init HW without FW..\n"); 9078c2ecf20Sopenharmony_ci return 1; 9088c2ecf20Sopenharmony_ci } 9098c2ecf20Sopenharmony_ci rtlhal->last_hmeboxnum = 0; 9108c2ecf20Sopenharmony_ci rtlpriv->psc.fw_current_inpsmode = false; 9118c2ecf20Sopenharmony_ci 9128c2ecf20Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, 0x605); 9138c2ecf20Sopenharmony_ci tmp_u1b = tmp_u1b | 0x30; 9148c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x605, tmp_u1b); 9158c2ecf20Sopenharmony_ci 9168c2ecf20Sopenharmony_ci if (rtlhal->earlymode_enable) { 9178c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 9188c2ecf20Sopenharmony_ci "EarlyMode Enabled!!!\n"); 9198c2ecf20Sopenharmony_ci 9208c2ecf20Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, 0x4d0); 9218c2ecf20Sopenharmony_ci tmp_u1b = tmp_u1b | 0x1f; 9228c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x4d0, tmp_u1b); 9238c2ecf20Sopenharmony_ci 9248c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x4d3, 0x80); 9258c2ecf20Sopenharmony_ci 9268c2ecf20Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, 0x605); 9278c2ecf20Sopenharmony_ci tmp_u1b = tmp_u1b | 0x40; 9288c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x605, tmp_u1b); 9298c2ecf20Sopenharmony_ci } 9308c2ecf20Sopenharmony_ci 9318c2ecf20Sopenharmony_ci if (mac->rdg_en) { 9328c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RD_CTRL, 0xff); 9338c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_RD_NAV_NXT, 0x200); 9348c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RD_RESP_PKT_TH, 0x05); 9358c2ecf20Sopenharmony_ci } 9368c2ecf20Sopenharmony_ci 9378c2ecf20Sopenharmony_ci rtl92d_phy_mac_config(hw); 9388c2ecf20Sopenharmony_ci /* because last function modify RCR, so we update 9398c2ecf20Sopenharmony_ci * rcr var here, or TP will unstable for receive_config 9408c2ecf20Sopenharmony_ci * is wrong, RX RCR_ACRC32 will cause TP unstabel & Rx 9418c2ecf20Sopenharmony_ci * RCR_APP_ICV will cause mac80211 unassoc for cisco 1252*/ 9428c2ecf20Sopenharmony_ci rtlpci->receive_config = rtl_read_dword(rtlpriv, REG_RCR); 9438c2ecf20Sopenharmony_ci rtlpci->receive_config &= ~(RCR_ACRC32 | RCR_AICV); 9448c2ecf20Sopenharmony_ci 9458c2ecf20Sopenharmony_ci rtl92d_phy_bb_config(hw); 9468c2ecf20Sopenharmony_ci 9478c2ecf20Sopenharmony_ci rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; 9488c2ecf20Sopenharmony_ci /* set before initialize RF */ 9498c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); 9508c2ecf20Sopenharmony_ci 9518c2ecf20Sopenharmony_ci /* config RF */ 9528c2ecf20Sopenharmony_ci rtl92d_phy_rf_config(hw); 9538c2ecf20Sopenharmony_ci 9548c2ecf20Sopenharmony_ci /* After read predefined TXT, we must set BB/MAC/RF 9558c2ecf20Sopenharmony_ci * register as our requirement */ 9568c2ecf20Sopenharmony_ci /* After load BB,RF params,we need do more for 92D. */ 9578c2ecf20Sopenharmony_ci rtl92d_update_bbrf_configuration(hw); 9588c2ecf20Sopenharmony_ci /* set default value after initialize RF, */ 9598c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0); 9608c2ecf20Sopenharmony_ci rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, 9618c2ecf20Sopenharmony_ci RF_CHNLBW, RFREG_OFFSET_MASK); 9628c2ecf20Sopenharmony_ci rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, 9638c2ecf20Sopenharmony_ci RF_CHNLBW, RFREG_OFFSET_MASK); 9648c2ecf20Sopenharmony_ci 9658c2ecf20Sopenharmony_ci /*---- Set CCK and OFDM Block "ON"----*/ 9668c2ecf20Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_2_4G) 9678c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BCCKEN, 0x1); 9688c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_RFMOD, BOFDMEN, 0x1); 9698c2ecf20Sopenharmony_ci if (rtlhal->interfaceindex == 0) { 9708c2ecf20Sopenharmony_ci /* RFPGA0_ANALOGPARAMETER2: cck clock select, 9718c2ecf20Sopenharmony_ci * set to 20MHz by default */ 9728c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10) | 9738c2ecf20Sopenharmony_ci BIT(11), 3); 9748c2ecf20Sopenharmony_ci } else { 9758c2ecf20Sopenharmony_ci /* Mac1 */ 9768c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(11) | 9778c2ecf20Sopenharmony_ci BIT(10), 3); 9788c2ecf20Sopenharmony_ci } 9798c2ecf20Sopenharmony_ci 9808c2ecf20Sopenharmony_ci _rtl92de_hw_configure(hw); 9818c2ecf20Sopenharmony_ci 9828c2ecf20Sopenharmony_ci /* reset hw sec */ 9838c2ecf20Sopenharmony_ci rtl_cam_reset_all_entry(hw); 9848c2ecf20Sopenharmony_ci rtl92de_enable_hw_security_config(hw); 9858c2ecf20Sopenharmony_ci 9868c2ecf20Sopenharmony_ci /* Read EEPROM TX power index and PHY_REG_PG.txt to capture correct */ 9878c2ecf20Sopenharmony_ci /* TX power index for different rate set. */ 9888c2ecf20Sopenharmony_ci rtl92d_phy_get_hw_reg_originalvalue(hw); 9898c2ecf20Sopenharmony_ci rtl92d_phy_set_txpower_level(hw, rtlphy->current_channel); 9908c2ecf20Sopenharmony_ci 9918c2ecf20Sopenharmony_ci ppsc->rfpwr_state = ERFON; 9928c2ecf20Sopenharmony_ci 9938c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); 9948c2ecf20Sopenharmony_ci 9958c2ecf20Sopenharmony_ci _rtl92de_enable_aspm_back_door(hw); 9968c2ecf20Sopenharmony_ci /* rtlpriv->intf_ops->enable_aspm(hw); */ 9978c2ecf20Sopenharmony_ci 9988c2ecf20Sopenharmony_ci rtl92d_dm_init(hw); 9998c2ecf20Sopenharmony_ci rtlpci->being_init_adapter = false; 10008c2ecf20Sopenharmony_ci 10018c2ecf20Sopenharmony_ci if (ppsc->rfpwr_state == ERFON) { 10028c2ecf20Sopenharmony_ci rtl92d_phy_lc_calibrate(hw); 10038c2ecf20Sopenharmony_ci /* 5G and 2.4G must wait sometime to let RF LO ready */ 10048c2ecf20Sopenharmony_ci if (rtlhal->macphymode == DUALMAC_DUALPHY) { 10058c2ecf20Sopenharmony_ci u32 tmp_rega; 10068c2ecf20Sopenharmony_ci for (i = 0; i < 10000; i++) { 10078c2ecf20Sopenharmony_ci udelay(MAX_STALL_TIME); 10088c2ecf20Sopenharmony_ci 10098c2ecf20Sopenharmony_ci tmp_rega = rtl_get_rfreg(hw, 10108c2ecf20Sopenharmony_ci (enum radio_path)RF90_PATH_A, 10118c2ecf20Sopenharmony_ci 0x2a, MASKDWORD); 10128c2ecf20Sopenharmony_ci 10138c2ecf20Sopenharmony_ci if (((tmp_rega & BIT(11)) == BIT(11))) 10148c2ecf20Sopenharmony_ci break; 10158c2ecf20Sopenharmony_ci } 10168c2ecf20Sopenharmony_ci /* check that loop was successful. If not, exit now */ 10178c2ecf20Sopenharmony_ci if (i == 10000) { 10188c2ecf20Sopenharmony_ci rtlpci->init_ready = false; 10198c2ecf20Sopenharmony_ci return 1; 10208c2ecf20Sopenharmony_ci } 10218c2ecf20Sopenharmony_ci } 10228c2ecf20Sopenharmony_ci } 10238c2ecf20Sopenharmony_ci rtlpci->init_ready = true; 10248c2ecf20Sopenharmony_ci return err; 10258c2ecf20Sopenharmony_ci} 10268c2ecf20Sopenharmony_ci 10278c2ecf20Sopenharmony_cistatic enum version_8192d _rtl92de_read_chip_version(struct ieee80211_hw *hw) 10288c2ecf20Sopenharmony_ci{ 10298c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10308c2ecf20Sopenharmony_ci enum version_8192d version = VERSION_NORMAL_CHIP_92D_SINGLEPHY; 10318c2ecf20Sopenharmony_ci u32 value32; 10328c2ecf20Sopenharmony_ci 10338c2ecf20Sopenharmony_ci value32 = rtl_read_dword(rtlpriv, REG_SYS_CFG); 10348c2ecf20Sopenharmony_ci if (!(value32 & 0x000f0000)) { 10358c2ecf20Sopenharmony_ci version = VERSION_TEST_CHIP_92D_SINGLEPHY; 10368c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "TEST CHIP!!!\n"); 10378c2ecf20Sopenharmony_ci } else { 10388c2ecf20Sopenharmony_ci version = VERSION_NORMAL_CHIP_92D_SINGLEPHY; 10398c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Normal CHIP!!!\n"); 10408c2ecf20Sopenharmony_ci } 10418c2ecf20Sopenharmony_ci return version; 10428c2ecf20Sopenharmony_ci} 10438c2ecf20Sopenharmony_ci 10448c2ecf20Sopenharmony_cistatic int _rtl92de_set_media_status(struct ieee80211_hw *hw, 10458c2ecf20Sopenharmony_ci enum nl80211_iftype type) 10468c2ecf20Sopenharmony_ci{ 10478c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10488c2ecf20Sopenharmony_ci u8 bt_msr = rtl_read_byte(rtlpriv, MSR); 10498c2ecf20Sopenharmony_ci enum led_ctl_mode ledaction = LED_CTL_NO_LINK; 10508c2ecf20Sopenharmony_ci u8 bcnfunc_enable; 10518c2ecf20Sopenharmony_ci 10528c2ecf20Sopenharmony_ci bt_msr &= 0xfc; 10538c2ecf20Sopenharmony_ci 10548c2ecf20Sopenharmony_ci if (type == NL80211_IFTYPE_UNSPECIFIED || 10558c2ecf20Sopenharmony_ci type == NL80211_IFTYPE_STATION) { 10568c2ecf20Sopenharmony_ci _rtl92de_stop_tx_beacon(hw); 10578c2ecf20Sopenharmony_ci _rtl92de_enable_bcn_sub_func(hw); 10588c2ecf20Sopenharmony_ci } else if (type == NL80211_IFTYPE_ADHOC || 10598c2ecf20Sopenharmony_ci type == NL80211_IFTYPE_AP) { 10608c2ecf20Sopenharmony_ci _rtl92de_resume_tx_beacon(hw); 10618c2ecf20Sopenharmony_ci _rtl92de_disable_bcn_sub_func(hw); 10628c2ecf20Sopenharmony_ci } else { 10638c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 10648c2ecf20Sopenharmony_ci "Set HW_VAR_MEDIA_STATUS: No such media status(%x)\n", 10658c2ecf20Sopenharmony_ci type); 10668c2ecf20Sopenharmony_ci } 10678c2ecf20Sopenharmony_ci bcnfunc_enable = rtl_read_byte(rtlpriv, REG_BCN_CTRL); 10688c2ecf20Sopenharmony_ci switch (type) { 10698c2ecf20Sopenharmony_ci case NL80211_IFTYPE_UNSPECIFIED: 10708c2ecf20Sopenharmony_ci bt_msr |= MSR_NOLINK; 10718c2ecf20Sopenharmony_ci ledaction = LED_CTL_LINK; 10728c2ecf20Sopenharmony_ci bcnfunc_enable &= 0xF7; 10738c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 10748c2ecf20Sopenharmony_ci "Set Network type to NO LINK!\n"); 10758c2ecf20Sopenharmony_ci break; 10768c2ecf20Sopenharmony_ci case NL80211_IFTYPE_ADHOC: 10778c2ecf20Sopenharmony_ci bt_msr |= MSR_ADHOC; 10788c2ecf20Sopenharmony_ci bcnfunc_enable |= 0x08; 10798c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 10808c2ecf20Sopenharmony_ci "Set Network type to Ad Hoc!\n"); 10818c2ecf20Sopenharmony_ci break; 10828c2ecf20Sopenharmony_ci case NL80211_IFTYPE_STATION: 10838c2ecf20Sopenharmony_ci bt_msr |= MSR_INFRA; 10848c2ecf20Sopenharmony_ci ledaction = LED_CTL_LINK; 10858c2ecf20Sopenharmony_ci bcnfunc_enable &= 0xF7; 10868c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 10878c2ecf20Sopenharmony_ci "Set Network type to STA!\n"); 10888c2ecf20Sopenharmony_ci break; 10898c2ecf20Sopenharmony_ci case NL80211_IFTYPE_AP: 10908c2ecf20Sopenharmony_ci bt_msr |= MSR_AP; 10918c2ecf20Sopenharmony_ci bcnfunc_enable |= 0x08; 10928c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 10938c2ecf20Sopenharmony_ci "Set Network type to AP!\n"); 10948c2ecf20Sopenharmony_ci break; 10958c2ecf20Sopenharmony_ci default: 10968c2ecf20Sopenharmony_ci pr_err("Network type %d not supported!\n", type); 10978c2ecf20Sopenharmony_ci return 1; 10988c2ecf20Sopenharmony_ci } 10998c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, MSR, bt_msr); 11008c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, ledaction); 11018c2ecf20Sopenharmony_ci if ((bt_msr & MSR_MASK) == MSR_AP) 11028c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 11038c2ecf20Sopenharmony_ci else 11048c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 11058c2ecf20Sopenharmony_ci return 0; 11068c2ecf20Sopenharmony_ci} 11078c2ecf20Sopenharmony_ci 11088c2ecf20Sopenharmony_civoid rtl92de_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 11098c2ecf20Sopenharmony_ci{ 11108c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11118c2ecf20Sopenharmony_ci u32 reg_rcr; 11128c2ecf20Sopenharmony_ci 11138c2ecf20Sopenharmony_ci if (rtlpriv->psc.rfpwr_state != ERFON) 11148c2ecf20Sopenharmony_ci return; 11158c2ecf20Sopenharmony_ci 11168c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); 11178c2ecf20Sopenharmony_ci 11188c2ecf20Sopenharmony_ci if (check_bssid) { 11198c2ecf20Sopenharmony_ci reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); 11208c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); 11218c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, 0, BIT(4)); 11228c2ecf20Sopenharmony_ci } else if (!check_bssid) { 11238c2ecf20Sopenharmony_ci reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); 11248c2ecf20Sopenharmony_ci _rtl92de_set_bcn_ctrl_reg(hw, BIT(4), 0); 11258c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); 11268c2ecf20Sopenharmony_ci } 11278c2ecf20Sopenharmony_ci} 11288c2ecf20Sopenharmony_ci 11298c2ecf20Sopenharmony_ciint rtl92de_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) 11308c2ecf20Sopenharmony_ci{ 11318c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11328c2ecf20Sopenharmony_ci 11338c2ecf20Sopenharmony_ci if (_rtl92de_set_media_status(hw, type)) 11348c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 11358c2ecf20Sopenharmony_ci 11368c2ecf20Sopenharmony_ci /* check bssid */ 11378c2ecf20Sopenharmony_ci if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { 11388c2ecf20Sopenharmony_ci if (type != NL80211_IFTYPE_AP) 11398c2ecf20Sopenharmony_ci rtl92de_set_check_bssid(hw, true); 11408c2ecf20Sopenharmony_ci } else { 11418c2ecf20Sopenharmony_ci rtl92de_set_check_bssid(hw, false); 11428c2ecf20Sopenharmony_ci } 11438c2ecf20Sopenharmony_ci return 0; 11448c2ecf20Sopenharmony_ci} 11458c2ecf20Sopenharmony_ci 11468c2ecf20Sopenharmony_ci/* do iqk or reload iqk */ 11478c2ecf20Sopenharmony_ci/* windows just rtl92d_phy_reload_iqk_setting in set channel, 11488c2ecf20Sopenharmony_ci * but it's very strict for time sequence so we add 11498c2ecf20Sopenharmony_ci * rtl92d_phy_reload_iqk_setting here */ 11508c2ecf20Sopenharmony_civoid rtl92d_linked_set_reg(struct ieee80211_hw *hw) 11518c2ecf20Sopenharmony_ci{ 11528c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11538c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 11548c2ecf20Sopenharmony_ci u8 indexforchannel; 11558c2ecf20Sopenharmony_ci u8 channel = rtlphy->current_channel; 11568c2ecf20Sopenharmony_ci 11578c2ecf20Sopenharmony_ci indexforchannel = rtl92d_get_rightchnlplace_for_iqk(channel); 11588c2ecf20Sopenharmony_ci if (!rtlphy->iqk_matrix[indexforchannel].iqk_done) { 11598c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SCAN | COMP_INIT, DBG_DMESG, 11608c2ecf20Sopenharmony_ci "Do IQK for channel:%d\n", channel); 11618c2ecf20Sopenharmony_ci rtl92d_phy_iq_calibrate(hw); 11628c2ecf20Sopenharmony_ci } 11638c2ecf20Sopenharmony_ci} 11648c2ecf20Sopenharmony_ci 11658c2ecf20Sopenharmony_ci/* don't set REG_EDCA_BE_PARAM here because 11668c2ecf20Sopenharmony_ci * mac80211 will send pkt when scan */ 11678c2ecf20Sopenharmony_civoid rtl92de_set_qos(struct ieee80211_hw *hw, int aci) 11688c2ecf20Sopenharmony_ci{ 11698c2ecf20Sopenharmony_ci rtl92d_dm_init_edca_turbo(hw); 11708c2ecf20Sopenharmony_ci} 11718c2ecf20Sopenharmony_ci 11728c2ecf20Sopenharmony_civoid rtl92de_enable_interrupt(struct ieee80211_hw *hw) 11738c2ecf20Sopenharmony_ci{ 11748c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11758c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 11768c2ecf20Sopenharmony_ci 11778c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HIMR, rtlpci->irq_mask[0] & 0xFFFFFFFF); 11788c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HIMRE, rtlpci->irq_mask[1] & 0xFFFFFFFF); 11798c2ecf20Sopenharmony_ci rtlpci->irq_enabled = true; 11808c2ecf20Sopenharmony_ci} 11818c2ecf20Sopenharmony_ci 11828c2ecf20Sopenharmony_civoid rtl92de_disable_interrupt(struct ieee80211_hw *hw) 11838c2ecf20Sopenharmony_ci{ 11848c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11858c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 11868c2ecf20Sopenharmony_ci 11878c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HIMR, IMR8190_DISABLED); 11888c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_HIMRE, IMR8190_DISABLED); 11898c2ecf20Sopenharmony_ci rtlpci->irq_enabled = false; 11908c2ecf20Sopenharmony_ci} 11918c2ecf20Sopenharmony_ci 11928c2ecf20Sopenharmony_cistatic void _rtl92de_poweroff_adapter(struct ieee80211_hw *hw) 11938c2ecf20Sopenharmony_ci{ 11948c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11958c2ecf20Sopenharmony_ci u8 u1b_tmp; 11968c2ecf20Sopenharmony_ci unsigned long flags; 11978c2ecf20Sopenharmony_ci 11988c2ecf20Sopenharmony_ci rtlpriv->intf_ops->enable_aspm(hw); 11998c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x00); 12008c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_RFPARAMETER, BIT(3), 0); 12018c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_RFPARAMETER, BIT(15), 0); 12028c2ecf20Sopenharmony_ci 12038c2ecf20Sopenharmony_ci /* 0x20:value 05-->04 */ 12048c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04); 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_ci /* ==== Reset digital sequence ====== */ 12078c2ecf20Sopenharmony_ci rtl92d_firmware_selfreset(hw); 12088c2ecf20Sopenharmony_ci 12098c2ecf20Sopenharmony_ci /* f. SYS_FUNC_EN 0x03[7:0]=0x51 reset MCU, MAC register, DCORE */ 12108c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x51); 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci /* g. MCUFWDL 0x80[1:0]=0 reset MCU ready status */ 12138c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, 0x00); 12148c2ecf20Sopenharmony_ci 12158c2ecf20Sopenharmony_ci /* ==== Pull GPIO PIN to balance level and LED control ====== */ 12168c2ecf20Sopenharmony_ci 12178c2ecf20Sopenharmony_ci /* h. GPIO_PIN_CTRL 0x44[31:0]=0x000 */ 12188c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 0x00000000); 12198c2ecf20Sopenharmony_ci 12208c2ecf20Sopenharmony_ci /* i. Value = GPIO_PIN_CTRL[7:0] */ 12218c2ecf20Sopenharmony_ci u1b_tmp = rtl_read_byte(rtlpriv, REG_GPIO_PIN_CTRL); 12228c2ecf20Sopenharmony_ci 12238c2ecf20Sopenharmony_ci /* j. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); */ 12248c2ecf20Sopenharmony_ci /* write external PIN level */ 12258c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, 12268c2ecf20Sopenharmony_ci 0x00FF0000 | (u1b_tmp << 8)); 12278c2ecf20Sopenharmony_ci 12288c2ecf20Sopenharmony_ci /* k. GPIO_MUXCFG 0x42 [15:0] = 0x0780 */ 12298c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_GPIO_IO_SEL, 0x0790); 12308c2ecf20Sopenharmony_ci 12318c2ecf20Sopenharmony_ci /* l. LEDCFG 0x4C[15:0] = 0x8080 */ 12328c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); 12338c2ecf20Sopenharmony_ci 12348c2ecf20Sopenharmony_ci /* ==== Disable analog sequence === */ 12358c2ecf20Sopenharmony_ci 12368c2ecf20Sopenharmony_ci /* m. AFE_PLL_CTRL[7:0] = 0x80 disable PLL */ 12378c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); 12388c2ecf20Sopenharmony_ci 12398c2ecf20Sopenharmony_ci /* n. SPS0_CTRL 0x11[7:0] = 0x22 enter PFM mode */ 12408c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); 12418c2ecf20Sopenharmony_ci 12428c2ecf20Sopenharmony_ci /* o. AFE_XTAL_CTRL 0x24[7:0] = 0x0E disable XTAL, if No BT COEX */ 12438c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL, 0x0e); 12448c2ecf20Sopenharmony_ci 12458c2ecf20Sopenharmony_ci /* p. RSV_CTRL 0x1C[7:0] = 0x0E lock ISO/CLK/Power control register */ 12468c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0e); 12478c2ecf20Sopenharmony_ci 12488c2ecf20Sopenharmony_ci /* ==== interface into suspend === */ 12498c2ecf20Sopenharmony_ci 12508c2ecf20Sopenharmony_ci /* q. APS_FSMCO[15:8] = 0x58 PCIe suspend mode */ 12518c2ecf20Sopenharmony_ci /* According to power document V11, we need to set this */ 12528c2ecf20Sopenharmony_ci /* value as 0x18. Otherwise, we may not L0s sometimes. */ 12538c2ecf20Sopenharmony_ci /* This indluences power consumption. Bases on SD1's test, */ 12548c2ecf20Sopenharmony_ci /* set as 0x00 do not affect power current. And if it */ 12558c2ecf20Sopenharmony_ci /* is set as 0x18, they had ever met auto load fail problem. */ 12568c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APS_FSMCO + 1, 0x10); 12578c2ecf20Sopenharmony_ci 12588c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 12598c2ecf20Sopenharmony_ci "In PowerOff,reg0x%x=%X\n", 12608c2ecf20Sopenharmony_ci REG_SPS0_CTRL, rtl_read_byte(rtlpriv, REG_SPS0_CTRL)); 12618c2ecf20Sopenharmony_ci /* r. Note: for PCIe interface, PON will not turn */ 12628c2ecf20Sopenharmony_ci /* off m-bias and BandGap in PCIe suspend mode. */ 12638c2ecf20Sopenharmony_ci 12648c2ecf20Sopenharmony_ci /* 0x17[7] 1b': power off in process 0b' : power off over */ 12658c2ecf20Sopenharmony_ci if (rtlpriv->rtlhal.macphymode != SINGLEMAC_SINGLEPHY) { 12668c2ecf20Sopenharmony_ci spin_lock_irqsave(&globalmutex_power, flags); 12678c2ecf20Sopenharmony_ci u1b_tmp = rtl_read_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS); 12688c2ecf20Sopenharmony_ci u1b_tmp &= (~BIT(7)); 12698c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_POWER_OFF_IN_PROCESS, u1b_tmp); 12708c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&globalmutex_power, flags); 12718c2ecf20Sopenharmony_ci } 12728c2ecf20Sopenharmony_ci 12738c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "<=======\n"); 12748c2ecf20Sopenharmony_ci} 12758c2ecf20Sopenharmony_ci 12768c2ecf20Sopenharmony_civoid rtl92de_card_disable(struct ieee80211_hw *hw) 12778c2ecf20Sopenharmony_ci{ 12788c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 12798c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 12808c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 12818c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 12828c2ecf20Sopenharmony_ci enum nl80211_iftype opmode; 12838c2ecf20Sopenharmony_ci 12848c2ecf20Sopenharmony_ci mac->link_state = MAC80211_NOLINK; 12858c2ecf20Sopenharmony_ci opmode = NL80211_IFTYPE_UNSPECIFIED; 12868c2ecf20Sopenharmony_ci _rtl92de_set_media_status(hw, opmode); 12878c2ecf20Sopenharmony_ci 12888c2ecf20Sopenharmony_ci if (rtlpci->driver_is_goingto_unload || 12898c2ecf20Sopenharmony_ci ppsc->rfoff_reason > RF_CHANGE_BY_PS) 12908c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); 12918c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 12928c2ecf20Sopenharmony_ci /* Power sequence for each MAC. */ 12938c2ecf20Sopenharmony_ci /* a. stop tx DMA */ 12948c2ecf20Sopenharmony_ci /* b. close RF */ 12958c2ecf20Sopenharmony_ci /* c. clear rx buf */ 12968c2ecf20Sopenharmony_ci /* d. stop rx DMA */ 12978c2ecf20Sopenharmony_ci /* e. reset MAC */ 12988c2ecf20Sopenharmony_ci 12998c2ecf20Sopenharmony_ci /* a. stop tx DMA */ 13008c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xFE); 13018c2ecf20Sopenharmony_ci udelay(50); 13028c2ecf20Sopenharmony_ci 13038c2ecf20Sopenharmony_ci /* b. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue */ 13048c2ecf20Sopenharmony_ci 13058c2ecf20Sopenharmony_ci /* c. ========RF OFF sequence========== */ 13068c2ecf20Sopenharmony_ci /* 0x88c[23:20] = 0xf. */ 13078c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER4, 0x00f00000, 0xf); 13088c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 13098c2ecf20Sopenharmony_ci 13108c2ecf20Sopenharmony_ci /* APSD_CTRL 0x600[7:0] = 0x40 */ 13118c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 13128c2ecf20Sopenharmony_ci 13138c2ecf20Sopenharmony_ci /* Close antenna 0,0xc04,0xd04 */ 13148c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0); 13158c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_TRXPATHENABLE, BDWORD, 0); 13168c2ecf20Sopenharmony_ci 13178c2ecf20Sopenharmony_ci /* SYS_FUNC_EN 0x02[7:0] = 0xE2 reset BB state machine */ 13188c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 13198c2ecf20Sopenharmony_ci 13208c2ecf20Sopenharmony_ci /* Mac0 can not do Global reset. Mac1 can do. */ 13218c2ecf20Sopenharmony_ci /* SYS_FUNC_EN 0x02[7:0] = 0xE0 reset BB state machine */ 13228c2ecf20Sopenharmony_ci if (rtlpriv->rtlhal.interfaceindex == 1) 13238c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE0); 13248c2ecf20Sopenharmony_ci udelay(50); 13258c2ecf20Sopenharmony_ci 13268c2ecf20Sopenharmony_ci /* d. stop tx/rx dma before disable REG_CR (0x100) to fix */ 13278c2ecf20Sopenharmony_ci /* dma hang issue when disable/enable device. */ 13288c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PCIE_CTRL_REG + 1, 0xff); 13298c2ecf20Sopenharmony_ci udelay(50); 13308c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR, 0x0); 13318c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "==> Do power off.......\n"); 13328c2ecf20Sopenharmony_ci if (rtl92d_phy_check_poweroff(hw)) 13338c2ecf20Sopenharmony_ci _rtl92de_poweroff_adapter(hw); 13348c2ecf20Sopenharmony_ci return; 13358c2ecf20Sopenharmony_ci} 13368c2ecf20Sopenharmony_ci 13378c2ecf20Sopenharmony_civoid rtl92de_interrupt_recognized(struct ieee80211_hw *hw, 13388c2ecf20Sopenharmony_ci struct rtl_int *intvec) 13398c2ecf20Sopenharmony_ci{ 13408c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13418c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 13428c2ecf20Sopenharmony_ci 13438c2ecf20Sopenharmony_ci intvec->inta = rtl_read_dword(rtlpriv, ISR) & rtlpci->irq_mask[0]; 13448c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, ISR, intvec->inta); 13458c2ecf20Sopenharmony_ci} 13468c2ecf20Sopenharmony_ci 13478c2ecf20Sopenharmony_civoid rtl92de_set_beacon_related_registers(struct ieee80211_hw *hw) 13488c2ecf20Sopenharmony_ci{ 13498c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13508c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 13518c2ecf20Sopenharmony_ci u16 bcn_interval, atim_window; 13528c2ecf20Sopenharmony_ci 13538c2ecf20Sopenharmony_ci bcn_interval = mac->beacon_interval; 13548c2ecf20Sopenharmony_ci atim_window = 2; 13558c2ecf20Sopenharmony_ci rtl92de_disable_interrupt(hw); 13568c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); 13578c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); 13588c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660f); 13598c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x20); 13608c2ecf20Sopenharmony_ci if (rtlpriv->rtlhal.current_bandtype == BAND_ON_5G) 13618c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x30); 13628c2ecf20Sopenharmony_ci else 13638c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x20); 13648c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x606, 0x30); 13658c2ecf20Sopenharmony_ci} 13668c2ecf20Sopenharmony_ci 13678c2ecf20Sopenharmony_civoid rtl92de_set_beacon_interval(struct ieee80211_hw *hw) 13688c2ecf20Sopenharmony_ci{ 13698c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13708c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 13718c2ecf20Sopenharmony_ci u16 bcn_interval = mac->beacon_interval; 13728c2ecf20Sopenharmony_ci 13738c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, 13748c2ecf20Sopenharmony_ci "beacon_interval:%d\n", bcn_interval); 13758c2ecf20Sopenharmony_ci rtl92de_disable_interrupt(hw); 13768c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); 13778c2ecf20Sopenharmony_ci rtl92de_enable_interrupt(hw); 13788c2ecf20Sopenharmony_ci} 13798c2ecf20Sopenharmony_ci 13808c2ecf20Sopenharmony_civoid rtl92de_update_interrupt_mask(struct ieee80211_hw *hw, 13818c2ecf20Sopenharmony_ci u32 add_msr, u32 rm_msr) 13828c2ecf20Sopenharmony_ci{ 13838c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13848c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 13858c2ecf20Sopenharmony_ci 13868c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, "add_msr:%x, rm_msr:%x\n", 13878c2ecf20Sopenharmony_ci add_msr, rm_msr); 13888c2ecf20Sopenharmony_ci if (add_msr) 13898c2ecf20Sopenharmony_ci rtlpci->irq_mask[0] |= add_msr; 13908c2ecf20Sopenharmony_ci if (rm_msr) 13918c2ecf20Sopenharmony_ci rtlpci->irq_mask[0] &= (~rm_msr); 13928c2ecf20Sopenharmony_ci rtl92de_disable_interrupt(hw); 13938c2ecf20Sopenharmony_ci rtl92de_enable_interrupt(hw); 13948c2ecf20Sopenharmony_ci} 13958c2ecf20Sopenharmony_ci 13968c2ecf20Sopenharmony_cistatic void _rtl92de_readpowervalue_fromprom(struct txpower_info *pwrinfo, 13978c2ecf20Sopenharmony_ci u8 *rom_content, bool autoloadfail) 13988c2ecf20Sopenharmony_ci{ 13998c2ecf20Sopenharmony_ci u32 rfpath, eeaddr, group, offset1, offset2; 14008c2ecf20Sopenharmony_ci u8 i; 14018c2ecf20Sopenharmony_ci 14028c2ecf20Sopenharmony_ci memset(pwrinfo, 0, sizeof(struct txpower_info)); 14038c2ecf20Sopenharmony_ci if (autoloadfail) { 14048c2ecf20Sopenharmony_ci for (group = 0; group < CHANNEL_GROUP_MAX; group++) { 14058c2ecf20Sopenharmony_ci for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { 14068c2ecf20Sopenharmony_ci if (group < CHANNEL_GROUP_MAX_2G) { 14078c2ecf20Sopenharmony_ci pwrinfo->cck_index[rfpath][group] = 14088c2ecf20Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL_2G; 14098c2ecf20Sopenharmony_ci pwrinfo->ht40_1sindex[rfpath][group] = 14108c2ecf20Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL_2G; 14118c2ecf20Sopenharmony_ci } else { 14128c2ecf20Sopenharmony_ci pwrinfo->ht40_1sindex[rfpath][group] = 14138c2ecf20Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL_5G; 14148c2ecf20Sopenharmony_ci } 14158c2ecf20Sopenharmony_ci pwrinfo->ht40_2sindexdiff[rfpath][group] = 14168c2ecf20Sopenharmony_ci EEPROM_DEFAULT_HT40_2SDIFF; 14178c2ecf20Sopenharmony_ci pwrinfo->ht20indexdiff[rfpath][group] = 14188c2ecf20Sopenharmony_ci EEPROM_DEFAULT_HT20_DIFF; 14198c2ecf20Sopenharmony_ci pwrinfo->ofdmindexdiff[rfpath][group] = 14208c2ecf20Sopenharmony_ci EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; 14218c2ecf20Sopenharmony_ci pwrinfo->ht40maxoffset[rfpath][group] = 14228c2ecf20Sopenharmony_ci EEPROM_DEFAULT_HT40_PWRMAXOFFSET; 14238c2ecf20Sopenharmony_ci pwrinfo->ht20maxoffset[rfpath][group] = 14248c2ecf20Sopenharmony_ci EEPROM_DEFAULT_HT20_PWRMAXOFFSET; 14258c2ecf20Sopenharmony_ci } 14268c2ecf20Sopenharmony_ci } 14278c2ecf20Sopenharmony_ci for (i = 0; i < 3; i++) { 14288c2ecf20Sopenharmony_ci pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI; 14298c2ecf20Sopenharmony_ci pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI; 14308c2ecf20Sopenharmony_ci } 14318c2ecf20Sopenharmony_ci return; 14328c2ecf20Sopenharmony_ci } 14338c2ecf20Sopenharmony_ci 14348c2ecf20Sopenharmony_ci /* Maybe autoload OK,buf the tx power index value is not filled. 14358c2ecf20Sopenharmony_ci * If we find it, we set it to default value. */ 14368c2ecf20Sopenharmony_ci for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { 14378c2ecf20Sopenharmony_ci for (group = 0; group < CHANNEL_GROUP_MAX_2G; group++) { 14388c2ecf20Sopenharmony_ci eeaddr = EEPROM_CCK_TX_PWR_INX_2G + (rfpath * 3) 14398c2ecf20Sopenharmony_ci + group; 14408c2ecf20Sopenharmony_ci pwrinfo->cck_index[rfpath][group] = 14418c2ecf20Sopenharmony_ci (rom_content[eeaddr] == 0xFF) ? 14428c2ecf20Sopenharmony_ci (eeaddr > 0x7B ? 14438c2ecf20Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL_5G : 14448c2ecf20Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL_2G) : 14458c2ecf20Sopenharmony_ci rom_content[eeaddr]; 14468c2ecf20Sopenharmony_ci } 14478c2ecf20Sopenharmony_ci } 14488c2ecf20Sopenharmony_ci for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { 14498c2ecf20Sopenharmony_ci for (group = 0; group < CHANNEL_GROUP_MAX; group++) { 14508c2ecf20Sopenharmony_ci offset1 = group / 3; 14518c2ecf20Sopenharmony_ci offset2 = group % 3; 14528c2ecf20Sopenharmony_ci eeaddr = EEPROM_HT40_1S_TX_PWR_INX_2G + (rfpath * 3) + 14538c2ecf20Sopenharmony_ci offset2 + offset1 * 21; 14548c2ecf20Sopenharmony_ci pwrinfo->ht40_1sindex[rfpath][group] = 14558c2ecf20Sopenharmony_ci (rom_content[eeaddr] == 0xFF) ? (eeaddr > 0x7B ? 14568c2ecf20Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL_5G : 14578c2ecf20Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL_2G) : 14588c2ecf20Sopenharmony_ci rom_content[eeaddr]; 14598c2ecf20Sopenharmony_ci } 14608c2ecf20Sopenharmony_ci } 14618c2ecf20Sopenharmony_ci /* These just for 92D efuse offset. */ 14628c2ecf20Sopenharmony_ci for (group = 0; group < CHANNEL_GROUP_MAX; group++) { 14638c2ecf20Sopenharmony_ci for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { 14648c2ecf20Sopenharmony_ci int base1 = EEPROM_HT40_2S_TX_PWR_INX_DIFF_2G; 14658c2ecf20Sopenharmony_ci 14668c2ecf20Sopenharmony_ci offset1 = group / 3; 14678c2ecf20Sopenharmony_ci offset2 = group % 3; 14688c2ecf20Sopenharmony_ci 14698c2ecf20Sopenharmony_ci if (rom_content[base1 + offset2 + offset1 * 21] != 0xFF) 14708c2ecf20Sopenharmony_ci pwrinfo->ht40_2sindexdiff[rfpath][group] = 14718c2ecf20Sopenharmony_ci (rom_content[base1 + 14728c2ecf20Sopenharmony_ci offset2 + offset1 * 21] >> (rfpath * 4)) 14738c2ecf20Sopenharmony_ci & 0xF; 14748c2ecf20Sopenharmony_ci else 14758c2ecf20Sopenharmony_ci pwrinfo->ht40_2sindexdiff[rfpath][group] = 14768c2ecf20Sopenharmony_ci EEPROM_DEFAULT_HT40_2SDIFF; 14778c2ecf20Sopenharmony_ci if (rom_content[EEPROM_HT20_TX_PWR_INX_DIFF_2G + offset2 14788c2ecf20Sopenharmony_ci + offset1 * 21] != 0xFF) 14798c2ecf20Sopenharmony_ci pwrinfo->ht20indexdiff[rfpath][group] = 14808c2ecf20Sopenharmony_ci (rom_content[EEPROM_HT20_TX_PWR_INX_DIFF_2G 14818c2ecf20Sopenharmony_ci + offset2 + offset1 * 21] >> (rfpath * 4)) 14828c2ecf20Sopenharmony_ci & 0xF; 14838c2ecf20Sopenharmony_ci else 14848c2ecf20Sopenharmony_ci pwrinfo->ht20indexdiff[rfpath][group] = 14858c2ecf20Sopenharmony_ci EEPROM_DEFAULT_HT20_DIFF; 14868c2ecf20Sopenharmony_ci if (rom_content[EEPROM_OFDM_TX_PWR_INX_DIFF_2G + offset2 14878c2ecf20Sopenharmony_ci + offset1 * 21] != 0xFF) 14888c2ecf20Sopenharmony_ci pwrinfo->ofdmindexdiff[rfpath][group] = 14898c2ecf20Sopenharmony_ci (rom_content[EEPROM_OFDM_TX_PWR_INX_DIFF_2G 14908c2ecf20Sopenharmony_ci + offset2 + offset1 * 21] >> (rfpath * 4)) 14918c2ecf20Sopenharmony_ci & 0xF; 14928c2ecf20Sopenharmony_ci else 14938c2ecf20Sopenharmony_ci pwrinfo->ofdmindexdiff[rfpath][group] = 14948c2ecf20Sopenharmony_ci EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; 14958c2ecf20Sopenharmony_ci if (rom_content[EEPROM_HT40_MAX_PWR_OFFSET_2G + offset2 14968c2ecf20Sopenharmony_ci + offset1 * 21] != 0xFF) 14978c2ecf20Sopenharmony_ci pwrinfo->ht40maxoffset[rfpath][group] = 14988c2ecf20Sopenharmony_ci (rom_content[EEPROM_HT40_MAX_PWR_OFFSET_2G 14998c2ecf20Sopenharmony_ci + offset2 + offset1 * 21] >> (rfpath * 4)) 15008c2ecf20Sopenharmony_ci & 0xF; 15018c2ecf20Sopenharmony_ci else 15028c2ecf20Sopenharmony_ci pwrinfo->ht40maxoffset[rfpath][group] = 15038c2ecf20Sopenharmony_ci EEPROM_DEFAULT_HT40_PWRMAXOFFSET; 15048c2ecf20Sopenharmony_ci if (rom_content[EEPROM_HT20_MAX_PWR_OFFSET_2G + offset2 15058c2ecf20Sopenharmony_ci + offset1 * 21] != 0xFF) 15068c2ecf20Sopenharmony_ci pwrinfo->ht20maxoffset[rfpath][group] = 15078c2ecf20Sopenharmony_ci (rom_content[EEPROM_HT20_MAX_PWR_OFFSET_2G + 15088c2ecf20Sopenharmony_ci offset2 + offset1 * 21] >> (rfpath * 4)) & 15098c2ecf20Sopenharmony_ci 0xF; 15108c2ecf20Sopenharmony_ci else 15118c2ecf20Sopenharmony_ci pwrinfo->ht20maxoffset[rfpath][group] = 15128c2ecf20Sopenharmony_ci EEPROM_DEFAULT_HT20_PWRMAXOFFSET; 15138c2ecf20Sopenharmony_ci } 15148c2ecf20Sopenharmony_ci } 15158c2ecf20Sopenharmony_ci if (rom_content[EEPROM_TSSI_A_5G] != 0xFF) { 15168c2ecf20Sopenharmony_ci /* 5GL */ 15178c2ecf20Sopenharmony_ci pwrinfo->tssi_a[0] = rom_content[EEPROM_TSSI_A_5G] & 0x3F; 15188c2ecf20Sopenharmony_ci pwrinfo->tssi_b[0] = rom_content[EEPROM_TSSI_B_5G] & 0x3F; 15198c2ecf20Sopenharmony_ci /* 5GM */ 15208c2ecf20Sopenharmony_ci pwrinfo->tssi_a[1] = rom_content[EEPROM_TSSI_AB_5G] & 0x3F; 15218c2ecf20Sopenharmony_ci pwrinfo->tssi_b[1] = 15228c2ecf20Sopenharmony_ci (rom_content[EEPROM_TSSI_AB_5G] & 0xC0) >> 6 | 15238c2ecf20Sopenharmony_ci (rom_content[EEPROM_TSSI_AB_5G + 1] & 0x0F) << 2; 15248c2ecf20Sopenharmony_ci /* 5GH */ 15258c2ecf20Sopenharmony_ci pwrinfo->tssi_a[2] = (rom_content[EEPROM_TSSI_AB_5G + 1] & 15268c2ecf20Sopenharmony_ci 0xF0) >> 4 | 15278c2ecf20Sopenharmony_ci (rom_content[EEPROM_TSSI_AB_5G + 2] & 0x03) << 4; 15288c2ecf20Sopenharmony_ci pwrinfo->tssi_b[2] = (rom_content[EEPROM_TSSI_AB_5G + 2] & 15298c2ecf20Sopenharmony_ci 0xFC) >> 2; 15308c2ecf20Sopenharmony_ci } else { 15318c2ecf20Sopenharmony_ci for (i = 0; i < 3; i++) { 15328c2ecf20Sopenharmony_ci pwrinfo->tssi_a[i] = EEPROM_DEFAULT_TSSI; 15338c2ecf20Sopenharmony_ci pwrinfo->tssi_b[i] = EEPROM_DEFAULT_TSSI; 15348c2ecf20Sopenharmony_ci } 15358c2ecf20Sopenharmony_ci } 15368c2ecf20Sopenharmony_ci} 15378c2ecf20Sopenharmony_ci 15388c2ecf20Sopenharmony_cistatic void _rtl92de_read_txpower_info(struct ieee80211_hw *hw, 15398c2ecf20Sopenharmony_ci bool autoload_fail, u8 *hwinfo) 15408c2ecf20Sopenharmony_ci{ 15418c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 15428c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 15438c2ecf20Sopenharmony_ci struct txpower_info pwrinfo; 15448c2ecf20Sopenharmony_ci u8 tempval[2], i, pwr, diff; 15458c2ecf20Sopenharmony_ci u32 ch, rfpath, group; 15468c2ecf20Sopenharmony_ci 15478c2ecf20Sopenharmony_ci _rtl92de_readpowervalue_fromprom(&pwrinfo, hwinfo, autoload_fail); 15488c2ecf20Sopenharmony_ci if (!autoload_fail) { 15498c2ecf20Sopenharmony_ci /* bit0~2 */ 15508c2ecf20Sopenharmony_ci rtlefuse->eeprom_regulatory = (hwinfo[EEPROM_RF_OPT1] & 0x7); 15518c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter = 15528c2ecf20Sopenharmony_ci hwinfo[EEPROM_THERMAL_METER] & 0x1f; 15538c2ecf20Sopenharmony_ci rtlefuse->crystalcap = hwinfo[EEPROM_XTAL_K]; 15548c2ecf20Sopenharmony_ci tempval[0] = hwinfo[EEPROM_IQK_DELTA] & 0x03; 15558c2ecf20Sopenharmony_ci tempval[1] = (hwinfo[EEPROM_LCK_DELTA] & 0x0C) >> 2; 15568c2ecf20Sopenharmony_ci rtlefuse->txpwr_fromeprom = true; 15578c2ecf20Sopenharmony_ci if (IS_92D_D_CUT(rtlpriv->rtlhal.version) || 15588c2ecf20Sopenharmony_ci IS_92D_E_CUT(rtlpriv->rtlhal.version)) { 15598c2ecf20Sopenharmony_ci rtlefuse->internal_pa_5g[0] = 15608c2ecf20Sopenharmony_ci !((hwinfo[EEPROM_TSSI_A_5G] & BIT(6)) >> 6); 15618c2ecf20Sopenharmony_ci rtlefuse->internal_pa_5g[1] = 15628c2ecf20Sopenharmony_ci !((hwinfo[EEPROM_TSSI_B_5G] & BIT(6)) >> 6); 15638c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, 15648c2ecf20Sopenharmony_ci "Is D cut,Internal PA0 %d Internal PA1 %d\n", 15658c2ecf20Sopenharmony_ci rtlefuse->internal_pa_5g[0], 15668c2ecf20Sopenharmony_ci rtlefuse->internal_pa_5g[1]); 15678c2ecf20Sopenharmony_ci } 15688c2ecf20Sopenharmony_ci rtlefuse->eeprom_c9 = hwinfo[EEPROM_RF_OPT6]; 15698c2ecf20Sopenharmony_ci rtlefuse->eeprom_cc = hwinfo[EEPROM_RF_OPT7]; 15708c2ecf20Sopenharmony_ci } else { 15718c2ecf20Sopenharmony_ci rtlefuse->eeprom_regulatory = 0; 15728c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter = EEPROM_DEFAULT_THERMALMETER; 15738c2ecf20Sopenharmony_ci rtlefuse->crystalcap = EEPROM_DEFAULT_CRYSTALCAP; 15748c2ecf20Sopenharmony_ci tempval[0] = tempval[1] = 3; 15758c2ecf20Sopenharmony_ci } 15768c2ecf20Sopenharmony_ci 15778c2ecf20Sopenharmony_ci /* Use default value to fill parameters if 15788c2ecf20Sopenharmony_ci * efuse is not filled on some place. */ 15798c2ecf20Sopenharmony_ci 15808c2ecf20Sopenharmony_ci /* ThermalMeter from EEPROM */ 15818c2ecf20Sopenharmony_ci if (rtlefuse->eeprom_thermalmeter < 0x06 || 15828c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter > 0x1c) 15838c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter = 0x12; 15848c2ecf20Sopenharmony_ci rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; 15858c2ecf20Sopenharmony_ci 15868c2ecf20Sopenharmony_ci /* check XTAL_K */ 15878c2ecf20Sopenharmony_ci if (rtlefuse->crystalcap == 0xFF) 15888c2ecf20Sopenharmony_ci rtlefuse->crystalcap = 0; 15898c2ecf20Sopenharmony_ci if (rtlefuse->eeprom_regulatory > 3) 15908c2ecf20Sopenharmony_ci rtlefuse->eeprom_regulatory = 0; 15918c2ecf20Sopenharmony_ci 15928c2ecf20Sopenharmony_ci for (i = 0; i < 2; i++) { 15938c2ecf20Sopenharmony_ci switch (tempval[i]) { 15948c2ecf20Sopenharmony_ci case 0: 15958c2ecf20Sopenharmony_ci tempval[i] = 5; 15968c2ecf20Sopenharmony_ci break; 15978c2ecf20Sopenharmony_ci case 1: 15988c2ecf20Sopenharmony_ci tempval[i] = 4; 15998c2ecf20Sopenharmony_ci break; 16008c2ecf20Sopenharmony_ci case 2: 16018c2ecf20Sopenharmony_ci tempval[i] = 3; 16028c2ecf20Sopenharmony_ci break; 16038c2ecf20Sopenharmony_ci case 3: 16048c2ecf20Sopenharmony_ci default: 16058c2ecf20Sopenharmony_ci tempval[i] = 0; 16068c2ecf20Sopenharmony_ci break; 16078c2ecf20Sopenharmony_ci } 16088c2ecf20Sopenharmony_ci } 16098c2ecf20Sopenharmony_ci 16108c2ecf20Sopenharmony_ci rtlefuse->delta_iqk = tempval[0]; 16118c2ecf20Sopenharmony_ci if (tempval[1] > 0) 16128c2ecf20Sopenharmony_ci rtlefuse->delta_lck = tempval[1] - 1; 16138c2ecf20Sopenharmony_ci if (rtlefuse->eeprom_c9 == 0xFF) 16148c2ecf20Sopenharmony_ci rtlefuse->eeprom_c9 = 0x00; 16158c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, 16168c2ecf20Sopenharmony_ci "EEPROMRegulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 16178c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, 16188c2ecf20Sopenharmony_ci "ThermalMeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); 16198c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, 16208c2ecf20Sopenharmony_ci "CrystalCap = 0x%x\n", rtlefuse->crystalcap); 16218c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INTR, DBG_LOUD, 16228c2ecf20Sopenharmony_ci "Delta_IQK = 0x%x Delta_LCK = 0x%x\n", 16238c2ecf20Sopenharmony_ci rtlefuse->delta_iqk, rtlefuse->delta_lck); 16248c2ecf20Sopenharmony_ci 16258c2ecf20Sopenharmony_ci for (rfpath = 0; rfpath < RF6052_MAX_PATH; rfpath++) { 16268c2ecf20Sopenharmony_ci for (ch = 0; ch < CHANNEL_MAX_NUMBER; ch++) { 16278c2ecf20Sopenharmony_ci group = rtl92d_get_chnlgroup_fromarray((u8) ch); 16288c2ecf20Sopenharmony_ci if (ch < CHANNEL_MAX_NUMBER_2G) 16298c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_cck[rfpath][ch] = 16308c2ecf20Sopenharmony_ci pwrinfo.cck_index[rfpath][group]; 16318c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[rfpath][ch] = 16328c2ecf20Sopenharmony_ci pwrinfo.ht40_1sindex[rfpath][group]; 16338c2ecf20Sopenharmony_ci rtlefuse->txpwr_ht20diff[rfpath][ch] = 16348c2ecf20Sopenharmony_ci pwrinfo.ht20indexdiff[rfpath][group]; 16358c2ecf20Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[rfpath][ch] = 16368c2ecf20Sopenharmony_ci pwrinfo.ofdmindexdiff[rfpath][group]; 16378c2ecf20Sopenharmony_ci rtlefuse->pwrgroup_ht20[rfpath][ch] = 16388c2ecf20Sopenharmony_ci pwrinfo.ht20maxoffset[rfpath][group]; 16398c2ecf20Sopenharmony_ci rtlefuse->pwrgroup_ht40[rfpath][ch] = 16408c2ecf20Sopenharmony_ci pwrinfo.ht40maxoffset[rfpath][group]; 16418c2ecf20Sopenharmony_ci pwr = pwrinfo.ht40_1sindex[rfpath][group]; 16428c2ecf20Sopenharmony_ci diff = pwrinfo.ht40_2sindexdiff[rfpath][group]; 16438c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rfpath][ch] = 16448c2ecf20Sopenharmony_ci (pwr > diff) ? (pwr - diff) : 0; 16458c2ecf20Sopenharmony_ci } 16468c2ecf20Sopenharmony_ci } 16478c2ecf20Sopenharmony_ci} 16488c2ecf20Sopenharmony_ci 16498c2ecf20Sopenharmony_cistatic void _rtl92de_read_macphymode_from_prom(struct ieee80211_hw *hw, 16508c2ecf20Sopenharmony_ci u8 *content) 16518c2ecf20Sopenharmony_ci{ 16528c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 16538c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 16548c2ecf20Sopenharmony_ci u8 macphy_crvalue = content[EEPROM_MAC_FUNCTION]; 16558c2ecf20Sopenharmony_ci 16568c2ecf20Sopenharmony_ci if (macphy_crvalue & BIT(3)) { 16578c2ecf20Sopenharmony_ci rtlhal->macphymode = SINGLEMAC_SINGLEPHY; 16588c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 16598c2ecf20Sopenharmony_ci "MacPhyMode SINGLEMAC_SINGLEPHY\n"); 16608c2ecf20Sopenharmony_ci } else { 16618c2ecf20Sopenharmony_ci rtlhal->macphymode = DUALMAC_DUALPHY; 16628c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 16638c2ecf20Sopenharmony_ci "MacPhyMode DUALMAC_DUALPHY\n"); 16648c2ecf20Sopenharmony_ci } 16658c2ecf20Sopenharmony_ci} 16668c2ecf20Sopenharmony_ci 16678c2ecf20Sopenharmony_cistatic void _rtl92de_read_macphymode_and_bandtype(struct ieee80211_hw *hw, 16688c2ecf20Sopenharmony_ci u8 *content) 16698c2ecf20Sopenharmony_ci{ 16708c2ecf20Sopenharmony_ci _rtl92de_read_macphymode_from_prom(hw, content); 16718c2ecf20Sopenharmony_ci rtl92d_phy_config_macphymode(hw); 16728c2ecf20Sopenharmony_ci rtl92d_phy_config_macphymode_info(hw); 16738c2ecf20Sopenharmony_ci} 16748c2ecf20Sopenharmony_ci 16758c2ecf20Sopenharmony_cistatic void _rtl92de_efuse_update_chip_version(struct ieee80211_hw *hw) 16768c2ecf20Sopenharmony_ci{ 16778c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 16788c2ecf20Sopenharmony_ci enum version_8192d chipver = rtlpriv->rtlhal.version; 16798c2ecf20Sopenharmony_ci u8 cutvalue[2]; 16808c2ecf20Sopenharmony_ci u16 chipvalue; 16818c2ecf20Sopenharmony_ci 16828c2ecf20Sopenharmony_ci rtlpriv->intf_ops->read_efuse_byte(hw, EEPROME_CHIP_VERSION_H, 16838c2ecf20Sopenharmony_ci &cutvalue[1]); 16848c2ecf20Sopenharmony_ci rtlpriv->intf_ops->read_efuse_byte(hw, EEPROME_CHIP_VERSION_L, 16858c2ecf20Sopenharmony_ci &cutvalue[0]); 16868c2ecf20Sopenharmony_ci chipvalue = (cutvalue[1] << 8) | cutvalue[0]; 16878c2ecf20Sopenharmony_ci switch (chipvalue) { 16888c2ecf20Sopenharmony_ci case 0xAA55: 16898c2ecf20Sopenharmony_ci chipver |= CHIP_92D_C_CUT; 16908c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "C-CUT!!!\n"); 16918c2ecf20Sopenharmony_ci break; 16928c2ecf20Sopenharmony_ci case 0x9966: 16938c2ecf20Sopenharmony_ci chipver |= CHIP_92D_D_CUT; 16948c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "D-CUT!!!\n"); 16958c2ecf20Sopenharmony_ci break; 16968c2ecf20Sopenharmony_ci case 0xCC33: 16978c2ecf20Sopenharmony_ci chipver |= CHIP_92D_E_CUT; 16988c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "E-CUT!!!\n"); 16998c2ecf20Sopenharmony_ci break; 17008c2ecf20Sopenharmony_ci default: 17018c2ecf20Sopenharmony_ci chipver |= CHIP_92D_D_CUT; 17028c2ecf20Sopenharmony_ci pr_err("Unknown CUT!\n"); 17038c2ecf20Sopenharmony_ci break; 17048c2ecf20Sopenharmony_ci } 17058c2ecf20Sopenharmony_ci rtlpriv->rtlhal.version = chipver; 17068c2ecf20Sopenharmony_ci} 17078c2ecf20Sopenharmony_ci 17088c2ecf20Sopenharmony_cistatic void _rtl92de_read_adapter_info(struct ieee80211_hw *hw) 17098c2ecf20Sopenharmony_ci{ 17108c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 17118c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 17128c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 17138c2ecf20Sopenharmony_ci int params[] = {RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID, 17148c2ecf20Sopenharmony_ci EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR_MAC0_92D, 17158c2ecf20Sopenharmony_ci EEPROM_CHANNEL_PLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, 17168c2ecf20Sopenharmony_ci COUNTRY_CODE_WORLD_WIDE_13}; 17178c2ecf20Sopenharmony_ci int i; 17188c2ecf20Sopenharmony_ci u16 usvalue; 17198c2ecf20Sopenharmony_ci u8 *hwinfo; 17208c2ecf20Sopenharmony_ci 17218c2ecf20Sopenharmony_ci hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); 17228c2ecf20Sopenharmony_ci if (!hwinfo) 17238c2ecf20Sopenharmony_ci return; 17248c2ecf20Sopenharmony_ci 17258c2ecf20Sopenharmony_ci if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) 17268c2ecf20Sopenharmony_ci goto exit; 17278c2ecf20Sopenharmony_ci 17288c2ecf20Sopenharmony_ci _rtl92de_efuse_update_chip_version(hw); 17298c2ecf20Sopenharmony_ci _rtl92de_read_macphymode_and_bandtype(hw, hwinfo); 17308c2ecf20Sopenharmony_ci 17318c2ecf20Sopenharmony_ci /* Read Permanent MAC address for 2nd interface */ 17328c2ecf20Sopenharmony_ci if (rtlhal->interfaceindex != 0) { 17338c2ecf20Sopenharmony_ci for (i = 0; i < 6; i += 2) { 17348c2ecf20Sopenharmony_ci usvalue = *(u16 *)&hwinfo[EEPROM_MAC_ADDR_MAC1_92D + i]; 17358c2ecf20Sopenharmony_ci *((u16 *) (&rtlefuse->dev_addr[i])) = usvalue; 17368c2ecf20Sopenharmony_ci } 17378c2ecf20Sopenharmony_ci } 17388c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, 17398c2ecf20Sopenharmony_ci rtlefuse->dev_addr); 17408c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "%pM\n", rtlefuse->dev_addr); 17418c2ecf20Sopenharmony_ci _rtl92de_read_txpower_info(hw, rtlefuse->autoload_failflag, hwinfo); 17428c2ecf20Sopenharmony_ci 17438c2ecf20Sopenharmony_ci /* Read Channel Plan */ 17448c2ecf20Sopenharmony_ci switch (rtlhal->bandset) { 17458c2ecf20Sopenharmony_ci case BAND_ON_2_4G: 17468c2ecf20Sopenharmony_ci rtlefuse->channel_plan = COUNTRY_CODE_TELEC; 17478c2ecf20Sopenharmony_ci break; 17488c2ecf20Sopenharmony_ci case BAND_ON_5G: 17498c2ecf20Sopenharmony_ci rtlefuse->channel_plan = COUNTRY_CODE_FCC; 17508c2ecf20Sopenharmony_ci break; 17518c2ecf20Sopenharmony_ci case BAND_ON_BOTH: 17528c2ecf20Sopenharmony_ci rtlefuse->channel_plan = COUNTRY_CODE_FCC; 17538c2ecf20Sopenharmony_ci break; 17548c2ecf20Sopenharmony_ci default: 17558c2ecf20Sopenharmony_ci rtlefuse->channel_plan = COUNTRY_CODE_FCC; 17568c2ecf20Sopenharmony_ci break; 17578c2ecf20Sopenharmony_ci } 17588c2ecf20Sopenharmony_ci rtlefuse->txpwr_fromeprom = true; 17598c2ecf20Sopenharmony_ciexit: 17608c2ecf20Sopenharmony_ci kfree(hwinfo); 17618c2ecf20Sopenharmony_ci} 17628c2ecf20Sopenharmony_ci 17638c2ecf20Sopenharmony_civoid rtl92de_read_eeprom_info(struct ieee80211_hw *hw) 17648c2ecf20Sopenharmony_ci{ 17658c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 17668c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 17678c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 17688c2ecf20Sopenharmony_ci u8 tmp_u1b; 17698c2ecf20Sopenharmony_ci 17708c2ecf20Sopenharmony_ci rtlhal->version = _rtl92de_read_chip_version(hw); 17718c2ecf20Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); 17728c2ecf20Sopenharmony_ci rtlefuse->autoload_status = tmp_u1b; 17738c2ecf20Sopenharmony_ci if (tmp_u1b & BIT(4)) { 17748c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EEPROM\n"); 17758c2ecf20Sopenharmony_ci rtlefuse->epromtype = EEPROM_93C46; 17768c2ecf20Sopenharmony_ci } else { 17778c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from EFUSE\n"); 17788c2ecf20Sopenharmony_ci rtlefuse->epromtype = EEPROM_BOOT_EFUSE; 17798c2ecf20Sopenharmony_ci } 17808c2ecf20Sopenharmony_ci if (tmp_u1b & BIT(5)) { 17818c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload OK\n"); 17828c2ecf20Sopenharmony_ci 17838c2ecf20Sopenharmony_ci rtlefuse->autoload_failflag = false; 17848c2ecf20Sopenharmony_ci _rtl92de_read_adapter_info(hw); 17858c2ecf20Sopenharmony_ci } else { 17868c2ecf20Sopenharmony_ci pr_err("Autoload ERR!!\n"); 17878c2ecf20Sopenharmony_ci } 17888c2ecf20Sopenharmony_ci return; 17898c2ecf20Sopenharmony_ci} 17908c2ecf20Sopenharmony_ci 17918c2ecf20Sopenharmony_cistatic void rtl92de_update_hal_rate_table(struct ieee80211_hw *hw, 17928c2ecf20Sopenharmony_ci struct ieee80211_sta *sta) 17938c2ecf20Sopenharmony_ci{ 17948c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 17958c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 17968c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 17978c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 17988c2ecf20Sopenharmony_ci u32 ratr_value; 17998c2ecf20Sopenharmony_ci u8 ratr_index = 0; 18008c2ecf20Sopenharmony_ci u8 nmode = mac->ht_enable; 18018c2ecf20Sopenharmony_ci u8 mimo_ps = IEEE80211_SMPS_OFF; 18028c2ecf20Sopenharmony_ci u16 shortgi_rate; 18038c2ecf20Sopenharmony_ci u32 tmp_ratr_value; 18048c2ecf20Sopenharmony_ci u8 curtxbw_40mhz = mac->bw_40; 18058c2ecf20Sopenharmony_ci u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 18068c2ecf20Sopenharmony_ci 1 : 0; 18078c2ecf20Sopenharmony_ci u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 18088c2ecf20Sopenharmony_ci 1 : 0; 18098c2ecf20Sopenharmony_ci enum wireless_mode wirelessmode = mac->mode; 18108c2ecf20Sopenharmony_ci 18118c2ecf20Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_5G) 18128c2ecf20Sopenharmony_ci ratr_value = sta->supp_rates[1] << 4; 18138c2ecf20Sopenharmony_ci else 18148c2ecf20Sopenharmony_ci ratr_value = sta->supp_rates[0]; 18158c2ecf20Sopenharmony_ci ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | 18168c2ecf20Sopenharmony_ci sta->ht_cap.mcs.rx_mask[0] << 12); 18178c2ecf20Sopenharmony_ci switch (wirelessmode) { 18188c2ecf20Sopenharmony_ci case WIRELESS_MODE_A: 18198c2ecf20Sopenharmony_ci ratr_value &= 0x00000FF0; 18208c2ecf20Sopenharmony_ci break; 18218c2ecf20Sopenharmony_ci case WIRELESS_MODE_B: 18228c2ecf20Sopenharmony_ci if (ratr_value & 0x0000000c) 18238c2ecf20Sopenharmony_ci ratr_value &= 0x0000000d; 18248c2ecf20Sopenharmony_ci else 18258c2ecf20Sopenharmony_ci ratr_value &= 0x0000000f; 18268c2ecf20Sopenharmony_ci break; 18278c2ecf20Sopenharmony_ci case WIRELESS_MODE_G: 18288c2ecf20Sopenharmony_ci ratr_value &= 0x00000FF5; 18298c2ecf20Sopenharmony_ci break; 18308c2ecf20Sopenharmony_ci case WIRELESS_MODE_N_24G: 18318c2ecf20Sopenharmony_ci case WIRELESS_MODE_N_5G: 18328c2ecf20Sopenharmony_ci nmode = 1; 18338c2ecf20Sopenharmony_ci if (mimo_ps == IEEE80211_SMPS_STATIC) { 18348c2ecf20Sopenharmony_ci ratr_value &= 0x0007F005; 18358c2ecf20Sopenharmony_ci } else { 18368c2ecf20Sopenharmony_ci u32 ratr_mask; 18378c2ecf20Sopenharmony_ci 18388c2ecf20Sopenharmony_ci if (get_rf_type(rtlphy) == RF_1T2R || 18398c2ecf20Sopenharmony_ci get_rf_type(rtlphy) == RF_1T1R) { 18408c2ecf20Sopenharmony_ci ratr_mask = 0x000ff005; 18418c2ecf20Sopenharmony_ci } else { 18428c2ecf20Sopenharmony_ci ratr_mask = 0x0f0ff005; 18438c2ecf20Sopenharmony_ci } 18448c2ecf20Sopenharmony_ci 18458c2ecf20Sopenharmony_ci ratr_value &= ratr_mask; 18468c2ecf20Sopenharmony_ci } 18478c2ecf20Sopenharmony_ci break; 18488c2ecf20Sopenharmony_ci default: 18498c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) 18508c2ecf20Sopenharmony_ci ratr_value &= 0x000ff0ff; 18518c2ecf20Sopenharmony_ci else 18528c2ecf20Sopenharmony_ci ratr_value &= 0x0f0ff0ff; 18538c2ecf20Sopenharmony_ci 18548c2ecf20Sopenharmony_ci break; 18558c2ecf20Sopenharmony_ci } 18568c2ecf20Sopenharmony_ci ratr_value &= 0x0FFFFFFF; 18578c2ecf20Sopenharmony_ci if (nmode && ((curtxbw_40mhz && curshortgi_40mhz) || 18588c2ecf20Sopenharmony_ci (!curtxbw_40mhz && curshortgi_20mhz))) { 18598c2ecf20Sopenharmony_ci ratr_value |= 0x10000000; 18608c2ecf20Sopenharmony_ci tmp_ratr_value = (ratr_value >> 12); 18618c2ecf20Sopenharmony_ci for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { 18628c2ecf20Sopenharmony_ci if ((1 << shortgi_rate) & tmp_ratr_value) 18638c2ecf20Sopenharmony_ci break; 18648c2ecf20Sopenharmony_ci } 18658c2ecf20Sopenharmony_ci shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | 18668c2ecf20Sopenharmony_ci (shortgi_rate << 4) | (shortgi_rate); 18678c2ecf20Sopenharmony_ci } 18688c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); 18698c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", 18708c2ecf20Sopenharmony_ci rtl_read_dword(rtlpriv, REG_ARFR0)); 18718c2ecf20Sopenharmony_ci} 18728c2ecf20Sopenharmony_ci 18738c2ecf20Sopenharmony_cistatic void rtl92de_update_hal_rate_mask(struct ieee80211_hw *hw, 18748c2ecf20Sopenharmony_ci struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) 18758c2ecf20Sopenharmony_ci{ 18768c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 18778c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 18788c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 18798c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 18808c2ecf20Sopenharmony_ci struct rtl_sta_info *sta_entry = NULL; 18818c2ecf20Sopenharmony_ci u32 ratr_bitmap; 18828c2ecf20Sopenharmony_ci u8 ratr_index; 18838c2ecf20Sopenharmony_ci u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; 18848c2ecf20Sopenharmony_ci u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 18858c2ecf20Sopenharmony_ci 1 : 0; 18868c2ecf20Sopenharmony_ci u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 18878c2ecf20Sopenharmony_ci 1 : 0; 18888c2ecf20Sopenharmony_ci enum wireless_mode wirelessmode = 0; 18898c2ecf20Sopenharmony_ci bool shortgi = false; 18908c2ecf20Sopenharmony_ci u32 value[2]; 18918c2ecf20Sopenharmony_ci u8 macid = 0; 18928c2ecf20Sopenharmony_ci u8 mimo_ps = IEEE80211_SMPS_OFF; 18938c2ecf20Sopenharmony_ci 18948c2ecf20Sopenharmony_ci sta_entry = (struct rtl_sta_info *) sta->drv_priv; 18958c2ecf20Sopenharmony_ci mimo_ps = sta_entry->mimo_ps; 18968c2ecf20Sopenharmony_ci wirelessmode = sta_entry->wireless_mode; 18978c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_STATION) 18988c2ecf20Sopenharmony_ci curtxbw_40mhz = mac->bw_40; 18998c2ecf20Sopenharmony_ci else if (mac->opmode == NL80211_IFTYPE_AP || 19008c2ecf20Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC) 19018c2ecf20Sopenharmony_ci macid = sta->aid + 1; 19028c2ecf20Sopenharmony_ci 19038c2ecf20Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_5G) 19048c2ecf20Sopenharmony_ci ratr_bitmap = sta->supp_rates[1] << 4; 19058c2ecf20Sopenharmony_ci else 19068c2ecf20Sopenharmony_ci ratr_bitmap = sta->supp_rates[0]; 19078c2ecf20Sopenharmony_ci ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | 19088c2ecf20Sopenharmony_ci sta->ht_cap.mcs.rx_mask[0] << 12); 19098c2ecf20Sopenharmony_ci switch (wirelessmode) { 19108c2ecf20Sopenharmony_ci case WIRELESS_MODE_B: 19118c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_B; 19128c2ecf20Sopenharmony_ci if (ratr_bitmap & 0x0000000c) 19138c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0000000d; 19148c2ecf20Sopenharmony_ci else 19158c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0000000f; 19168c2ecf20Sopenharmony_ci break; 19178c2ecf20Sopenharmony_ci case WIRELESS_MODE_G: 19188c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_GB; 19198c2ecf20Sopenharmony_ci 19208c2ecf20Sopenharmony_ci if (rssi_level == 1) 19218c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00000f00; 19228c2ecf20Sopenharmony_ci else if (rssi_level == 2) 19238c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00000ff0; 19248c2ecf20Sopenharmony_ci else 19258c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00000ff5; 19268c2ecf20Sopenharmony_ci break; 19278c2ecf20Sopenharmony_ci case WIRELESS_MODE_A: 19288c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_G; 19298c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00000ff0; 19308c2ecf20Sopenharmony_ci break; 19318c2ecf20Sopenharmony_ci case WIRELESS_MODE_N_24G: 19328c2ecf20Sopenharmony_ci case WIRELESS_MODE_N_5G: 19338c2ecf20Sopenharmony_ci if (wirelessmode == WIRELESS_MODE_N_24G) 19348c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 19358c2ecf20Sopenharmony_ci else 19368c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NG; 19378c2ecf20Sopenharmony_ci if (mimo_ps == IEEE80211_SMPS_STATIC) { 19388c2ecf20Sopenharmony_ci if (rssi_level == 1) 19398c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00070000; 19408c2ecf20Sopenharmony_ci else if (rssi_level == 2) 19418c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0007f000; 19428c2ecf20Sopenharmony_ci else 19438c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0007f005; 19448c2ecf20Sopenharmony_ci } else { 19458c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R || 19468c2ecf20Sopenharmony_ci rtlphy->rf_type == RF_1T1R) { 19478c2ecf20Sopenharmony_ci if (curtxbw_40mhz) { 19488c2ecf20Sopenharmony_ci if (rssi_level == 1) 19498c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000f0000; 19508c2ecf20Sopenharmony_ci else if (rssi_level == 2) 19518c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff000; 19528c2ecf20Sopenharmony_ci else 19538c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff015; 19548c2ecf20Sopenharmony_ci } else { 19558c2ecf20Sopenharmony_ci if (rssi_level == 1) 19568c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000f0000; 19578c2ecf20Sopenharmony_ci else if (rssi_level == 2) 19588c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff000; 19598c2ecf20Sopenharmony_ci else 19608c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff005; 19618c2ecf20Sopenharmony_ci } 19628c2ecf20Sopenharmony_ci } else { 19638c2ecf20Sopenharmony_ci if (curtxbw_40mhz) { 19648c2ecf20Sopenharmony_ci if (rssi_level == 1) 19658c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0f0000; 19668c2ecf20Sopenharmony_ci else if (rssi_level == 2) 19678c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff000; 19688c2ecf20Sopenharmony_ci else 19698c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff015; 19708c2ecf20Sopenharmony_ci } else { 19718c2ecf20Sopenharmony_ci if (rssi_level == 1) 19728c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0f0000; 19738c2ecf20Sopenharmony_ci else if (rssi_level == 2) 19748c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff000; 19758c2ecf20Sopenharmony_ci else 19768c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff005; 19778c2ecf20Sopenharmony_ci } 19788c2ecf20Sopenharmony_ci } 19798c2ecf20Sopenharmony_ci } 19808c2ecf20Sopenharmony_ci if ((curtxbw_40mhz && curshortgi_40mhz) || 19818c2ecf20Sopenharmony_ci (!curtxbw_40mhz && curshortgi_20mhz)) { 19828c2ecf20Sopenharmony_ci 19838c2ecf20Sopenharmony_ci if (macid == 0) 19848c2ecf20Sopenharmony_ci shortgi = true; 19858c2ecf20Sopenharmony_ci else if (macid == 1) 19868c2ecf20Sopenharmony_ci shortgi = false; 19878c2ecf20Sopenharmony_ci } 19888c2ecf20Sopenharmony_ci break; 19898c2ecf20Sopenharmony_ci default: 19908c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 19918c2ecf20Sopenharmony_ci 19928c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) 19938c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff0ff; 19948c2ecf20Sopenharmony_ci else 19958c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff0ff; 19968c2ecf20Sopenharmony_ci break; 19978c2ecf20Sopenharmony_ci } 19988c2ecf20Sopenharmony_ci 19998c2ecf20Sopenharmony_ci value[0] = (ratr_bitmap & 0x0fffffff) | (ratr_index << 28); 20008c2ecf20Sopenharmony_ci value[1] = macid | (shortgi ? 0x20 : 0x00) | 0x80; 20018c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, 20028c2ecf20Sopenharmony_ci "ratr_bitmap :%x value0:%x value1:%x\n", 20038c2ecf20Sopenharmony_ci ratr_bitmap, value[0], value[1]); 20048c2ecf20Sopenharmony_ci rtl92d_fill_h2c_cmd(hw, H2C_RA_MASK, 5, (u8 *) value); 20058c2ecf20Sopenharmony_ci if (macid != 0) 20068c2ecf20Sopenharmony_ci sta_entry->ratr_index = ratr_index; 20078c2ecf20Sopenharmony_ci} 20088c2ecf20Sopenharmony_ci 20098c2ecf20Sopenharmony_civoid rtl92de_update_hal_rate_tbl(struct ieee80211_hw *hw, 20108c2ecf20Sopenharmony_ci struct ieee80211_sta *sta, u8 rssi_level, bool update_bw) 20118c2ecf20Sopenharmony_ci{ 20128c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 20138c2ecf20Sopenharmony_ci 20148c2ecf20Sopenharmony_ci if (rtlpriv->dm.useramask) 20158c2ecf20Sopenharmony_ci rtl92de_update_hal_rate_mask(hw, sta, rssi_level, update_bw); 20168c2ecf20Sopenharmony_ci else 20178c2ecf20Sopenharmony_ci rtl92de_update_hal_rate_table(hw, sta); 20188c2ecf20Sopenharmony_ci} 20198c2ecf20Sopenharmony_ci 20208c2ecf20Sopenharmony_civoid rtl92de_update_channel_access_setting(struct ieee80211_hw *hw) 20218c2ecf20Sopenharmony_ci{ 20228c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 20238c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 20248c2ecf20Sopenharmony_ci u16 sifs_timer; 20258c2ecf20Sopenharmony_ci 20268c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, 20278c2ecf20Sopenharmony_ci &mac->slot_time); 20288c2ecf20Sopenharmony_ci if (!mac->ht_enable) 20298c2ecf20Sopenharmony_ci sifs_timer = 0x0a0a; 20308c2ecf20Sopenharmony_ci else 20318c2ecf20Sopenharmony_ci sifs_timer = 0x1010; 20328c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); 20338c2ecf20Sopenharmony_ci} 20348c2ecf20Sopenharmony_ci 20358c2ecf20Sopenharmony_cibool rtl92de_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 *valid) 20368c2ecf20Sopenharmony_ci{ 20378c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 20388c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 20398c2ecf20Sopenharmony_ci struct rtl_pci *rtlpci = rtl_pcidev(rtl_pcipriv(hw)); 20408c2ecf20Sopenharmony_ci enum rf_pwrstate e_rfpowerstate_toset; 20418c2ecf20Sopenharmony_ci u8 u1tmp; 20428c2ecf20Sopenharmony_ci bool actuallyset = false; 20438c2ecf20Sopenharmony_ci unsigned long flag; 20448c2ecf20Sopenharmony_ci 20458c2ecf20Sopenharmony_ci if (rtlpci->being_init_adapter) 20468c2ecf20Sopenharmony_ci return false; 20478c2ecf20Sopenharmony_ci if (ppsc->swrf_processing) 20488c2ecf20Sopenharmony_ci return false; 20498c2ecf20Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 20508c2ecf20Sopenharmony_ci if (ppsc->rfchange_inprogress) { 20518c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 20528c2ecf20Sopenharmony_ci return false; 20538c2ecf20Sopenharmony_ci } else { 20548c2ecf20Sopenharmony_ci ppsc->rfchange_inprogress = true; 20558c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 20568c2ecf20Sopenharmony_ci } 20578c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, rtl_read_byte(rtlpriv, 20588c2ecf20Sopenharmony_ci REG_MAC_PINMUX_CFG) & ~(BIT(3))); 20598c2ecf20Sopenharmony_ci u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); 20608c2ecf20Sopenharmony_ci e_rfpowerstate_toset = (u1tmp & BIT(3)) ? ERFON : ERFOFF; 20618c2ecf20Sopenharmony_ci if (ppsc->hwradiooff && (e_rfpowerstate_toset == ERFON)) { 20628c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 20638c2ecf20Sopenharmony_ci "GPIOChangeRF - HW Radio ON, RF ON\n"); 20648c2ecf20Sopenharmony_ci e_rfpowerstate_toset = ERFON; 20658c2ecf20Sopenharmony_ci ppsc->hwradiooff = false; 20668c2ecf20Sopenharmony_ci actuallyset = true; 20678c2ecf20Sopenharmony_ci } else if (!ppsc->hwradiooff && (e_rfpowerstate_toset == ERFOFF)) { 20688c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG, 20698c2ecf20Sopenharmony_ci "GPIOChangeRF - HW Radio OFF, RF OFF\n"); 20708c2ecf20Sopenharmony_ci e_rfpowerstate_toset = ERFOFF; 20718c2ecf20Sopenharmony_ci ppsc->hwradiooff = true; 20728c2ecf20Sopenharmony_ci actuallyset = true; 20738c2ecf20Sopenharmony_ci } 20748c2ecf20Sopenharmony_ci if (actuallyset) { 20758c2ecf20Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 20768c2ecf20Sopenharmony_ci ppsc->rfchange_inprogress = false; 20778c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 20788c2ecf20Sopenharmony_ci } else { 20798c2ecf20Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) 20808c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 20818c2ecf20Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 20828c2ecf20Sopenharmony_ci ppsc->rfchange_inprogress = false; 20838c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 20848c2ecf20Sopenharmony_ci } 20858c2ecf20Sopenharmony_ci *valid = 1; 20868c2ecf20Sopenharmony_ci return !ppsc->hwradiooff; 20878c2ecf20Sopenharmony_ci} 20888c2ecf20Sopenharmony_ci 20898c2ecf20Sopenharmony_civoid rtl92de_set_key(struct ieee80211_hw *hw, u32 key_index, 20908c2ecf20Sopenharmony_ci u8 *p_macaddr, bool is_group, u8 enc_algo, 20918c2ecf20Sopenharmony_ci bool is_wepkey, bool clear_all) 20928c2ecf20Sopenharmony_ci{ 20938c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 20948c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 20958c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 20968c2ecf20Sopenharmony_ci u8 *macaddr = p_macaddr; 20978c2ecf20Sopenharmony_ci u32 entry_id; 20988c2ecf20Sopenharmony_ci bool is_pairwise = false; 20998c2ecf20Sopenharmony_ci static u8 cam_const_addr[4][6] = { 21008c2ecf20Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 21018c2ecf20Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x01}, 21028c2ecf20Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x02}, 21038c2ecf20Sopenharmony_ci {0x00, 0x00, 0x00, 0x00, 0x00, 0x03} 21048c2ecf20Sopenharmony_ci }; 21058c2ecf20Sopenharmony_ci static u8 cam_const_broad[] = { 21068c2ecf20Sopenharmony_ci 0xff, 0xff, 0xff, 0xff, 0xff, 0xff 21078c2ecf20Sopenharmony_ci }; 21088c2ecf20Sopenharmony_ci 21098c2ecf20Sopenharmony_ci if (clear_all) { 21108c2ecf20Sopenharmony_ci u8 idx; 21118c2ecf20Sopenharmony_ci u8 cam_offset = 0; 21128c2ecf20Sopenharmony_ci u8 clear_number = 5; 21138c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, "clear_all\n"); 21148c2ecf20Sopenharmony_ci for (idx = 0; idx < clear_number; idx++) { 21158c2ecf20Sopenharmony_ci rtl_cam_mark_invalid(hw, cam_offset + idx); 21168c2ecf20Sopenharmony_ci rtl_cam_empty_entry(hw, cam_offset + idx); 21178c2ecf20Sopenharmony_ci 21188c2ecf20Sopenharmony_ci if (idx < 5) { 21198c2ecf20Sopenharmony_ci memset(rtlpriv->sec.key_buf[idx], 0, 21208c2ecf20Sopenharmony_ci MAX_KEY_LEN); 21218c2ecf20Sopenharmony_ci rtlpriv->sec.key_len[idx] = 0; 21228c2ecf20Sopenharmony_ci } 21238c2ecf20Sopenharmony_ci } 21248c2ecf20Sopenharmony_ci } else { 21258c2ecf20Sopenharmony_ci switch (enc_algo) { 21268c2ecf20Sopenharmony_ci case WEP40_ENCRYPTION: 21278c2ecf20Sopenharmony_ci enc_algo = CAM_WEP40; 21288c2ecf20Sopenharmony_ci break; 21298c2ecf20Sopenharmony_ci case WEP104_ENCRYPTION: 21308c2ecf20Sopenharmony_ci enc_algo = CAM_WEP104; 21318c2ecf20Sopenharmony_ci break; 21328c2ecf20Sopenharmony_ci case TKIP_ENCRYPTION: 21338c2ecf20Sopenharmony_ci enc_algo = CAM_TKIP; 21348c2ecf20Sopenharmony_ci break; 21358c2ecf20Sopenharmony_ci case AESCCMP_ENCRYPTION: 21368c2ecf20Sopenharmony_ci enc_algo = CAM_AES; 21378c2ecf20Sopenharmony_ci break; 21388c2ecf20Sopenharmony_ci default: 21398c2ecf20Sopenharmony_ci pr_err("switch case %#x not processed\n", 21408c2ecf20Sopenharmony_ci enc_algo); 21418c2ecf20Sopenharmony_ci enc_algo = CAM_TKIP; 21428c2ecf20Sopenharmony_ci break; 21438c2ecf20Sopenharmony_ci } 21448c2ecf20Sopenharmony_ci if (is_wepkey || rtlpriv->sec.use_defaultkey) { 21458c2ecf20Sopenharmony_ci macaddr = cam_const_addr[key_index]; 21468c2ecf20Sopenharmony_ci entry_id = key_index; 21478c2ecf20Sopenharmony_ci } else { 21488c2ecf20Sopenharmony_ci if (is_group) { 21498c2ecf20Sopenharmony_ci macaddr = cam_const_broad; 21508c2ecf20Sopenharmony_ci entry_id = key_index; 21518c2ecf20Sopenharmony_ci } else { 21528c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP) { 21538c2ecf20Sopenharmony_ci entry_id = rtl_cam_get_free_entry(hw, 21548c2ecf20Sopenharmony_ci p_macaddr); 21558c2ecf20Sopenharmony_ci if (entry_id >= TOTAL_CAM_ENTRY) { 21568c2ecf20Sopenharmony_ci pr_err("Can not find free hw security cam entry\n"); 21578c2ecf20Sopenharmony_ci return; 21588c2ecf20Sopenharmony_ci } 21598c2ecf20Sopenharmony_ci } else { 21608c2ecf20Sopenharmony_ci entry_id = CAM_PAIRWISE_KEY_POSITION; 21618c2ecf20Sopenharmony_ci } 21628c2ecf20Sopenharmony_ci key_index = PAIRWISE_KEYIDX; 21638c2ecf20Sopenharmony_ci is_pairwise = true; 21648c2ecf20Sopenharmony_ci } 21658c2ecf20Sopenharmony_ci } 21668c2ecf20Sopenharmony_ci if (rtlpriv->sec.key_len[key_index] == 0) { 21678c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 21688c2ecf20Sopenharmony_ci "delete one entry, entry_id is %d\n", 21698c2ecf20Sopenharmony_ci entry_id); 21708c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP) 21718c2ecf20Sopenharmony_ci rtl_cam_del_entry(hw, p_macaddr); 21728c2ecf20Sopenharmony_ci rtl_cam_delete_one_entry(hw, p_macaddr, entry_id); 21738c2ecf20Sopenharmony_ci } else { 21748c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, 21758c2ecf20Sopenharmony_ci "The insert KEY length is %d\n", 21768c2ecf20Sopenharmony_ci rtlpriv->sec.key_len[PAIRWISE_KEYIDX]); 21778c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, 21788c2ecf20Sopenharmony_ci "The insert KEY is %x %x\n", 21798c2ecf20Sopenharmony_ci rtlpriv->sec.key_buf[0][0], 21808c2ecf20Sopenharmony_ci rtlpriv->sec.key_buf[0][1]); 21818c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 21828c2ecf20Sopenharmony_ci "add one entry\n"); 21838c2ecf20Sopenharmony_ci if (is_pairwise) { 21848c2ecf20Sopenharmony_ci RT_PRINT_DATA(rtlpriv, COMP_SEC, DBG_LOUD, 21858c2ecf20Sopenharmony_ci "Pairwise Key content", 21868c2ecf20Sopenharmony_ci rtlpriv->sec.pairwise_key, 21878c2ecf20Sopenharmony_ci rtlpriv-> 21888c2ecf20Sopenharmony_ci sec.key_len[PAIRWISE_KEYIDX]); 21898c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 21908c2ecf20Sopenharmony_ci "set Pairwise key\n"); 21918c2ecf20Sopenharmony_ci rtl_cam_add_one_entry(hw, macaddr, key_index, 21928c2ecf20Sopenharmony_ci entry_id, enc_algo, 21938c2ecf20Sopenharmony_ci CAM_CONFIG_NO_USEDK, 21948c2ecf20Sopenharmony_ci rtlpriv-> 21958c2ecf20Sopenharmony_ci sec.key_buf[key_index]); 21968c2ecf20Sopenharmony_ci } else { 21978c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 21988c2ecf20Sopenharmony_ci "set group key\n"); 21998c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) { 22008c2ecf20Sopenharmony_ci rtl_cam_add_one_entry(hw, 22018c2ecf20Sopenharmony_ci rtlefuse->dev_addr, 22028c2ecf20Sopenharmony_ci PAIRWISE_KEYIDX, 22038c2ecf20Sopenharmony_ci CAM_PAIRWISE_KEY_POSITION, 22048c2ecf20Sopenharmony_ci enc_algo, CAM_CONFIG_NO_USEDK, 22058c2ecf20Sopenharmony_ci rtlpriv->sec.key_buf[entry_id]); 22068c2ecf20Sopenharmony_ci } 22078c2ecf20Sopenharmony_ci rtl_cam_add_one_entry(hw, macaddr, key_index, 22088c2ecf20Sopenharmony_ci entry_id, enc_algo, 22098c2ecf20Sopenharmony_ci CAM_CONFIG_NO_USEDK, 22108c2ecf20Sopenharmony_ci rtlpriv->sec.key_buf 22118c2ecf20Sopenharmony_ci [entry_id]); 22128c2ecf20Sopenharmony_ci } 22138c2ecf20Sopenharmony_ci } 22148c2ecf20Sopenharmony_ci } 22158c2ecf20Sopenharmony_ci} 22168c2ecf20Sopenharmony_ci 22178c2ecf20Sopenharmony_civoid rtl92de_suspend(struct ieee80211_hw *hw) 22188c2ecf20Sopenharmony_ci{ 22198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 22208c2ecf20Sopenharmony_ci 22218c2ecf20Sopenharmony_ci rtlpriv->rtlhal.macphyctl_reg = rtl_read_byte(rtlpriv, 22228c2ecf20Sopenharmony_ci REG_MAC_PHY_CTRL_NORMAL); 22238c2ecf20Sopenharmony_ci} 22248c2ecf20Sopenharmony_ci 22258c2ecf20Sopenharmony_civoid rtl92de_resume(struct ieee80211_hw *hw) 22268c2ecf20Sopenharmony_ci{ 22278c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 22288c2ecf20Sopenharmony_ci 22298c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_PHY_CTRL_NORMAL, 22308c2ecf20Sopenharmony_ci rtlpriv->rtlhal.macphyctl_reg); 22318c2ecf20Sopenharmony_ci} 2232