162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2012 Realtek Corporation.*/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "../wifi.h" 562306a36Sopenharmony_ci#include "../efuse.h" 662306a36Sopenharmony_ci#include "../base.h" 762306a36Sopenharmony_ci#include "../cam.h" 862306a36Sopenharmony_ci#include "../ps.h" 962306a36Sopenharmony_ci#include "../usb.h" 1062306a36Sopenharmony_ci#include "reg.h" 1162306a36Sopenharmony_ci#include "def.h" 1262306a36Sopenharmony_ci#include "phy.h" 1362306a36Sopenharmony_ci#include "../rtl8192c/phy_common.h" 1462306a36Sopenharmony_ci#include "mac.h" 1562306a36Sopenharmony_ci#include "dm.h" 1662306a36Sopenharmony_ci#include "../rtl8192c/dm_common.h" 1762306a36Sopenharmony_ci#include "../rtl8192c/fw_common.h" 1862306a36Sopenharmony_ci#include "hw.h" 1962306a36Sopenharmony_ci#include "../rtl8192ce/hw.h" 2062306a36Sopenharmony_ci#include "trx.h" 2162306a36Sopenharmony_ci#include "led.h" 2262306a36Sopenharmony_ci#include "table.h" 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_cistatic void _rtl92cu_phy_param_tab_init(struct ieee80211_hw *hw) 2562306a36Sopenharmony_ci{ 2662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 2862306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci rtlphy->hwparam_tables[MAC_REG].length = RTL8192CUMAC_2T_ARRAYLENGTH; 3162306a36Sopenharmony_ci rtlphy->hwparam_tables[MAC_REG].pdata = RTL8192CUMAC_2T_ARRAY; 3262306a36Sopenharmony_ci if (IS_HIGHT_PA(rtlefuse->board_type)) { 3362306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_PG].length = 3462306a36Sopenharmony_ci RTL8192CUPHY_REG_ARRAY_PG_HPLENGTH; 3562306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_PG].pdata = 3662306a36Sopenharmony_ci RTL8192CUPHY_REG_ARRAY_PG_HP; 3762306a36Sopenharmony_ci } else { 3862306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_PG].length = 3962306a36Sopenharmony_ci RTL8192CUPHY_REG_ARRAY_PGLENGTH; 4062306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_PG].pdata = 4162306a36Sopenharmony_ci RTL8192CUPHY_REG_ARRAY_PG; 4262306a36Sopenharmony_ci } 4362306a36Sopenharmony_ci /* 2T */ 4462306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_2T].length = 4562306a36Sopenharmony_ci RTL8192CUPHY_REG_2TARRAY_LENGTH; 4662306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_2T].pdata = 4762306a36Sopenharmony_ci RTL8192CUPHY_REG_2TARRAY; 4862306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_2T].length = 4962306a36Sopenharmony_ci RTL8192CURADIOA_2TARRAYLENGTH; 5062306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_2T].pdata = 5162306a36Sopenharmony_ci RTL8192CURADIOA_2TARRAY; 5262306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_2T].length = 5362306a36Sopenharmony_ci RTL8192CURADIOB_2TARRAYLENGTH; 5462306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_2T].pdata = 5562306a36Sopenharmony_ci RTL8192CU_RADIOB_2TARRAY; 5662306a36Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_2T].length = 5762306a36Sopenharmony_ci RTL8192CUAGCTAB_2TARRAYLENGTH; 5862306a36Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_2T].pdata = 5962306a36Sopenharmony_ci RTL8192CUAGCTAB_2TARRAY; 6062306a36Sopenharmony_ci /* 1T */ 6162306a36Sopenharmony_ci if (IS_HIGHT_PA(rtlefuse->board_type)) { 6262306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_1T].length = 6362306a36Sopenharmony_ci RTL8192CUPHY_REG_1T_HPARRAYLENGTH; 6462306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_1T].pdata = 6562306a36Sopenharmony_ci RTL8192CUPHY_REG_1T_HPARRAY; 6662306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_1T].length = 6762306a36Sopenharmony_ci RTL8192CURADIOA_1T_HPARRAYLENGTH; 6862306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_1T].pdata = 6962306a36Sopenharmony_ci RTL8192CURADIOA_1T_HPARRAY; 7062306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_1T].length = 7162306a36Sopenharmony_ci RTL8192CURADIOB_1TARRAYLENGTH; 7262306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_1T].pdata = 7362306a36Sopenharmony_ci RTL8192CU_RADIOB_1TARRAY; 7462306a36Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_1T].length = 7562306a36Sopenharmony_ci RTL8192CUAGCTAB_1T_HPARRAYLENGTH; 7662306a36Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_1T].pdata = 7762306a36Sopenharmony_ci RTL8192CUAGCTAB_1T_HPARRAY; 7862306a36Sopenharmony_ci } else { 7962306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_1T].length = 8062306a36Sopenharmony_ci RTL8192CUPHY_REG_1TARRAY_LENGTH; 8162306a36Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_1T].pdata = 8262306a36Sopenharmony_ci RTL8192CUPHY_REG_1TARRAY; 8362306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_1T].length = 8462306a36Sopenharmony_ci RTL8192CURADIOA_1TARRAYLENGTH; 8562306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_1T].pdata = 8662306a36Sopenharmony_ci RTL8192CU_RADIOA_1TARRAY; 8762306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_1T].length = 8862306a36Sopenharmony_ci RTL8192CURADIOB_1TARRAYLENGTH; 8962306a36Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_1T].pdata = 9062306a36Sopenharmony_ci RTL8192CU_RADIOB_1TARRAY; 9162306a36Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_1T].length = 9262306a36Sopenharmony_ci RTL8192CUAGCTAB_1TARRAYLENGTH; 9362306a36Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_1T].pdata = 9462306a36Sopenharmony_ci RTL8192CUAGCTAB_1TARRAY; 9562306a36Sopenharmony_ci } 9662306a36Sopenharmony_ci} 9762306a36Sopenharmony_ci 9862306a36Sopenharmony_cistatic void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 9962306a36Sopenharmony_ci bool autoload_fail, 10062306a36Sopenharmony_ci u8 *hwinfo) 10162306a36Sopenharmony_ci{ 10262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10362306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 10462306a36Sopenharmony_ci u8 rf_path, index, tempval; 10562306a36Sopenharmony_ci u16 i; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 10862306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 10962306a36Sopenharmony_ci if (!autoload_fail) { 11062306a36Sopenharmony_ci rtlefuse-> 11162306a36Sopenharmony_ci eeprom_chnlarea_txpwr_cck[rf_path][i] = 11262306a36Sopenharmony_ci hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; 11362306a36Sopenharmony_ci rtlefuse-> 11462306a36Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = 11562306a36Sopenharmony_ci hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + 11662306a36Sopenharmony_ci i]; 11762306a36Sopenharmony_ci } else { 11862306a36Sopenharmony_ci rtlefuse-> 11962306a36Sopenharmony_ci eeprom_chnlarea_txpwr_cck[rf_path][i] = 12062306a36Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL; 12162306a36Sopenharmony_ci rtlefuse-> 12262306a36Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = 12362306a36Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL; 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci } 12662306a36Sopenharmony_ci } 12762306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 12862306a36Sopenharmony_ci if (!autoload_fail) 12962306a36Sopenharmony_ci tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; 13062306a36Sopenharmony_ci else 13162306a36Sopenharmony_ci tempval = EEPROM_DEFAULT_HT40_2SDIFF; 13262306a36Sopenharmony_ci rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = 13362306a36Sopenharmony_ci (tempval & 0xf); 13462306a36Sopenharmony_ci rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = 13562306a36Sopenharmony_ci ((tempval & 0xf0) >> 4); 13662306a36Sopenharmony_ci } 13762306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) 13862306a36Sopenharmony_ci for (i = 0; i < 3; i++) 13962306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_EEPROM, 14062306a36Sopenharmony_ci "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", 14162306a36Sopenharmony_ci rf_path, i, 14262306a36Sopenharmony_ci rtlefuse-> 14362306a36Sopenharmony_ci eeprom_chnlarea_txpwr_cck[rf_path][i]); 14462306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) 14562306a36Sopenharmony_ci for (i = 0; i < 3; i++) 14662306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_EEPROM, 14762306a36Sopenharmony_ci "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", 14862306a36Sopenharmony_ci rf_path, i, 14962306a36Sopenharmony_ci rtlefuse-> 15062306a36Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); 15162306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) 15262306a36Sopenharmony_ci for (i = 0; i < 3; i++) 15362306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_EEPROM, 15462306a36Sopenharmony_ci "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", 15562306a36Sopenharmony_ci rf_path, i, 15662306a36Sopenharmony_ci rtlefuse-> 15762306a36Sopenharmony_ci eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); 15862306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 15962306a36Sopenharmony_ci for (i = 0; i < 14; i++) { 16062306a36Sopenharmony_ci index = rtl92c_get_chnl_group((u8)i); 16162306a36Sopenharmony_ci rtlefuse->txpwrlevel_cck[rf_path][i] = 16262306a36Sopenharmony_ci rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index]; 16362306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = 16462306a36Sopenharmony_ci rtlefuse-> 16562306a36Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][index]; 16662306a36Sopenharmony_ci if ((rtlefuse-> 16762306a36Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - 16862306a36Sopenharmony_ci rtlefuse-> 16962306a36Sopenharmony_ci eprom_chnl_txpwr_ht40_2sdf[rf_path][index]) 17062306a36Sopenharmony_ci > 0) { 17162306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 17262306a36Sopenharmony_ci rtlefuse-> 17362306a36Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path] 17462306a36Sopenharmony_ci [index] - rtlefuse-> 17562306a36Sopenharmony_ci eprom_chnl_txpwr_ht40_2sdf[rf_path] 17662306a36Sopenharmony_ci [index]; 17762306a36Sopenharmony_ci } else { 17862306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; 17962306a36Sopenharmony_ci } 18062306a36Sopenharmony_ci } 18162306a36Sopenharmony_ci for (i = 0; i < 14; i++) { 18262306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 18362306a36Sopenharmony_ci "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i, 18462306a36Sopenharmony_ci rtlefuse->txpwrlevel_cck[rf_path][i], 18562306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[rf_path][i], 18662306a36Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); 18762306a36Sopenharmony_ci } 18862306a36Sopenharmony_ci } 18962306a36Sopenharmony_ci for (i = 0; i < 3; i++) { 19062306a36Sopenharmony_ci if (!autoload_fail) { 19162306a36Sopenharmony_ci rtlefuse->eeprom_pwrlimit_ht40[i] = 19262306a36Sopenharmony_ci hwinfo[EEPROM_TXPWR_GROUP + i]; 19362306a36Sopenharmony_ci rtlefuse->eeprom_pwrlimit_ht20[i] = 19462306a36Sopenharmony_ci hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; 19562306a36Sopenharmony_ci } else { 19662306a36Sopenharmony_ci rtlefuse->eeprom_pwrlimit_ht40[i] = 0; 19762306a36Sopenharmony_ci rtlefuse->eeprom_pwrlimit_ht20[i] = 0; 19862306a36Sopenharmony_ci } 19962306a36Sopenharmony_ci } 20062306a36Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 20162306a36Sopenharmony_ci for (i = 0; i < 14; i++) { 20262306a36Sopenharmony_ci index = rtl92c_get_chnl_group((u8)i); 20362306a36Sopenharmony_ci if (rf_path == RF90_PATH_A) { 20462306a36Sopenharmony_ci rtlefuse->pwrgroup_ht20[rf_path][i] = 20562306a36Sopenharmony_ci (rtlefuse->eeprom_pwrlimit_ht20[index] 20662306a36Sopenharmony_ci & 0xf); 20762306a36Sopenharmony_ci rtlefuse->pwrgroup_ht40[rf_path][i] = 20862306a36Sopenharmony_ci (rtlefuse->eeprom_pwrlimit_ht40[index] 20962306a36Sopenharmony_ci & 0xf); 21062306a36Sopenharmony_ci } else if (rf_path == RF90_PATH_B) { 21162306a36Sopenharmony_ci rtlefuse->pwrgroup_ht20[rf_path][i] = 21262306a36Sopenharmony_ci ((rtlefuse->eeprom_pwrlimit_ht20[index] 21362306a36Sopenharmony_ci & 0xf0) >> 4); 21462306a36Sopenharmony_ci rtlefuse->pwrgroup_ht40[rf_path][i] = 21562306a36Sopenharmony_ci ((rtlefuse->eeprom_pwrlimit_ht40[index] 21662306a36Sopenharmony_ci & 0xf0) >> 4); 21762306a36Sopenharmony_ci } 21862306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 21962306a36Sopenharmony_ci "RF-%d pwrgroup_ht20[%d] = 0x%x\n", 22062306a36Sopenharmony_ci rf_path, i, 22162306a36Sopenharmony_ci rtlefuse->pwrgroup_ht20[rf_path][i]); 22262306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 22362306a36Sopenharmony_ci "RF-%d pwrgroup_ht40[%d] = 0x%x\n", 22462306a36Sopenharmony_ci rf_path, i, 22562306a36Sopenharmony_ci rtlefuse->pwrgroup_ht40[rf_path][i]); 22662306a36Sopenharmony_ci } 22762306a36Sopenharmony_ci } 22862306a36Sopenharmony_ci for (i = 0; i < 14; i++) { 22962306a36Sopenharmony_ci index = rtl92c_get_chnl_group((u8)i); 23062306a36Sopenharmony_ci if (!autoload_fail) 23162306a36Sopenharmony_ci tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; 23262306a36Sopenharmony_ci else 23362306a36Sopenharmony_ci tempval = EEPROM_DEFAULT_HT20_DIFF; 23462306a36Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); 23562306a36Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = 23662306a36Sopenharmony_ci ((tempval >> 4) & 0xF); 23762306a36Sopenharmony_ci if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) 23862306a36Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; 23962306a36Sopenharmony_ci if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) 24062306a36Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; 24162306a36Sopenharmony_ci index = rtl92c_get_chnl_group((u8)i); 24262306a36Sopenharmony_ci if (!autoload_fail) 24362306a36Sopenharmony_ci tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; 24462306a36Sopenharmony_ci else 24562306a36Sopenharmony_ci tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; 24662306a36Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); 24762306a36Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = 24862306a36Sopenharmony_ci ((tempval >> 4) & 0xF); 24962306a36Sopenharmony_ci } 25062306a36Sopenharmony_ci rtlefuse->legacy_ht_txpowerdiff = 25162306a36Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; 25262306a36Sopenharmony_ci for (i = 0; i < 14; i++) 25362306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 25462306a36Sopenharmony_ci "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", 25562306a36Sopenharmony_ci i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); 25662306a36Sopenharmony_ci for (i = 0; i < 14; i++) 25762306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 25862306a36Sopenharmony_ci "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", 25962306a36Sopenharmony_ci i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); 26062306a36Sopenharmony_ci for (i = 0; i < 14; i++) 26162306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 26262306a36Sopenharmony_ci "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", 26362306a36Sopenharmony_ci i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); 26462306a36Sopenharmony_ci for (i = 0; i < 14; i++) 26562306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 26662306a36Sopenharmony_ci "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", 26762306a36Sopenharmony_ci i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); 26862306a36Sopenharmony_ci if (!autoload_fail) 26962306a36Sopenharmony_ci rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); 27062306a36Sopenharmony_ci else 27162306a36Sopenharmony_ci rtlefuse->eeprom_regulatory = 0; 27262306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 27362306a36Sopenharmony_ci "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 27462306a36Sopenharmony_ci if (!autoload_fail) { 27562306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; 27662306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; 27762306a36Sopenharmony_ci } else { 27862306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; 27962306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; 28062306a36Sopenharmony_ci } 28162306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 28262306a36Sopenharmony_ci "TSSI_A = 0x%x, TSSI_B = 0x%x\n", 28362306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_A], 28462306a36Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_B]); 28562306a36Sopenharmony_ci if (!autoload_fail) 28662306a36Sopenharmony_ci tempval = hwinfo[EEPROM_THERMAL_METER]; 28762306a36Sopenharmony_ci else 28862306a36Sopenharmony_ci tempval = EEPROM_DEFAULT_THERMALMETER; 28962306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); 29062306a36Sopenharmony_ci if (rtlefuse->eeprom_thermalmeter < 0x06 || 29162306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter > 0x1c) 29262306a36Sopenharmony_ci rtlefuse->eeprom_thermalmeter = 0x12; 29362306a36Sopenharmony_ci if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) 29462306a36Sopenharmony_ci rtlefuse->apk_thermalmeterignore = true; 29562306a36Sopenharmony_ci rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; 29662306a36Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 29762306a36Sopenharmony_ci "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); 29862306a36Sopenharmony_ci} 29962306a36Sopenharmony_ci 30062306a36Sopenharmony_cistatic void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) 30162306a36Sopenharmony_ci{ 30262306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 30362306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 30462306a36Sopenharmony_ci u8 boardtype; 30562306a36Sopenharmony_ci 30662306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 30762306a36Sopenharmony_ci boardtype = ((contents[EEPROM_RF_OPT1]) & 30862306a36Sopenharmony_ci BOARD_TYPE_NORMAL_MASK) >> 5; /*bit[7:5]*/ 30962306a36Sopenharmony_ci } else { 31062306a36Sopenharmony_ci boardtype = contents[EEPROM_RF_OPT4]; 31162306a36Sopenharmony_ci boardtype &= BOARD_TYPE_TEST_MASK; 31262306a36Sopenharmony_ci } 31362306a36Sopenharmony_ci rtlefuse->board_type = boardtype; 31462306a36Sopenharmony_ci if (IS_HIGHT_PA(rtlefuse->board_type)) 31562306a36Sopenharmony_ci rtlefuse->external_pa = 1; 31662306a36Sopenharmony_ci pr_info("Board Type %x\n", rtlefuse->board_type); 31762306a36Sopenharmony_ci} 31862306a36Sopenharmony_ci 31962306a36Sopenharmony_cistatic void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) 32062306a36Sopenharmony_ci{ 32162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 32262306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 32362306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 32462306a36Sopenharmony_ci int params[] = {RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID, 32562306a36Sopenharmony_ci EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, 32662306a36Sopenharmony_ci EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, 32762306a36Sopenharmony_ci 0}; 32862306a36Sopenharmony_ci u8 *hwinfo; 32962306a36Sopenharmony_ci 33062306a36Sopenharmony_ci hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); 33162306a36Sopenharmony_ci if (!hwinfo) 33262306a36Sopenharmony_ci return; 33362306a36Sopenharmony_ci 33462306a36Sopenharmony_ci if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) 33562306a36Sopenharmony_ci goto exit; 33662306a36Sopenharmony_ci 33762306a36Sopenharmony_ci _rtl92cu_read_txpower_info_from_hwpg(hw, 33862306a36Sopenharmony_ci rtlefuse->autoload_failflag, hwinfo); 33962306a36Sopenharmony_ci _rtl92cu_read_board_type(hw, hwinfo); 34062306a36Sopenharmony_ci 34162306a36Sopenharmony_ci rtlefuse->txpwr_fromeprom = true; 34262306a36Sopenharmony_ci if (rtlhal->oem_id == RT_CID_DEFAULT) { 34362306a36Sopenharmony_ci switch (rtlefuse->eeprom_oemid) { 34462306a36Sopenharmony_ci case EEPROM_CID_DEFAULT: 34562306a36Sopenharmony_ci if (rtlefuse->eeprom_did == 0x8176) { 34662306a36Sopenharmony_ci if ((rtlefuse->eeprom_svid == 0x103C && 34762306a36Sopenharmony_ci rtlefuse->eeprom_smid == 0x1629)) 34862306a36Sopenharmony_ci rtlhal->oem_id = RT_CID_819X_HP; 34962306a36Sopenharmony_ci else 35062306a36Sopenharmony_ci rtlhal->oem_id = RT_CID_DEFAULT; 35162306a36Sopenharmony_ci } else { 35262306a36Sopenharmony_ci rtlhal->oem_id = RT_CID_DEFAULT; 35362306a36Sopenharmony_ci } 35462306a36Sopenharmony_ci break; 35562306a36Sopenharmony_ci case EEPROM_CID_TOSHIBA: 35662306a36Sopenharmony_ci rtlhal->oem_id = RT_CID_TOSHIBA; 35762306a36Sopenharmony_ci break; 35862306a36Sopenharmony_ci case EEPROM_CID_QMI: 35962306a36Sopenharmony_ci rtlhal->oem_id = RT_CID_819X_QMI; 36062306a36Sopenharmony_ci break; 36162306a36Sopenharmony_ci case EEPROM_CID_WHQL: 36262306a36Sopenharmony_ci default: 36362306a36Sopenharmony_ci rtlhal->oem_id = RT_CID_DEFAULT; 36462306a36Sopenharmony_ci break; 36562306a36Sopenharmony_ci } 36662306a36Sopenharmony_ci } 36762306a36Sopenharmony_ciexit: 36862306a36Sopenharmony_ci kfree(hwinfo); 36962306a36Sopenharmony_ci} 37062306a36Sopenharmony_ci 37162306a36Sopenharmony_cistatic void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) 37262306a36Sopenharmony_ci{ 37362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 37462306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 37562306a36Sopenharmony_ci 37662306a36Sopenharmony_ci switch (rtlhal->oem_id) { 37762306a36Sopenharmony_ci case RT_CID_819X_HP: 37862306a36Sopenharmony_ci rtlpriv->ledctl.led_opendrain = true; 37962306a36Sopenharmony_ci break; 38062306a36Sopenharmony_ci case RT_CID_819X_LENOVO: 38162306a36Sopenharmony_ci case RT_CID_DEFAULT: 38262306a36Sopenharmony_ci case RT_CID_TOSHIBA: 38362306a36Sopenharmony_ci case RT_CID_CCX: 38462306a36Sopenharmony_ci case RT_CID_819X_ACER: 38562306a36Sopenharmony_ci case RT_CID_WHQL: 38662306a36Sopenharmony_ci default: 38762306a36Sopenharmony_ci break; 38862306a36Sopenharmony_ci } 38962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n", 39062306a36Sopenharmony_ci rtlhal->oem_id); 39162306a36Sopenharmony_ci} 39262306a36Sopenharmony_ci 39362306a36Sopenharmony_civoid rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) 39462306a36Sopenharmony_ci{ 39562306a36Sopenharmony_ci 39662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 39762306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 39862306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 39962306a36Sopenharmony_ci u8 tmp_u1b; 40062306a36Sopenharmony_ci 40162306a36Sopenharmony_ci if (!IS_NORMAL_CHIP(rtlhal->version)) 40262306a36Sopenharmony_ci return; 40362306a36Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); 40462306a36Sopenharmony_ci rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ? 40562306a36Sopenharmony_ci EEPROM_93C46 : EEPROM_BOOT_EFUSE; 40662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from %s\n", 40762306a36Sopenharmony_ci tmp_u1b & BOOT_FROM_EEPROM ? "EERROM" : "EFUSE"); 40862306a36Sopenharmony_ci rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; 40962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload %s\n", 41062306a36Sopenharmony_ci tmp_u1b & EEPROM_EN ? "OK!!" : "ERR!!"); 41162306a36Sopenharmony_ci _rtl92cu_read_adapter_info(hw); 41262306a36Sopenharmony_ci _rtl92cu_hal_customized_behavior(hw); 41362306a36Sopenharmony_ci return; 41462306a36Sopenharmony_ci} 41562306a36Sopenharmony_ci 41662306a36Sopenharmony_cistatic int _rtl92cu_init_power_on(struct ieee80211_hw *hw) 41762306a36Sopenharmony_ci{ 41862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 41962306a36Sopenharmony_ci int status = 0; 42062306a36Sopenharmony_ci u16 value16; 42162306a36Sopenharmony_ci u8 value8; 42262306a36Sopenharmony_ci /* polling autoload done. */ 42362306a36Sopenharmony_ci u32 pollingcount = 0; 42462306a36Sopenharmony_ci 42562306a36Sopenharmony_ci do { 42662306a36Sopenharmony_ci if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) { 42762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, 42862306a36Sopenharmony_ci "Autoload Done!\n"); 42962306a36Sopenharmony_ci break; 43062306a36Sopenharmony_ci } 43162306a36Sopenharmony_ci if (pollingcount++ > 100) { 43262306a36Sopenharmony_ci pr_err("Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n"); 43362306a36Sopenharmony_ci return -ENODEV; 43462306a36Sopenharmony_ci } 43562306a36Sopenharmony_ci } while (true); 43662306a36Sopenharmony_ci /* 0. RSV_CTRL 0x1C[7:0] = 0 unlock ISO/CLK/Power control register */ 43762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); 43862306a36Sopenharmony_ci /* Power on when re-enter from IPS/Radio off/card disable */ 43962306a36Sopenharmony_ci /* enable SPS into PWM mode */ 44062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); 44162306a36Sopenharmony_ci udelay(100); 44262306a36Sopenharmony_ci value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); 44362306a36Sopenharmony_ci if (0 == (value8 & LDV12_EN)) { 44462306a36Sopenharmony_ci value8 |= LDV12_EN; 44562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); 44662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, 44762306a36Sopenharmony_ci " power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x\n", 44862306a36Sopenharmony_ci value8); 44962306a36Sopenharmony_ci udelay(100); 45062306a36Sopenharmony_ci value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); 45162306a36Sopenharmony_ci value8 &= ~ISO_MD2PP; 45262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, value8); 45362306a36Sopenharmony_ci } 45462306a36Sopenharmony_ci /* auto enable WLAN */ 45562306a36Sopenharmony_ci pollingcount = 0; 45662306a36Sopenharmony_ci value16 = rtl_read_word(rtlpriv, REG_APS_FSMCO); 45762306a36Sopenharmony_ci value16 |= APFM_ONMAC; 45862306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_APS_FSMCO, value16); 45962306a36Sopenharmony_ci do { 46062306a36Sopenharmony_ci if (!(rtl_read_word(rtlpriv, REG_APS_FSMCO) & APFM_ONMAC)) { 46162306a36Sopenharmony_ci pr_info("MAC auto ON okay!\n"); 46262306a36Sopenharmony_ci break; 46362306a36Sopenharmony_ci } 46462306a36Sopenharmony_ci if (pollingcount++ > 1000) { 46562306a36Sopenharmony_ci pr_err("Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n"); 46662306a36Sopenharmony_ci return -ENODEV; 46762306a36Sopenharmony_ci } 46862306a36Sopenharmony_ci } while (true); 46962306a36Sopenharmony_ci /* Enable Radio ,GPIO ,and LED function */ 47062306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x0812); 47162306a36Sopenharmony_ci /* release RF digital isolation */ 47262306a36Sopenharmony_ci value16 = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); 47362306a36Sopenharmony_ci value16 &= ~ISO_DIOR; 47462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, value16); 47562306a36Sopenharmony_ci /* Reconsider when to do this operation after asking HWSD. */ 47662306a36Sopenharmony_ci pollingcount = 0; 47762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, (rtl_read_byte(rtlpriv, 47862306a36Sopenharmony_ci REG_APSD_CTRL) & ~BIT(6))); 47962306a36Sopenharmony_ci do { 48062306a36Sopenharmony_ci pollingcount++; 48162306a36Sopenharmony_ci } while ((pollingcount < 200) && 48262306a36Sopenharmony_ci (rtl_read_byte(rtlpriv, REG_APSD_CTRL) & BIT(7))); 48362306a36Sopenharmony_ci /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ 48462306a36Sopenharmony_ci value16 = rtl_read_word(rtlpriv, REG_CR); 48562306a36Sopenharmony_ci value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN | 48662306a36Sopenharmony_ci PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC); 48762306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_CR, value16); 48862306a36Sopenharmony_ci return status; 48962306a36Sopenharmony_ci} 49062306a36Sopenharmony_ci 49162306a36Sopenharmony_cistatic void _rtl92cu_init_queue_reserved_page(struct ieee80211_hw *hw, 49262306a36Sopenharmony_ci bool wmm_enable, 49362306a36Sopenharmony_ci u8 out_ep_num, 49462306a36Sopenharmony_ci u8 queue_sel) 49562306a36Sopenharmony_ci{ 49662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 49762306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 49862306a36Sopenharmony_ci bool ischipn = IS_NORMAL_CHIP(rtlhal->version); 49962306a36Sopenharmony_ci u32 outepnum = (u32)out_ep_num; 50062306a36Sopenharmony_ci u32 numhq = 0; 50162306a36Sopenharmony_ci u32 numlq = 0; 50262306a36Sopenharmony_ci u32 numnq = 0; 50362306a36Sopenharmony_ci u32 numpubq; 50462306a36Sopenharmony_ci u32 value32; 50562306a36Sopenharmony_ci u8 value8; 50662306a36Sopenharmony_ci u32 txqpagenum, txqpageunit, txqremaininpage; 50762306a36Sopenharmony_ci 50862306a36Sopenharmony_ci if (!wmm_enable) { 50962306a36Sopenharmony_ci numpubq = (ischipn) ? CHIP_B_PAGE_NUM_PUBQ : 51062306a36Sopenharmony_ci CHIP_A_PAGE_NUM_PUBQ; 51162306a36Sopenharmony_ci txqpagenum = TX_TOTAL_PAGE_NUMBER - numpubq; 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_ci txqpageunit = txqpagenum / outepnum; 51462306a36Sopenharmony_ci txqremaininpage = txqpagenum % outepnum; 51562306a36Sopenharmony_ci if (queue_sel & TX_SELE_HQ) 51662306a36Sopenharmony_ci numhq = txqpageunit; 51762306a36Sopenharmony_ci if (queue_sel & TX_SELE_LQ) 51862306a36Sopenharmony_ci numlq = txqpageunit; 51962306a36Sopenharmony_ci /* HIGH priority queue always present in the configuration of 52062306a36Sopenharmony_ci * 2 out-ep. Remainder pages have assigned to High queue */ 52162306a36Sopenharmony_ci if (outepnum > 1 && txqremaininpage) 52262306a36Sopenharmony_ci numhq += txqremaininpage; 52362306a36Sopenharmony_ci /* NOTE: This step done before writing REG_RQPN. */ 52462306a36Sopenharmony_ci if (ischipn) { 52562306a36Sopenharmony_ci if (queue_sel & TX_SELE_NQ) 52662306a36Sopenharmony_ci numnq = txqpageunit; 52762306a36Sopenharmony_ci value8 = (u8)_NPQ(numnq); 52862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); 52962306a36Sopenharmony_ci } 53062306a36Sopenharmony_ci } else { 53162306a36Sopenharmony_ci /* for WMM ,number of out-ep must more than or equal to 2! */ 53262306a36Sopenharmony_ci numpubq = ischipn ? WMM_CHIP_B_PAGE_NUM_PUBQ : 53362306a36Sopenharmony_ci WMM_CHIP_A_PAGE_NUM_PUBQ; 53462306a36Sopenharmony_ci if (queue_sel & TX_SELE_HQ) { 53562306a36Sopenharmony_ci numhq = ischipn ? WMM_CHIP_B_PAGE_NUM_HPQ : 53662306a36Sopenharmony_ci WMM_CHIP_A_PAGE_NUM_HPQ; 53762306a36Sopenharmony_ci } 53862306a36Sopenharmony_ci if (queue_sel & TX_SELE_LQ) { 53962306a36Sopenharmony_ci numlq = ischipn ? WMM_CHIP_B_PAGE_NUM_LPQ : 54062306a36Sopenharmony_ci WMM_CHIP_A_PAGE_NUM_LPQ; 54162306a36Sopenharmony_ci } 54262306a36Sopenharmony_ci /* NOTE: This step done before writing REG_RQPN. */ 54362306a36Sopenharmony_ci if (ischipn) { 54462306a36Sopenharmony_ci if (queue_sel & TX_SELE_NQ) 54562306a36Sopenharmony_ci numnq = WMM_CHIP_B_PAGE_NUM_NPQ; 54662306a36Sopenharmony_ci value8 = (u8)_NPQ(numnq); 54762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); 54862306a36Sopenharmony_ci } 54962306a36Sopenharmony_ci } 55062306a36Sopenharmony_ci /* TX DMA */ 55162306a36Sopenharmony_ci value32 = _HPQ(numhq) | _LPQ(numlq) | _PUBQ(numpubq) | LD_RQPN; 55262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RQPN, value32); 55362306a36Sopenharmony_ci} 55462306a36Sopenharmony_ci 55562306a36Sopenharmony_cistatic void _rtl92c_init_trx_buffer(struct ieee80211_hw *hw, bool wmm_enable) 55662306a36Sopenharmony_ci{ 55762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 55862306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 55962306a36Sopenharmony_ci u8 txpktbuf_bndy; 56062306a36Sopenharmony_ci u8 value8; 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci if (!wmm_enable) 56362306a36Sopenharmony_ci txpktbuf_bndy = TX_PAGE_BOUNDARY; 56462306a36Sopenharmony_ci else /* for WMM */ 56562306a36Sopenharmony_ci txpktbuf_bndy = (IS_NORMAL_CHIP(rtlhal->version)) 56662306a36Sopenharmony_ci ? WMM_CHIP_B_TX_PAGE_BOUNDARY 56762306a36Sopenharmony_ci : WMM_CHIP_A_TX_PAGE_BOUNDARY; 56862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); 56962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); 57062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); 57162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy); 57262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TDECTRL+1, txpktbuf_bndy); 57362306a36Sopenharmony_ci rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF); 57462306a36Sopenharmony_ci value8 = _PSRX(RX_PAGE_SIZE_REG_VALUE) | _PSTX(PBP_128); 57562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PBP, value8); 57662306a36Sopenharmony_ci} 57762306a36Sopenharmony_ci 57862306a36Sopenharmony_cistatic void _rtl92c_init_chipn_reg_priority(struct ieee80211_hw *hw, u16 beq, 57962306a36Sopenharmony_ci u16 bkq, u16 viq, u16 voq, 58062306a36Sopenharmony_ci u16 mgtq, u16 hiq) 58162306a36Sopenharmony_ci{ 58262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 58362306a36Sopenharmony_ci u16 value16 = (rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0x7); 58462306a36Sopenharmony_ci 58562306a36Sopenharmony_ci value16 |= _TXDMA_BEQ_MAP(beq) | _TXDMA_BKQ_MAP(bkq) | 58662306a36Sopenharmony_ci _TXDMA_VIQ_MAP(viq) | _TXDMA_VOQ_MAP(voq) | 58762306a36Sopenharmony_ci _TXDMA_MGQ_MAP(mgtq) | _TXDMA_HIQ_MAP(hiq); 58862306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, value16); 58962306a36Sopenharmony_ci} 59062306a36Sopenharmony_ci 59162306a36Sopenharmony_cistatic void _rtl92cu_init_chipn_one_out_ep_priority(struct ieee80211_hw *hw, 59262306a36Sopenharmony_ci bool wmm_enable, 59362306a36Sopenharmony_ci u8 queue_sel) 59462306a36Sopenharmony_ci{ 59562306a36Sopenharmony_ci u16 value; 59662306a36Sopenharmony_ci 59762306a36Sopenharmony_ci switch (queue_sel) { 59862306a36Sopenharmony_ci case TX_SELE_HQ: 59962306a36Sopenharmony_ci value = QUEUE_HIGH; 60062306a36Sopenharmony_ci break; 60162306a36Sopenharmony_ci case TX_SELE_LQ: 60262306a36Sopenharmony_ci value = QUEUE_LOW; 60362306a36Sopenharmony_ci break; 60462306a36Sopenharmony_ci case TX_SELE_NQ: 60562306a36Sopenharmony_ci value = QUEUE_NORMAL; 60662306a36Sopenharmony_ci break; 60762306a36Sopenharmony_ci default: 60862306a36Sopenharmony_ci WARN_ON(1); /* Shall not reach here! */ 60962306a36Sopenharmony_ci return; 61062306a36Sopenharmony_ci } 61162306a36Sopenharmony_ci _rtl92c_init_chipn_reg_priority(hw, value, value, value, value, 61262306a36Sopenharmony_ci value, value); 61362306a36Sopenharmony_ci pr_info("Tx queue select: 0x%02x\n", queue_sel); 61462306a36Sopenharmony_ci} 61562306a36Sopenharmony_ci 61662306a36Sopenharmony_cistatic void _rtl92cu_init_chipn_two_out_ep_priority(struct ieee80211_hw *hw, 61762306a36Sopenharmony_ci bool wmm_enable, 61862306a36Sopenharmony_ci u8 queue_sel) 61962306a36Sopenharmony_ci{ 62062306a36Sopenharmony_ci u16 beq, bkq, viq, voq, mgtq, hiq; 62162306a36Sopenharmony_ci u16 valuehi; 62262306a36Sopenharmony_ci u16 valuelow; 62362306a36Sopenharmony_ci 62462306a36Sopenharmony_ci switch (queue_sel) { 62562306a36Sopenharmony_ci case (TX_SELE_HQ | TX_SELE_LQ): 62662306a36Sopenharmony_ci valuehi = QUEUE_HIGH; 62762306a36Sopenharmony_ci valuelow = QUEUE_LOW; 62862306a36Sopenharmony_ci break; 62962306a36Sopenharmony_ci case (TX_SELE_NQ | TX_SELE_LQ): 63062306a36Sopenharmony_ci valuehi = QUEUE_NORMAL; 63162306a36Sopenharmony_ci valuelow = QUEUE_LOW; 63262306a36Sopenharmony_ci break; 63362306a36Sopenharmony_ci case (TX_SELE_HQ | TX_SELE_NQ): 63462306a36Sopenharmony_ci valuehi = QUEUE_HIGH; 63562306a36Sopenharmony_ci valuelow = QUEUE_NORMAL; 63662306a36Sopenharmony_ci break; 63762306a36Sopenharmony_ci default: 63862306a36Sopenharmony_ci WARN_ON(1); 63962306a36Sopenharmony_ci break; 64062306a36Sopenharmony_ci } 64162306a36Sopenharmony_ci if (!wmm_enable) { 64262306a36Sopenharmony_ci beq = valuelow; 64362306a36Sopenharmony_ci bkq = valuelow; 64462306a36Sopenharmony_ci viq = valuehi; 64562306a36Sopenharmony_ci voq = valuehi; 64662306a36Sopenharmony_ci mgtq = valuehi; 64762306a36Sopenharmony_ci hiq = valuehi; 64862306a36Sopenharmony_ci } else {/* for WMM ,CONFIG_OUT_EP_WIFI_MODE */ 64962306a36Sopenharmony_ci beq = valuehi; 65062306a36Sopenharmony_ci bkq = valuelow; 65162306a36Sopenharmony_ci viq = valuelow; 65262306a36Sopenharmony_ci voq = valuehi; 65362306a36Sopenharmony_ci mgtq = valuehi; 65462306a36Sopenharmony_ci hiq = valuehi; 65562306a36Sopenharmony_ci } 65662306a36Sopenharmony_ci _rtl92c_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq); 65762306a36Sopenharmony_ci pr_info("Tx queue select: 0x%02x\n", queue_sel); 65862306a36Sopenharmony_ci} 65962306a36Sopenharmony_ci 66062306a36Sopenharmony_cistatic void _rtl92cu_init_chipn_three_out_ep_priority(struct ieee80211_hw *hw, 66162306a36Sopenharmony_ci bool wmm_enable, 66262306a36Sopenharmony_ci u8 queue_sel) 66362306a36Sopenharmony_ci{ 66462306a36Sopenharmony_ci u16 beq, bkq, viq, voq, mgtq, hiq; 66562306a36Sopenharmony_ci 66662306a36Sopenharmony_ci if (!wmm_enable) { /* typical setting */ 66762306a36Sopenharmony_ci beq = QUEUE_LOW; 66862306a36Sopenharmony_ci bkq = QUEUE_LOW; 66962306a36Sopenharmony_ci viq = QUEUE_NORMAL; 67062306a36Sopenharmony_ci voq = QUEUE_HIGH; 67162306a36Sopenharmony_ci mgtq = QUEUE_HIGH; 67262306a36Sopenharmony_ci hiq = QUEUE_HIGH; 67362306a36Sopenharmony_ci } else { /* for WMM */ 67462306a36Sopenharmony_ci beq = QUEUE_LOW; 67562306a36Sopenharmony_ci bkq = QUEUE_NORMAL; 67662306a36Sopenharmony_ci viq = QUEUE_NORMAL; 67762306a36Sopenharmony_ci voq = QUEUE_HIGH; 67862306a36Sopenharmony_ci mgtq = QUEUE_HIGH; 67962306a36Sopenharmony_ci hiq = QUEUE_HIGH; 68062306a36Sopenharmony_ci } 68162306a36Sopenharmony_ci _rtl92c_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq); 68262306a36Sopenharmony_ci pr_info("Tx queue select :0x%02x..\n", queue_sel); 68362306a36Sopenharmony_ci} 68462306a36Sopenharmony_ci 68562306a36Sopenharmony_cistatic void _rtl92cu_init_chipn_queue_priority(struct ieee80211_hw *hw, 68662306a36Sopenharmony_ci bool wmm_enable, 68762306a36Sopenharmony_ci u8 out_ep_num, 68862306a36Sopenharmony_ci u8 queue_sel) 68962306a36Sopenharmony_ci{ 69062306a36Sopenharmony_ci switch (out_ep_num) { 69162306a36Sopenharmony_ci case 1: 69262306a36Sopenharmony_ci _rtl92cu_init_chipn_one_out_ep_priority(hw, wmm_enable, 69362306a36Sopenharmony_ci queue_sel); 69462306a36Sopenharmony_ci break; 69562306a36Sopenharmony_ci case 2: 69662306a36Sopenharmony_ci _rtl92cu_init_chipn_two_out_ep_priority(hw, wmm_enable, 69762306a36Sopenharmony_ci queue_sel); 69862306a36Sopenharmony_ci break; 69962306a36Sopenharmony_ci case 3: 70062306a36Sopenharmony_ci _rtl92cu_init_chipn_three_out_ep_priority(hw, wmm_enable, 70162306a36Sopenharmony_ci queue_sel); 70262306a36Sopenharmony_ci break; 70362306a36Sopenharmony_ci default: 70462306a36Sopenharmony_ci WARN_ON(1); /* Shall not reach here! */ 70562306a36Sopenharmony_ci break; 70662306a36Sopenharmony_ci } 70762306a36Sopenharmony_ci} 70862306a36Sopenharmony_ci 70962306a36Sopenharmony_cistatic void _rtl92cu_init_chipt_queue_priority(struct ieee80211_hw *hw, 71062306a36Sopenharmony_ci bool wmm_enable, 71162306a36Sopenharmony_ci u8 out_ep_num, 71262306a36Sopenharmony_ci u8 queue_sel) 71362306a36Sopenharmony_ci{ 71462306a36Sopenharmony_ci u8 hq_sele = 0; 71562306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci switch (out_ep_num) { 71862306a36Sopenharmony_ci case 2: /* (TX_SELE_HQ|TX_SELE_LQ) */ 71962306a36Sopenharmony_ci if (!wmm_enable) /* typical setting */ 72062306a36Sopenharmony_ci hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_MGTQ | 72162306a36Sopenharmony_ci HQSEL_HIQ; 72262306a36Sopenharmony_ci else /* for WMM */ 72362306a36Sopenharmony_ci hq_sele = HQSEL_VOQ | HQSEL_BEQ | HQSEL_MGTQ | 72462306a36Sopenharmony_ci HQSEL_HIQ; 72562306a36Sopenharmony_ci break; 72662306a36Sopenharmony_ci case 1: 72762306a36Sopenharmony_ci if (TX_SELE_LQ == queue_sel) { 72862306a36Sopenharmony_ci /* map all endpoint to Low queue */ 72962306a36Sopenharmony_ci hq_sele = 0; 73062306a36Sopenharmony_ci } else if (TX_SELE_HQ == queue_sel) { 73162306a36Sopenharmony_ci /* map all endpoint to High queue */ 73262306a36Sopenharmony_ci hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_BEQ | 73362306a36Sopenharmony_ci HQSEL_BKQ | HQSEL_MGTQ | HQSEL_HIQ; 73462306a36Sopenharmony_ci } 73562306a36Sopenharmony_ci break; 73662306a36Sopenharmony_ci default: 73762306a36Sopenharmony_ci WARN_ON(1); /* Shall not reach here! */ 73862306a36Sopenharmony_ci break; 73962306a36Sopenharmony_ci } 74062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele); 74162306a36Sopenharmony_ci pr_info("Tx queue select :0x%02x..\n", hq_sele); 74262306a36Sopenharmony_ci} 74362306a36Sopenharmony_ci 74462306a36Sopenharmony_cistatic void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw, 74562306a36Sopenharmony_ci bool wmm_enable, 74662306a36Sopenharmony_ci u8 out_ep_num, 74762306a36Sopenharmony_ci u8 queue_sel) 74862306a36Sopenharmony_ci{ 74962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 75062306a36Sopenharmony_ci 75162306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 75262306a36Sopenharmony_ci _rtl92cu_init_chipn_queue_priority(hw, wmm_enable, out_ep_num, 75362306a36Sopenharmony_ci queue_sel); 75462306a36Sopenharmony_ci else 75562306a36Sopenharmony_ci _rtl92cu_init_chipt_queue_priority(hw, wmm_enable, out_ep_num, 75662306a36Sopenharmony_ci queue_sel); 75762306a36Sopenharmony_ci} 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_cistatic void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw) 76062306a36Sopenharmony_ci{ 76162306a36Sopenharmony_ci u16 value16; 76262306a36Sopenharmony_ci u32 value32; 76362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 76462306a36Sopenharmony_ci 76562306a36Sopenharmony_ci value32 = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APPFCS | 76662306a36Sopenharmony_ci RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | 76762306a36Sopenharmony_ci RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32); 76862306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&value32)); 76962306a36Sopenharmony_ci /* Accept all multicast address */ 77062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MAR, 0xFFFFFFFF); 77162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MAR + 4, 0xFFFFFFFF); 77262306a36Sopenharmony_ci /* Accept all management frames */ 77362306a36Sopenharmony_ci value16 = 0xFFFF; 77462306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER, 77562306a36Sopenharmony_ci (u8 *)(&value16)); 77662306a36Sopenharmony_ci /* Reject all control frame - default value is 0 */ 77762306a36Sopenharmony_ci value16 = 0x0; 77862306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER, 77962306a36Sopenharmony_ci (u8 *)(&value16)); 78062306a36Sopenharmony_ci /* Accept all data frames */ 78162306a36Sopenharmony_ci value16 = 0xFFFF; 78262306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DATA_FILTER, 78362306a36Sopenharmony_ci (u8 *)(&value16)); 78462306a36Sopenharmony_ci} 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_cistatic void _rtl92cu_init_beacon_parameters(struct ieee80211_hw *hw) 78762306a36Sopenharmony_ci{ 78862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 78962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 79062306a36Sopenharmony_ci 79162306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010); 79262306a36Sopenharmony_ci 79362306a36Sopenharmony_ci /* TODO: Remove these magic number */ 79462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404); 79562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME); 79662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); 79762306a36Sopenharmony_ci /* Change beacon AIFS to the largest number 79862306a36Sopenharmony_ci * beacause test chip does not contension before sending beacon. 79962306a36Sopenharmony_ci */ 80062306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 80162306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F); 80262306a36Sopenharmony_ci else 80362306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF); 80462306a36Sopenharmony_ci} 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_cistatic int _rtl92cu_init_mac(struct ieee80211_hw *hw) 80762306a36Sopenharmony_ci{ 80862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 80962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 81062306a36Sopenharmony_ci struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); 81162306a36Sopenharmony_ci struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); 81262306a36Sopenharmony_ci int err = 0; 81362306a36Sopenharmony_ci u32 boundary = 0; 81462306a36Sopenharmony_ci u8 wmm_enable = false; /* TODO */ 81562306a36Sopenharmony_ci u8 out_ep_nums = rtlusb->out_ep_nums; 81662306a36Sopenharmony_ci u8 queue_sel = rtlusb->out_queue_sel; 81762306a36Sopenharmony_ci 81862306a36Sopenharmony_ci err = _rtl92cu_init_power_on(hw); 81962306a36Sopenharmony_ci 82062306a36Sopenharmony_ci if (err) { 82162306a36Sopenharmony_ci pr_err("Failed to init power on!\n"); 82262306a36Sopenharmony_ci return err; 82362306a36Sopenharmony_ci } 82462306a36Sopenharmony_ci if (!wmm_enable) { 82562306a36Sopenharmony_ci boundary = TX_PAGE_BOUNDARY; 82662306a36Sopenharmony_ci } else { /* for WMM */ 82762306a36Sopenharmony_ci boundary = (IS_NORMAL_CHIP(rtlhal->version)) 82862306a36Sopenharmony_ci ? WMM_CHIP_B_TX_PAGE_BOUNDARY 82962306a36Sopenharmony_ci : WMM_CHIP_A_TX_PAGE_BOUNDARY; 83062306a36Sopenharmony_ci } 83162306a36Sopenharmony_ci if (!rtl92c_init_llt_table(hw, boundary)) { 83262306a36Sopenharmony_ci pr_err("Failed to init LLT Table!\n"); 83362306a36Sopenharmony_ci return -EINVAL; 83462306a36Sopenharmony_ci } 83562306a36Sopenharmony_ci _rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums, 83662306a36Sopenharmony_ci queue_sel); 83762306a36Sopenharmony_ci _rtl92c_init_trx_buffer(hw, wmm_enable); 83862306a36Sopenharmony_ci _rtl92cu_init_queue_priority(hw, wmm_enable, out_ep_nums, 83962306a36Sopenharmony_ci queue_sel); 84062306a36Sopenharmony_ci /* Get Rx PHY status in order to report RSSI and others. */ 84162306a36Sopenharmony_ci rtl92c_init_driver_info_size(hw, RTL92C_DRIVER_INFO_SIZE); 84262306a36Sopenharmony_ci rtl92c_init_interrupt(hw); 84362306a36Sopenharmony_ci rtl92c_init_network_type(hw); 84462306a36Sopenharmony_ci _rtl92cu_init_wmac_setting(hw); 84562306a36Sopenharmony_ci rtl92c_init_adaptive_ctrl(hw); 84662306a36Sopenharmony_ci rtl92c_init_edca(hw); 84762306a36Sopenharmony_ci rtl92c_init_rate_fallback(hw); 84862306a36Sopenharmony_ci rtl92c_init_retry_function(hw); 84962306a36Sopenharmony_ci rtlpriv->cfg->ops->set_bw_mode(hw, NL80211_CHAN_HT20); 85062306a36Sopenharmony_ci rtl92c_set_min_space(hw, IS_92C_SERIAL(rtlhal->version)); 85162306a36Sopenharmony_ci _rtl92cu_init_beacon_parameters(hw); 85262306a36Sopenharmony_ci rtl92c_init_ampdu_aggregation(hw); 85362306a36Sopenharmony_ci rtl92c_init_beacon_max_error(hw); 85462306a36Sopenharmony_ci return err; 85562306a36Sopenharmony_ci} 85662306a36Sopenharmony_ci 85762306a36Sopenharmony_civoid rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) 85862306a36Sopenharmony_ci{ 85962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 86062306a36Sopenharmony_ci u8 sec_reg_value = 0x0; 86162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 86462306a36Sopenharmony_ci "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", 86562306a36Sopenharmony_ci rtlpriv->sec.pairwise_enc_algorithm, 86662306a36Sopenharmony_ci rtlpriv->sec.group_enc_algorithm); 86762306a36Sopenharmony_ci if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { 86862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 86962306a36Sopenharmony_ci "not open sw encryption\n"); 87062306a36Sopenharmony_ci return; 87162306a36Sopenharmony_ci } 87262306a36Sopenharmony_ci sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; 87362306a36Sopenharmony_ci if (rtlpriv->sec.use_defaultkey) { 87462306a36Sopenharmony_ci sec_reg_value |= SCR_TXUSEDK; 87562306a36Sopenharmony_ci sec_reg_value |= SCR_RXUSEDK; 87662306a36Sopenharmony_ci } 87762306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 87862306a36Sopenharmony_ci sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); 87962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); 88062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", 88162306a36Sopenharmony_ci sec_reg_value); 88262306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); 88362306a36Sopenharmony_ci} 88462306a36Sopenharmony_ci 88562306a36Sopenharmony_cistatic void _rtl92cu_hw_configure(struct ieee80211_hw *hw) 88662306a36Sopenharmony_ci{ 88762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 88862306a36Sopenharmony_ci struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 88962306a36Sopenharmony_ci 89062306a36Sopenharmony_ci /* To Fix MAC loopback mode fail. */ 89162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); 89262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x15, 0xe9); 89362306a36Sopenharmony_ci /* HW SEQ CTRL */ 89462306a36Sopenharmony_ci /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */ 89562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); 89662306a36Sopenharmony_ci /* fixed USB interface interference issue */ 89762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xfe40, 0xe0); 89862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xfe41, 0x8d); 89962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0xfe42, 0x80); 90062306a36Sopenharmony_ci rtlusb->reg_bcn_ctrl_val = 0x18; 90162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val); 90262306a36Sopenharmony_ci} 90362306a36Sopenharmony_ci 90462306a36Sopenharmony_cistatic void _initpabias(struct ieee80211_hw *hw) 90562306a36Sopenharmony_ci{ 90662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 90762306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 90862306a36Sopenharmony_ci u8 pa_setting; 90962306a36Sopenharmony_ci 91062306a36Sopenharmony_ci /* FIXED PA current issue */ 91162306a36Sopenharmony_ci pa_setting = efuse_read_1byte(hw, 0x1FA); 91262306a36Sopenharmony_ci if (!(pa_setting & BIT(0))) { 91362306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x0F406); 91462306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x4F406); 91562306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x8F406); 91662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0xCF406); 91762306a36Sopenharmony_ci } 91862306a36Sopenharmony_ci if (!(pa_setting & BIT(1)) && IS_NORMAL_CHIP(rtlhal->version) && 91962306a36Sopenharmony_ci IS_92C_SERIAL(rtlhal->version)) { 92062306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x0F406); 92162306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x4F406); 92262306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x8F406); 92362306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0xCF406); 92462306a36Sopenharmony_ci } 92562306a36Sopenharmony_ci if (!(pa_setting & BIT(4))) { 92662306a36Sopenharmony_ci pa_setting = rtl_read_byte(rtlpriv, 0x16); 92762306a36Sopenharmony_ci pa_setting &= 0x0F; 92862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x16, pa_setting | 0x90); 92962306a36Sopenharmony_ci } 93062306a36Sopenharmony_ci} 93162306a36Sopenharmony_ci 93262306a36Sopenharmony_ciint rtl92cu_hw_init(struct ieee80211_hw *hw) 93362306a36Sopenharmony_ci{ 93462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 93562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 93662306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 93762306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 93862306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 93962306a36Sopenharmony_ci int err = 0; 94062306a36Sopenharmony_ci unsigned long flags; 94162306a36Sopenharmony_ci 94262306a36Sopenharmony_ci /* As this function can take a very long time (up to 350 ms) 94362306a36Sopenharmony_ci * and can be called with irqs disabled, reenable the irqs 94462306a36Sopenharmony_ci * to let the other devices continue being serviced. 94562306a36Sopenharmony_ci * 94662306a36Sopenharmony_ci * It is safe doing so since our own interrupts will only be enabled 94762306a36Sopenharmony_ci * in a subsequent step. 94862306a36Sopenharmony_ci */ 94962306a36Sopenharmony_ci local_save_flags(flags); 95062306a36Sopenharmony_ci local_irq_enable(); 95162306a36Sopenharmony_ci 95262306a36Sopenharmony_ci rtlhal->fw_ready = false; 95362306a36Sopenharmony_ci rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; 95462306a36Sopenharmony_ci err = _rtl92cu_init_mac(hw); 95562306a36Sopenharmony_ci if (err) { 95662306a36Sopenharmony_ci pr_err("init mac failed!\n"); 95762306a36Sopenharmony_ci goto exit; 95862306a36Sopenharmony_ci } 95962306a36Sopenharmony_ci err = rtl92c_download_fw(hw); 96062306a36Sopenharmony_ci if (err) { 96162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 96262306a36Sopenharmony_ci "Failed to download FW. Init HW without FW now..\n"); 96362306a36Sopenharmony_ci err = 1; 96462306a36Sopenharmony_ci goto exit; 96562306a36Sopenharmony_ci } 96662306a36Sopenharmony_ci 96762306a36Sopenharmony_ci rtlhal->fw_ready = true; 96862306a36Sopenharmony_ci rtlhal->last_hmeboxnum = 0; /* h2c */ 96962306a36Sopenharmony_ci _rtl92cu_phy_param_tab_init(hw); 97062306a36Sopenharmony_ci rtl92cu_phy_mac_config(hw); 97162306a36Sopenharmony_ci rtl92cu_phy_bb_config(hw); 97262306a36Sopenharmony_ci rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; 97362306a36Sopenharmony_ci rtl92c_phy_rf_config(hw); 97462306a36Sopenharmony_ci if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && 97562306a36Sopenharmony_ci !IS_92C_SERIAL(rtlhal->version)) { 97662306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); 97762306a36Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); 97862306a36Sopenharmony_ci } 97962306a36Sopenharmony_ci rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, 98062306a36Sopenharmony_ci RF_CHNLBW, RFREG_OFFSET_MASK); 98162306a36Sopenharmony_ci rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, 98262306a36Sopenharmony_ci RF_CHNLBW, RFREG_OFFSET_MASK); 98362306a36Sopenharmony_ci rtl92cu_bb_block_on(hw); 98462306a36Sopenharmony_ci rtl_cam_reset_all_entry(hw); 98562306a36Sopenharmony_ci rtl92cu_enable_hw_security_config(hw); 98662306a36Sopenharmony_ci ppsc->rfpwr_state = ERFON; 98762306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); 98862306a36Sopenharmony_ci if (ppsc->rfpwr_state == ERFON) { 98962306a36Sopenharmony_ci rtl92c_phy_set_rfpath_switch(hw, 1); 99062306a36Sopenharmony_ci if (rtlphy->iqk_initialized) { 99162306a36Sopenharmony_ci rtl92c_phy_iq_calibrate(hw, true); 99262306a36Sopenharmony_ci } else { 99362306a36Sopenharmony_ci rtl92c_phy_iq_calibrate(hw, false); 99462306a36Sopenharmony_ci rtlphy->iqk_initialized = true; 99562306a36Sopenharmony_ci } 99662306a36Sopenharmony_ci rtl92c_dm_check_txpower_tracking(hw); 99762306a36Sopenharmony_ci rtl92c_phy_lc_calibrate(hw); 99862306a36Sopenharmony_ci } 99962306a36Sopenharmony_ci _rtl92cu_hw_configure(hw); 100062306a36Sopenharmony_ci _initpabias(hw); 100162306a36Sopenharmony_ci rtl92c_dm_init(hw); 100262306a36Sopenharmony_ciexit: 100362306a36Sopenharmony_ci local_irq_disable(); 100462306a36Sopenharmony_ci local_irq_restore(flags); 100562306a36Sopenharmony_ci return err; 100662306a36Sopenharmony_ci} 100762306a36Sopenharmony_ci 100862306a36Sopenharmony_cistatic void disable_rfafeandresetbb(struct ieee80211_hw *hw) 100962306a36Sopenharmony_ci{ 101062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 101162306a36Sopenharmony_ci/************************************** 101262306a36Sopenharmony_cia. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue 101362306a36Sopenharmony_cib. RF path 0 offset 0x00 = 0x00 disable RF 101462306a36Sopenharmony_cic. APSD_CTRL 0x600[7:0] = 0x40 101562306a36Sopenharmony_cid. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine 101662306a36Sopenharmony_cie. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine 101762306a36Sopenharmony_ci***************************************/ 101862306a36Sopenharmony_ci u8 erfpath = 0, value8 = 0; 101962306a36Sopenharmony_ci 102062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 102162306a36Sopenharmony_ci rtl_set_rfreg(hw, (enum radio_path)erfpath, 0x0, MASKBYTE0, 0x0); 102262306a36Sopenharmony_ci 102362306a36Sopenharmony_ci value8 |= APSDOFF; 102462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, value8); /*0x40*/ 102562306a36Sopenharmony_ci value8 = 0; 102662306a36Sopenharmony_ci value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTN); 102762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8);/*0x16*/ 102862306a36Sopenharmony_ci value8 &= (~FEN_BB_GLB_RSTN); 102962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8); /*0x14*/ 103062306a36Sopenharmony_ci} 103162306a36Sopenharmony_ci 103262306a36Sopenharmony_cistatic void _resetdigitalprocedure1(struct ieee80211_hw *hw, bool withouthwsm) 103362306a36Sopenharmony_ci{ 103462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 103562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 103662306a36Sopenharmony_ci 103762306a36Sopenharmony_ci if (rtlhal->fw_version <= 0x20) { 103862306a36Sopenharmony_ci /***************************** 103962306a36Sopenharmony_ci f. MCUFWDL 0x80[7:0]=0 reset MCU ready status 104062306a36Sopenharmony_ci g. SYS_FUNC_EN 0x02[10]= 0 reset MCU reg, (8051 reset) 104162306a36Sopenharmony_ci h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC reg, DCORE 104262306a36Sopenharmony_ci i. SYS_FUNC_EN 0x02[10]= 1 enable MCU reg, (8051 enable) 104362306a36Sopenharmony_ci ******************************/ 104462306a36Sopenharmony_ci u16 valu16 = 0; 104562306a36Sopenharmony_ci 104662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); 104762306a36Sopenharmony_ci valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 104862306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 & 104962306a36Sopenharmony_ci (~FEN_CPUEN))); /* reset MCU ,8051 */ 105062306a36Sopenharmony_ci valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN)&0x0FFF; 105162306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | 105262306a36Sopenharmony_ci (FEN_HWPDN|FEN_ELDR))); /* reset MAC */ 105362306a36Sopenharmony_ci valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 105462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | 105562306a36Sopenharmony_ci FEN_CPUEN)); /* enable MCU ,8051 */ 105662306a36Sopenharmony_ci } else { 105762306a36Sopenharmony_ci u8 retry_cnts = 0; 105862306a36Sopenharmony_ci 105962306a36Sopenharmony_ci /* IF fw in RAM code, do reset */ 106062306a36Sopenharmony_ci if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) { 106162306a36Sopenharmony_ci /* reset MCU ready status */ 106262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); 106362306a36Sopenharmony_ci /* 8051 reset by self */ 106462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); 106562306a36Sopenharmony_ci while ((retry_cnts++ < 100) && 106662306a36Sopenharmony_ci (FEN_CPUEN & rtl_read_word(rtlpriv, 106762306a36Sopenharmony_ci REG_SYS_FUNC_EN))) { 106862306a36Sopenharmony_ci udelay(50); 106962306a36Sopenharmony_ci } 107062306a36Sopenharmony_ci if (retry_cnts >= 100) { 107162306a36Sopenharmony_ci pr_err("8051 reset failed!.........................\n"); 107262306a36Sopenharmony_ci /* if 8051 reset fail, reset MAC. */ 107362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 107462306a36Sopenharmony_ci REG_SYS_FUNC_EN + 1, 107562306a36Sopenharmony_ci 0x50); 107662306a36Sopenharmony_ci udelay(100); 107762306a36Sopenharmony_ci } 107862306a36Sopenharmony_ci } 107962306a36Sopenharmony_ci /* Reset MAC and Enable 8051 */ 108062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x54); 108162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); 108262306a36Sopenharmony_ci } 108362306a36Sopenharmony_ci if (withouthwsm) { 108462306a36Sopenharmony_ci /***************************** 108562306a36Sopenharmony_ci Without HW auto state machine 108662306a36Sopenharmony_ci g.SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock 108762306a36Sopenharmony_ci h.AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL 108862306a36Sopenharmony_ci i.AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK 108962306a36Sopenharmony_ci j.SYS_ISu_CTRL 0x00[7:0] = 0xF9 isolated digital to PON 109062306a36Sopenharmony_ci ******************************/ 109162306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); 109262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); 109362306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_AFE_XTAL_CTRL, 0x880F); 109462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xF9); 109562306a36Sopenharmony_ci } 109662306a36Sopenharmony_ci} 109762306a36Sopenharmony_ci 109862306a36Sopenharmony_cistatic void _resetdigitalprocedure2(struct ieee80211_hw *hw) 109962306a36Sopenharmony_ci{ 110062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 110162306a36Sopenharmony_ci/***************************** 110262306a36Sopenharmony_cik. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction 110362306a36Sopenharmony_cil. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock 110462306a36Sopenharmony_cim. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON 110562306a36Sopenharmony_ci******************************/ 110662306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); 110762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL+1, 0x82); 110862306a36Sopenharmony_ci} 110962306a36Sopenharmony_ci 111062306a36Sopenharmony_cistatic void _disablegpio(struct ieee80211_hw *hw) 111162306a36Sopenharmony_ci{ 111262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 111362306a36Sopenharmony_ci/*************************************** 111462306a36Sopenharmony_cij. GPIO_PIN_CTRL 0x44[31:0]=0x000 111562306a36Sopenharmony_cik. Value = GPIO_PIN_CTRL[7:0] 111662306a36Sopenharmony_cil. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write ext PIN level 111762306a36Sopenharmony_cim. GPIO_MUXCFG 0x42 [15:0] = 0x0780 111862306a36Sopenharmony_cin. LEDCFG 0x4C[15:0] = 0x8080 111962306a36Sopenharmony_ci***************************************/ 112062306a36Sopenharmony_ci u8 value8; 112162306a36Sopenharmony_ci u16 value16; 112262306a36Sopenharmony_ci u32 value32; 112362306a36Sopenharmony_ci 112462306a36Sopenharmony_ci /* 1. Disable GPIO[7:0] */ 112562306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, 0x0000); 112662306a36Sopenharmony_ci value32 = rtl_read_dword(rtlpriv, REG_GPIO_PIN_CTRL) & 0xFFFF00FF; 112762306a36Sopenharmony_ci value8 = (u8)(value32&0x000000FF); 112862306a36Sopenharmony_ci value32 |= ((value8<<8) | 0x00FF0000); 112962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, value32); 113062306a36Sopenharmony_ci /* 2. Disable GPIO[10:8] */ 113162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG+3, 0x00); 113262306a36Sopenharmony_ci value16 = rtl_read_word(rtlpriv, REG_GPIO_MUXCFG+2) & 0xFF0F; 113362306a36Sopenharmony_ci value8 = (u8)(value16&0x000F); 113462306a36Sopenharmony_ci value16 |= ((value8<<4) | 0x0780); 113562306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, value16); 113662306a36Sopenharmony_ci /* 3. Disable LED0 & 1 */ 113762306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); 113862306a36Sopenharmony_ci} 113962306a36Sopenharmony_ci 114062306a36Sopenharmony_cistatic void disable_analog(struct ieee80211_hw *hw, bool withouthwsm) 114162306a36Sopenharmony_ci{ 114262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 114362306a36Sopenharmony_ci u16 value16 = 0; 114462306a36Sopenharmony_ci u8 value8 = 0; 114562306a36Sopenharmony_ci 114662306a36Sopenharmony_ci if (withouthwsm) { 114762306a36Sopenharmony_ci /***************************** 114862306a36Sopenharmony_ci n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power 114962306a36Sopenharmony_ci o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power 115062306a36Sopenharmony_ci r. When driver call disable, the ASIC will turn off remaining 115162306a36Sopenharmony_ci clock automatically 115262306a36Sopenharmony_ci ******************************/ 115362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04); 115462306a36Sopenharmony_ci value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); 115562306a36Sopenharmony_ci value8 &= (~LDV12_EN); 115662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); 115762306a36Sopenharmony_ci } 115862306a36Sopenharmony_ci 115962306a36Sopenharmony_ci/***************************** 116062306a36Sopenharmony_cih. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode 116162306a36Sopenharmony_cii. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend 116262306a36Sopenharmony_ci******************************/ 116362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); 116462306a36Sopenharmony_ci value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); 116562306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_APS_FSMCO, (u16)value16); 116662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E); 116762306a36Sopenharmony_ci} 116862306a36Sopenharmony_ci 116962306a36Sopenharmony_cistatic void carddisable_hwsm(struct ieee80211_hw *hw) 117062306a36Sopenharmony_ci{ 117162306a36Sopenharmony_ci /* ==== RF Off Sequence ==== */ 117262306a36Sopenharmony_ci disable_rfafeandresetbb(hw); 117362306a36Sopenharmony_ci /* ==== Reset digital sequence ====== */ 117462306a36Sopenharmony_ci _resetdigitalprocedure1(hw, false); 117562306a36Sopenharmony_ci /* ==== Pull GPIO PIN to balance level and LED control ====== */ 117662306a36Sopenharmony_ci _disablegpio(hw); 117762306a36Sopenharmony_ci /* ==== Disable analog sequence === */ 117862306a36Sopenharmony_ci disable_analog(hw, false); 117962306a36Sopenharmony_ci} 118062306a36Sopenharmony_ci 118162306a36Sopenharmony_cistatic void carddisablewithout_hwsm(struct ieee80211_hw *hw) 118262306a36Sopenharmony_ci{ 118362306a36Sopenharmony_ci /*==== RF Off Sequence ==== */ 118462306a36Sopenharmony_ci disable_rfafeandresetbb(hw); 118562306a36Sopenharmony_ci /* ==== Reset digital sequence ====== */ 118662306a36Sopenharmony_ci _resetdigitalprocedure1(hw, true); 118762306a36Sopenharmony_ci /* ==== Pull GPIO PIN to balance level and LED control ====== */ 118862306a36Sopenharmony_ci _disablegpio(hw); 118962306a36Sopenharmony_ci /* ==== Reset digital sequence ====== */ 119062306a36Sopenharmony_ci _resetdigitalprocedure2(hw); 119162306a36Sopenharmony_ci /* ==== Disable analog sequence === */ 119262306a36Sopenharmony_ci disable_analog(hw, true); 119362306a36Sopenharmony_ci} 119462306a36Sopenharmony_ci 119562306a36Sopenharmony_cistatic void _rtl92cu_set_bcn_ctrl_reg(struct ieee80211_hw *hw, 119662306a36Sopenharmony_ci u8 set_bits, u8 clear_bits) 119762306a36Sopenharmony_ci{ 119862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 119962306a36Sopenharmony_ci struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 120062306a36Sopenharmony_ci 120162306a36Sopenharmony_ci rtlusb->reg_bcn_ctrl_val |= set_bits; 120262306a36Sopenharmony_ci rtlusb->reg_bcn_ctrl_val &= ~clear_bits; 120362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val); 120462306a36Sopenharmony_ci} 120562306a36Sopenharmony_ci 120662306a36Sopenharmony_cistatic void _rtl92cu_stop_tx_beacon(struct ieee80211_hw *hw) 120762306a36Sopenharmony_ci{ 120862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 120962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 121062306a36Sopenharmony_ci u8 tmp1byte = 0; 121162306a36Sopenharmony_ci 121262306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 121362306a36Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); 121462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, 121562306a36Sopenharmony_ci tmp1byte & (~BIT(6))); 121662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); 121762306a36Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); 121862306a36Sopenharmony_ci tmp1byte &= ~(BIT(0)); 121962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); 122062306a36Sopenharmony_ci } else { 122162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 122262306a36Sopenharmony_ci rtl_read_byte(rtlpriv, REG_TXPAUSE) | BIT(6)); 122362306a36Sopenharmony_ci } 122462306a36Sopenharmony_ci} 122562306a36Sopenharmony_ci 122662306a36Sopenharmony_cistatic void _rtl92cu_resume_tx_beacon(struct ieee80211_hw *hw) 122762306a36Sopenharmony_ci{ 122862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 122962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 123062306a36Sopenharmony_ci u8 tmp1byte = 0; 123162306a36Sopenharmony_ci 123262306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 123362306a36Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); 123462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, 123562306a36Sopenharmony_ci tmp1byte | BIT(6)); 123662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); 123762306a36Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); 123862306a36Sopenharmony_ci tmp1byte |= BIT(0); 123962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); 124062306a36Sopenharmony_ci } else { 124162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 124262306a36Sopenharmony_ci rtl_read_byte(rtlpriv, REG_TXPAUSE) & (~BIT(6))); 124362306a36Sopenharmony_ci } 124462306a36Sopenharmony_ci} 124562306a36Sopenharmony_ci 124662306a36Sopenharmony_cistatic void _rtl92cu_enable_bcn_sub_func(struct ieee80211_hw *hw) 124762306a36Sopenharmony_ci{ 124862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 124962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 125062306a36Sopenharmony_ci 125162306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 125262306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(1)); 125362306a36Sopenharmony_ci else 125462306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); 125562306a36Sopenharmony_ci} 125662306a36Sopenharmony_ci 125762306a36Sopenharmony_cistatic void _rtl92cu_disable_bcn_sub_func(struct ieee80211_hw *hw) 125862306a36Sopenharmony_ci{ 125962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 126062306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 126162306a36Sopenharmony_ci 126262306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 126362306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(1), 0); 126462306a36Sopenharmony_ci else 126562306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); 126662306a36Sopenharmony_ci} 126762306a36Sopenharmony_ci 126862306a36Sopenharmony_cistatic int _rtl92cu_set_media_status(struct ieee80211_hw *hw, 126962306a36Sopenharmony_ci enum nl80211_iftype type) 127062306a36Sopenharmony_ci{ 127162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 127262306a36Sopenharmony_ci u8 bt_msr = rtl_read_byte(rtlpriv, MSR); 127362306a36Sopenharmony_ci enum led_ctl_mode ledaction = LED_CTL_NO_LINK; 127462306a36Sopenharmony_ci 127562306a36Sopenharmony_ci bt_msr &= 0xfc; 127662306a36Sopenharmony_ci if (type == NL80211_IFTYPE_UNSPECIFIED || type == 127762306a36Sopenharmony_ci NL80211_IFTYPE_STATION) { 127862306a36Sopenharmony_ci _rtl92cu_stop_tx_beacon(hw); 127962306a36Sopenharmony_ci _rtl92cu_enable_bcn_sub_func(hw); 128062306a36Sopenharmony_ci } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { 128162306a36Sopenharmony_ci _rtl92cu_resume_tx_beacon(hw); 128262306a36Sopenharmony_ci _rtl92cu_disable_bcn_sub_func(hw); 128362306a36Sopenharmony_ci } else { 128462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 128562306a36Sopenharmony_ci "Set HW_VAR_MEDIA_STATUS:No such media status(%x)\n", 128662306a36Sopenharmony_ci type); 128762306a36Sopenharmony_ci } 128862306a36Sopenharmony_ci switch (type) { 128962306a36Sopenharmony_ci case NL80211_IFTYPE_UNSPECIFIED: 129062306a36Sopenharmony_ci bt_msr |= MSR_NOLINK; 129162306a36Sopenharmony_ci ledaction = LED_CTL_LINK; 129262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 129362306a36Sopenharmony_ci "Set Network type to NO LINK!\n"); 129462306a36Sopenharmony_ci break; 129562306a36Sopenharmony_ci case NL80211_IFTYPE_ADHOC: 129662306a36Sopenharmony_ci bt_msr |= MSR_ADHOC; 129762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 129862306a36Sopenharmony_ci "Set Network type to Ad Hoc!\n"); 129962306a36Sopenharmony_ci break; 130062306a36Sopenharmony_ci case NL80211_IFTYPE_STATION: 130162306a36Sopenharmony_ci bt_msr |= MSR_INFRA; 130262306a36Sopenharmony_ci ledaction = LED_CTL_LINK; 130362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 130462306a36Sopenharmony_ci "Set Network type to STA!\n"); 130562306a36Sopenharmony_ci break; 130662306a36Sopenharmony_ci case NL80211_IFTYPE_AP: 130762306a36Sopenharmony_ci bt_msr |= MSR_AP; 130862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 130962306a36Sopenharmony_ci "Set Network type to AP!\n"); 131062306a36Sopenharmony_ci break; 131162306a36Sopenharmony_ci default: 131262306a36Sopenharmony_ci pr_err("Network type %d not supported!\n", type); 131362306a36Sopenharmony_ci goto error_out; 131462306a36Sopenharmony_ci } 131562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, MSR, bt_msr); 131662306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, ledaction); 131762306a36Sopenharmony_ci if ((bt_msr & MSR_MASK) == MSR_AP) 131862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 131962306a36Sopenharmony_ci else 132062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 132162306a36Sopenharmony_ci return 0; 132262306a36Sopenharmony_cierror_out: 132362306a36Sopenharmony_ci return 1; 132462306a36Sopenharmony_ci} 132562306a36Sopenharmony_ci 132662306a36Sopenharmony_civoid rtl92cu_card_disable(struct ieee80211_hw *hw) 132762306a36Sopenharmony_ci{ 132862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 132962306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 133062306a36Sopenharmony_ci struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 133162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 133262306a36Sopenharmony_ci enum nl80211_iftype opmode; 133362306a36Sopenharmony_ci 133462306a36Sopenharmony_ci mac->link_state = MAC80211_NOLINK; 133562306a36Sopenharmony_ci opmode = NL80211_IFTYPE_UNSPECIFIED; 133662306a36Sopenharmony_ci _rtl92cu_set_media_status(hw, opmode); 133762306a36Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); 133862306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 133962306a36Sopenharmony_ci if (rtlusb->disablehwsm) 134062306a36Sopenharmony_ci carddisable_hwsm(hw); 134162306a36Sopenharmony_ci else 134262306a36Sopenharmony_ci carddisablewithout_hwsm(hw); 134362306a36Sopenharmony_ci 134462306a36Sopenharmony_ci /* after power off we should do iqk again */ 134562306a36Sopenharmony_ci rtlpriv->phy.iqk_initialized = false; 134662306a36Sopenharmony_ci} 134762306a36Sopenharmony_ci 134862306a36Sopenharmony_civoid rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 134962306a36Sopenharmony_ci{ 135062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 135162306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 135262306a36Sopenharmony_ci u32 reg_rcr; 135362306a36Sopenharmony_ci 135462306a36Sopenharmony_ci if (rtlpriv->psc.rfpwr_state != ERFON) 135562306a36Sopenharmony_ci return; 135662306a36Sopenharmony_ci 135762306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); 135862306a36Sopenharmony_ci 135962306a36Sopenharmony_ci if (check_bssid) { 136062306a36Sopenharmony_ci u8 tmp; 136162306a36Sopenharmony_ci 136262306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 136362306a36Sopenharmony_ci reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); 136462306a36Sopenharmony_ci tmp = BIT(4); 136562306a36Sopenharmony_ci } else { 136662306a36Sopenharmony_ci reg_rcr |= RCR_CBSSID; 136762306a36Sopenharmony_ci tmp = BIT(4) | BIT(5); 136862306a36Sopenharmony_ci } 136962306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, 137062306a36Sopenharmony_ci (u8 *) (®_rcr)); 137162306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp); 137262306a36Sopenharmony_ci } else { 137362306a36Sopenharmony_ci u8 tmp; 137462306a36Sopenharmony_ci 137562306a36Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 137662306a36Sopenharmony_ci reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); 137762306a36Sopenharmony_ci tmp = BIT(4); 137862306a36Sopenharmony_ci } else { 137962306a36Sopenharmony_ci reg_rcr &= ~RCR_CBSSID; 138062306a36Sopenharmony_ci tmp = BIT(4) | BIT(5); 138162306a36Sopenharmony_ci } 138262306a36Sopenharmony_ci reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); 138362306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 138462306a36Sopenharmony_ci HW_VAR_RCR, (u8 *) (®_rcr)); 138562306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0); 138662306a36Sopenharmony_ci } 138762306a36Sopenharmony_ci} 138862306a36Sopenharmony_ci 138962306a36Sopenharmony_ci/*========================================================================== */ 139062306a36Sopenharmony_ci 139162306a36Sopenharmony_ciint rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) 139262306a36Sopenharmony_ci{ 139362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 139462306a36Sopenharmony_ci 139562306a36Sopenharmony_ci if (_rtl92cu_set_media_status(hw, type)) 139662306a36Sopenharmony_ci return -EOPNOTSUPP; 139762306a36Sopenharmony_ci 139862306a36Sopenharmony_ci if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { 139962306a36Sopenharmony_ci if (type != NL80211_IFTYPE_AP) 140062306a36Sopenharmony_ci rtl92cu_set_check_bssid(hw, true); 140162306a36Sopenharmony_ci } else { 140262306a36Sopenharmony_ci rtl92cu_set_check_bssid(hw, false); 140362306a36Sopenharmony_ci } 140462306a36Sopenharmony_ci 140562306a36Sopenharmony_ci return 0; 140662306a36Sopenharmony_ci} 140762306a36Sopenharmony_ci 140862306a36Sopenharmony_cistatic void _beacon_function_enable(struct ieee80211_hw *hw) 140962306a36Sopenharmony_ci{ 141062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 141162306a36Sopenharmony_ci 141262306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4) | BIT(3) | BIT(1)), 0x00); 141362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RD_CTRL+1, 0x6F); 141462306a36Sopenharmony_ci} 141562306a36Sopenharmony_ci 141662306a36Sopenharmony_civoid rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw) 141762306a36Sopenharmony_ci{ 141862306a36Sopenharmony_ci 141962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 142062306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 142162306a36Sopenharmony_ci u16 bcn_interval, atim_window; 142262306a36Sopenharmony_ci u32 value32; 142362306a36Sopenharmony_ci 142462306a36Sopenharmony_ci bcn_interval = mac->beacon_interval; 142562306a36Sopenharmony_ci atim_window = 2; /*FIX MERGE */ 142662306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); 142762306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); 142862306a36Sopenharmony_ci _rtl92cu_init_beacon_parameters(hw); 142962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SLOT, 0x09); 143062306a36Sopenharmony_ci /* 143162306a36Sopenharmony_ci * Force beacon frame transmission even after receiving beacon frame 143262306a36Sopenharmony_ci * from other ad hoc STA 143362306a36Sopenharmony_ci * 143462306a36Sopenharmony_ci * 143562306a36Sopenharmony_ci * Reset TSF Timer to zero, added by Roger. 2008.06.24 143662306a36Sopenharmony_ci */ 143762306a36Sopenharmony_ci value32 = rtl_read_dword(rtlpriv, REG_TCR); 143862306a36Sopenharmony_ci value32 &= ~TSFRST; 143962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TCR, value32); 144062306a36Sopenharmony_ci value32 |= TSFRST; 144162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TCR, value32); 144262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT | COMP_BEACON, DBG_LOUD, 144362306a36Sopenharmony_ci "SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", 144462306a36Sopenharmony_ci value32); 144562306a36Sopenharmony_ci /* TODO: Modify later (Find the right parameters) 144662306a36Sopenharmony_ci * NOTE: Fix test chip's bug (about contention windows's randomness) */ 144762306a36Sopenharmony_ci if ((mac->opmode == NL80211_IFTYPE_ADHOC) || 144862306a36Sopenharmony_ci (mac->opmode == NL80211_IFTYPE_MESH_POINT) || 144962306a36Sopenharmony_ci (mac->opmode == NL80211_IFTYPE_AP)) { 145062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50); 145162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50); 145262306a36Sopenharmony_ci } 145362306a36Sopenharmony_ci _beacon_function_enable(hw); 145462306a36Sopenharmony_ci} 145562306a36Sopenharmony_ci 145662306a36Sopenharmony_civoid rtl92cu_set_beacon_interval(struct ieee80211_hw *hw) 145762306a36Sopenharmony_ci{ 145862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 145962306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 146062306a36Sopenharmony_ci u16 bcn_interval = mac->beacon_interval; 146162306a36Sopenharmony_ci 146262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", 146362306a36Sopenharmony_ci bcn_interval); 146462306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); 146562306a36Sopenharmony_ci} 146662306a36Sopenharmony_ci 146762306a36Sopenharmony_civoid rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, 146862306a36Sopenharmony_ci u32 add_msr, u32 rm_msr) 146962306a36Sopenharmony_ci{ 147062306a36Sopenharmony_ci} 147162306a36Sopenharmony_ci 147262306a36Sopenharmony_civoid rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 147362306a36Sopenharmony_ci{ 147462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 147562306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 147662306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 147762306a36Sopenharmony_ci 147862306a36Sopenharmony_ci switch (variable) { 147962306a36Sopenharmony_ci case HW_VAR_RCR: 148062306a36Sopenharmony_ci *((u32 *)(val)) = mac->rx_conf; 148162306a36Sopenharmony_ci break; 148262306a36Sopenharmony_ci case HW_VAR_RF_STATE: 148362306a36Sopenharmony_ci *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; 148462306a36Sopenharmony_ci break; 148562306a36Sopenharmony_ci case HW_VAR_FWLPS_RF_ON:{ 148662306a36Sopenharmony_ci enum rf_pwrstate rfstate; 148762306a36Sopenharmony_ci u32 val_rcr; 148862306a36Sopenharmony_ci 148962306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, 149062306a36Sopenharmony_ci (u8 *)(&rfstate)); 149162306a36Sopenharmony_ci if (rfstate == ERFOFF) { 149262306a36Sopenharmony_ci *((bool *) (val)) = true; 149362306a36Sopenharmony_ci } else { 149462306a36Sopenharmony_ci val_rcr = rtl_read_dword(rtlpriv, REG_RCR); 149562306a36Sopenharmony_ci val_rcr &= 0x00070000; 149662306a36Sopenharmony_ci if (val_rcr) 149762306a36Sopenharmony_ci *((bool *) (val)) = false; 149862306a36Sopenharmony_ci else 149962306a36Sopenharmony_ci *((bool *) (val)) = true; 150062306a36Sopenharmony_ci } 150162306a36Sopenharmony_ci break; 150262306a36Sopenharmony_ci } 150362306a36Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: 150462306a36Sopenharmony_ci *((bool *) (val)) = ppsc->fw_current_inpsmode; 150562306a36Sopenharmony_ci break; 150662306a36Sopenharmony_ci case HW_VAR_CORRECT_TSF:{ 150762306a36Sopenharmony_ci u64 tsf; 150862306a36Sopenharmony_ci u32 *ptsf_low = (u32 *)&tsf; 150962306a36Sopenharmony_ci u32 *ptsf_high = ((u32 *)&tsf) + 1; 151062306a36Sopenharmony_ci 151162306a36Sopenharmony_ci *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); 151262306a36Sopenharmony_ci *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); 151362306a36Sopenharmony_ci *((u64 *)(val)) = tsf; 151462306a36Sopenharmony_ci break; 151562306a36Sopenharmony_ci } 151662306a36Sopenharmony_ci case HW_VAR_MGT_FILTER: 151762306a36Sopenharmony_ci *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); 151862306a36Sopenharmony_ci break; 151962306a36Sopenharmony_ci case HW_VAR_CTRL_FILTER: 152062306a36Sopenharmony_ci *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); 152162306a36Sopenharmony_ci break; 152262306a36Sopenharmony_ci case HW_VAR_DATA_FILTER: 152362306a36Sopenharmony_ci *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); 152462306a36Sopenharmony_ci break; 152562306a36Sopenharmony_ci case HAL_DEF_WOWLAN: 152662306a36Sopenharmony_ci break; 152762306a36Sopenharmony_ci default: 152862306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", variable); 152962306a36Sopenharmony_ci break; 153062306a36Sopenharmony_ci } 153162306a36Sopenharmony_ci} 153262306a36Sopenharmony_ci 153362306a36Sopenharmony_cistatic bool usb_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb) 153462306a36Sopenharmony_ci{ 153562306a36Sopenharmony_ci /* Currently nothing happens here. 153662306a36Sopenharmony_ci * Traffic stops after some seconds in WPA2 802.11n mode. 153762306a36Sopenharmony_ci * Maybe because rtl8192cu chip should be set from here? 153862306a36Sopenharmony_ci * If I understand correctly, the realtek vendor driver sends some urbs 153962306a36Sopenharmony_ci * if its "here". 154062306a36Sopenharmony_ci * 154162306a36Sopenharmony_ci * This is maybe necessary: 154262306a36Sopenharmony_ci * rtlpriv->cfg->ops->fill_tx_cmddesc(hw, buffer, 1, 1, skb); 154362306a36Sopenharmony_ci */ 154462306a36Sopenharmony_ci dev_kfree_skb(skb); 154562306a36Sopenharmony_ci 154662306a36Sopenharmony_ci return true; 154762306a36Sopenharmony_ci} 154862306a36Sopenharmony_ci 154962306a36Sopenharmony_civoid rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 155062306a36Sopenharmony_ci{ 155162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 155262306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 155362306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 155462306a36Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 155562306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 155662306a36Sopenharmony_ci enum wireless_mode wirelessmode = mac->mode; 155762306a36Sopenharmony_ci u8 idx = 0; 155862306a36Sopenharmony_ci 155962306a36Sopenharmony_ci switch (variable) { 156062306a36Sopenharmony_ci case HW_VAR_ETHER_ADDR:{ 156162306a36Sopenharmony_ci for (idx = 0; idx < ETH_ALEN; idx++) { 156262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_MACID + idx), 156362306a36Sopenharmony_ci val[idx]); 156462306a36Sopenharmony_ci } 156562306a36Sopenharmony_ci break; 156662306a36Sopenharmony_ci } 156762306a36Sopenharmony_ci case HW_VAR_BASIC_RATE:{ 156862306a36Sopenharmony_ci u16 rate_cfg = ((u16 *) val)[0]; 156962306a36Sopenharmony_ci u8 rate_index = 0; 157062306a36Sopenharmony_ci 157162306a36Sopenharmony_ci rate_cfg &= 0x15f; 157262306a36Sopenharmony_ci /* TODO */ 157362306a36Sopenharmony_ci /* if (mac->current_network.vender == HT_IOT_PEER_CISCO 157462306a36Sopenharmony_ci * && ((rate_cfg & 0x150) == 0)) { 157562306a36Sopenharmony_ci * rate_cfg |= 0x010; 157662306a36Sopenharmony_ci * } */ 157762306a36Sopenharmony_ci rate_cfg |= 0x01; 157862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); 157962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 1, 158062306a36Sopenharmony_ci (rate_cfg >> 8) & 0xff); 158162306a36Sopenharmony_ci while (rate_cfg > 0x1) { 158262306a36Sopenharmony_ci rate_cfg >>= 1; 158362306a36Sopenharmony_ci rate_index++; 158462306a36Sopenharmony_ci } 158562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 158662306a36Sopenharmony_ci rate_index); 158762306a36Sopenharmony_ci break; 158862306a36Sopenharmony_ci } 158962306a36Sopenharmony_ci case HW_VAR_BSSID:{ 159062306a36Sopenharmony_ci for (idx = 0; idx < ETH_ALEN; idx++) { 159162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_BSSID + idx), 159262306a36Sopenharmony_ci val[idx]); 159362306a36Sopenharmony_ci } 159462306a36Sopenharmony_ci break; 159562306a36Sopenharmony_ci } 159662306a36Sopenharmony_ci case HW_VAR_SIFS:{ 159762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SIFS_CCK + 1, val[0]); 159862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SIFS_OFDM + 1, val[1]); 159962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); 160062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); 160162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]); 160262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]); 160362306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, "HW_VAR_SIFS\n"); 160462306a36Sopenharmony_ci break; 160562306a36Sopenharmony_ci } 160662306a36Sopenharmony_ci case HW_VAR_SLOT_TIME:{ 160762306a36Sopenharmony_ci u8 e_aci; 160862306a36Sopenharmony_ci u8 QOS_MODE = 1; 160962306a36Sopenharmony_ci 161062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SLOT, val[0]); 161162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 161262306a36Sopenharmony_ci "HW_VAR_SLOT_TIME %x\n", val[0]); 161362306a36Sopenharmony_ci if (QOS_MODE) { 161462306a36Sopenharmony_ci for (e_aci = 0; e_aci < AC_MAX; e_aci++) 161562306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 161662306a36Sopenharmony_ci HW_VAR_AC_PARAM, 161762306a36Sopenharmony_ci &e_aci); 161862306a36Sopenharmony_ci } else { 161962306a36Sopenharmony_ci u8 sifstime = 0; 162062306a36Sopenharmony_ci u8 u1baifs; 162162306a36Sopenharmony_ci 162262306a36Sopenharmony_ci if (IS_WIRELESS_MODE_A(wirelessmode) || 162362306a36Sopenharmony_ci IS_WIRELESS_MODE_N_24G(wirelessmode) || 162462306a36Sopenharmony_ci IS_WIRELESS_MODE_N_5G(wirelessmode)) 162562306a36Sopenharmony_ci sifstime = 16; 162662306a36Sopenharmony_ci else 162762306a36Sopenharmony_ci sifstime = 10; 162862306a36Sopenharmony_ci u1baifs = sifstime + (2 * val[0]); 162962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_EDCA_VO_PARAM, 163062306a36Sopenharmony_ci u1baifs); 163162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_EDCA_VI_PARAM, 163262306a36Sopenharmony_ci u1baifs); 163362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_EDCA_BE_PARAM, 163462306a36Sopenharmony_ci u1baifs); 163562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_EDCA_BK_PARAM, 163662306a36Sopenharmony_ci u1baifs); 163762306a36Sopenharmony_ci } 163862306a36Sopenharmony_ci break; 163962306a36Sopenharmony_ci } 164062306a36Sopenharmony_ci case HW_VAR_ACK_PREAMBLE:{ 164162306a36Sopenharmony_ci u8 reg_tmp; 164262306a36Sopenharmony_ci u8 short_preamble = (bool)*val; 164362306a36Sopenharmony_ci 164462306a36Sopenharmony_ci reg_tmp = 0; 164562306a36Sopenharmony_ci if (short_preamble) 164662306a36Sopenharmony_ci reg_tmp |= 0x80; 164762306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); 164862306a36Sopenharmony_ci break; 164962306a36Sopenharmony_ci } 165062306a36Sopenharmony_ci case HW_VAR_AMPDU_MIN_SPACE:{ 165162306a36Sopenharmony_ci u8 min_spacing_to_set; 165262306a36Sopenharmony_ci u8 sec_min_space; 165362306a36Sopenharmony_ci 165462306a36Sopenharmony_ci min_spacing_to_set = *val; 165562306a36Sopenharmony_ci if (min_spacing_to_set <= 7) { 165662306a36Sopenharmony_ci switch (rtlpriv->sec.pairwise_enc_algorithm) { 165762306a36Sopenharmony_ci case NO_ENCRYPTION: 165862306a36Sopenharmony_ci case AESCCMP_ENCRYPTION: 165962306a36Sopenharmony_ci sec_min_space = 0; 166062306a36Sopenharmony_ci break; 166162306a36Sopenharmony_ci case WEP40_ENCRYPTION: 166262306a36Sopenharmony_ci case WEP104_ENCRYPTION: 166362306a36Sopenharmony_ci case TKIP_ENCRYPTION: 166462306a36Sopenharmony_ci sec_min_space = 6; 166562306a36Sopenharmony_ci break; 166662306a36Sopenharmony_ci default: 166762306a36Sopenharmony_ci sec_min_space = 7; 166862306a36Sopenharmony_ci break; 166962306a36Sopenharmony_ci } 167062306a36Sopenharmony_ci if (min_spacing_to_set < sec_min_space) 167162306a36Sopenharmony_ci min_spacing_to_set = sec_min_space; 167262306a36Sopenharmony_ci mac->min_space_cfg = ((mac->min_space_cfg & 167362306a36Sopenharmony_ci 0xf8) | 167462306a36Sopenharmony_ci min_spacing_to_set); 167562306a36Sopenharmony_ci *val = min_spacing_to_set; 167662306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 167762306a36Sopenharmony_ci "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", 167862306a36Sopenharmony_ci mac->min_space_cfg); 167962306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 168062306a36Sopenharmony_ci mac->min_space_cfg); 168162306a36Sopenharmony_ci } 168262306a36Sopenharmony_ci break; 168362306a36Sopenharmony_ci } 168462306a36Sopenharmony_ci case HW_VAR_SHORTGI_DENSITY:{ 168562306a36Sopenharmony_ci u8 density_to_set; 168662306a36Sopenharmony_ci 168762306a36Sopenharmony_ci density_to_set = *val; 168862306a36Sopenharmony_ci density_to_set &= 0x1f; 168962306a36Sopenharmony_ci mac->min_space_cfg &= 0x07; 169062306a36Sopenharmony_ci mac->min_space_cfg |= (density_to_set << 3); 169162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 169262306a36Sopenharmony_ci "Set HW_VAR_SHORTGI_DENSITY: %#x\n", 169362306a36Sopenharmony_ci mac->min_space_cfg); 169462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 169562306a36Sopenharmony_ci mac->min_space_cfg); 169662306a36Sopenharmony_ci break; 169762306a36Sopenharmony_ci } 169862306a36Sopenharmony_ci case HW_VAR_AMPDU_FACTOR:{ 169962306a36Sopenharmony_ci u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; 170062306a36Sopenharmony_ci u8 factor_toset; 170162306a36Sopenharmony_ci u8 *p_regtoset = NULL; 170262306a36Sopenharmony_ci u8 index = 0; 170362306a36Sopenharmony_ci 170462306a36Sopenharmony_ci p_regtoset = regtoset_normal; 170562306a36Sopenharmony_ci factor_toset = *val; 170662306a36Sopenharmony_ci if (factor_toset <= 3) { 170762306a36Sopenharmony_ci factor_toset = (1 << (factor_toset + 2)); 170862306a36Sopenharmony_ci if (factor_toset > 0xf) 170962306a36Sopenharmony_ci factor_toset = 0xf; 171062306a36Sopenharmony_ci for (index = 0; index < 4; index++) { 171162306a36Sopenharmony_ci if ((p_regtoset[index] & 0xf0) > 171262306a36Sopenharmony_ci (factor_toset << 4)) 171362306a36Sopenharmony_ci p_regtoset[index] = 171462306a36Sopenharmony_ci (p_regtoset[index] & 0x0f) 171562306a36Sopenharmony_ci | (factor_toset << 4); 171662306a36Sopenharmony_ci if ((p_regtoset[index] & 0x0f) > 171762306a36Sopenharmony_ci factor_toset) 171862306a36Sopenharmony_ci p_regtoset[index] = 171962306a36Sopenharmony_ci (p_regtoset[index] & 0xf0) 172062306a36Sopenharmony_ci | (factor_toset); 172162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 172262306a36Sopenharmony_ci (REG_AGGLEN_LMT + index), 172362306a36Sopenharmony_ci p_regtoset[index]); 172462306a36Sopenharmony_ci } 172562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 172662306a36Sopenharmony_ci "Set HW_VAR_AMPDU_FACTOR: %#x\n", 172762306a36Sopenharmony_ci factor_toset); 172862306a36Sopenharmony_ci } 172962306a36Sopenharmony_ci break; 173062306a36Sopenharmony_ci } 173162306a36Sopenharmony_ci case HW_VAR_AC_PARAM:{ 173262306a36Sopenharmony_ci u8 e_aci = *val; 173362306a36Sopenharmony_ci u32 u4b_ac_param; 173462306a36Sopenharmony_ci u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); 173562306a36Sopenharmony_ci u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); 173662306a36Sopenharmony_ci u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op); 173762306a36Sopenharmony_ci 173862306a36Sopenharmony_ci u4b_ac_param = (u32) mac->ac[e_aci].aifs; 173962306a36Sopenharmony_ci u4b_ac_param |= (u32) ((cw_min & 0xF) << 174062306a36Sopenharmony_ci AC_PARAM_ECW_MIN_OFFSET); 174162306a36Sopenharmony_ci u4b_ac_param |= (u32) ((cw_max & 0xF) << 174262306a36Sopenharmony_ci AC_PARAM_ECW_MAX_OFFSET); 174362306a36Sopenharmony_ci u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET; 174462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 174562306a36Sopenharmony_ci "queue:%x, ac_param:%x\n", 174662306a36Sopenharmony_ci e_aci, u4b_ac_param); 174762306a36Sopenharmony_ci switch (e_aci) { 174862306a36Sopenharmony_ci case AC1_BK: 174962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 175062306a36Sopenharmony_ci u4b_ac_param); 175162306a36Sopenharmony_ci break; 175262306a36Sopenharmony_ci case AC0_BE: 175362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 175462306a36Sopenharmony_ci u4b_ac_param); 175562306a36Sopenharmony_ci break; 175662306a36Sopenharmony_ci case AC2_VI: 175762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 175862306a36Sopenharmony_ci u4b_ac_param); 175962306a36Sopenharmony_ci break; 176062306a36Sopenharmony_ci case AC3_VO: 176162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 176262306a36Sopenharmony_ci u4b_ac_param); 176362306a36Sopenharmony_ci break; 176462306a36Sopenharmony_ci default: 176562306a36Sopenharmony_ci WARN_ONCE(true, "rtl8192cu: invalid aci: %d !\n", 176662306a36Sopenharmony_ci e_aci); 176762306a36Sopenharmony_ci break; 176862306a36Sopenharmony_ci } 176962306a36Sopenharmony_ci break; 177062306a36Sopenharmony_ci } 177162306a36Sopenharmony_ci case HW_VAR_RCR:{ 177262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); 177362306a36Sopenharmony_ci mac->rx_conf = ((u32 *) (val))[0]; 177462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RECV, DBG_DMESG, 177562306a36Sopenharmony_ci "### Set RCR(0x%08x) ###\n", mac->rx_conf); 177662306a36Sopenharmony_ci break; 177762306a36Sopenharmony_ci } 177862306a36Sopenharmony_ci case HW_VAR_RETRY_LIMIT:{ 177962306a36Sopenharmony_ci u8 retry_limit = val[0]; 178062306a36Sopenharmony_ci 178162306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RL, 178262306a36Sopenharmony_ci retry_limit << RETRY_LIMIT_SHORT_SHIFT | 178362306a36Sopenharmony_ci retry_limit << RETRY_LIMIT_LONG_SHIFT); 178462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_DMESG, 178562306a36Sopenharmony_ci "Set HW_VAR_RETRY_LIMIT(0x%08x)\n", 178662306a36Sopenharmony_ci retry_limit); 178762306a36Sopenharmony_ci break; 178862306a36Sopenharmony_ci } 178962306a36Sopenharmony_ci case HW_VAR_DUAL_TSF_RST: 179062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); 179162306a36Sopenharmony_ci break; 179262306a36Sopenharmony_ci case HW_VAR_EFUSE_BYTES: 179362306a36Sopenharmony_ci rtlefuse->efuse_usedbytes = *((u16 *) val); 179462306a36Sopenharmony_ci break; 179562306a36Sopenharmony_ci case HW_VAR_EFUSE_USAGE: 179662306a36Sopenharmony_ci rtlefuse->efuse_usedpercentage = *val; 179762306a36Sopenharmony_ci break; 179862306a36Sopenharmony_ci case HW_VAR_IO_CMD: 179962306a36Sopenharmony_ci rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); 180062306a36Sopenharmony_ci break; 180162306a36Sopenharmony_ci case HW_VAR_WPA_CONFIG: 180262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SECCFG, *val); 180362306a36Sopenharmony_ci break; 180462306a36Sopenharmony_ci case HW_VAR_SET_RPWM:{ 180562306a36Sopenharmony_ci u8 rpwm_val = rtl_read_byte(rtlpriv, REG_USB_HRPWM); 180662306a36Sopenharmony_ci 180762306a36Sopenharmony_ci if (rpwm_val & BIT(7)) 180862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_USB_HRPWM, *val); 180962306a36Sopenharmony_ci else 181062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_USB_HRPWM, 181162306a36Sopenharmony_ci *val | BIT(7)); 181262306a36Sopenharmony_ci break; 181362306a36Sopenharmony_ci } 181462306a36Sopenharmony_ci case HW_VAR_H2C_FW_PWRMODE:{ 181562306a36Sopenharmony_ci u8 psmode = *val; 181662306a36Sopenharmony_ci 181762306a36Sopenharmony_ci if ((psmode != FW_PS_ACTIVE_MODE) && 181862306a36Sopenharmony_ci (!IS_92C_SERIAL(rtlhal->version))) 181962306a36Sopenharmony_ci rtl92c_dm_rf_saving(hw, true); 182062306a36Sopenharmony_ci rtl92c_set_fw_pwrmode_cmd(hw, (*val)); 182162306a36Sopenharmony_ci break; 182262306a36Sopenharmony_ci } 182362306a36Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: 182462306a36Sopenharmony_ci ppsc->fw_current_inpsmode = *((bool *) val); 182562306a36Sopenharmony_ci break; 182662306a36Sopenharmony_ci case HW_VAR_H2C_FW_JOINBSSRPT:{ 182762306a36Sopenharmony_ci u8 mstatus = *val; 182862306a36Sopenharmony_ci u8 tmp_reg422; 182962306a36Sopenharmony_ci bool recover = false; 183062306a36Sopenharmony_ci 183162306a36Sopenharmony_ci if (mstatus == RT_MEDIA_CONNECT) { 183262306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 183362306a36Sopenharmony_ci HW_VAR_AID, NULL); 183462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, 0x03); 183562306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); 183662306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); 183762306a36Sopenharmony_ci tmp_reg422 = rtl_read_byte(rtlpriv, 183862306a36Sopenharmony_ci REG_FWHW_TXQ_CTRL + 2); 183962306a36Sopenharmony_ci if (tmp_reg422 & BIT(6)) 184062306a36Sopenharmony_ci recover = true; 184162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, 184262306a36Sopenharmony_ci tmp_reg422 & (~BIT(6))); 184362306a36Sopenharmony_ci rtl92c_set_fw_rsvdpagepkt(hw, 184462306a36Sopenharmony_ci &usb_cmd_send_packet); 184562306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); 184662306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); 184762306a36Sopenharmony_ci if (recover) 184862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 184962306a36Sopenharmony_ci REG_FWHW_TXQ_CTRL + 2, 185062306a36Sopenharmony_ci tmp_reg422 | BIT(6)); 185162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); 185262306a36Sopenharmony_ci } 185362306a36Sopenharmony_ci rtl92c_set_fw_joinbss_report_cmd(hw, (*val)); 185462306a36Sopenharmony_ci break; 185562306a36Sopenharmony_ci } 185662306a36Sopenharmony_ci case HW_VAR_AID:{ 185762306a36Sopenharmony_ci u16 u2btmp; 185862306a36Sopenharmony_ci 185962306a36Sopenharmony_ci u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); 186062306a36Sopenharmony_ci u2btmp &= 0xC000; 186162306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, 186262306a36Sopenharmony_ci (u2btmp | mac->assoc_id)); 186362306a36Sopenharmony_ci break; 186462306a36Sopenharmony_ci } 186562306a36Sopenharmony_ci case HW_VAR_CORRECT_TSF:{ 186662306a36Sopenharmony_ci u8 btype_ibss = val[0]; 186762306a36Sopenharmony_ci 186862306a36Sopenharmony_ci if (btype_ibss) 186962306a36Sopenharmony_ci _rtl92cu_stop_tx_beacon(hw); 187062306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); 187162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTR, (u32)(mac->tsf & 187262306a36Sopenharmony_ci 0xffffffff)); 187362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTR + 4, 187462306a36Sopenharmony_ci (u32)((mac->tsf >> 32) & 0xffffffff)); 187562306a36Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); 187662306a36Sopenharmony_ci if (btype_ibss) 187762306a36Sopenharmony_ci _rtl92cu_resume_tx_beacon(hw); 187862306a36Sopenharmony_ci break; 187962306a36Sopenharmony_ci } 188062306a36Sopenharmony_ci case HW_VAR_MGT_FILTER: 188162306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *)val); 188262306a36Sopenharmony_ci mac->rx_mgt_filter = *(u16 *)val; 188362306a36Sopenharmony_ci break; 188462306a36Sopenharmony_ci case HW_VAR_CTRL_FILTER: 188562306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *)val); 188662306a36Sopenharmony_ci mac->rx_ctrl_filter = *(u16 *)val; 188762306a36Sopenharmony_ci break; 188862306a36Sopenharmony_ci case HW_VAR_DATA_FILTER: 188962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val); 189062306a36Sopenharmony_ci mac->rx_data_filter = *(u16 *)val; 189162306a36Sopenharmony_ci break; 189262306a36Sopenharmony_ci case HW_VAR_KEEP_ALIVE:{ 189362306a36Sopenharmony_ci u8 array[2]; 189462306a36Sopenharmony_ci 189562306a36Sopenharmony_ci array[0] = 0xff; 189662306a36Sopenharmony_ci array[1] = *((u8 *)val); 189762306a36Sopenharmony_ci rtl92c_fill_h2c_cmd(hw, H2C_92C_KEEP_ALIVE_CTRL, 2, 189862306a36Sopenharmony_ci array); 189962306a36Sopenharmony_ci break; 190062306a36Sopenharmony_ci } 190162306a36Sopenharmony_ci default: 190262306a36Sopenharmony_ci pr_err("switch case %#x not processed\n", variable); 190362306a36Sopenharmony_ci break; 190462306a36Sopenharmony_ci } 190562306a36Sopenharmony_ci} 190662306a36Sopenharmony_ci 190762306a36Sopenharmony_cistatic void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, 190862306a36Sopenharmony_ci struct ieee80211_sta *sta) 190962306a36Sopenharmony_ci{ 191062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 191162306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 191262306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 191362306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 191462306a36Sopenharmony_ci u32 ratr_value; 191562306a36Sopenharmony_ci u8 ratr_index = 0; 191662306a36Sopenharmony_ci u8 nmode = mac->ht_enable; 191762306a36Sopenharmony_ci u8 mimo_ps = IEEE80211_SMPS_OFF; 191862306a36Sopenharmony_ci u16 shortgi_rate; 191962306a36Sopenharmony_ci u32 tmp_ratr_value; 192062306a36Sopenharmony_ci u8 curtxbw_40mhz = mac->bw_40; 192162306a36Sopenharmony_ci u8 curshortgi_40mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 192262306a36Sopenharmony_ci 1 : 0; 192362306a36Sopenharmony_ci u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 192462306a36Sopenharmony_ci 1 : 0; 192562306a36Sopenharmony_ci enum wireless_mode wirelessmode = mac->mode; 192662306a36Sopenharmony_ci 192762306a36Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_5G) 192862306a36Sopenharmony_ci ratr_value = sta->deflink.supp_rates[1] << 4; 192962306a36Sopenharmony_ci else 193062306a36Sopenharmony_ci ratr_value = sta->deflink.supp_rates[0]; 193162306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) 193262306a36Sopenharmony_ci ratr_value = 0xfff; 193362306a36Sopenharmony_ci 193462306a36Sopenharmony_ci ratr_value |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | 193562306a36Sopenharmony_ci sta->deflink.ht_cap.mcs.rx_mask[0] << 12); 193662306a36Sopenharmony_ci switch (wirelessmode) { 193762306a36Sopenharmony_ci case WIRELESS_MODE_B: 193862306a36Sopenharmony_ci if (ratr_value & 0x0000000c) 193962306a36Sopenharmony_ci ratr_value &= 0x0000000d; 194062306a36Sopenharmony_ci else 194162306a36Sopenharmony_ci ratr_value &= 0x0000000f; 194262306a36Sopenharmony_ci break; 194362306a36Sopenharmony_ci case WIRELESS_MODE_G: 194462306a36Sopenharmony_ci ratr_value &= 0x00000FF5; 194562306a36Sopenharmony_ci break; 194662306a36Sopenharmony_ci case WIRELESS_MODE_N_24G: 194762306a36Sopenharmony_ci case WIRELESS_MODE_N_5G: 194862306a36Sopenharmony_ci nmode = 1; 194962306a36Sopenharmony_ci if (mimo_ps == IEEE80211_SMPS_STATIC) { 195062306a36Sopenharmony_ci ratr_value &= 0x0007F005; 195162306a36Sopenharmony_ci } else { 195262306a36Sopenharmony_ci u32 ratr_mask; 195362306a36Sopenharmony_ci 195462306a36Sopenharmony_ci if (get_rf_type(rtlphy) == RF_1T2R || 195562306a36Sopenharmony_ci get_rf_type(rtlphy) == RF_1T1R) 195662306a36Sopenharmony_ci ratr_mask = 0x000ff005; 195762306a36Sopenharmony_ci else 195862306a36Sopenharmony_ci ratr_mask = 0x0f0ff005; 195962306a36Sopenharmony_ci 196062306a36Sopenharmony_ci ratr_value &= ratr_mask; 196162306a36Sopenharmony_ci } 196262306a36Sopenharmony_ci break; 196362306a36Sopenharmony_ci default: 196462306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) 196562306a36Sopenharmony_ci ratr_value &= 0x000ff0ff; 196662306a36Sopenharmony_ci else 196762306a36Sopenharmony_ci ratr_value &= 0x0f0ff0ff; 196862306a36Sopenharmony_ci 196962306a36Sopenharmony_ci break; 197062306a36Sopenharmony_ci } 197162306a36Sopenharmony_ci 197262306a36Sopenharmony_ci ratr_value &= 0x0FFFFFFF; 197362306a36Sopenharmony_ci 197462306a36Sopenharmony_ci if (nmode && ((curtxbw_40mhz && 197562306a36Sopenharmony_ci curshortgi_40mhz) || (!curtxbw_40mhz && 197662306a36Sopenharmony_ci curshortgi_20mhz))) { 197762306a36Sopenharmony_ci ratr_value |= 0x10000000; 197862306a36Sopenharmony_ci tmp_ratr_value = (ratr_value >> 12); 197962306a36Sopenharmony_ci 198062306a36Sopenharmony_ci for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { 198162306a36Sopenharmony_ci if ((1 << shortgi_rate) & tmp_ratr_value) 198262306a36Sopenharmony_ci break; 198362306a36Sopenharmony_ci } 198462306a36Sopenharmony_ci 198562306a36Sopenharmony_ci shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | 198662306a36Sopenharmony_ci (shortgi_rate << 4) | (shortgi_rate); 198762306a36Sopenharmony_ci } 198862306a36Sopenharmony_ci 198962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); 199062306a36Sopenharmony_ci 199162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", 199262306a36Sopenharmony_ci rtl_read_dword(rtlpriv, REG_ARFR0)); 199362306a36Sopenharmony_ci} 199462306a36Sopenharmony_ci 199562306a36Sopenharmony_cistatic void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, 199662306a36Sopenharmony_ci struct ieee80211_sta *sta, 199762306a36Sopenharmony_ci u8 rssi_level, bool update_bw) 199862306a36Sopenharmony_ci{ 199962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 200062306a36Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 200162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 200262306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 200362306a36Sopenharmony_ci struct rtl_sta_info *sta_entry = NULL; 200462306a36Sopenharmony_ci u32 ratr_bitmap; 200562306a36Sopenharmony_ci u8 ratr_index; 200662306a36Sopenharmony_ci u8 curtxbw_40mhz = (sta->deflink.bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; 200762306a36Sopenharmony_ci u8 curshortgi_40mhz = curtxbw_40mhz && 200862306a36Sopenharmony_ci (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 200962306a36Sopenharmony_ci 1 : 0; 201062306a36Sopenharmony_ci u8 curshortgi_20mhz = (sta->deflink.ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 201162306a36Sopenharmony_ci 1 : 0; 201262306a36Sopenharmony_ci enum wireless_mode wirelessmode = 0; 201362306a36Sopenharmony_ci bool shortgi = false; 201462306a36Sopenharmony_ci u8 rate_mask[5]; 201562306a36Sopenharmony_ci u8 macid = 0; 201662306a36Sopenharmony_ci u8 mimo_ps = IEEE80211_SMPS_OFF; 201762306a36Sopenharmony_ci 201862306a36Sopenharmony_ci sta_entry = (struct rtl_sta_info *) sta->drv_priv; 201962306a36Sopenharmony_ci wirelessmode = sta_entry->wireless_mode; 202062306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_STATION || 202162306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_MESH_POINT) 202262306a36Sopenharmony_ci curtxbw_40mhz = mac->bw_40; 202362306a36Sopenharmony_ci else if (mac->opmode == NL80211_IFTYPE_AP || 202462306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC) 202562306a36Sopenharmony_ci macid = sta->aid + 1; 202662306a36Sopenharmony_ci 202762306a36Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_5G) 202862306a36Sopenharmony_ci ratr_bitmap = sta->deflink.supp_rates[1] << 4; 202962306a36Sopenharmony_ci else 203062306a36Sopenharmony_ci ratr_bitmap = sta->deflink.supp_rates[0]; 203162306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) 203262306a36Sopenharmony_ci ratr_bitmap = 0xfff; 203362306a36Sopenharmony_ci ratr_bitmap |= (sta->deflink.ht_cap.mcs.rx_mask[1] << 20 | 203462306a36Sopenharmony_ci sta->deflink.ht_cap.mcs.rx_mask[0] << 12); 203562306a36Sopenharmony_ci switch (wirelessmode) { 203662306a36Sopenharmony_ci case WIRELESS_MODE_B: 203762306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_B; 203862306a36Sopenharmony_ci if (ratr_bitmap & 0x0000000c) 203962306a36Sopenharmony_ci ratr_bitmap &= 0x0000000d; 204062306a36Sopenharmony_ci else 204162306a36Sopenharmony_ci ratr_bitmap &= 0x0000000f; 204262306a36Sopenharmony_ci break; 204362306a36Sopenharmony_ci case WIRELESS_MODE_G: 204462306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_GB; 204562306a36Sopenharmony_ci 204662306a36Sopenharmony_ci if (rssi_level == 1) 204762306a36Sopenharmony_ci ratr_bitmap &= 0x00000f00; 204862306a36Sopenharmony_ci else if (rssi_level == 2) 204962306a36Sopenharmony_ci ratr_bitmap &= 0x00000ff0; 205062306a36Sopenharmony_ci else 205162306a36Sopenharmony_ci ratr_bitmap &= 0x00000ff5; 205262306a36Sopenharmony_ci break; 205362306a36Sopenharmony_ci case WIRELESS_MODE_A: 205462306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_A; 205562306a36Sopenharmony_ci ratr_bitmap &= 0x00000ff0; 205662306a36Sopenharmony_ci break; 205762306a36Sopenharmony_ci case WIRELESS_MODE_N_24G: 205862306a36Sopenharmony_ci case WIRELESS_MODE_N_5G: 205962306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 206062306a36Sopenharmony_ci 206162306a36Sopenharmony_ci if (mimo_ps == IEEE80211_SMPS_STATIC) { 206262306a36Sopenharmony_ci if (rssi_level == 1) 206362306a36Sopenharmony_ci ratr_bitmap &= 0x00070000; 206462306a36Sopenharmony_ci else if (rssi_level == 2) 206562306a36Sopenharmony_ci ratr_bitmap &= 0x0007f000; 206662306a36Sopenharmony_ci else 206762306a36Sopenharmony_ci ratr_bitmap &= 0x0007f005; 206862306a36Sopenharmony_ci } else { 206962306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R || 207062306a36Sopenharmony_ci rtlphy->rf_type == RF_1T1R) { 207162306a36Sopenharmony_ci if (curtxbw_40mhz) { 207262306a36Sopenharmony_ci if (rssi_level == 1) 207362306a36Sopenharmony_ci ratr_bitmap &= 0x000f0000; 207462306a36Sopenharmony_ci else if (rssi_level == 2) 207562306a36Sopenharmony_ci ratr_bitmap &= 0x000ff000; 207662306a36Sopenharmony_ci else 207762306a36Sopenharmony_ci ratr_bitmap &= 0x000ff015; 207862306a36Sopenharmony_ci } else { 207962306a36Sopenharmony_ci if (rssi_level == 1) 208062306a36Sopenharmony_ci ratr_bitmap &= 0x000f0000; 208162306a36Sopenharmony_ci else if (rssi_level == 2) 208262306a36Sopenharmony_ci ratr_bitmap &= 0x000ff000; 208362306a36Sopenharmony_ci else 208462306a36Sopenharmony_ci ratr_bitmap &= 0x000ff005; 208562306a36Sopenharmony_ci } 208662306a36Sopenharmony_ci } else { 208762306a36Sopenharmony_ci if (curtxbw_40mhz) { 208862306a36Sopenharmony_ci if (rssi_level == 1) 208962306a36Sopenharmony_ci ratr_bitmap &= 0x0f0f0000; 209062306a36Sopenharmony_ci else if (rssi_level == 2) 209162306a36Sopenharmony_ci ratr_bitmap &= 0x0f0ff000; 209262306a36Sopenharmony_ci else 209362306a36Sopenharmony_ci ratr_bitmap &= 0x0f0ff015; 209462306a36Sopenharmony_ci } else { 209562306a36Sopenharmony_ci if (rssi_level == 1) 209662306a36Sopenharmony_ci ratr_bitmap &= 0x0f0f0000; 209762306a36Sopenharmony_ci else if (rssi_level == 2) 209862306a36Sopenharmony_ci ratr_bitmap &= 0x0f0ff000; 209962306a36Sopenharmony_ci else 210062306a36Sopenharmony_ci ratr_bitmap &= 0x0f0ff005; 210162306a36Sopenharmony_ci } 210262306a36Sopenharmony_ci } 210362306a36Sopenharmony_ci } 210462306a36Sopenharmony_ci 210562306a36Sopenharmony_ci if ((curtxbw_40mhz && curshortgi_40mhz) || 210662306a36Sopenharmony_ci (!curtxbw_40mhz && curshortgi_20mhz)) { 210762306a36Sopenharmony_ci 210862306a36Sopenharmony_ci if (macid == 0) 210962306a36Sopenharmony_ci shortgi = true; 211062306a36Sopenharmony_ci else if (macid == 1) 211162306a36Sopenharmony_ci shortgi = false; 211262306a36Sopenharmony_ci } 211362306a36Sopenharmony_ci break; 211462306a36Sopenharmony_ci default: 211562306a36Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 211662306a36Sopenharmony_ci 211762306a36Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) 211862306a36Sopenharmony_ci ratr_bitmap &= 0x000ff0ff; 211962306a36Sopenharmony_ci else 212062306a36Sopenharmony_ci ratr_bitmap &= 0x0f0ff0ff; 212162306a36Sopenharmony_ci break; 212262306a36Sopenharmony_ci } 212362306a36Sopenharmony_ci sta_entry->ratr_index = ratr_index; 212462306a36Sopenharmony_ci 212562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, 212662306a36Sopenharmony_ci "ratr_bitmap :%x\n", ratr_bitmap); 212762306a36Sopenharmony_ci *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | 212862306a36Sopenharmony_ci (ratr_index << 28); 212962306a36Sopenharmony_ci rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; 213062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, 213162306a36Sopenharmony_ci "Rate_index:%x, ratr_val:%x, %5phC\n", 213262306a36Sopenharmony_ci ratr_index, ratr_bitmap, rate_mask); 213362306a36Sopenharmony_ci memcpy(rtlpriv->rate_mask, rate_mask, 5); 213462306a36Sopenharmony_ci /* rtl92c_fill_h2c_cmd() does USB I/O and will result in a 213562306a36Sopenharmony_ci * "scheduled while atomic" if called directly */ 213662306a36Sopenharmony_ci schedule_work(&rtlpriv->works.fill_h2c_cmd); 213762306a36Sopenharmony_ci 213862306a36Sopenharmony_ci if (macid != 0) 213962306a36Sopenharmony_ci sta_entry->ratr_index = ratr_index; 214062306a36Sopenharmony_ci} 214162306a36Sopenharmony_ci 214262306a36Sopenharmony_civoid rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, 214362306a36Sopenharmony_ci struct ieee80211_sta *sta, 214462306a36Sopenharmony_ci u8 rssi_level, bool update_bw) 214562306a36Sopenharmony_ci{ 214662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 214762306a36Sopenharmony_ci 214862306a36Sopenharmony_ci if (rtlpriv->dm.useramask) 214962306a36Sopenharmony_ci rtl92cu_update_hal_rate_mask(hw, sta, rssi_level, update_bw); 215062306a36Sopenharmony_ci else 215162306a36Sopenharmony_ci rtl92cu_update_hal_rate_table(hw, sta); 215262306a36Sopenharmony_ci} 215362306a36Sopenharmony_ci 215462306a36Sopenharmony_civoid rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) 215562306a36Sopenharmony_ci{ 215662306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 215762306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 215862306a36Sopenharmony_ci u16 sifs_timer; 215962306a36Sopenharmony_ci 216062306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, 216162306a36Sopenharmony_ci &mac->slot_time); 216262306a36Sopenharmony_ci if (!mac->ht_enable) 216362306a36Sopenharmony_ci sifs_timer = 0x0a0a; 216462306a36Sopenharmony_ci else 216562306a36Sopenharmony_ci sifs_timer = 0x0e0e; 216662306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); 216762306a36Sopenharmony_ci} 216862306a36Sopenharmony_ci 216962306a36Sopenharmony_cibool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) 217062306a36Sopenharmony_ci{ 217162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 217262306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 217362306a36Sopenharmony_ci enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; 217462306a36Sopenharmony_ci u8 u1tmp = 0; 217562306a36Sopenharmony_ci bool actuallyset = false; 217662306a36Sopenharmony_ci unsigned long flag = 0; 217762306a36Sopenharmony_ci /* to do - usb autosuspend */ 217862306a36Sopenharmony_ci u8 usb_autosuspend = 0; 217962306a36Sopenharmony_ci 218062306a36Sopenharmony_ci if (ppsc->swrf_processing) 218162306a36Sopenharmony_ci return false; 218262306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 218362306a36Sopenharmony_ci if (ppsc->rfchange_inprogress) { 218462306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 218562306a36Sopenharmony_ci return false; 218662306a36Sopenharmony_ci } else { 218762306a36Sopenharmony_ci ppsc->rfchange_inprogress = true; 218862306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 218962306a36Sopenharmony_ci } 219062306a36Sopenharmony_ci cur_rfstate = ppsc->rfpwr_state; 219162306a36Sopenharmony_ci if (usb_autosuspend) { 219262306a36Sopenharmony_ci /* to do................... */ 219362306a36Sopenharmony_ci } else { 219462306a36Sopenharmony_ci if (ppsc->pwrdown_mode) { 219562306a36Sopenharmony_ci u1tmp = rtl_read_byte(rtlpriv, REG_HSISR); 219662306a36Sopenharmony_ci e_rfpowerstate_toset = (u1tmp & BIT(7)) ? 219762306a36Sopenharmony_ci ERFOFF : ERFON; 219862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 219962306a36Sopenharmony_ci "pwrdown, 0x5c(BIT7)=%02x\n", u1tmp); 220062306a36Sopenharmony_ci } else { 220162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, 220262306a36Sopenharmony_ci rtl_read_byte(rtlpriv, 220362306a36Sopenharmony_ci REG_MAC_PINMUX_CFG) & ~(BIT(3))); 220462306a36Sopenharmony_ci u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); 220562306a36Sopenharmony_ci e_rfpowerstate_toset = (u1tmp & BIT(3)) ? 220662306a36Sopenharmony_ci ERFON : ERFOFF; 220762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 220862306a36Sopenharmony_ci "GPIO_IN=%02x\n", u1tmp); 220962306a36Sopenharmony_ci } 221062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "N-SS RF =%x\n", 221162306a36Sopenharmony_ci e_rfpowerstate_toset); 221262306a36Sopenharmony_ci } 221362306a36Sopenharmony_ci if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { 221462306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 221562306a36Sopenharmony_ci "GPIOChangeRF - HW Radio ON, RF ON\n"); 221662306a36Sopenharmony_ci ppsc->hwradiooff = false; 221762306a36Sopenharmony_ci actuallyset = true; 221862306a36Sopenharmony_ci } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset == 221962306a36Sopenharmony_ci ERFOFF)) { 222062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 222162306a36Sopenharmony_ci "GPIOChangeRF - HW Radio OFF\n"); 222262306a36Sopenharmony_ci ppsc->hwradiooff = true; 222362306a36Sopenharmony_ci actuallyset = true; 222462306a36Sopenharmony_ci } else { 222562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 222662306a36Sopenharmony_ci "pHalData->bHwRadioOff and eRfPowerStateToSet do not match: pHalData->bHwRadioOff %x, eRfPowerStateToSet %x\n", 222762306a36Sopenharmony_ci ppsc->hwradiooff, e_rfpowerstate_toset); 222862306a36Sopenharmony_ci } 222962306a36Sopenharmony_ci if (actuallyset) { 223062306a36Sopenharmony_ci ppsc->hwradiooff = true; 223162306a36Sopenharmony_ci if (e_rfpowerstate_toset == ERFON) { 223262306a36Sopenharmony_ci if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && 223362306a36Sopenharmony_ci RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) 223462306a36Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); 223562306a36Sopenharmony_ci else if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) 223662306a36Sopenharmony_ci && RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3)) 223762306a36Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); 223862306a36Sopenharmony_ci } 223962306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 224062306a36Sopenharmony_ci ppsc->rfchange_inprogress = false; 224162306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 224262306a36Sopenharmony_ci /* For power down module, we need to enable register block 224362306a36Sopenharmony_ci * contrl reg at 0x1c. Then enable power down control bit 224462306a36Sopenharmony_ci * of register 0x04 BIT4 and BIT15 as 1. 224562306a36Sopenharmony_ci */ 224662306a36Sopenharmony_ci if (ppsc->pwrdown_mode && e_rfpowerstate_toset == ERFOFF) { 224762306a36Sopenharmony_ci /* Enable register area 0x0-0xc. */ 224862306a36Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); 224962306a36Sopenharmony_ci rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x8812); 225062306a36Sopenharmony_ci } 225162306a36Sopenharmony_ci if (e_rfpowerstate_toset == ERFOFF) { 225262306a36Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) 225362306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); 225462306a36Sopenharmony_ci else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) 225562306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); 225662306a36Sopenharmony_ci } 225762306a36Sopenharmony_ci } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { 225862306a36Sopenharmony_ci /* Enter D3 or ASPM after GPIO had been done. */ 225962306a36Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) 226062306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); 226162306a36Sopenharmony_ci else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) 226262306a36Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); 226362306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 226462306a36Sopenharmony_ci ppsc->rfchange_inprogress = false; 226562306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 226662306a36Sopenharmony_ci } else { 226762306a36Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 226862306a36Sopenharmony_ci ppsc->rfchange_inprogress = false; 226962306a36Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 227062306a36Sopenharmony_ci } 227162306a36Sopenharmony_ci *valid = 1; 227262306a36Sopenharmony_ci return !ppsc->hwradiooff; 227362306a36Sopenharmony_ci} 2274