18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* Copyright(c) 2009-2012 Realtek Corporation.*/ 38c2ecf20Sopenharmony_ci 48c2ecf20Sopenharmony_ci#include "../wifi.h" 58c2ecf20Sopenharmony_ci#include "../efuse.h" 68c2ecf20Sopenharmony_ci#include "../base.h" 78c2ecf20Sopenharmony_ci#include "../cam.h" 88c2ecf20Sopenharmony_ci#include "../ps.h" 98c2ecf20Sopenharmony_ci#include "../usb.h" 108c2ecf20Sopenharmony_ci#include "reg.h" 118c2ecf20Sopenharmony_ci#include "def.h" 128c2ecf20Sopenharmony_ci#include "phy.h" 138c2ecf20Sopenharmony_ci#include "../rtl8192c/phy_common.h" 148c2ecf20Sopenharmony_ci#include "mac.h" 158c2ecf20Sopenharmony_ci#include "dm.h" 168c2ecf20Sopenharmony_ci#include "../rtl8192c/dm_common.h" 178c2ecf20Sopenharmony_ci#include "../rtl8192c/fw_common.h" 188c2ecf20Sopenharmony_ci#include "hw.h" 198c2ecf20Sopenharmony_ci#include "../rtl8192ce/hw.h" 208c2ecf20Sopenharmony_ci#include "trx.h" 218c2ecf20Sopenharmony_ci#include "led.h" 228c2ecf20Sopenharmony_ci#include "table.h" 238c2ecf20Sopenharmony_ci 248c2ecf20Sopenharmony_cistatic void _rtl92cu_phy_param_tab_init(struct ieee80211_hw *hw) 258c2ecf20Sopenharmony_ci{ 268c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 278c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 288c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); 298c2ecf20Sopenharmony_ci 308c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[MAC_REG].length = RTL8192CUMAC_2T_ARRAYLENGTH; 318c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[MAC_REG].pdata = RTL8192CUMAC_2T_ARRAY; 328c2ecf20Sopenharmony_ci if (IS_HIGHT_PA(rtlefuse->board_type)) { 338c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_PG].length = 348c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_ARRAY_PG_HPLENGTH; 358c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_PG].pdata = 368c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_ARRAY_PG_HP; 378c2ecf20Sopenharmony_ci } else { 388c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_PG].length = 398c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_ARRAY_PGLENGTH; 408c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_PG].pdata = 418c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_ARRAY_PG; 428c2ecf20Sopenharmony_ci } 438c2ecf20Sopenharmony_ci /* 2T */ 448c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_2T].length = 458c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_2TARRAY_LENGTH; 468c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_2T].pdata = 478c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_2TARRAY; 488c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_2T].length = 498c2ecf20Sopenharmony_ci RTL8192CURADIOA_2TARRAYLENGTH; 508c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_2T].pdata = 518c2ecf20Sopenharmony_ci RTL8192CURADIOA_2TARRAY; 528c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_2T].length = 538c2ecf20Sopenharmony_ci RTL8192CURADIOB_2TARRAYLENGTH; 548c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_2T].pdata = 558c2ecf20Sopenharmony_ci RTL8192CU_RADIOB_2TARRAY; 568c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_2T].length = 578c2ecf20Sopenharmony_ci RTL8192CUAGCTAB_2TARRAYLENGTH; 588c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_2T].pdata = 598c2ecf20Sopenharmony_ci RTL8192CUAGCTAB_2TARRAY; 608c2ecf20Sopenharmony_ci /* 1T */ 618c2ecf20Sopenharmony_ci if (IS_HIGHT_PA(rtlefuse->board_type)) { 628c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_1T].length = 638c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_1T_HPARRAYLENGTH; 648c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_1T].pdata = 658c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_1T_HPARRAY; 668c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_1T].length = 678c2ecf20Sopenharmony_ci RTL8192CURADIOA_1T_HPARRAYLENGTH; 688c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_1T].pdata = 698c2ecf20Sopenharmony_ci RTL8192CURADIOA_1T_HPARRAY; 708c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_1T].length = 718c2ecf20Sopenharmony_ci RTL8192CURADIOB_1TARRAYLENGTH; 728c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_1T].pdata = 738c2ecf20Sopenharmony_ci RTL8192CU_RADIOB_1TARRAY; 748c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_1T].length = 758c2ecf20Sopenharmony_ci RTL8192CUAGCTAB_1T_HPARRAYLENGTH; 768c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_1T].pdata = 778c2ecf20Sopenharmony_ci RTL8192CUAGCTAB_1T_HPARRAY; 788c2ecf20Sopenharmony_ci } else { 798c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_1T].length = 808c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_1TARRAY_LENGTH; 818c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[PHY_REG_1T].pdata = 828c2ecf20Sopenharmony_ci RTL8192CUPHY_REG_1TARRAY; 838c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_1T].length = 848c2ecf20Sopenharmony_ci RTL8192CURADIOA_1TARRAYLENGTH; 858c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOA_1T].pdata = 868c2ecf20Sopenharmony_ci RTL8192CU_RADIOA_1TARRAY; 878c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_1T].length = 888c2ecf20Sopenharmony_ci RTL8192CURADIOB_1TARRAYLENGTH; 898c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[RADIOB_1T].pdata = 908c2ecf20Sopenharmony_ci RTL8192CU_RADIOB_1TARRAY; 918c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_1T].length = 928c2ecf20Sopenharmony_ci RTL8192CUAGCTAB_1TARRAYLENGTH; 938c2ecf20Sopenharmony_ci rtlphy->hwparam_tables[AGCTAB_1T].pdata = 948c2ecf20Sopenharmony_ci RTL8192CUAGCTAB_1TARRAY; 958c2ecf20Sopenharmony_ci } 968c2ecf20Sopenharmony_ci} 978c2ecf20Sopenharmony_ci 988c2ecf20Sopenharmony_cistatic void _rtl92cu_read_txpower_info_from_hwpg(struct ieee80211_hw *hw, 998c2ecf20Sopenharmony_ci bool autoload_fail, 1008c2ecf20Sopenharmony_ci u8 *hwinfo) 1018c2ecf20Sopenharmony_ci{ 1028c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1038c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 1048c2ecf20Sopenharmony_ci u8 rf_path, index, tempval; 1058c2ecf20Sopenharmony_ci u16 i; 1068c2ecf20Sopenharmony_ci 1078c2ecf20Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 1088c2ecf20Sopenharmony_ci for (i = 0; i < 3; i++) { 1098c2ecf20Sopenharmony_ci if (!autoload_fail) { 1108c2ecf20Sopenharmony_ci rtlefuse-> 1118c2ecf20Sopenharmony_ci eeprom_chnlarea_txpwr_cck[rf_path][i] = 1128c2ecf20Sopenharmony_ci hwinfo[EEPROM_TXPOWERCCK + rf_path * 3 + i]; 1138c2ecf20Sopenharmony_ci rtlefuse-> 1148c2ecf20Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = 1158c2ecf20Sopenharmony_ci hwinfo[EEPROM_TXPOWERHT40_1S + rf_path * 3 + 1168c2ecf20Sopenharmony_ci i]; 1178c2ecf20Sopenharmony_ci } else { 1188c2ecf20Sopenharmony_ci rtlefuse-> 1198c2ecf20Sopenharmony_ci eeprom_chnlarea_txpwr_cck[rf_path][i] = 1208c2ecf20Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL; 1218c2ecf20Sopenharmony_ci rtlefuse-> 1228c2ecf20Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][i] = 1238c2ecf20Sopenharmony_ci EEPROM_DEFAULT_TXPOWERLEVEL; 1248c2ecf20Sopenharmony_ci } 1258c2ecf20Sopenharmony_ci } 1268c2ecf20Sopenharmony_ci } 1278c2ecf20Sopenharmony_ci for (i = 0; i < 3; i++) { 1288c2ecf20Sopenharmony_ci if (!autoload_fail) 1298c2ecf20Sopenharmony_ci tempval = hwinfo[EEPROM_TXPOWERHT40_2SDIFF + i]; 1308c2ecf20Sopenharmony_ci else 1318c2ecf20Sopenharmony_ci tempval = EEPROM_DEFAULT_HT40_2SDIFF; 1328c2ecf20Sopenharmony_ci rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_A][i] = 1338c2ecf20Sopenharmony_ci (tempval & 0xf); 1348c2ecf20Sopenharmony_ci rtlefuse->eprom_chnl_txpwr_ht40_2sdf[RF90_PATH_B][i] = 1358c2ecf20Sopenharmony_ci ((tempval & 0xf0) >> 4); 1368c2ecf20Sopenharmony_ci } 1378c2ecf20Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) 1388c2ecf20Sopenharmony_ci for (i = 0; i < 3; i++) 1398c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_EEPROM, 1408c2ecf20Sopenharmony_ci "RF(%d) EEPROM CCK Area(%d) = 0x%x\n", 1418c2ecf20Sopenharmony_ci rf_path, i, 1428c2ecf20Sopenharmony_ci rtlefuse-> 1438c2ecf20Sopenharmony_ci eeprom_chnlarea_txpwr_cck[rf_path][i]); 1448c2ecf20Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) 1458c2ecf20Sopenharmony_ci for (i = 0; i < 3; i++) 1468c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_EEPROM, 1478c2ecf20Sopenharmony_ci "RF(%d) EEPROM HT40 1S Area(%d) = 0x%x\n", 1488c2ecf20Sopenharmony_ci rf_path, i, 1498c2ecf20Sopenharmony_ci rtlefuse-> 1508c2ecf20Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][i]); 1518c2ecf20Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) 1528c2ecf20Sopenharmony_ci for (i = 0; i < 3; i++) 1538c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_EEPROM, 1548c2ecf20Sopenharmony_ci "RF(%d) EEPROM HT40 2S Diff Area(%d) = 0x%x\n", 1558c2ecf20Sopenharmony_ci rf_path, i, 1568c2ecf20Sopenharmony_ci rtlefuse-> 1578c2ecf20Sopenharmony_ci eprom_chnl_txpwr_ht40_2sdf[rf_path][i]); 1588c2ecf20Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 1598c2ecf20Sopenharmony_ci for (i = 0; i < 14; i++) { 1608c2ecf20Sopenharmony_ci index = rtl92c_get_chnl_group((u8)i); 1618c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_cck[rf_path][i] = 1628c2ecf20Sopenharmony_ci rtlefuse->eeprom_chnlarea_txpwr_cck[rf_path][index]; 1638c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[rf_path][i] = 1648c2ecf20Sopenharmony_ci rtlefuse-> 1658c2ecf20Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][index]; 1668c2ecf20Sopenharmony_ci if ((rtlefuse-> 1678c2ecf20Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path][index] - 1688c2ecf20Sopenharmony_ci rtlefuse-> 1698c2ecf20Sopenharmony_ci eprom_chnl_txpwr_ht40_2sdf[rf_path][index]) 1708c2ecf20Sopenharmony_ci > 0) { 1718c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 1728c2ecf20Sopenharmony_ci rtlefuse-> 1738c2ecf20Sopenharmony_ci eeprom_chnlarea_txpwr_ht40_1s[rf_path] 1748c2ecf20Sopenharmony_ci [index] - rtlefuse-> 1758c2ecf20Sopenharmony_ci eprom_chnl_txpwr_ht40_2sdf[rf_path] 1768c2ecf20Sopenharmony_ci [index]; 1778c2ecf20Sopenharmony_ci } else { 1788c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rf_path][i] = 0; 1798c2ecf20Sopenharmony_ci } 1808c2ecf20Sopenharmony_ci } 1818c2ecf20Sopenharmony_ci for (i = 0; i < 14; i++) { 1828c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 1838c2ecf20Sopenharmony_ci "RF(%d)-Ch(%d) [CCK / HT40_1S / HT40_2S] = [0x%x / 0x%x / 0x%x]\n", rf_path, i, 1848c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_cck[rf_path][i], 1858c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_ht40_1s[rf_path][i], 1868c2ecf20Sopenharmony_ci rtlefuse->txpwrlevel_ht40_2s[rf_path][i]); 1878c2ecf20Sopenharmony_ci } 1888c2ecf20Sopenharmony_ci } 1898c2ecf20Sopenharmony_ci for (i = 0; i < 3; i++) { 1908c2ecf20Sopenharmony_ci if (!autoload_fail) { 1918c2ecf20Sopenharmony_ci rtlefuse->eeprom_pwrlimit_ht40[i] = 1928c2ecf20Sopenharmony_ci hwinfo[EEPROM_TXPWR_GROUP + i]; 1938c2ecf20Sopenharmony_ci rtlefuse->eeprom_pwrlimit_ht20[i] = 1948c2ecf20Sopenharmony_ci hwinfo[EEPROM_TXPWR_GROUP + 3 + i]; 1958c2ecf20Sopenharmony_ci } else { 1968c2ecf20Sopenharmony_ci rtlefuse->eeprom_pwrlimit_ht40[i] = 0; 1978c2ecf20Sopenharmony_ci rtlefuse->eeprom_pwrlimit_ht20[i] = 0; 1988c2ecf20Sopenharmony_ci } 1998c2ecf20Sopenharmony_ci } 2008c2ecf20Sopenharmony_ci for (rf_path = 0; rf_path < 2; rf_path++) { 2018c2ecf20Sopenharmony_ci for (i = 0; i < 14; i++) { 2028c2ecf20Sopenharmony_ci index = rtl92c_get_chnl_group((u8)i); 2038c2ecf20Sopenharmony_ci if (rf_path == RF90_PATH_A) { 2048c2ecf20Sopenharmony_ci rtlefuse->pwrgroup_ht20[rf_path][i] = 2058c2ecf20Sopenharmony_ci (rtlefuse->eeprom_pwrlimit_ht20[index] 2068c2ecf20Sopenharmony_ci & 0xf); 2078c2ecf20Sopenharmony_ci rtlefuse->pwrgroup_ht40[rf_path][i] = 2088c2ecf20Sopenharmony_ci (rtlefuse->eeprom_pwrlimit_ht40[index] 2098c2ecf20Sopenharmony_ci & 0xf); 2108c2ecf20Sopenharmony_ci } else if (rf_path == RF90_PATH_B) { 2118c2ecf20Sopenharmony_ci rtlefuse->pwrgroup_ht20[rf_path][i] = 2128c2ecf20Sopenharmony_ci ((rtlefuse->eeprom_pwrlimit_ht20[index] 2138c2ecf20Sopenharmony_ci & 0xf0) >> 4); 2148c2ecf20Sopenharmony_ci rtlefuse->pwrgroup_ht40[rf_path][i] = 2158c2ecf20Sopenharmony_ci ((rtlefuse->eeprom_pwrlimit_ht40[index] 2168c2ecf20Sopenharmony_ci & 0xf0) >> 4); 2178c2ecf20Sopenharmony_ci } 2188c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 2198c2ecf20Sopenharmony_ci "RF-%d pwrgroup_ht20[%d] = 0x%x\n", 2208c2ecf20Sopenharmony_ci rf_path, i, 2218c2ecf20Sopenharmony_ci rtlefuse->pwrgroup_ht20[rf_path][i]); 2228c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 2238c2ecf20Sopenharmony_ci "RF-%d pwrgroup_ht40[%d] = 0x%x\n", 2248c2ecf20Sopenharmony_ci rf_path, i, 2258c2ecf20Sopenharmony_ci rtlefuse->pwrgroup_ht40[rf_path][i]); 2268c2ecf20Sopenharmony_ci } 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci for (i = 0; i < 14; i++) { 2298c2ecf20Sopenharmony_ci index = rtl92c_get_chnl_group((u8)i); 2308c2ecf20Sopenharmony_ci if (!autoload_fail) 2318c2ecf20Sopenharmony_ci tempval = hwinfo[EEPROM_TXPOWERHT20DIFF + index]; 2328c2ecf20Sopenharmony_ci else 2338c2ecf20Sopenharmony_ci tempval = EEPROM_DEFAULT_HT20_DIFF; 2348c2ecf20Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] = (tempval & 0xF); 2358c2ecf20Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] = 2368c2ecf20Sopenharmony_ci ((tempval >> 4) & 0xF); 2378c2ecf20Sopenharmony_ci if (rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] & BIT(3)) 2388c2ecf20Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_A][i] |= 0xF0; 2398c2ecf20Sopenharmony_ci if (rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] & BIT(3)) 2408c2ecf20Sopenharmony_ci rtlefuse->txpwr_ht20diff[RF90_PATH_B][i] |= 0xF0; 2418c2ecf20Sopenharmony_ci index = rtl92c_get_chnl_group((u8)i); 2428c2ecf20Sopenharmony_ci if (!autoload_fail) 2438c2ecf20Sopenharmony_ci tempval = hwinfo[EEPROM_TXPOWER_OFDMDIFF + index]; 2448c2ecf20Sopenharmony_ci else 2458c2ecf20Sopenharmony_ci tempval = EEPROM_DEFAULT_LEGACYHTTXPOWERDIFF; 2468c2ecf20Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i] = (tempval & 0xF); 2478c2ecf20Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i] = 2488c2ecf20Sopenharmony_ci ((tempval >> 4) & 0xF); 2498c2ecf20Sopenharmony_ci } 2508c2ecf20Sopenharmony_ci rtlefuse->legacy_ht_txpowerdiff = 2518c2ecf20Sopenharmony_ci rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][7]; 2528c2ecf20Sopenharmony_ci for (i = 0; i < 14; i++) 2538c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 2548c2ecf20Sopenharmony_ci "RF-A Ht20 to HT40 Diff[%d] = 0x%x\n", 2558c2ecf20Sopenharmony_ci i, rtlefuse->txpwr_ht20diff[RF90_PATH_A][i]); 2568c2ecf20Sopenharmony_ci for (i = 0; i < 14; i++) 2578c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 2588c2ecf20Sopenharmony_ci "RF-A Legacy to Ht40 Diff[%d] = 0x%x\n", 2598c2ecf20Sopenharmony_ci i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_A][i]); 2608c2ecf20Sopenharmony_ci for (i = 0; i < 14; i++) 2618c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 2628c2ecf20Sopenharmony_ci "RF-B Ht20 to HT40 Diff[%d] = 0x%x\n", 2638c2ecf20Sopenharmony_ci i, rtlefuse->txpwr_ht20diff[RF90_PATH_B][i]); 2648c2ecf20Sopenharmony_ci for (i = 0; i < 14; i++) 2658c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 2668c2ecf20Sopenharmony_ci "RF-B Legacy to HT40 Diff[%d] = 0x%x\n", 2678c2ecf20Sopenharmony_ci i, rtlefuse->txpwr_legacyhtdiff[RF90_PATH_B][i]); 2688c2ecf20Sopenharmony_ci if (!autoload_fail) 2698c2ecf20Sopenharmony_ci rtlefuse->eeprom_regulatory = (hwinfo[RF_OPTION1] & 0x7); 2708c2ecf20Sopenharmony_ci else 2718c2ecf20Sopenharmony_ci rtlefuse->eeprom_regulatory = 0; 2728c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 2738c2ecf20Sopenharmony_ci "eeprom_regulatory = 0x%x\n", rtlefuse->eeprom_regulatory); 2748c2ecf20Sopenharmony_ci if (!autoload_fail) { 2758c2ecf20Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_A] = hwinfo[EEPROM_TSSI_A]; 2768c2ecf20Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_B] = hwinfo[EEPROM_TSSI_B]; 2778c2ecf20Sopenharmony_ci } else { 2788c2ecf20Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_A] = EEPROM_DEFAULT_TSSI; 2798c2ecf20Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_B] = EEPROM_DEFAULT_TSSI; 2808c2ecf20Sopenharmony_ci } 2818c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 2828c2ecf20Sopenharmony_ci "TSSI_A = 0x%x, TSSI_B = 0x%x\n", 2838c2ecf20Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_A], 2848c2ecf20Sopenharmony_ci rtlefuse->eeprom_tssi[RF90_PATH_B]); 2858c2ecf20Sopenharmony_ci if (!autoload_fail) 2868c2ecf20Sopenharmony_ci tempval = hwinfo[EEPROM_THERMAL_METER]; 2878c2ecf20Sopenharmony_ci else 2888c2ecf20Sopenharmony_ci tempval = EEPROM_DEFAULT_THERMALMETER; 2898c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter = (tempval & 0x1f); 2908c2ecf20Sopenharmony_ci if (rtlefuse->eeprom_thermalmeter < 0x06 || 2918c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter > 0x1c) 2928c2ecf20Sopenharmony_ci rtlefuse->eeprom_thermalmeter = 0x12; 2938c2ecf20Sopenharmony_ci if (rtlefuse->eeprom_thermalmeter == 0x1f || autoload_fail) 2948c2ecf20Sopenharmony_ci rtlefuse->apk_thermalmeterignore = true; 2958c2ecf20Sopenharmony_ci rtlefuse->thermalmeter[0] = rtlefuse->eeprom_thermalmeter; 2968c2ecf20Sopenharmony_ci RTPRINT(rtlpriv, FINIT, INIT_TXPOWER, 2978c2ecf20Sopenharmony_ci "thermalmeter = 0x%x\n", rtlefuse->eeprom_thermalmeter); 2988c2ecf20Sopenharmony_ci} 2998c2ecf20Sopenharmony_ci 3008c2ecf20Sopenharmony_cistatic void _rtl92cu_read_board_type(struct ieee80211_hw *hw, u8 *contents) 3018c2ecf20Sopenharmony_ci{ 3028c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 3038c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3048c2ecf20Sopenharmony_ci u8 boardtype; 3058c2ecf20Sopenharmony_ci 3068c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 3078c2ecf20Sopenharmony_ci boardtype = ((contents[EEPROM_RF_OPT1]) & 3088c2ecf20Sopenharmony_ci BOARD_TYPE_NORMAL_MASK) >> 5; /*bit[7:5]*/ 3098c2ecf20Sopenharmony_ci } else { 3108c2ecf20Sopenharmony_ci boardtype = contents[EEPROM_RF_OPT4]; 3118c2ecf20Sopenharmony_ci boardtype &= BOARD_TYPE_TEST_MASK; 3128c2ecf20Sopenharmony_ci } 3138c2ecf20Sopenharmony_ci rtlefuse->board_type = boardtype; 3148c2ecf20Sopenharmony_ci if (IS_HIGHT_PA(rtlefuse->board_type)) 3158c2ecf20Sopenharmony_ci rtlefuse->external_pa = 1; 3168c2ecf20Sopenharmony_ci pr_info("Board Type %x\n", rtlefuse->board_type); 3178c2ecf20Sopenharmony_ci} 3188c2ecf20Sopenharmony_ci 3198c2ecf20Sopenharmony_cistatic void _rtl92cu_read_adapter_info(struct ieee80211_hw *hw) 3208c2ecf20Sopenharmony_ci{ 3218c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3228c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 3238c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3248c2ecf20Sopenharmony_ci int params[] = {RTL8190_EEPROM_ID, EEPROM_VID, EEPROM_DID, 3258c2ecf20Sopenharmony_ci EEPROM_SVID, EEPROM_SMID, EEPROM_MAC_ADDR, 3268c2ecf20Sopenharmony_ci EEPROM_CHANNELPLAN, EEPROM_VERSION, EEPROM_CUSTOMER_ID, 3278c2ecf20Sopenharmony_ci 0}; 3288c2ecf20Sopenharmony_ci u8 *hwinfo; 3298c2ecf20Sopenharmony_ci 3308c2ecf20Sopenharmony_ci hwinfo = kzalloc(HWSET_MAX_SIZE, GFP_KERNEL); 3318c2ecf20Sopenharmony_ci if (!hwinfo) 3328c2ecf20Sopenharmony_ci return; 3338c2ecf20Sopenharmony_ci 3348c2ecf20Sopenharmony_ci if (rtl_get_hwinfo(hw, rtlpriv, HWSET_MAX_SIZE, hwinfo, params)) 3358c2ecf20Sopenharmony_ci goto exit; 3368c2ecf20Sopenharmony_ci 3378c2ecf20Sopenharmony_ci _rtl92cu_read_txpower_info_from_hwpg(hw, 3388c2ecf20Sopenharmony_ci rtlefuse->autoload_failflag, hwinfo); 3398c2ecf20Sopenharmony_ci _rtl92cu_read_board_type(hw, hwinfo); 3408c2ecf20Sopenharmony_ci 3418c2ecf20Sopenharmony_ci rtlefuse->txpwr_fromeprom = true; 3428c2ecf20Sopenharmony_ci if (rtlhal->oem_id == RT_CID_DEFAULT) { 3438c2ecf20Sopenharmony_ci switch (rtlefuse->eeprom_oemid) { 3448c2ecf20Sopenharmony_ci case EEPROM_CID_DEFAULT: 3458c2ecf20Sopenharmony_ci if (rtlefuse->eeprom_did == 0x8176) { 3468c2ecf20Sopenharmony_ci if ((rtlefuse->eeprom_svid == 0x103C && 3478c2ecf20Sopenharmony_ci rtlefuse->eeprom_smid == 0x1629)) 3488c2ecf20Sopenharmony_ci rtlhal->oem_id = RT_CID_819X_HP; 3498c2ecf20Sopenharmony_ci else 3508c2ecf20Sopenharmony_ci rtlhal->oem_id = RT_CID_DEFAULT; 3518c2ecf20Sopenharmony_ci } else { 3528c2ecf20Sopenharmony_ci rtlhal->oem_id = RT_CID_DEFAULT; 3538c2ecf20Sopenharmony_ci } 3548c2ecf20Sopenharmony_ci break; 3558c2ecf20Sopenharmony_ci case EEPROM_CID_TOSHIBA: 3568c2ecf20Sopenharmony_ci rtlhal->oem_id = RT_CID_TOSHIBA; 3578c2ecf20Sopenharmony_ci break; 3588c2ecf20Sopenharmony_ci case EEPROM_CID_QMI: 3598c2ecf20Sopenharmony_ci rtlhal->oem_id = RT_CID_819X_QMI; 3608c2ecf20Sopenharmony_ci break; 3618c2ecf20Sopenharmony_ci case EEPROM_CID_WHQL: 3628c2ecf20Sopenharmony_ci default: 3638c2ecf20Sopenharmony_ci rtlhal->oem_id = RT_CID_DEFAULT; 3648c2ecf20Sopenharmony_ci break; 3658c2ecf20Sopenharmony_ci } 3668c2ecf20Sopenharmony_ci } 3678c2ecf20Sopenharmony_ciexit: 3688c2ecf20Sopenharmony_ci kfree(hwinfo); 3698c2ecf20Sopenharmony_ci} 3708c2ecf20Sopenharmony_ci 3718c2ecf20Sopenharmony_cistatic void _rtl92cu_hal_customized_behavior(struct ieee80211_hw *hw) 3728c2ecf20Sopenharmony_ci{ 3738c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3748c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3758c2ecf20Sopenharmony_ci 3768c2ecf20Sopenharmony_ci switch (rtlhal->oem_id) { 3778c2ecf20Sopenharmony_ci case RT_CID_819X_HP: 3788c2ecf20Sopenharmony_ci rtlpriv->ledctl.led_opendrain = true; 3798c2ecf20Sopenharmony_ci break; 3808c2ecf20Sopenharmony_ci case RT_CID_819X_LENOVO: 3818c2ecf20Sopenharmony_ci case RT_CID_DEFAULT: 3828c2ecf20Sopenharmony_ci case RT_CID_TOSHIBA: 3838c2ecf20Sopenharmony_ci case RT_CID_CCX: 3848c2ecf20Sopenharmony_ci case RT_CID_819X_ACER: 3858c2ecf20Sopenharmony_ci case RT_CID_WHQL: 3868c2ecf20Sopenharmony_ci default: 3878c2ecf20Sopenharmony_ci break; 3888c2ecf20Sopenharmony_ci } 3898c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "RT Customized ID: 0x%02X\n", 3908c2ecf20Sopenharmony_ci rtlhal->oem_id); 3918c2ecf20Sopenharmony_ci} 3928c2ecf20Sopenharmony_ci 3938c2ecf20Sopenharmony_civoid rtl92cu_read_eeprom_info(struct ieee80211_hw *hw) 3948c2ecf20Sopenharmony_ci{ 3958c2ecf20Sopenharmony_ci 3968c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3978c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 3988c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3998c2ecf20Sopenharmony_ci u8 tmp_u1b; 4008c2ecf20Sopenharmony_ci 4018c2ecf20Sopenharmony_ci if (!IS_NORMAL_CHIP(rtlhal->version)) 4028c2ecf20Sopenharmony_ci return; 4038c2ecf20Sopenharmony_ci tmp_u1b = rtl_read_byte(rtlpriv, REG_9346CR); 4048c2ecf20Sopenharmony_ci rtlefuse->epromtype = (tmp_u1b & BOOT_FROM_EEPROM) ? 4058c2ecf20Sopenharmony_ci EEPROM_93C46 : EEPROM_BOOT_EFUSE; 4068c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, "Boot from %s\n", 4078c2ecf20Sopenharmony_ci tmp_u1b & BOOT_FROM_EEPROM ? "EERROM" : "EFUSE"); 4088c2ecf20Sopenharmony_ci rtlefuse->autoload_failflag = (tmp_u1b & EEPROM_EN) ? false : true; 4098c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, "Autoload %s\n", 4108c2ecf20Sopenharmony_ci tmp_u1b & EEPROM_EN ? "OK!!" : "ERR!!"); 4118c2ecf20Sopenharmony_ci _rtl92cu_read_adapter_info(hw); 4128c2ecf20Sopenharmony_ci _rtl92cu_hal_customized_behavior(hw); 4138c2ecf20Sopenharmony_ci return; 4148c2ecf20Sopenharmony_ci} 4158c2ecf20Sopenharmony_ci 4168c2ecf20Sopenharmony_cistatic int _rtl92cu_init_power_on(struct ieee80211_hw *hw) 4178c2ecf20Sopenharmony_ci{ 4188c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4198c2ecf20Sopenharmony_ci int status = 0; 4208c2ecf20Sopenharmony_ci u16 value16; 4218c2ecf20Sopenharmony_ci u8 value8; 4228c2ecf20Sopenharmony_ci /* polling autoload done. */ 4238c2ecf20Sopenharmony_ci u32 pollingcount = 0; 4248c2ecf20Sopenharmony_ci 4258c2ecf20Sopenharmony_ci do { 4268c2ecf20Sopenharmony_ci if (rtl_read_byte(rtlpriv, REG_APS_FSMCO) & PFM_ALDN) { 4278c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, 4288c2ecf20Sopenharmony_ci "Autoload Done!\n"); 4298c2ecf20Sopenharmony_ci break; 4308c2ecf20Sopenharmony_ci } 4318c2ecf20Sopenharmony_ci if (pollingcount++ > 100) { 4328c2ecf20Sopenharmony_ci pr_err("Failed to polling REG_APS_FSMCO[PFM_ALDN] done!\n"); 4338c2ecf20Sopenharmony_ci return -ENODEV; 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci } while (true); 4368c2ecf20Sopenharmony_ci /* 0. RSV_CTRL 0x1C[7:0] = 0 unlock ISO/CLK/Power control register */ 4378c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); 4388c2ecf20Sopenharmony_ci /* Power on when re-enter from IPS/Radio off/card disable */ 4398c2ecf20Sopenharmony_ci /* enable SPS into PWM mode */ 4408c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); 4418c2ecf20Sopenharmony_ci udelay(100); 4428c2ecf20Sopenharmony_ci value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); 4438c2ecf20Sopenharmony_ci if (0 == (value8 & LDV12_EN)) { 4448c2ecf20Sopenharmony_ci value8 |= LDV12_EN; 4458c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); 4468c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_DMESG, 4478c2ecf20Sopenharmony_ci " power-on :REG_LDOV12D_CTRL Reg0x21:0x%02x\n", 4488c2ecf20Sopenharmony_ci value8); 4498c2ecf20Sopenharmony_ci udelay(100); 4508c2ecf20Sopenharmony_ci value8 = rtl_read_byte(rtlpriv, REG_SYS_ISO_CTRL); 4518c2ecf20Sopenharmony_ci value8 &= ~ISO_MD2PP; 4528c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, value8); 4538c2ecf20Sopenharmony_ci } 4548c2ecf20Sopenharmony_ci /* auto enable WLAN */ 4558c2ecf20Sopenharmony_ci pollingcount = 0; 4568c2ecf20Sopenharmony_ci value16 = rtl_read_word(rtlpriv, REG_APS_FSMCO); 4578c2ecf20Sopenharmony_ci value16 |= APFM_ONMAC; 4588c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_APS_FSMCO, value16); 4598c2ecf20Sopenharmony_ci do { 4608c2ecf20Sopenharmony_ci if (!(rtl_read_word(rtlpriv, REG_APS_FSMCO) & APFM_ONMAC)) { 4618c2ecf20Sopenharmony_ci pr_info("MAC auto ON okay!\n"); 4628c2ecf20Sopenharmony_ci break; 4638c2ecf20Sopenharmony_ci } 4648c2ecf20Sopenharmony_ci if (pollingcount++ > 1000) { 4658c2ecf20Sopenharmony_ci pr_err("Failed to polling REG_APS_FSMCO[APFM_ONMAC] done!\n"); 4668c2ecf20Sopenharmony_ci return -ENODEV; 4678c2ecf20Sopenharmony_ci } 4688c2ecf20Sopenharmony_ci } while (true); 4698c2ecf20Sopenharmony_ci /* Enable Radio ,GPIO ,and LED function */ 4708c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x0812); 4718c2ecf20Sopenharmony_ci /* release RF digital isolation */ 4728c2ecf20Sopenharmony_ci value16 = rtl_read_word(rtlpriv, REG_SYS_ISO_CTRL); 4738c2ecf20Sopenharmony_ci value16 &= ~ISO_DIOR; 4748c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_ISO_CTRL, value16); 4758c2ecf20Sopenharmony_ci /* Reconsider when to do this operation after asking HWSD. */ 4768c2ecf20Sopenharmony_ci pollingcount = 0; 4778c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, (rtl_read_byte(rtlpriv, 4788c2ecf20Sopenharmony_ci REG_APSD_CTRL) & ~BIT(6))); 4798c2ecf20Sopenharmony_ci do { 4808c2ecf20Sopenharmony_ci pollingcount++; 4818c2ecf20Sopenharmony_ci } while ((pollingcount < 200) && 4828c2ecf20Sopenharmony_ci (rtl_read_byte(rtlpriv, REG_APSD_CTRL) & BIT(7))); 4838c2ecf20Sopenharmony_ci /* Enable MAC DMA/WMAC/SCHEDULE/SEC block */ 4848c2ecf20Sopenharmony_ci value16 = rtl_read_word(rtlpriv, REG_CR); 4858c2ecf20Sopenharmony_ci value16 |= (HCI_TXDMA_EN | HCI_RXDMA_EN | TXDMA_EN | RXDMA_EN | 4868c2ecf20Sopenharmony_ci PROTOCOL_EN | SCHEDULE_EN | MACTXEN | MACRXEN | ENSEC); 4878c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_CR, value16); 4888c2ecf20Sopenharmony_ci return status; 4898c2ecf20Sopenharmony_ci} 4908c2ecf20Sopenharmony_ci 4918c2ecf20Sopenharmony_cistatic void _rtl92cu_init_queue_reserved_page(struct ieee80211_hw *hw, 4928c2ecf20Sopenharmony_ci bool wmm_enable, 4938c2ecf20Sopenharmony_ci u8 out_ep_num, 4948c2ecf20Sopenharmony_ci u8 queue_sel) 4958c2ecf20Sopenharmony_ci{ 4968c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4978c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 4988c2ecf20Sopenharmony_ci bool ischipn = IS_NORMAL_CHIP(rtlhal->version); 4998c2ecf20Sopenharmony_ci u32 outepnum = (u32)out_ep_num; 5008c2ecf20Sopenharmony_ci u32 numhq = 0; 5018c2ecf20Sopenharmony_ci u32 numlq = 0; 5028c2ecf20Sopenharmony_ci u32 numnq = 0; 5038c2ecf20Sopenharmony_ci u32 numpubq; 5048c2ecf20Sopenharmony_ci u32 value32; 5058c2ecf20Sopenharmony_ci u8 value8; 5068c2ecf20Sopenharmony_ci u32 txqpagenum, txqpageunit, txqremaininpage; 5078c2ecf20Sopenharmony_ci 5088c2ecf20Sopenharmony_ci if (!wmm_enable) { 5098c2ecf20Sopenharmony_ci numpubq = (ischipn) ? CHIP_B_PAGE_NUM_PUBQ : 5108c2ecf20Sopenharmony_ci CHIP_A_PAGE_NUM_PUBQ; 5118c2ecf20Sopenharmony_ci txqpagenum = TX_TOTAL_PAGE_NUMBER - numpubq; 5128c2ecf20Sopenharmony_ci 5138c2ecf20Sopenharmony_ci txqpageunit = txqpagenum / outepnum; 5148c2ecf20Sopenharmony_ci txqremaininpage = txqpagenum % outepnum; 5158c2ecf20Sopenharmony_ci if (queue_sel & TX_SELE_HQ) 5168c2ecf20Sopenharmony_ci numhq = txqpageunit; 5178c2ecf20Sopenharmony_ci if (queue_sel & TX_SELE_LQ) 5188c2ecf20Sopenharmony_ci numlq = txqpageunit; 5198c2ecf20Sopenharmony_ci /* HIGH priority queue always present in the configuration of 5208c2ecf20Sopenharmony_ci * 2 out-ep. Remainder pages have assigned to High queue */ 5218c2ecf20Sopenharmony_ci if (outepnum > 1 && txqremaininpage) 5228c2ecf20Sopenharmony_ci numhq += txqremaininpage; 5238c2ecf20Sopenharmony_ci /* NOTE: This step done before writting REG_RQPN. */ 5248c2ecf20Sopenharmony_ci if (ischipn) { 5258c2ecf20Sopenharmony_ci if (queue_sel & TX_SELE_NQ) 5268c2ecf20Sopenharmony_ci numnq = txqpageunit; 5278c2ecf20Sopenharmony_ci value8 = (u8)_NPQ(numnq); 5288c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); 5298c2ecf20Sopenharmony_ci } 5308c2ecf20Sopenharmony_ci } else { 5318c2ecf20Sopenharmony_ci /* for WMM ,number of out-ep must more than or equal to 2! */ 5328c2ecf20Sopenharmony_ci numpubq = ischipn ? WMM_CHIP_B_PAGE_NUM_PUBQ : 5338c2ecf20Sopenharmony_ci WMM_CHIP_A_PAGE_NUM_PUBQ; 5348c2ecf20Sopenharmony_ci if (queue_sel & TX_SELE_HQ) { 5358c2ecf20Sopenharmony_ci numhq = ischipn ? WMM_CHIP_B_PAGE_NUM_HPQ : 5368c2ecf20Sopenharmony_ci WMM_CHIP_A_PAGE_NUM_HPQ; 5378c2ecf20Sopenharmony_ci } 5388c2ecf20Sopenharmony_ci if (queue_sel & TX_SELE_LQ) { 5398c2ecf20Sopenharmony_ci numlq = ischipn ? WMM_CHIP_B_PAGE_NUM_LPQ : 5408c2ecf20Sopenharmony_ci WMM_CHIP_A_PAGE_NUM_LPQ; 5418c2ecf20Sopenharmony_ci } 5428c2ecf20Sopenharmony_ci /* NOTE: This step done before writting REG_RQPN. */ 5438c2ecf20Sopenharmony_ci if (ischipn) { 5448c2ecf20Sopenharmony_ci if (queue_sel & TX_SELE_NQ) 5458c2ecf20Sopenharmony_ci numnq = WMM_CHIP_B_PAGE_NUM_NPQ; 5468c2ecf20Sopenharmony_ci value8 = (u8)_NPQ(numnq); 5478c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RQPN_NPQ, value8); 5488c2ecf20Sopenharmony_ci } 5498c2ecf20Sopenharmony_ci } 5508c2ecf20Sopenharmony_ci /* TX DMA */ 5518c2ecf20Sopenharmony_ci value32 = _HPQ(numhq) | _LPQ(numlq) | _PUBQ(numpubq) | LD_RQPN; 5528c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RQPN, value32); 5538c2ecf20Sopenharmony_ci} 5548c2ecf20Sopenharmony_ci 5558c2ecf20Sopenharmony_cistatic void _rtl92c_init_trx_buffer(struct ieee80211_hw *hw, bool wmm_enable) 5568c2ecf20Sopenharmony_ci{ 5578c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5588c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 5598c2ecf20Sopenharmony_ci u8 txpktbuf_bndy; 5608c2ecf20Sopenharmony_ci u8 value8; 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci if (!wmm_enable) 5638c2ecf20Sopenharmony_ci txpktbuf_bndy = TX_PAGE_BOUNDARY; 5648c2ecf20Sopenharmony_ci else /* for WMM */ 5658c2ecf20Sopenharmony_ci txpktbuf_bndy = (IS_NORMAL_CHIP(rtlhal->version)) 5668c2ecf20Sopenharmony_ci ? WMM_CHIP_B_TX_PAGE_BOUNDARY 5678c2ecf20Sopenharmony_ci : WMM_CHIP_A_TX_PAGE_BOUNDARY; 5688c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPKTBUF_BCNQ_BDNY, txpktbuf_bndy); 5698c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPKTBUF_MGQ_BDNY, txpktbuf_bndy); 5708c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPKTBUF_WMAC_LBK_BF_HD, txpktbuf_bndy); 5718c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TRXFF_BNDY, txpktbuf_bndy); 5728c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TDECTRL+1, txpktbuf_bndy); 5738c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, (REG_TRXFF_BNDY + 2), 0x27FF); 5748c2ecf20Sopenharmony_ci value8 = _PSRX(RX_PAGE_SIZE_REG_VALUE) | _PSTX(PBP_128); 5758c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_PBP, value8); 5768c2ecf20Sopenharmony_ci} 5778c2ecf20Sopenharmony_ci 5788c2ecf20Sopenharmony_cistatic void _rtl92c_init_chipn_reg_priority(struct ieee80211_hw *hw, u16 beq, 5798c2ecf20Sopenharmony_ci u16 bkq, u16 viq, u16 voq, 5808c2ecf20Sopenharmony_ci u16 mgtq, u16 hiq) 5818c2ecf20Sopenharmony_ci{ 5828c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5838c2ecf20Sopenharmony_ci u16 value16 = (rtl_read_word(rtlpriv, REG_TRXDMA_CTRL) & 0x7); 5848c2ecf20Sopenharmony_ci 5858c2ecf20Sopenharmony_ci value16 |= _TXDMA_BEQ_MAP(beq) | _TXDMA_BKQ_MAP(bkq) | 5868c2ecf20Sopenharmony_ci _TXDMA_VIQ_MAP(viq) | _TXDMA_VOQ_MAP(voq) | 5878c2ecf20Sopenharmony_ci _TXDMA_MGQ_MAP(mgtq) | _TXDMA_HIQ_MAP(hiq); 5888c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_TRXDMA_CTRL, value16); 5898c2ecf20Sopenharmony_ci} 5908c2ecf20Sopenharmony_ci 5918c2ecf20Sopenharmony_cistatic void _rtl92cu_init_chipn_one_out_ep_priority(struct ieee80211_hw *hw, 5928c2ecf20Sopenharmony_ci bool wmm_enable, 5938c2ecf20Sopenharmony_ci u8 queue_sel) 5948c2ecf20Sopenharmony_ci{ 5958c2ecf20Sopenharmony_ci u16 value; 5968c2ecf20Sopenharmony_ci 5978c2ecf20Sopenharmony_ci switch (queue_sel) { 5988c2ecf20Sopenharmony_ci case TX_SELE_HQ: 5998c2ecf20Sopenharmony_ci value = QUEUE_HIGH; 6008c2ecf20Sopenharmony_ci break; 6018c2ecf20Sopenharmony_ci case TX_SELE_LQ: 6028c2ecf20Sopenharmony_ci value = QUEUE_LOW; 6038c2ecf20Sopenharmony_ci break; 6048c2ecf20Sopenharmony_ci case TX_SELE_NQ: 6058c2ecf20Sopenharmony_ci value = QUEUE_NORMAL; 6068c2ecf20Sopenharmony_ci break; 6078c2ecf20Sopenharmony_ci default: 6088c2ecf20Sopenharmony_ci WARN_ON(1); /* Shall not reach here! */ 6098c2ecf20Sopenharmony_ci return; 6108c2ecf20Sopenharmony_ci } 6118c2ecf20Sopenharmony_ci _rtl92c_init_chipn_reg_priority(hw, value, value, value, value, 6128c2ecf20Sopenharmony_ci value, value); 6138c2ecf20Sopenharmony_ci pr_info("Tx queue select: 0x%02x\n", queue_sel); 6148c2ecf20Sopenharmony_ci} 6158c2ecf20Sopenharmony_ci 6168c2ecf20Sopenharmony_cistatic void _rtl92cu_init_chipn_two_out_ep_priority(struct ieee80211_hw *hw, 6178c2ecf20Sopenharmony_ci bool wmm_enable, 6188c2ecf20Sopenharmony_ci u8 queue_sel) 6198c2ecf20Sopenharmony_ci{ 6208c2ecf20Sopenharmony_ci u16 beq, bkq, viq, voq, mgtq, hiq; 6218c2ecf20Sopenharmony_ci u16 valuehi; 6228c2ecf20Sopenharmony_ci u16 valuelow; 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci switch (queue_sel) { 6258c2ecf20Sopenharmony_ci case (TX_SELE_HQ | TX_SELE_LQ): 6268c2ecf20Sopenharmony_ci valuehi = QUEUE_HIGH; 6278c2ecf20Sopenharmony_ci valuelow = QUEUE_LOW; 6288c2ecf20Sopenharmony_ci break; 6298c2ecf20Sopenharmony_ci case (TX_SELE_NQ | TX_SELE_LQ): 6308c2ecf20Sopenharmony_ci valuehi = QUEUE_NORMAL; 6318c2ecf20Sopenharmony_ci valuelow = QUEUE_LOW; 6328c2ecf20Sopenharmony_ci break; 6338c2ecf20Sopenharmony_ci case (TX_SELE_HQ | TX_SELE_NQ): 6348c2ecf20Sopenharmony_ci valuehi = QUEUE_HIGH; 6358c2ecf20Sopenharmony_ci valuelow = QUEUE_NORMAL; 6368c2ecf20Sopenharmony_ci break; 6378c2ecf20Sopenharmony_ci default: 6388c2ecf20Sopenharmony_ci WARN_ON(1); 6398c2ecf20Sopenharmony_ci break; 6408c2ecf20Sopenharmony_ci } 6418c2ecf20Sopenharmony_ci if (!wmm_enable) { 6428c2ecf20Sopenharmony_ci beq = valuelow; 6438c2ecf20Sopenharmony_ci bkq = valuelow; 6448c2ecf20Sopenharmony_ci viq = valuehi; 6458c2ecf20Sopenharmony_ci voq = valuehi; 6468c2ecf20Sopenharmony_ci mgtq = valuehi; 6478c2ecf20Sopenharmony_ci hiq = valuehi; 6488c2ecf20Sopenharmony_ci } else {/* for WMM ,CONFIG_OUT_EP_WIFI_MODE */ 6498c2ecf20Sopenharmony_ci beq = valuehi; 6508c2ecf20Sopenharmony_ci bkq = valuelow; 6518c2ecf20Sopenharmony_ci viq = valuelow; 6528c2ecf20Sopenharmony_ci voq = valuehi; 6538c2ecf20Sopenharmony_ci mgtq = valuehi; 6548c2ecf20Sopenharmony_ci hiq = valuehi; 6558c2ecf20Sopenharmony_ci } 6568c2ecf20Sopenharmony_ci _rtl92c_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq); 6578c2ecf20Sopenharmony_ci pr_info("Tx queue select: 0x%02x\n", queue_sel); 6588c2ecf20Sopenharmony_ci} 6598c2ecf20Sopenharmony_ci 6608c2ecf20Sopenharmony_cistatic void _rtl92cu_init_chipn_three_out_ep_priority(struct ieee80211_hw *hw, 6618c2ecf20Sopenharmony_ci bool wmm_enable, 6628c2ecf20Sopenharmony_ci u8 queue_sel) 6638c2ecf20Sopenharmony_ci{ 6648c2ecf20Sopenharmony_ci u16 beq, bkq, viq, voq, mgtq, hiq; 6658c2ecf20Sopenharmony_ci 6668c2ecf20Sopenharmony_ci if (!wmm_enable) { /* typical setting */ 6678c2ecf20Sopenharmony_ci beq = QUEUE_LOW; 6688c2ecf20Sopenharmony_ci bkq = QUEUE_LOW; 6698c2ecf20Sopenharmony_ci viq = QUEUE_NORMAL; 6708c2ecf20Sopenharmony_ci voq = QUEUE_HIGH; 6718c2ecf20Sopenharmony_ci mgtq = QUEUE_HIGH; 6728c2ecf20Sopenharmony_ci hiq = QUEUE_HIGH; 6738c2ecf20Sopenharmony_ci } else { /* for WMM */ 6748c2ecf20Sopenharmony_ci beq = QUEUE_LOW; 6758c2ecf20Sopenharmony_ci bkq = QUEUE_NORMAL; 6768c2ecf20Sopenharmony_ci viq = QUEUE_NORMAL; 6778c2ecf20Sopenharmony_ci voq = QUEUE_HIGH; 6788c2ecf20Sopenharmony_ci mgtq = QUEUE_HIGH; 6798c2ecf20Sopenharmony_ci hiq = QUEUE_HIGH; 6808c2ecf20Sopenharmony_ci } 6818c2ecf20Sopenharmony_ci _rtl92c_init_chipn_reg_priority(hw, beq, bkq, viq, voq, mgtq, hiq); 6828c2ecf20Sopenharmony_ci pr_info("Tx queue select :0x%02x..\n", queue_sel); 6838c2ecf20Sopenharmony_ci} 6848c2ecf20Sopenharmony_ci 6858c2ecf20Sopenharmony_cistatic void _rtl92cu_init_chipn_queue_priority(struct ieee80211_hw *hw, 6868c2ecf20Sopenharmony_ci bool wmm_enable, 6878c2ecf20Sopenharmony_ci u8 out_ep_num, 6888c2ecf20Sopenharmony_ci u8 queue_sel) 6898c2ecf20Sopenharmony_ci{ 6908c2ecf20Sopenharmony_ci switch (out_ep_num) { 6918c2ecf20Sopenharmony_ci case 1: 6928c2ecf20Sopenharmony_ci _rtl92cu_init_chipn_one_out_ep_priority(hw, wmm_enable, 6938c2ecf20Sopenharmony_ci queue_sel); 6948c2ecf20Sopenharmony_ci break; 6958c2ecf20Sopenharmony_ci case 2: 6968c2ecf20Sopenharmony_ci _rtl92cu_init_chipn_two_out_ep_priority(hw, wmm_enable, 6978c2ecf20Sopenharmony_ci queue_sel); 6988c2ecf20Sopenharmony_ci break; 6998c2ecf20Sopenharmony_ci case 3: 7008c2ecf20Sopenharmony_ci _rtl92cu_init_chipn_three_out_ep_priority(hw, wmm_enable, 7018c2ecf20Sopenharmony_ci queue_sel); 7028c2ecf20Sopenharmony_ci break; 7038c2ecf20Sopenharmony_ci default: 7048c2ecf20Sopenharmony_ci WARN_ON(1); /* Shall not reach here! */ 7058c2ecf20Sopenharmony_ci break; 7068c2ecf20Sopenharmony_ci } 7078c2ecf20Sopenharmony_ci} 7088c2ecf20Sopenharmony_ci 7098c2ecf20Sopenharmony_cistatic void _rtl92cu_init_chipt_queue_priority(struct ieee80211_hw *hw, 7108c2ecf20Sopenharmony_ci bool wmm_enable, 7118c2ecf20Sopenharmony_ci u8 out_ep_num, 7128c2ecf20Sopenharmony_ci u8 queue_sel) 7138c2ecf20Sopenharmony_ci{ 7148c2ecf20Sopenharmony_ci u8 hq_sele = 0; 7158c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7168c2ecf20Sopenharmony_ci 7178c2ecf20Sopenharmony_ci switch (out_ep_num) { 7188c2ecf20Sopenharmony_ci case 2: /* (TX_SELE_HQ|TX_SELE_LQ) */ 7198c2ecf20Sopenharmony_ci if (!wmm_enable) /* typical setting */ 7208c2ecf20Sopenharmony_ci hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_MGTQ | 7218c2ecf20Sopenharmony_ci HQSEL_HIQ; 7228c2ecf20Sopenharmony_ci else /* for WMM */ 7238c2ecf20Sopenharmony_ci hq_sele = HQSEL_VOQ | HQSEL_BEQ | HQSEL_MGTQ | 7248c2ecf20Sopenharmony_ci HQSEL_HIQ; 7258c2ecf20Sopenharmony_ci break; 7268c2ecf20Sopenharmony_ci case 1: 7278c2ecf20Sopenharmony_ci if (TX_SELE_LQ == queue_sel) { 7288c2ecf20Sopenharmony_ci /* map all endpoint to Low queue */ 7298c2ecf20Sopenharmony_ci hq_sele = 0; 7308c2ecf20Sopenharmony_ci } else if (TX_SELE_HQ == queue_sel) { 7318c2ecf20Sopenharmony_ci /* map all endpoint to High queue */ 7328c2ecf20Sopenharmony_ci hq_sele = HQSEL_VOQ | HQSEL_VIQ | HQSEL_BEQ | 7338c2ecf20Sopenharmony_ci HQSEL_BKQ | HQSEL_MGTQ | HQSEL_HIQ; 7348c2ecf20Sopenharmony_ci } 7358c2ecf20Sopenharmony_ci break; 7368c2ecf20Sopenharmony_ci default: 7378c2ecf20Sopenharmony_ci WARN_ON(1); /* Shall not reach here! */ 7388c2ecf20Sopenharmony_ci break; 7398c2ecf20Sopenharmony_ci } 7408c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_TRXDMA_CTRL+1), hq_sele); 7418c2ecf20Sopenharmony_ci pr_info("Tx queue select :0x%02x..\n", hq_sele); 7428c2ecf20Sopenharmony_ci} 7438c2ecf20Sopenharmony_ci 7448c2ecf20Sopenharmony_cistatic void _rtl92cu_init_queue_priority(struct ieee80211_hw *hw, 7458c2ecf20Sopenharmony_ci bool wmm_enable, 7468c2ecf20Sopenharmony_ci u8 out_ep_num, 7478c2ecf20Sopenharmony_ci u8 queue_sel) 7488c2ecf20Sopenharmony_ci{ 7498c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 7508c2ecf20Sopenharmony_ci 7518c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 7528c2ecf20Sopenharmony_ci _rtl92cu_init_chipn_queue_priority(hw, wmm_enable, out_ep_num, 7538c2ecf20Sopenharmony_ci queue_sel); 7548c2ecf20Sopenharmony_ci else 7558c2ecf20Sopenharmony_ci _rtl92cu_init_chipt_queue_priority(hw, wmm_enable, out_ep_num, 7568c2ecf20Sopenharmony_ci queue_sel); 7578c2ecf20Sopenharmony_ci} 7588c2ecf20Sopenharmony_ci 7598c2ecf20Sopenharmony_cistatic void _rtl92cu_init_wmac_setting(struct ieee80211_hw *hw) 7608c2ecf20Sopenharmony_ci{ 7618c2ecf20Sopenharmony_ci u16 value16; 7628c2ecf20Sopenharmony_ci u32 value32; 7638c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7648c2ecf20Sopenharmony_ci 7658c2ecf20Sopenharmony_ci value32 = (RCR_APM | RCR_AM | RCR_ADF | RCR_AB | RCR_APPFCS | 7668c2ecf20Sopenharmony_ci RCR_APP_ICV | RCR_AMF | RCR_HTC_LOC_CTRL | 7678c2ecf20Sopenharmony_ci RCR_APP_MIC | RCR_APP_PHYSTS | RCR_ACRC32); 7688c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, (u8 *)(&value32)); 7698c2ecf20Sopenharmony_ci /* Accept all multicast address */ 7708c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MAR, 0xFFFFFFFF); 7718c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_MAR + 4, 0xFFFFFFFF); 7728c2ecf20Sopenharmony_ci /* Accept all management frames */ 7738c2ecf20Sopenharmony_ci value16 = 0xFFFF; 7748c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MGT_FILTER, 7758c2ecf20Sopenharmony_ci (u8 *)(&value16)); 7768c2ecf20Sopenharmony_ci /* Reject all control frame - default value is 0 */ 7778c2ecf20Sopenharmony_ci value16 = 0x0; 7788c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_CTRL_FILTER, 7798c2ecf20Sopenharmony_ci (u8 *)(&value16)); 7808c2ecf20Sopenharmony_ci /* Accept all data frames */ 7818c2ecf20Sopenharmony_ci value16 = 0xFFFF; 7828c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_DATA_FILTER, 7838c2ecf20Sopenharmony_ci (u8 *)(&value16)); 7848c2ecf20Sopenharmony_ci} 7858c2ecf20Sopenharmony_ci 7868c2ecf20Sopenharmony_cistatic void _rtl92cu_init_beacon_parameters(struct ieee80211_hw *hw) 7878c2ecf20Sopenharmony_ci{ 7888c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7898c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 7908c2ecf20Sopenharmony_ci 7918c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_CTRL, 0x1010); 7928c2ecf20Sopenharmony_ci 7938c2ecf20Sopenharmony_ci /* TODO: Remove these magic number */ 7948c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_TBTT_PROHIBIT, 0x6404); 7958c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DRVERLYINT, DRIVER_EARLY_INT_TIME); 7968c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNDMATIM, BCN_DMA_ATIME_INT_TIME); 7978c2ecf20Sopenharmony_ci /* Change beacon AIFS to the largest number 7988c2ecf20Sopenharmony_ci * beacause test chip does not contension before sending beacon. 7998c2ecf20Sopenharmony_ci */ 8008c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 8018c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCNTCFG, 0x660F); 8028c2ecf20Sopenharmony_ci else 8038c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCNTCFG, 0x66FF); 8048c2ecf20Sopenharmony_ci} 8058c2ecf20Sopenharmony_ci 8068c2ecf20Sopenharmony_cistatic int _rtl92cu_init_mac(struct ieee80211_hw *hw) 8078c2ecf20Sopenharmony_ci{ 8088c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8098c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 8108c2ecf20Sopenharmony_ci struct rtl_usb_priv *usb_priv = rtl_usbpriv(hw); 8118c2ecf20Sopenharmony_ci struct rtl_usb *rtlusb = rtl_usbdev(usb_priv); 8128c2ecf20Sopenharmony_ci int err = 0; 8138c2ecf20Sopenharmony_ci u32 boundary = 0; 8148c2ecf20Sopenharmony_ci u8 wmm_enable = false; /* TODO */ 8158c2ecf20Sopenharmony_ci u8 out_ep_nums = rtlusb->out_ep_nums; 8168c2ecf20Sopenharmony_ci u8 queue_sel = rtlusb->out_queue_sel; 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_ci err = _rtl92cu_init_power_on(hw); 8198c2ecf20Sopenharmony_ci 8208c2ecf20Sopenharmony_ci if (err) { 8218c2ecf20Sopenharmony_ci pr_err("Failed to init power on!\n"); 8228c2ecf20Sopenharmony_ci return err; 8238c2ecf20Sopenharmony_ci } 8248c2ecf20Sopenharmony_ci if (!wmm_enable) { 8258c2ecf20Sopenharmony_ci boundary = TX_PAGE_BOUNDARY; 8268c2ecf20Sopenharmony_ci } else { /* for WMM */ 8278c2ecf20Sopenharmony_ci boundary = (IS_NORMAL_CHIP(rtlhal->version)) 8288c2ecf20Sopenharmony_ci ? WMM_CHIP_B_TX_PAGE_BOUNDARY 8298c2ecf20Sopenharmony_ci : WMM_CHIP_A_TX_PAGE_BOUNDARY; 8308c2ecf20Sopenharmony_ci } 8318c2ecf20Sopenharmony_ci if (!rtl92c_init_llt_table(hw, boundary)) { 8328c2ecf20Sopenharmony_ci pr_err("Failed to init LLT Table!\n"); 8338c2ecf20Sopenharmony_ci return -EINVAL; 8348c2ecf20Sopenharmony_ci } 8358c2ecf20Sopenharmony_ci _rtl92cu_init_queue_reserved_page(hw, wmm_enable, out_ep_nums, 8368c2ecf20Sopenharmony_ci queue_sel); 8378c2ecf20Sopenharmony_ci _rtl92c_init_trx_buffer(hw, wmm_enable); 8388c2ecf20Sopenharmony_ci _rtl92cu_init_queue_priority(hw, wmm_enable, out_ep_nums, 8398c2ecf20Sopenharmony_ci queue_sel); 8408c2ecf20Sopenharmony_ci /* Get Rx PHY status in order to report RSSI and others. */ 8418c2ecf20Sopenharmony_ci rtl92c_init_driver_info_size(hw, RTL92C_DRIVER_INFO_SIZE); 8428c2ecf20Sopenharmony_ci rtl92c_init_interrupt(hw); 8438c2ecf20Sopenharmony_ci rtl92c_init_network_type(hw); 8448c2ecf20Sopenharmony_ci _rtl92cu_init_wmac_setting(hw); 8458c2ecf20Sopenharmony_ci rtl92c_init_adaptive_ctrl(hw); 8468c2ecf20Sopenharmony_ci rtl92c_init_edca(hw); 8478c2ecf20Sopenharmony_ci rtl92c_init_rate_fallback(hw); 8488c2ecf20Sopenharmony_ci rtl92c_init_retry_function(hw); 8498c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_bw_mode(hw, NL80211_CHAN_HT20); 8508c2ecf20Sopenharmony_ci rtl92c_set_min_space(hw, IS_92C_SERIAL(rtlhal->version)); 8518c2ecf20Sopenharmony_ci _rtl92cu_init_beacon_parameters(hw); 8528c2ecf20Sopenharmony_ci rtl92c_init_ampdu_aggregation(hw); 8538c2ecf20Sopenharmony_ci rtl92c_init_beacon_max_error(hw); 8548c2ecf20Sopenharmony_ci return err; 8558c2ecf20Sopenharmony_ci} 8568c2ecf20Sopenharmony_ci 8578c2ecf20Sopenharmony_civoid rtl92cu_enable_hw_security_config(struct ieee80211_hw *hw) 8588c2ecf20Sopenharmony_ci{ 8598c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8608c2ecf20Sopenharmony_ci u8 sec_reg_value = 0x0; 8618c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 8628c2ecf20Sopenharmony_ci 8638c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_LOUD, 8648c2ecf20Sopenharmony_ci "PairwiseEncAlgorithm = %d GroupEncAlgorithm = %d\n", 8658c2ecf20Sopenharmony_ci rtlpriv->sec.pairwise_enc_algorithm, 8668c2ecf20Sopenharmony_ci rtlpriv->sec.group_enc_algorithm); 8678c2ecf20Sopenharmony_ci if (rtlpriv->cfg->mod_params->sw_crypto || rtlpriv->sec.use_sw_sec) { 8688c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_DMESG, 8698c2ecf20Sopenharmony_ci "not open sw encryption\n"); 8708c2ecf20Sopenharmony_ci return; 8718c2ecf20Sopenharmony_ci } 8728c2ecf20Sopenharmony_ci sec_reg_value = SCR_TXENCENABLE | SCR_RXDECENABLE; 8738c2ecf20Sopenharmony_ci if (rtlpriv->sec.use_defaultkey) { 8748c2ecf20Sopenharmony_ci sec_reg_value |= SCR_TXUSEDK; 8758c2ecf20Sopenharmony_ci sec_reg_value |= SCR_RXUSEDK; 8768c2ecf20Sopenharmony_ci } 8778c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 8788c2ecf20Sopenharmony_ci sec_reg_value |= (SCR_RXBCUSEDK | SCR_TXBCUSEDK); 8798c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); 8808c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_SEC, DBG_LOUD, "The SECR-value %x\n", 8818c2ecf20Sopenharmony_ci sec_reg_value); 8828c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_WPA_CONFIG, &sec_reg_value); 8838c2ecf20Sopenharmony_ci} 8848c2ecf20Sopenharmony_ci 8858c2ecf20Sopenharmony_cistatic void _rtl92cu_hw_configure(struct ieee80211_hw *hw) 8868c2ecf20Sopenharmony_ci{ 8878c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8888c2ecf20Sopenharmony_ci struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 8898c2ecf20Sopenharmony_ci 8908c2ecf20Sopenharmony_ci /* To Fix MAC loopback mode fail. */ 8918c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOHCI12_CTRL, 0x0f); 8928c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x15, 0xe9); 8938c2ecf20Sopenharmony_ci /* HW SEQ CTRL */ 8948c2ecf20Sopenharmony_ci /* set 0x0 to 0xFF by tynli. Default enable HW SEQ NUM. */ 8958c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_HWSEQ_CTRL, 0xFF); 8968c2ecf20Sopenharmony_ci /* fixed USB interface interference issue */ 8978c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0xfe40, 0xe0); 8988c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0xfe41, 0x8d); 8998c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0xfe42, 0x80); 9008c2ecf20Sopenharmony_ci rtlusb->reg_bcn_ctrl_val = 0x18; 9018c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val); 9028c2ecf20Sopenharmony_ci} 9038c2ecf20Sopenharmony_ci 9048c2ecf20Sopenharmony_cistatic void _initpabias(struct ieee80211_hw *hw) 9058c2ecf20Sopenharmony_ci{ 9068c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 9078c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 9088c2ecf20Sopenharmony_ci u8 pa_setting; 9098c2ecf20Sopenharmony_ci 9108c2ecf20Sopenharmony_ci /* FIXED PA current issue */ 9118c2ecf20Sopenharmony_ci pa_setting = efuse_read_1byte(hw, 0x1FA); 9128c2ecf20Sopenharmony_ci if (!(pa_setting & BIT(0))) { 9138c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x0F406); 9148c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x4F406); 9158c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0x8F406); 9168c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, 0x15, 0x0FFFFF, 0xCF406); 9178c2ecf20Sopenharmony_ci } 9188c2ecf20Sopenharmony_ci if (!(pa_setting & BIT(1)) && IS_NORMAL_CHIP(rtlhal->version) && 9198c2ecf20Sopenharmony_ci IS_92C_SERIAL(rtlhal->version)) { 9208c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x0F406); 9218c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x4F406); 9228c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0x8F406); 9238c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_B, 0x15, 0x0FFFFF, 0xCF406); 9248c2ecf20Sopenharmony_ci } 9258c2ecf20Sopenharmony_ci if (!(pa_setting & BIT(4))) { 9268c2ecf20Sopenharmony_ci pa_setting = rtl_read_byte(rtlpriv, 0x16); 9278c2ecf20Sopenharmony_ci pa_setting &= 0x0F; 9288c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x16, pa_setting | 0x90); 9298c2ecf20Sopenharmony_ci } 9308c2ecf20Sopenharmony_ci} 9318c2ecf20Sopenharmony_ci 9328c2ecf20Sopenharmony_ciint rtl92cu_hw_init(struct ieee80211_hw *hw) 9338c2ecf20Sopenharmony_ci{ 9348c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 9358c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 9368c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 9378c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 9388c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 9398c2ecf20Sopenharmony_ci int err = 0; 9408c2ecf20Sopenharmony_ci unsigned long flags; 9418c2ecf20Sopenharmony_ci 9428c2ecf20Sopenharmony_ci /* As this function can take a very long time (up to 350 ms) 9438c2ecf20Sopenharmony_ci * and can be called with irqs disabled, reenable the irqs 9448c2ecf20Sopenharmony_ci * to let the other devices continue being serviced. 9458c2ecf20Sopenharmony_ci * 9468c2ecf20Sopenharmony_ci * It is safe doing so since our own interrupts will only be enabled 9478c2ecf20Sopenharmony_ci * in a subsequent step. 9488c2ecf20Sopenharmony_ci */ 9498c2ecf20Sopenharmony_ci local_save_flags(flags); 9508c2ecf20Sopenharmony_ci local_irq_enable(); 9518c2ecf20Sopenharmony_ci 9528c2ecf20Sopenharmony_ci rtlhal->fw_ready = false; 9538c2ecf20Sopenharmony_ci rtlhal->hw_type = HARDWARE_TYPE_RTL8192CU; 9548c2ecf20Sopenharmony_ci err = _rtl92cu_init_mac(hw); 9558c2ecf20Sopenharmony_ci if (err) { 9568c2ecf20Sopenharmony_ci pr_err("init mac failed!\n"); 9578c2ecf20Sopenharmony_ci goto exit; 9588c2ecf20Sopenharmony_ci } 9598c2ecf20Sopenharmony_ci err = rtl92c_download_fw(hw); 9608c2ecf20Sopenharmony_ci if (err) { 9618c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 9628c2ecf20Sopenharmony_ci "Failed to download FW. Init HW without FW now..\n"); 9638c2ecf20Sopenharmony_ci err = 1; 9648c2ecf20Sopenharmony_ci goto exit; 9658c2ecf20Sopenharmony_ci } 9668c2ecf20Sopenharmony_ci 9678c2ecf20Sopenharmony_ci rtlhal->fw_ready = true; 9688c2ecf20Sopenharmony_ci rtlhal->last_hmeboxnum = 0; /* h2c */ 9698c2ecf20Sopenharmony_ci _rtl92cu_phy_param_tab_init(hw); 9708c2ecf20Sopenharmony_ci rtl92cu_phy_mac_config(hw); 9718c2ecf20Sopenharmony_ci rtl92cu_phy_bb_config(hw); 9728c2ecf20Sopenharmony_ci rtlphy->rf_mode = RF_OP_BY_SW_3WIRE; 9738c2ecf20Sopenharmony_ci rtl92c_phy_rf_config(hw); 9748c2ecf20Sopenharmony_ci if (IS_VENDOR_UMC_A_CUT(rtlhal->version) && 9758c2ecf20Sopenharmony_ci !IS_92C_SERIAL(rtlhal->version)) { 9768c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1, MASKDWORD, 0x30255); 9778c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G2, MASKDWORD, 0x50a00); 9788c2ecf20Sopenharmony_ci } 9798c2ecf20Sopenharmony_ci rtlphy->rfreg_chnlval[0] = rtl_get_rfreg(hw, (enum radio_path)0, 9808c2ecf20Sopenharmony_ci RF_CHNLBW, RFREG_OFFSET_MASK); 9818c2ecf20Sopenharmony_ci rtlphy->rfreg_chnlval[1] = rtl_get_rfreg(hw, (enum radio_path)1, 9828c2ecf20Sopenharmony_ci RF_CHNLBW, RFREG_OFFSET_MASK); 9838c2ecf20Sopenharmony_ci rtl92cu_bb_block_on(hw); 9848c2ecf20Sopenharmony_ci rtl_cam_reset_all_entry(hw); 9858c2ecf20Sopenharmony_ci rtl92cu_enable_hw_security_config(hw); 9868c2ecf20Sopenharmony_ci ppsc->rfpwr_state = ERFON; 9878c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_ETHER_ADDR, mac->mac_addr); 9888c2ecf20Sopenharmony_ci if (ppsc->rfpwr_state == ERFON) { 9898c2ecf20Sopenharmony_ci rtl92c_phy_set_rfpath_switch(hw, 1); 9908c2ecf20Sopenharmony_ci if (rtlphy->iqk_initialized) { 9918c2ecf20Sopenharmony_ci rtl92c_phy_iq_calibrate(hw, true); 9928c2ecf20Sopenharmony_ci } else { 9938c2ecf20Sopenharmony_ci rtl92c_phy_iq_calibrate(hw, false); 9948c2ecf20Sopenharmony_ci rtlphy->iqk_initialized = true; 9958c2ecf20Sopenharmony_ci } 9968c2ecf20Sopenharmony_ci rtl92c_dm_check_txpower_tracking(hw); 9978c2ecf20Sopenharmony_ci rtl92c_phy_lc_calibrate(hw); 9988c2ecf20Sopenharmony_ci } 9998c2ecf20Sopenharmony_ci _rtl92cu_hw_configure(hw); 10008c2ecf20Sopenharmony_ci _initpabias(hw); 10018c2ecf20Sopenharmony_ci rtl92c_dm_init(hw); 10028c2ecf20Sopenharmony_ciexit: 10038c2ecf20Sopenharmony_ci local_irq_disable(); 10048c2ecf20Sopenharmony_ci local_irq_restore(flags); 10058c2ecf20Sopenharmony_ci return err; 10068c2ecf20Sopenharmony_ci} 10078c2ecf20Sopenharmony_ci 10088c2ecf20Sopenharmony_cistatic void disable_rfafeandresetbb(struct ieee80211_hw *hw) 10098c2ecf20Sopenharmony_ci{ 10108c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10118c2ecf20Sopenharmony_ci/************************************** 10128c2ecf20Sopenharmony_cia. TXPAUSE 0x522[7:0] = 0xFF Pause MAC TX queue 10138c2ecf20Sopenharmony_cib. RF path 0 offset 0x00 = 0x00 disable RF 10148c2ecf20Sopenharmony_cic. APSD_CTRL 0x600[7:0] = 0x40 10158c2ecf20Sopenharmony_cid. SYS_FUNC_EN 0x02[7:0] = 0x16 reset BB state machine 10168c2ecf20Sopenharmony_cie. SYS_FUNC_EN 0x02[7:0] = 0x14 reset BB state machine 10178c2ecf20Sopenharmony_ci***************************************/ 10188c2ecf20Sopenharmony_ci u8 erfpath = 0, value8 = 0; 10198c2ecf20Sopenharmony_ci 10208c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 10218c2ecf20Sopenharmony_ci rtl_set_rfreg(hw, (enum radio_path)erfpath, 0x0, MASKBYTE0, 0x0); 10228c2ecf20Sopenharmony_ci 10238c2ecf20Sopenharmony_ci value8 |= APSDOFF; 10248c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_APSD_CTRL, value8); /*0x40*/ 10258c2ecf20Sopenharmony_ci value8 = 0; 10268c2ecf20Sopenharmony_ci value8 |= (FEN_USBD | FEN_USBA | FEN_BB_GLB_RSTN); 10278c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8);/*0x16*/ 10288c2ecf20Sopenharmony_ci value8 &= (~FEN_BB_GLB_RSTN); 10298c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, value8); /*0x14*/ 10308c2ecf20Sopenharmony_ci} 10318c2ecf20Sopenharmony_ci 10328c2ecf20Sopenharmony_cistatic void _resetdigitalprocedure1(struct ieee80211_hw *hw, bool withouthwsm) 10338c2ecf20Sopenharmony_ci{ 10348c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10358c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 10368c2ecf20Sopenharmony_ci 10378c2ecf20Sopenharmony_ci if (rtlhal->fw_version <= 0x20) { 10388c2ecf20Sopenharmony_ci /***************************** 10398c2ecf20Sopenharmony_ci f. MCUFWDL 0x80[7:0]=0 reset MCU ready status 10408c2ecf20Sopenharmony_ci g. SYS_FUNC_EN 0x02[10]= 0 reset MCU reg, (8051 reset) 10418c2ecf20Sopenharmony_ci h. SYS_FUNC_EN 0x02[15-12]= 5 reset MAC reg, DCORE 10428c2ecf20Sopenharmony_ci i. SYS_FUNC_EN 0x02[10]= 1 enable MCU reg, (8051 enable) 10438c2ecf20Sopenharmony_ci ******************************/ 10448c2ecf20Sopenharmony_ci u16 valu16 = 0; 10458c2ecf20Sopenharmony_ci 10468c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); 10478c2ecf20Sopenharmony_ci valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 10488c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 & 10498c2ecf20Sopenharmony_ci (~FEN_CPUEN))); /* reset MCU ,8051 */ 10508c2ecf20Sopenharmony_ci valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN)&0x0FFF; 10518c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | 10528c2ecf20Sopenharmony_ci (FEN_HWPDN|FEN_ELDR))); /* reset MAC */ 10538c2ecf20Sopenharmony_ci valu16 = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN); 10548c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_FUNC_EN, (valu16 | 10558c2ecf20Sopenharmony_ci FEN_CPUEN)); /* enable MCU ,8051 */ 10568c2ecf20Sopenharmony_ci } else { 10578c2ecf20Sopenharmony_ci u8 retry_cnts = 0; 10588c2ecf20Sopenharmony_ci 10598c2ecf20Sopenharmony_ci /* IF fw in RAM code, do reset */ 10608c2ecf20Sopenharmony_ci if (rtl_read_byte(rtlpriv, REG_MCUFWDL) & BIT(1)) { 10618c2ecf20Sopenharmony_ci /* reset MCU ready status */ 10628c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); 10638c2ecf20Sopenharmony_ci /* 8051 reset by self */ 10648c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_HMETFR+3, 0x20); 10658c2ecf20Sopenharmony_ci while ((retry_cnts++ < 100) && 10668c2ecf20Sopenharmony_ci (FEN_CPUEN & rtl_read_word(rtlpriv, 10678c2ecf20Sopenharmony_ci REG_SYS_FUNC_EN))) { 10688c2ecf20Sopenharmony_ci udelay(50); 10698c2ecf20Sopenharmony_ci } 10708c2ecf20Sopenharmony_ci if (retry_cnts >= 100) { 10718c2ecf20Sopenharmony_ci pr_err("8051 reset failed!.........................\n"); 10728c2ecf20Sopenharmony_ci /* if 8051 reset fail, reset MAC. */ 10738c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 10748c2ecf20Sopenharmony_ci REG_SYS_FUNC_EN + 1, 10758c2ecf20Sopenharmony_ci 0x50); 10768c2ecf20Sopenharmony_ci udelay(100); 10778c2ecf20Sopenharmony_ci } 10788c2ecf20Sopenharmony_ci } 10798c2ecf20Sopenharmony_ci /* Reset MAC and Enable 8051 */ 10808c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN + 1, 0x54); 10818c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MCUFWDL, 0); 10828c2ecf20Sopenharmony_ci } 10838c2ecf20Sopenharmony_ci if (withouthwsm) { 10848c2ecf20Sopenharmony_ci /***************************** 10858c2ecf20Sopenharmony_ci Without HW auto state machine 10868c2ecf20Sopenharmony_ci g.SYS_CLKR 0x08[15:0] = 0x30A3 disable MAC clock 10878c2ecf20Sopenharmony_ci h.AFE_PLL_CTRL 0x28[7:0] = 0x80 disable AFE PLL 10888c2ecf20Sopenharmony_ci i.AFE_XTAL_CTRL 0x24[15:0] = 0x880F gated AFE DIG_CLOCK 10898c2ecf20Sopenharmony_ci j.SYS_ISu_CTRL 0x00[7:0] = 0xF9 isolated digital to PON 10908c2ecf20Sopenharmony_ci ******************************/ 10918c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); 10928c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, 0x80); 10938c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_AFE_XTAL_CTRL, 0x880F); 10948c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL, 0xF9); 10958c2ecf20Sopenharmony_ci } 10968c2ecf20Sopenharmony_ci} 10978c2ecf20Sopenharmony_ci 10988c2ecf20Sopenharmony_cistatic void _resetdigitalprocedure2(struct ieee80211_hw *hw) 10998c2ecf20Sopenharmony_ci{ 11008c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11018c2ecf20Sopenharmony_ci/***************************** 11028c2ecf20Sopenharmony_cik. SYS_FUNC_EN 0x03[7:0] = 0x44 disable ELDR runction 11038c2ecf20Sopenharmony_cil. SYS_CLKR 0x08[15:0] = 0x3083 disable ELDR clock 11048c2ecf20Sopenharmony_cim. SYS_ISO_CTRL 0x01[7:0] = 0x83 isolated ELDR to PON 11058c2ecf20Sopenharmony_ci******************************/ 11068c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_SYS_CLKR, 0x70A3); 11078c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SYS_ISO_CTRL+1, 0x82); 11088c2ecf20Sopenharmony_ci} 11098c2ecf20Sopenharmony_ci 11108c2ecf20Sopenharmony_cistatic void _disablegpio(struct ieee80211_hw *hw) 11118c2ecf20Sopenharmony_ci{ 11128c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11138c2ecf20Sopenharmony_ci/*************************************** 11148c2ecf20Sopenharmony_cij. GPIO_PIN_CTRL 0x44[31:0]=0x000 11158c2ecf20Sopenharmony_cik. Value = GPIO_PIN_CTRL[7:0] 11168c2ecf20Sopenharmony_cil. GPIO_PIN_CTRL 0x44[31:0] = 0x00FF0000 | (value <<8); write ext PIN level 11178c2ecf20Sopenharmony_cim. GPIO_MUXCFG 0x42 [15:0] = 0x0780 11188c2ecf20Sopenharmony_cin. LEDCFG 0x4C[15:0] = 0x8080 11198c2ecf20Sopenharmony_ci***************************************/ 11208c2ecf20Sopenharmony_ci u8 value8; 11218c2ecf20Sopenharmony_ci u16 value16; 11228c2ecf20Sopenharmony_ci u32 value32; 11238c2ecf20Sopenharmony_ci 11248c2ecf20Sopenharmony_ci /* 1. Disable GPIO[7:0] */ 11258c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, 0x0000); 11268c2ecf20Sopenharmony_ci value32 = rtl_read_dword(rtlpriv, REG_GPIO_PIN_CTRL) & 0xFFFF00FF; 11278c2ecf20Sopenharmony_ci value8 = (u8)(value32&0x000000FF); 11288c2ecf20Sopenharmony_ci value32 |= ((value8<<8) | 0x00FF0000); 11298c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_GPIO_PIN_CTRL, value32); 11308c2ecf20Sopenharmony_ci /* 2. Disable GPIO[10:8] */ 11318c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_GPIO_MUXCFG+3, 0x00); 11328c2ecf20Sopenharmony_ci value16 = rtl_read_word(rtlpriv, REG_GPIO_MUXCFG+2) & 0xFF0F; 11338c2ecf20Sopenharmony_ci value8 = (u8)(value16&0x000F); 11348c2ecf20Sopenharmony_ci value16 |= ((value8<<4) | 0x0780); 11358c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_GPIO_PIN_CTRL+2, value16); 11368c2ecf20Sopenharmony_ci /* 3. Disable LED0 & 1 */ 11378c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_LEDCFG0, 0x8080); 11388c2ecf20Sopenharmony_ci} 11398c2ecf20Sopenharmony_ci 11408c2ecf20Sopenharmony_cistatic void disable_analog(struct ieee80211_hw *hw, bool withouthwsm) 11418c2ecf20Sopenharmony_ci{ 11428c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11438c2ecf20Sopenharmony_ci u16 value16 = 0; 11448c2ecf20Sopenharmony_ci u8 value8 = 0; 11458c2ecf20Sopenharmony_ci 11468c2ecf20Sopenharmony_ci if (withouthwsm) { 11478c2ecf20Sopenharmony_ci /***************************** 11488c2ecf20Sopenharmony_ci n. LDOA15_CTRL 0x20[7:0] = 0x04 disable A15 power 11498c2ecf20Sopenharmony_ci o. LDOV12D_CTRL 0x21[7:0] = 0x54 disable digital core power 11508c2ecf20Sopenharmony_ci r. When driver call disable, the ASIC will turn off remaining 11518c2ecf20Sopenharmony_ci clock automatically 11528c2ecf20Sopenharmony_ci ******************************/ 11538c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOA15_CTRL, 0x04); 11548c2ecf20Sopenharmony_ci value8 = rtl_read_byte(rtlpriv, REG_LDOV12D_CTRL); 11558c2ecf20Sopenharmony_ci value8 &= (~LDV12_EN); 11568c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_LDOV12D_CTRL, value8); 11578c2ecf20Sopenharmony_ci } 11588c2ecf20Sopenharmony_ci 11598c2ecf20Sopenharmony_ci/***************************** 11608c2ecf20Sopenharmony_cih. SPS0_CTRL 0x11[7:0] = 0x23 enter PFM mode 11618c2ecf20Sopenharmony_cii. APS_FSMCO 0x04[15:0] = 0x4802 set USB suspend 11628c2ecf20Sopenharmony_ci******************************/ 11638c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x23); 11648c2ecf20Sopenharmony_ci value16 |= (APDM_HOST | AFSM_HSUS | PFM_ALDN); 11658c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_APS_FSMCO, (u16)value16); 11668c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0E); 11678c2ecf20Sopenharmony_ci} 11688c2ecf20Sopenharmony_ci 11698c2ecf20Sopenharmony_cistatic void carddisable_hwsm(struct ieee80211_hw *hw) 11708c2ecf20Sopenharmony_ci{ 11718c2ecf20Sopenharmony_ci /* ==== RF Off Sequence ==== */ 11728c2ecf20Sopenharmony_ci disable_rfafeandresetbb(hw); 11738c2ecf20Sopenharmony_ci /* ==== Reset digital sequence ====== */ 11748c2ecf20Sopenharmony_ci _resetdigitalprocedure1(hw, false); 11758c2ecf20Sopenharmony_ci /* ==== Pull GPIO PIN to balance level and LED control ====== */ 11768c2ecf20Sopenharmony_ci _disablegpio(hw); 11778c2ecf20Sopenharmony_ci /* ==== Disable analog sequence === */ 11788c2ecf20Sopenharmony_ci disable_analog(hw, false); 11798c2ecf20Sopenharmony_ci} 11808c2ecf20Sopenharmony_ci 11818c2ecf20Sopenharmony_cistatic void carddisablewithout_hwsm(struct ieee80211_hw *hw) 11828c2ecf20Sopenharmony_ci{ 11838c2ecf20Sopenharmony_ci /*==== RF Off Sequence ==== */ 11848c2ecf20Sopenharmony_ci disable_rfafeandresetbb(hw); 11858c2ecf20Sopenharmony_ci /* ==== Reset digital sequence ====== */ 11868c2ecf20Sopenharmony_ci _resetdigitalprocedure1(hw, true); 11878c2ecf20Sopenharmony_ci /* ==== Pull GPIO PIN to balance level and LED control ====== */ 11888c2ecf20Sopenharmony_ci _disablegpio(hw); 11898c2ecf20Sopenharmony_ci /* ==== Reset digital sequence ====== */ 11908c2ecf20Sopenharmony_ci _resetdigitalprocedure2(hw); 11918c2ecf20Sopenharmony_ci /* ==== Disable analog sequence === */ 11928c2ecf20Sopenharmony_ci disable_analog(hw, true); 11938c2ecf20Sopenharmony_ci} 11948c2ecf20Sopenharmony_ci 11958c2ecf20Sopenharmony_cistatic void _rtl92cu_set_bcn_ctrl_reg(struct ieee80211_hw *hw, 11968c2ecf20Sopenharmony_ci u8 set_bits, u8 clear_bits) 11978c2ecf20Sopenharmony_ci{ 11988c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 11998c2ecf20Sopenharmony_ci struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 12008c2ecf20Sopenharmony_ci 12018c2ecf20Sopenharmony_ci rtlusb->reg_bcn_ctrl_val |= set_bits; 12028c2ecf20Sopenharmony_ci rtlusb->reg_bcn_ctrl_val &= ~clear_bits; 12038c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCN_CTRL, (u8)rtlusb->reg_bcn_ctrl_val); 12048c2ecf20Sopenharmony_ci} 12058c2ecf20Sopenharmony_ci 12068c2ecf20Sopenharmony_cistatic void _rtl92cu_stop_tx_beacon(struct ieee80211_hw *hw) 12078c2ecf20Sopenharmony_ci{ 12088c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 12098c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 12108c2ecf20Sopenharmony_ci u8 tmp1byte = 0; 12118c2ecf20Sopenharmony_ci 12128c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 12138c2ecf20Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); 12148c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, 12158c2ecf20Sopenharmony_ci tmp1byte & (~BIT(6))); 12168c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0x64); 12178c2ecf20Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); 12188c2ecf20Sopenharmony_ci tmp1byte &= ~(BIT(0)); 12198c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); 12208c2ecf20Sopenharmony_ci } else { 12218c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 12228c2ecf20Sopenharmony_ci rtl_read_byte(rtlpriv, REG_TXPAUSE) | BIT(6)); 12238c2ecf20Sopenharmony_ci } 12248c2ecf20Sopenharmony_ci} 12258c2ecf20Sopenharmony_ci 12268c2ecf20Sopenharmony_cistatic void _rtl92cu_resume_tx_beacon(struct ieee80211_hw *hw) 12278c2ecf20Sopenharmony_ci{ 12288c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 12298c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 12308c2ecf20Sopenharmony_ci u8 tmp1byte = 0; 12318c2ecf20Sopenharmony_ci 12328c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 12338c2ecf20Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2); 12348c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, 12358c2ecf20Sopenharmony_ci tmp1byte | BIT(6)); 12368c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 1, 0xff); 12378c2ecf20Sopenharmony_ci tmp1byte = rtl_read_byte(rtlpriv, REG_TBTT_PROHIBIT + 2); 12388c2ecf20Sopenharmony_ci tmp1byte |= BIT(0); 12398c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TBTT_PROHIBIT + 2, tmp1byte); 12408c2ecf20Sopenharmony_ci } else { 12418c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_TXPAUSE, 12428c2ecf20Sopenharmony_ci rtl_read_byte(rtlpriv, REG_TXPAUSE) & (~BIT(6))); 12438c2ecf20Sopenharmony_ci } 12448c2ecf20Sopenharmony_ci} 12458c2ecf20Sopenharmony_ci 12468c2ecf20Sopenharmony_cistatic void _rtl92cu_enable_bcn_sub_func(struct ieee80211_hw *hw) 12478c2ecf20Sopenharmony_ci{ 12488c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 12498c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 12508c2ecf20Sopenharmony_ci 12518c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 12528c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(1)); 12538c2ecf20Sopenharmony_ci else 12548c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); 12558c2ecf20Sopenharmony_ci} 12568c2ecf20Sopenharmony_ci 12578c2ecf20Sopenharmony_cistatic void _rtl92cu_disable_bcn_sub_func(struct ieee80211_hw *hw) 12588c2ecf20Sopenharmony_ci{ 12598c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 12608c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 12618c2ecf20Sopenharmony_ci 12628c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) 12638c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(1), 0); 12648c2ecf20Sopenharmony_ci else 12658c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); 12668c2ecf20Sopenharmony_ci} 12678c2ecf20Sopenharmony_ci 12688c2ecf20Sopenharmony_cistatic int _rtl92cu_set_media_status(struct ieee80211_hw *hw, 12698c2ecf20Sopenharmony_ci enum nl80211_iftype type) 12708c2ecf20Sopenharmony_ci{ 12718c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 12728c2ecf20Sopenharmony_ci u8 bt_msr = rtl_read_byte(rtlpriv, MSR); 12738c2ecf20Sopenharmony_ci enum led_ctl_mode ledaction = LED_CTL_NO_LINK; 12748c2ecf20Sopenharmony_ci 12758c2ecf20Sopenharmony_ci bt_msr &= 0xfc; 12768c2ecf20Sopenharmony_ci if (type == NL80211_IFTYPE_UNSPECIFIED || type == 12778c2ecf20Sopenharmony_ci NL80211_IFTYPE_STATION) { 12788c2ecf20Sopenharmony_ci _rtl92cu_stop_tx_beacon(hw); 12798c2ecf20Sopenharmony_ci _rtl92cu_enable_bcn_sub_func(hw); 12808c2ecf20Sopenharmony_ci } else if (type == NL80211_IFTYPE_ADHOC || type == NL80211_IFTYPE_AP) { 12818c2ecf20Sopenharmony_ci _rtl92cu_resume_tx_beacon(hw); 12828c2ecf20Sopenharmony_ci _rtl92cu_disable_bcn_sub_func(hw); 12838c2ecf20Sopenharmony_ci } else { 12848c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING, 12858c2ecf20Sopenharmony_ci "Set HW_VAR_MEDIA_STATUS:No such media status(%x)\n", 12868c2ecf20Sopenharmony_ci type); 12878c2ecf20Sopenharmony_ci } 12888c2ecf20Sopenharmony_ci switch (type) { 12898c2ecf20Sopenharmony_ci case NL80211_IFTYPE_UNSPECIFIED: 12908c2ecf20Sopenharmony_ci bt_msr |= MSR_NOLINK; 12918c2ecf20Sopenharmony_ci ledaction = LED_CTL_LINK; 12928c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 12938c2ecf20Sopenharmony_ci "Set Network type to NO LINK!\n"); 12948c2ecf20Sopenharmony_ci break; 12958c2ecf20Sopenharmony_ci case NL80211_IFTYPE_ADHOC: 12968c2ecf20Sopenharmony_ci bt_msr |= MSR_ADHOC; 12978c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 12988c2ecf20Sopenharmony_ci "Set Network type to Ad Hoc!\n"); 12998c2ecf20Sopenharmony_ci break; 13008c2ecf20Sopenharmony_ci case NL80211_IFTYPE_STATION: 13018c2ecf20Sopenharmony_ci bt_msr |= MSR_INFRA; 13028c2ecf20Sopenharmony_ci ledaction = LED_CTL_LINK; 13038c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 13048c2ecf20Sopenharmony_ci "Set Network type to STA!\n"); 13058c2ecf20Sopenharmony_ci break; 13068c2ecf20Sopenharmony_ci case NL80211_IFTYPE_AP: 13078c2ecf20Sopenharmony_ci bt_msr |= MSR_AP; 13088c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, 13098c2ecf20Sopenharmony_ci "Set Network type to AP!\n"); 13108c2ecf20Sopenharmony_ci break; 13118c2ecf20Sopenharmony_ci default: 13128c2ecf20Sopenharmony_ci pr_err("Network type %d not supported!\n", type); 13138c2ecf20Sopenharmony_ci goto error_out; 13148c2ecf20Sopenharmony_ci } 13158c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, MSR, bt_msr); 13168c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, ledaction); 13178c2ecf20Sopenharmony_ci if ((bt_msr & MSR_MASK) == MSR_AP) 13188c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x00); 13198c2ecf20Sopenharmony_ci else 13208c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_BCNTCFG + 1, 0x66); 13218c2ecf20Sopenharmony_ci return 0; 13228c2ecf20Sopenharmony_cierror_out: 13238c2ecf20Sopenharmony_ci return 1; 13248c2ecf20Sopenharmony_ci} 13258c2ecf20Sopenharmony_ci 13268c2ecf20Sopenharmony_civoid rtl92cu_card_disable(struct ieee80211_hw *hw) 13278c2ecf20Sopenharmony_ci{ 13288c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13298c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 13308c2ecf20Sopenharmony_ci struct rtl_usb *rtlusb = rtl_usbdev(rtl_usbpriv(hw)); 13318c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 13328c2ecf20Sopenharmony_ci enum nl80211_iftype opmode; 13338c2ecf20Sopenharmony_ci 13348c2ecf20Sopenharmony_ci mac->link_state = MAC80211_NOLINK; 13358c2ecf20Sopenharmony_ci opmode = NL80211_IFTYPE_UNSPECIFIED; 13368c2ecf20Sopenharmony_ci _rtl92cu_set_media_status(hw, opmode); 13378c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->led_control(hw, LED_CTL_POWER_OFF); 13388c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 13398c2ecf20Sopenharmony_ci if (rtlusb->disablehwsm) 13408c2ecf20Sopenharmony_ci carddisable_hwsm(hw); 13418c2ecf20Sopenharmony_ci else 13428c2ecf20Sopenharmony_ci carddisablewithout_hwsm(hw); 13438c2ecf20Sopenharmony_ci 13448c2ecf20Sopenharmony_ci /* after power off we should do iqk again */ 13458c2ecf20Sopenharmony_ci rtlpriv->phy.iqk_initialized = false; 13468c2ecf20Sopenharmony_ci} 13478c2ecf20Sopenharmony_ci 13488c2ecf20Sopenharmony_civoid rtl92cu_set_check_bssid(struct ieee80211_hw *hw, bool check_bssid) 13498c2ecf20Sopenharmony_ci{ 13508c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13518c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 13528c2ecf20Sopenharmony_ci u32 reg_rcr; 13538c2ecf20Sopenharmony_ci 13548c2ecf20Sopenharmony_ci if (rtlpriv->psc.rfpwr_state != ERFON) 13558c2ecf20Sopenharmony_ci return; 13568c2ecf20Sopenharmony_ci 13578c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *)(®_rcr)); 13588c2ecf20Sopenharmony_ci 13598c2ecf20Sopenharmony_ci if (check_bssid) { 13608c2ecf20Sopenharmony_ci u8 tmp; 13618c2ecf20Sopenharmony_ci 13628c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 13638c2ecf20Sopenharmony_ci reg_rcr |= (RCR_CBSSID_DATA | RCR_CBSSID_BCN); 13648c2ecf20Sopenharmony_ci tmp = BIT(4); 13658c2ecf20Sopenharmony_ci } else { 13668c2ecf20Sopenharmony_ci reg_rcr |= RCR_CBSSID; 13678c2ecf20Sopenharmony_ci tmp = BIT(4) | BIT(5); 13688c2ecf20Sopenharmony_ci } 13698c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_RCR, 13708c2ecf20Sopenharmony_ci (u8 *) (®_rcr)); 13718c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, tmp); 13728c2ecf20Sopenharmony_ci } else { 13738c2ecf20Sopenharmony_ci u8 tmp; 13748c2ecf20Sopenharmony_ci 13758c2ecf20Sopenharmony_ci if (IS_NORMAL_CHIP(rtlhal->version)) { 13768c2ecf20Sopenharmony_ci reg_rcr &= ~(RCR_CBSSID_DATA | RCR_CBSSID_BCN); 13778c2ecf20Sopenharmony_ci tmp = BIT(4); 13788c2ecf20Sopenharmony_ci } else { 13798c2ecf20Sopenharmony_ci reg_rcr &= ~RCR_CBSSID; 13808c2ecf20Sopenharmony_ci tmp = BIT(4) | BIT(5); 13818c2ecf20Sopenharmony_ci } 13828c2ecf20Sopenharmony_ci reg_rcr &= (~(RCR_CBSSID_DATA | RCR_CBSSID_BCN)); 13838c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 13848c2ecf20Sopenharmony_ci HW_VAR_RCR, (u8 *) (®_rcr)); 13858c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, tmp, 0); 13868c2ecf20Sopenharmony_ci } 13878c2ecf20Sopenharmony_ci} 13888c2ecf20Sopenharmony_ci 13898c2ecf20Sopenharmony_ci/*========================================================================== */ 13908c2ecf20Sopenharmony_ci 13918c2ecf20Sopenharmony_ciint rtl92cu_set_network_type(struct ieee80211_hw *hw, enum nl80211_iftype type) 13928c2ecf20Sopenharmony_ci{ 13938c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13948c2ecf20Sopenharmony_ci 13958c2ecf20Sopenharmony_ci if (_rtl92cu_set_media_status(hw, type)) 13968c2ecf20Sopenharmony_ci return -EOPNOTSUPP; 13978c2ecf20Sopenharmony_ci 13988c2ecf20Sopenharmony_ci if (rtlpriv->mac80211.link_state == MAC80211_LINKED) { 13998c2ecf20Sopenharmony_ci if (type != NL80211_IFTYPE_AP) 14008c2ecf20Sopenharmony_ci rtl92cu_set_check_bssid(hw, true); 14018c2ecf20Sopenharmony_ci } else { 14028c2ecf20Sopenharmony_ci rtl92cu_set_check_bssid(hw, false); 14038c2ecf20Sopenharmony_ci } 14048c2ecf20Sopenharmony_ci 14058c2ecf20Sopenharmony_ci return 0; 14068c2ecf20Sopenharmony_ci} 14078c2ecf20Sopenharmony_ci 14088c2ecf20Sopenharmony_cistatic void _beacon_function_enable(struct ieee80211_hw *hw) 14098c2ecf20Sopenharmony_ci{ 14108c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14118c2ecf20Sopenharmony_ci 14128c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, (BIT(4) | BIT(3) | BIT(1)), 0x00); 14138c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RD_CTRL+1, 0x6F); 14148c2ecf20Sopenharmony_ci} 14158c2ecf20Sopenharmony_ci 14168c2ecf20Sopenharmony_civoid rtl92cu_set_beacon_related_registers(struct ieee80211_hw *hw) 14178c2ecf20Sopenharmony_ci{ 14188c2ecf20Sopenharmony_ci 14198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14208c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 14218c2ecf20Sopenharmony_ci u16 bcn_interval, atim_window; 14228c2ecf20Sopenharmony_ci u32 value32; 14238c2ecf20Sopenharmony_ci 14248c2ecf20Sopenharmony_ci bcn_interval = mac->beacon_interval; 14258c2ecf20Sopenharmony_ci atim_window = 2; /*FIX MERGE */ 14268c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_ATIMWND, atim_window); 14278c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); 14288c2ecf20Sopenharmony_ci _rtl92cu_init_beacon_parameters(hw); 14298c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SLOT, 0x09); 14308c2ecf20Sopenharmony_ci /* 14318c2ecf20Sopenharmony_ci * Force beacon frame transmission even after receiving beacon frame 14328c2ecf20Sopenharmony_ci * from other ad hoc STA 14338c2ecf20Sopenharmony_ci * 14348c2ecf20Sopenharmony_ci * 14358c2ecf20Sopenharmony_ci * Reset TSF Timer to zero, added by Roger. 2008.06.24 14368c2ecf20Sopenharmony_ci */ 14378c2ecf20Sopenharmony_ci value32 = rtl_read_dword(rtlpriv, REG_TCR); 14388c2ecf20Sopenharmony_ci value32 &= ~TSFRST; 14398c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TCR, value32); 14408c2ecf20Sopenharmony_ci value32 |= TSFRST; 14418c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TCR, value32); 14428c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_INIT | COMP_BEACON, DBG_LOUD, 14438c2ecf20Sopenharmony_ci "SetBeaconRelatedRegisters8192CUsb(): Set TCR(%x)\n", 14448c2ecf20Sopenharmony_ci value32); 14458c2ecf20Sopenharmony_ci /* TODO: Modify later (Find the right parameters) 14468c2ecf20Sopenharmony_ci * NOTE: Fix test chip's bug (about contention windows's randomness) */ 14478c2ecf20Sopenharmony_ci if ((mac->opmode == NL80211_IFTYPE_ADHOC) || 14488c2ecf20Sopenharmony_ci (mac->opmode == NL80211_IFTYPE_MESH_POINT) || 14498c2ecf20Sopenharmony_ci (mac->opmode == NL80211_IFTYPE_AP)) { 14508c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_CCK, 0x50); 14518c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RXTSF_OFFSET_OFDM, 0x50); 14528c2ecf20Sopenharmony_ci } 14538c2ecf20Sopenharmony_ci _beacon_function_enable(hw); 14548c2ecf20Sopenharmony_ci} 14558c2ecf20Sopenharmony_ci 14568c2ecf20Sopenharmony_civoid rtl92cu_set_beacon_interval(struct ieee80211_hw *hw) 14578c2ecf20Sopenharmony_ci{ 14588c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14598c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 14608c2ecf20Sopenharmony_ci u16 bcn_interval = mac->beacon_interval; 14618c2ecf20Sopenharmony_ci 14628c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BEACON, DBG_DMESG, "beacon_interval:%d\n", 14638c2ecf20Sopenharmony_ci bcn_interval); 14648c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_INTERVAL, bcn_interval); 14658c2ecf20Sopenharmony_ci} 14668c2ecf20Sopenharmony_ci 14678c2ecf20Sopenharmony_civoid rtl92cu_update_interrupt_mask(struct ieee80211_hw *hw, 14688c2ecf20Sopenharmony_ci u32 add_msr, u32 rm_msr) 14698c2ecf20Sopenharmony_ci{ 14708c2ecf20Sopenharmony_ci} 14718c2ecf20Sopenharmony_ci 14728c2ecf20Sopenharmony_civoid rtl92cu_get_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 14738c2ecf20Sopenharmony_ci{ 14748c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 14758c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 14768c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 14778c2ecf20Sopenharmony_ci 14788c2ecf20Sopenharmony_ci switch (variable) { 14798c2ecf20Sopenharmony_ci case HW_VAR_RCR: 14808c2ecf20Sopenharmony_ci *((u32 *)(val)) = mac->rx_conf; 14818c2ecf20Sopenharmony_ci break; 14828c2ecf20Sopenharmony_ci case HW_VAR_RF_STATE: 14838c2ecf20Sopenharmony_ci *((enum rf_pwrstate *)(val)) = ppsc->rfpwr_state; 14848c2ecf20Sopenharmony_ci break; 14858c2ecf20Sopenharmony_ci case HW_VAR_FWLPS_RF_ON:{ 14868c2ecf20Sopenharmony_ci enum rf_pwrstate rfstate; 14878c2ecf20Sopenharmony_ci u32 val_rcr; 14888c2ecf20Sopenharmony_ci 14898c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RF_STATE, 14908c2ecf20Sopenharmony_ci (u8 *)(&rfstate)); 14918c2ecf20Sopenharmony_ci if (rfstate == ERFOFF) { 14928c2ecf20Sopenharmony_ci *((bool *) (val)) = true; 14938c2ecf20Sopenharmony_ci } else { 14948c2ecf20Sopenharmony_ci val_rcr = rtl_read_dword(rtlpriv, REG_RCR); 14958c2ecf20Sopenharmony_ci val_rcr &= 0x00070000; 14968c2ecf20Sopenharmony_ci if (val_rcr) 14978c2ecf20Sopenharmony_ci *((bool *) (val)) = false; 14988c2ecf20Sopenharmony_ci else 14998c2ecf20Sopenharmony_ci *((bool *) (val)) = true; 15008c2ecf20Sopenharmony_ci } 15018c2ecf20Sopenharmony_ci break; 15028c2ecf20Sopenharmony_ci } 15038c2ecf20Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: 15048c2ecf20Sopenharmony_ci *((bool *) (val)) = ppsc->fw_current_inpsmode; 15058c2ecf20Sopenharmony_ci break; 15068c2ecf20Sopenharmony_ci case HW_VAR_CORRECT_TSF:{ 15078c2ecf20Sopenharmony_ci u64 tsf; 15088c2ecf20Sopenharmony_ci u32 *ptsf_low = (u32 *)&tsf; 15098c2ecf20Sopenharmony_ci u32 *ptsf_high = ((u32 *)&tsf) + 1; 15108c2ecf20Sopenharmony_ci 15118c2ecf20Sopenharmony_ci *ptsf_high = rtl_read_dword(rtlpriv, (REG_TSFTR + 4)); 15128c2ecf20Sopenharmony_ci *ptsf_low = rtl_read_dword(rtlpriv, REG_TSFTR); 15138c2ecf20Sopenharmony_ci *((u64 *)(val)) = tsf; 15148c2ecf20Sopenharmony_ci break; 15158c2ecf20Sopenharmony_ci } 15168c2ecf20Sopenharmony_ci case HW_VAR_MGT_FILTER: 15178c2ecf20Sopenharmony_ci *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP0); 15188c2ecf20Sopenharmony_ci break; 15198c2ecf20Sopenharmony_ci case HW_VAR_CTRL_FILTER: 15208c2ecf20Sopenharmony_ci *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP1); 15218c2ecf20Sopenharmony_ci break; 15228c2ecf20Sopenharmony_ci case HW_VAR_DATA_FILTER: 15238c2ecf20Sopenharmony_ci *((u16 *) (val)) = rtl_read_word(rtlpriv, REG_RXFLTMAP2); 15248c2ecf20Sopenharmony_ci break; 15258c2ecf20Sopenharmony_ci case HAL_DEF_WOWLAN: 15268c2ecf20Sopenharmony_ci break; 15278c2ecf20Sopenharmony_ci default: 15288c2ecf20Sopenharmony_ci pr_err("switch case %#x not processed\n", variable); 15298c2ecf20Sopenharmony_ci break; 15308c2ecf20Sopenharmony_ci } 15318c2ecf20Sopenharmony_ci} 15328c2ecf20Sopenharmony_ci 15338c2ecf20Sopenharmony_cistatic bool usb_cmd_send_packet(struct ieee80211_hw *hw, struct sk_buff *skb) 15348c2ecf20Sopenharmony_ci{ 15358c2ecf20Sopenharmony_ci /* Currently nothing happens here. 15368c2ecf20Sopenharmony_ci * Traffic stops after some seconds in WPA2 802.11n mode. 15378c2ecf20Sopenharmony_ci * Maybe because rtl8192cu chip should be set from here? 15388c2ecf20Sopenharmony_ci * If I understand correctly, the realtek vendor driver sends some urbs 15398c2ecf20Sopenharmony_ci * if its "here". 15408c2ecf20Sopenharmony_ci * 15418c2ecf20Sopenharmony_ci * This is maybe necessary: 15428c2ecf20Sopenharmony_ci * rtlpriv->cfg->ops->fill_tx_cmddesc(hw, buffer, 1, 1, skb); 15438c2ecf20Sopenharmony_ci */ 15448c2ecf20Sopenharmony_ci dev_kfree_skb(skb); 15458c2ecf20Sopenharmony_ci 15468c2ecf20Sopenharmony_ci return true; 15478c2ecf20Sopenharmony_ci} 15488c2ecf20Sopenharmony_ci 15498c2ecf20Sopenharmony_civoid rtl92cu_set_hw_reg(struct ieee80211_hw *hw, u8 variable, u8 *val) 15508c2ecf20Sopenharmony_ci{ 15518c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 15528c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 15538c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 15548c2ecf20Sopenharmony_ci struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 15558c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 15568c2ecf20Sopenharmony_ci enum wireless_mode wirelessmode = mac->mode; 15578c2ecf20Sopenharmony_ci u8 idx = 0; 15588c2ecf20Sopenharmony_ci 15598c2ecf20Sopenharmony_ci switch (variable) { 15608c2ecf20Sopenharmony_ci case HW_VAR_ETHER_ADDR:{ 15618c2ecf20Sopenharmony_ci for (idx = 0; idx < ETH_ALEN; idx++) { 15628c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_MACID + idx), 15638c2ecf20Sopenharmony_ci val[idx]); 15648c2ecf20Sopenharmony_ci } 15658c2ecf20Sopenharmony_ci break; 15668c2ecf20Sopenharmony_ci } 15678c2ecf20Sopenharmony_ci case HW_VAR_BASIC_RATE:{ 15688c2ecf20Sopenharmony_ci u16 rate_cfg = ((u16 *) val)[0]; 15698c2ecf20Sopenharmony_ci u8 rate_index = 0; 15708c2ecf20Sopenharmony_ci 15718c2ecf20Sopenharmony_ci rate_cfg &= 0x15f; 15728c2ecf20Sopenharmony_ci /* TODO */ 15738c2ecf20Sopenharmony_ci /* if (mac->current_network.vender == HT_IOT_PEER_CISCO 15748c2ecf20Sopenharmony_ci * && ((rate_cfg & 0x150) == 0)) { 15758c2ecf20Sopenharmony_ci * rate_cfg |= 0x010; 15768c2ecf20Sopenharmony_ci * } */ 15778c2ecf20Sopenharmony_ci rate_cfg |= 0x01; 15788c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR, rate_cfg & 0xff); 15798c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 1, 15808c2ecf20Sopenharmony_ci (rate_cfg >> 8) & 0xff); 15818c2ecf20Sopenharmony_ci while (rate_cfg > 0x1) { 15828c2ecf20Sopenharmony_ci rate_cfg >>= 1; 15838c2ecf20Sopenharmony_ci rate_index++; 15848c2ecf20Sopenharmony_ci } 15858c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_INIRTS_RATE_SEL, 15868c2ecf20Sopenharmony_ci rate_index); 15878c2ecf20Sopenharmony_ci break; 15888c2ecf20Sopenharmony_ci } 15898c2ecf20Sopenharmony_ci case HW_VAR_BSSID:{ 15908c2ecf20Sopenharmony_ci for (idx = 0; idx < ETH_ALEN; idx++) { 15918c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, (REG_BSSID + idx), 15928c2ecf20Sopenharmony_ci val[idx]); 15938c2ecf20Sopenharmony_ci } 15948c2ecf20Sopenharmony_ci break; 15958c2ecf20Sopenharmony_ci } 15968c2ecf20Sopenharmony_ci case HW_VAR_SIFS:{ 15978c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SIFS_CCK + 1, val[0]); 15988c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SIFS_OFDM + 1, val[1]); 15998c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SPEC_SIFS + 1, val[0]); 16008c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_SPEC_SIFS + 1, val[0]); 16018c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_R2T_SIFS+1, val[0]); 16028c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_T2T_SIFS+1, val[0]); 16038c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, "HW_VAR_SIFS\n"); 16048c2ecf20Sopenharmony_ci break; 16058c2ecf20Sopenharmony_ci } 16068c2ecf20Sopenharmony_ci case HW_VAR_SLOT_TIME:{ 16078c2ecf20Sopenharmony_ci u8 e_aci; 16088c2ecf20Sopenharmony_ci u8 QOS_MODE = 1; 16098c2ecf20Sopenharmony_ci 16108c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SLOT, val[0]); 16118c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 16128c2ecf20Sopenharmony_ci "HW_VAR_SLOT_TIME %x\n", val[0]); 16138c2ecf20Sopenharmony_ci if (QOS_MODE) { 16148c2ecf20Sopenharmony_ci for (e_aci = 0; e_aci < AC_MAX; e_aci++) 16158c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 16168c2ecf20Sopenharmony_ci HW_VAR_AC_PARAM, 16178c2ecf20Sopenharmony_ci &e_aci); 16188c2ecf20Sopenharmony_ci } else { 16198c2ecf20Sopenharmony_ci u8 sifstime = 0; 16208c2ecf20Sopenharmony_ci u8 u1baifs; 16218c2ecf20Sopenharmony_ci 16228c2ecf20Sopenharmony_ci if (IS_WIRELESS_MODE_A(wirelessmode) || 16238c2ecf20Sopenharmony_ci IS_WIRELESS_MODE_N_24G(wirelessmode) || 16248c2ecf20Sopenharmony_ci IS_WIRELESS_MODE_N_5G(wirelessmode)) 16258c2ecf20Sopenharmony_ci sifstime = 16; 16268c2ecf20Sopenharmony_ci else 16278c2ecf20Sopenharmony_ci sifstime = 10; 16288c2ecf20Sopenharmony_ci u1baifs = sifstime + (2 * val[0]); 16298c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_EDCA_VO_PARAM, 16308c2ecf20Sopenharmony_ci u1baifs); 16318c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_EDCA_VI_PARAM, 16328c2ecf20Sopenharmony_ci u1baifs); 16338c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_EDCA_BE_PARAM, 16348c2ecf20Sopenharmony_ci u1baifs); 16358c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_EDCA_BK_PARAM, 16368c2ecf20Sopenharmony_ci u1baifs); 16378c2ecf20Sopenharmony_ci } 16388c2ecf20Sopenharmony_ci break; 16398c2ecf20Sopenharmony_ci } 16408c2ecf20Sopenharmony_ci case HW_VAR_ACK_PREAMBLE:{ 16418c2ecf20Sopenharmony_ci u8 reg_tmp; 16428c2ecf20Sopenharmony_ci u8 short_preamble = (bool)*val; 16438c2ecf20Sopenharmony_ci 16448c2ecf20Sopenharmony_ci reg_tmp = 0; 16458c2ecf20Sopenharmony_ci if (short_preamble) 16468c2ecf20Sopenharmony_ci reg_tmp |= 0x80; 16478c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_tmp); 16488c2ecf20Sopenharmony_ci break; 16498c2ecf20Sopenharmony_ci } 16508c2ecf20Sopenharmony_ci case HW_VAR_AMPDU_MIN_SPACE:{ 16518c2ecf20Sopenharmony_ci u8 min_spacing_to_set; 16528c2ecf20Sopenharmony_ci u8 sec_min_space; 16538c2ecf20Sopenharmony_ci 16548c2ecf20Sopenharmony_ci min_spacing_to_set = *val; 16558c2ecf20Sopenharmony_ci if (min_spacing_to_set <= 7) { 16568c2ecf20Sopenharmony_ci switch (rtlpriv->sec.pairwise_enc_algorithm) { 16578c2ecf20Sopenharmony_ci case NO_ENCRYPTION: 16588c2ecf20Sopenharmony_ci case AESCCMP_ENCRYPTION: 16598c2ecf20Sopenharmony_ci sec_min_space = 0; 16608c2ecf20Sopenharmony_ci break; 16618c2ecf20Sopenharmony_ci case WEP40_ENCRYPTION: 16628c2ecf20Sopenharmony_ci case WEP104_ENCRYPTION: 16638c2ecf20Sopenharmony_ci case TKIP_ENCRYPTION: 16648c2ecf20Sopenharmony_ci sec_min_space = 6; 16658c2ecf20Sopenharmony_ci break; 16668c2ecf20Sopenharmony_ci default: 16678c2ecf20Sopenharmony_ci sec_min_space = 7; 16688c2ecf20Sopenharmony_ci break; 16698c2ecf20Sopenharmony_ci } 16708c2ecf20Sopenharmony_ci if (min_spacing_to_set < sec_min_space) 16718c2ecf20Sopenharmony_ci min_spacing_to_set = sec_min_space; 16728c2ecf20Sopenharmony_ci mac->min_space_cfg = ((mac->min_space_cfg & 16738c2ecf20Sopenharmony_ci 0xf8) | 16748c2ecf20Sopenharmony_ci min_spacing_to_set); 16758c2ecf20Sopenharmony_ci *val = min_spacing_to_set; 16768c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 16778c2ecf20Sopenharmony_ci "Set HW_VAR_AMPDU_MIN_SPACE: %#x\n", 16788c2ecf20Sopenharmony_ci mac->min_space_cfg); 16798c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 16808c2ecf20Sopenharmony_ci mac->min_space_cfg); 16818c2ecf20Sopenharmony_ci } 16828c2ecf20Sopenharmony_ci break; 16838c2ecf20Sopenharmony_ci } 16848c2ecf20Sopenharmony_ci case HW_VAR_SHORTGI_DENSITY:{ 16858c2ecf20Sopenharmony_ci u8 density_to_set; 16868c2ecf20Sopenharmony_ci 16878c2ecf20Sopenharmony_ci density_to_set = *val; 16888c2ecf20Sopenharmony_ci density_to_set &= 0x1f; 16898c2ecf20Sopenharmony_ci mac->min_space_cfg &= 0x07; 16908c2ecf20Sopenharmony_ci mac->min_space_cfg |= (density_to_set << 3); 16918c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 16928c2ecf20Sopenharmony_ci "Set HW_VAR_SHORTGI_DENSITY: %#x\n", 16938c2ecf20Sopenharmony_ci mac->min_space_cfg); 16948c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_AMPDU_MIN_SPACE, 16958c2ecf20Sopenharmony_ci mac->min_space_cfg); 16968c2ecf20Sopenharmony_ci break; 16978c2ecf20Sopenharmony_ci } 16988c2ecf20Sopenharmony_ci case HW_VAR_AMPDU_FACTOR:{ 16998c2ecf20Sopenharmony_ci u8 regtoset_normal[4] = {0x41, 0xa8, 0x72, 0xb9}; 17008c2ecf20Sopenharmony_ci u8 factor_toset; 17018c2ecf20Sopenharmony_ci u8 *p_regtoset = NULL; 17028c2ecf20Sopenharmony_ci u8 index = 0; 17038c2ecf20Sopenharmony_ci 17048c2ecf20Sopenharmony_ci p_regtoset = regtoset_normal; 17058c2ecf20Sopenharmony_ci factor_toset = *val; 17068c2ecf20Sopenharmony_ci if (factor_toset <= 3) { 17078c2ecf20Sopenharmony_ci factor_toset = (1 << (factor_toset + 2)); 17088c2ecf20Sopenharmony_ci if (factor_toset > 0xf) 17098c2ecf20Sopenharmony_ci factor_toset = 0xf; 17108c2ecf20Sopenharmony_ci for (index = 0; index < 4; index++) { 17118c2ecf20Sopenharmony_ci if ((p_regtoset[index] & 0xf0) > 17128c2ecf20Sopenharmony_ci (factor_toset << 4)) 17138c2ecf20Sopenharmony_ci p_regtoset[index] = 17148c2ecf20Sopenharmony_ci (p_regtoset[index] & 0x0f) 17158c2ecf20Sopenharmony_ci | (factor_toset << 4); 17168c2ecf20Sopenharmony_ci if ((p_regtoset[index] & 0x0f) > 17178c2ecf20Sopenharmony_ci factor_toset) 17188c2ecf20Sopenharmony_ci p_regtoset[index] = 17198c2ecf20Sopenharmony_ci (p_regtoset[index] & 0xf0) 17208c2ecf20Sopenharmony_ci | (factor_toset); 17218c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 17228c2ecf20Sopenharmony_ci (REG_AGGLEN_LMT + index), 17238c2ecf20Sopenharmony_ci p_regtoset[index]); 17248c2ecf20Sopenharmony_ci } 17258c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 17268c2ecf20Sopenharmony_ci "Set HW_VAR_AMPDU_FACTOR: %#x\n", 17278c2ecf20Sopenharmony_ci factor_toset); 17288c2ecf20Sopenharmony_ci } 17298c2ecf20Sopenharmony_ci break; 17308c2ecf20Sopenharmony_ci } 17318c2ecf20Sopenharmony_ci case HW_VAR_AC_PARAM:{ 17328c2ecf20Sopenharmony_ci u8 e_aci = *val; 17338c2ecf20Sopenharmony_ci u32 u4b_ac_param; 17348c2ecf20Sopenharmony_ci u16 cw_min = le16_to_cpu(mac->ac[e_aci].cw_min); 17358c2ecf20Sopenharmony_ci u16 cw_max = le16_to_cpu(mac->ac[e_aci].cw_max); 17368c2ecf20Sopenharmony_ci u16 tx_op = le16_to_cpu(mac->ac[e_aci].tx_op); 17378c2ecf20Sopenharmony_ci 17388c2ecf20Sopenharmony_ci u4b_ac_param = (u32) mac->ac[e_aci].aifs; 17398c2ecf20Sopenharmony_ci u4b_ac_param |= (u32) ((cw_min & 0xF) << 17408c2ecf20Sopenharmony_ci AC_PARAM_ECW_MIN_OFFSET); 17418c2ecf20Sopenharmony_ci u4b_ac_param |= (u32) ((cw_max & 0xF) << 17428c2ecf20Sopenharmony_ci AC_PARAM_ECW_MAX_OFFSET); 17438c2ecf20Sopenharmony_ci u4b_ac_param |= (u32) tx_op << AC_PARAM_TXOP_OFFSET; 17448c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_LOUD, 17458c2ecf20Sopenharmony_ci "queue:%x, ac_param:%x\n", 17468c2ecf20Sopenharmony_ci e_aci, u4b_ac_param); 17478c2ecf20Sopenharmony_ci switch (e_aci) { 17488c2ecf20Sopenharmony_ci case AC1_BK: 17498c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_BK_PARAM, 17508c2ecf20Sopenharmony_ci u4b_ac_param); 17518c2ecf20Sopenharmony_ci break; 17528c2ecf20Sopenharmony_ci case AC0_BE: 17538c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, 17548c2ecf20Sopenharmony_ci u4b_ac_param); 17558c2ecf20Sopenharmony_ci break; 17568c2ecf20Sopenharmony_ci case AC2_VI: 17578c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_VI_PARAM, 17588c2ecf20Sopenharmony_ci u4b_ac_param); 17598c2ecf20Sopenharmony_ci break; 17608c2ecf20Sopenharmony_ci case AC3_VO: 17618c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_EDCA_VO_PARAM, 17628c2ecf20Sopenharmony_ci u4b_ac_param); 17638c2ecf20Sopenharmony_ci break; 17648c2ecf20Sopenharmony_ci default: 17658c2ecf20Sopenharmony_ci WARN_ONCE(true, "rtl8192cu: invalid aci: %d !\n", 17668c2ecf20Sopenharmony_ci e_aci); 17678c2ecf20Sopenharmony_ci break; 17688c2ecf20Sopenharmony_ci } 17698c2ecf20Sopenharmony_ci break; 17708c2ecf20Sopenharmony_ci } 17718c2ecf20Sopenharmony_ci case HW_VAR_RCR:{ 17728c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_RCR, ((u32 *) (val))[0]); 17738c2ecf20Sopenharmony_ci mac->rx_conf = ((u32 *) (val))[0]; 17748c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RECV, DBG_DMESG, 17758c2ecf20Sopenharmony_ci "### Set RCR(0x%08x) ###\n", mac->rx_conf); 17768c2ecf20Sopenharmony_ci break; 17778c2ecf20Sopenharmony_ci } 17788c2ecf20Sopenharmony_ci case HW_VAR_RETRY_LIMIT:{ 17798c2ecf20Sopenharmony_ci u8 retry_limit = val[0]; 17808c2ecf20Sopenharmony_ci 17818c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_RL, 17828c2ecf20Sopenharmony_ci retry_limit << RETRY_LIMIT_SHORT_SHIFT | 17838c2ecf20Sopenharmony_ci retry_limit << RETRY_LIMIT_LONG_SHIFT); 17848c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_MLME, DBG_DMESG, 17858c2ecf20Sopenharmony_ci "Set HW_VAR_RETRY_LIMIT(0x%08x)\n", 17868c2ecf20Sopenharmony_ci retry_limit); 17878c2ecf20Sopenharmony_ci break; 17888c2ecf20Sopenharmony_ci } 17898c2ecf20Sopenharmony_ci case HW_VAR_DUAL_TSF_RST: 17908c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_DUAL_TSF_RST, (BIT(0) | BIT(1))); 17918c2ecf20Sopenharmony_ci break; 17928c2ecf20Sopenharmony_ci case HW_VAR_EFUSE_BYTES: 17938c2ecf20Sopenharmony_ci rtlefuse->efuse_usedbytes = *((u16 *) val); 17948c2ecf20Sopenharmony_ci break; 17958c2ecf20Sopenharmony_ci case HW_VAR_EFUSE_USAGE: 17968c2ecf20Sopenharmony_ci rtlefuse->efuse_usedpercentage = *val; 17978c2ecf20Sopenharmony_ci break; 17988c2ecf20Sopenharmony_ci case HW_VAR_IO_CMD: 17998c2ecf20Sopenharmony_ci rtl92c_phy_set_io_cmd(hw, (*(enum io_type *)val)); 18008c2ecf20Sopenharmony_ci break; 18018c2ecf20Sopenharmony_ci case HW_VAR_WPA_CONFIG: 18028c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_SECCFG, *val); 18038c2ecf20Sopenharmony_ci break; 18048c2ecf20Sopenharmony_ci case HW_VAR_SET_RPWM:{ 18058c2ecf20Sopenharmony_ci u8 rpwm_val = rtl_read_byte(rtlpriv, REG_USB_HRPWM); 18068c2ecf20Sopenharmony_ci 18078c2ecf20Sopenharmony_ci if (rpwm_val & BIT(7)) 18088c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_USB_HRPWM, *val); 18098c2ecf20Sopenharmony_ci else 18108c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_USB_HRPWM, 18118c2ecf20Sopenharmony_ci *val | BIT(7)); 18128c2ecf20Sopenharmony_ci break; 18138c2ecf20Sopenharmony_ci } 18148c2ecf20Sopenharmony_ci case HW_VAR_H2C_FW_PWRMODE:{ 18158c2ecf20Sopenharmony_ci u8 psmode = *val; 18168c2ecf20Sopenharmony_ci 18178c2ecf20Sopenharmony_ci if ((psmode != FW_PS_ACTIVE_MODE) && 18188c2ecf20Sopenharmony_ci (!IS_92C_SERIAL(rtlhal->version))) 18198c2ecf20Sopenharmony_ci rtl92c_dm_rf_saving(hw, true); 18208c2ecf20Sopenharmony_ci rtl92c_set_fw_pwrmode_cmd(hw, (*val)); 18218c2ecf20Sopenharmony_ci break; 18228c2ecf20Sopenharmony_ci } 18238c2ecf20Sopenharmony_ci case HW_VAR_FW_PSMODE_STATUS: 18248c2ecf20Sopenharmony_ci ppsc->fw_current_inpsmode = *((bool *) val); 18258c2ecf20Sopenharmony_ci break; 18268c2ecf20Sopenharmony_ci case HW_VAR_H2C_FW_JOINBSSRPT:{ 18278c2ecf20Sopenharmony_ci u8 mstatus = *val; 18288c2ecf20Sopenharmony_ci u8 tmp_reg422; 18298c2ecf20Sopenharmony_ci bool recover = false; 18308c2ecf20Sopenharmony_ci 18318c2ecf20Sopenharmony_ci if (mstatus == RT_MEDIA_CONNECT) { 18328c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 18338c2ecf20Sopenharmony_ci HW_VAR_AID, NULL); 18348c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, 0x03); 18358c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); 18368c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(4), 0); 18378c2ecf20Sopenharmony_ci tmp_reg422 = rtl_read_byte(rtlpriv, 18388c2ecf20Sopenharmony_ci REG_FWHW_TXQ_CTRL + 2); 18398c2ecf20Sopenharmony_ci if (tmp_reg422 & BIT(6)) 18408c2ecf20Sopenharmony_ci recover = true; 18418c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_FWHW_TXQ_CTRL + 2, 18428c2ecf20Sopenharmony_ci tmp_reg422 & (~BIT(6))); 18438c2ecf20Sopenharmony_ci rtl92c_set_fw_rsvdpagepkt(hw, 18448c2ecf20Sopenharmony_ci &usb_cmd_send_packet); 18458c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); 18468c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(4)); 18478c2ecf20Sopenharmony_ci if (recover) 18488c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 18498c2ecf20Sopenharmony_ci REG_FWHW_TXQ_CTRL + 2, 18508c2ecf20Sopenharmony_ci tmp_reg422 | BIT(6)); 18518c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_CR + 1, 0x02); 18528c2ecf20Sopenharmony_ci } 18538c2ecf20Sopenharmony_ci rtl92c_set_fw_joinbss_report_cmd(hw, (*val)); 18548c2ecf20Sopenharmony_ci break; 18558c2ecf20Sopenharmony_ci } 18568c2ecf20Sopenharmony_ci case HW_VAR_AID:{ 18578c2ecf20Sopenharmony_ci u16 u2btmp; 18588c2ecf20Sopenharmony_ci 18598c2ecf20Sopenharmony_ci u2btmp = rtl_read_word(rtlpriv, REG_BCN_PSR_RPT); 18608c2ecf20Sopenharmony_ci u2btmp &= 0xC000; 18618c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_BCN_PSR_RPT, 18628c2ecf20Sopenharmony_ci (u2btmp | mac->assoc_id)); 18638c2ecf20Sopenharmony_ci break; 18648c2ecf20Sopenharmony_ci } 18658c2ecf20Sopenharmony_ci case HW_VAR_CORRECT_TSF:{ 18668c2ecf20Sopenharmony_ci u8 btype_ibss = val[0]; 18678c2ecf20Sopenharmony_ci 18688c2ecf20Sopenharmony_ci if (btype_ibss) 18698c2ecf20Sopenharmony_ci _rtl92cu_stop_tx_beacon(hw); 18708c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, 0, BIT(3)); 18718c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTR, (u32)(mac->tsf & 18728c2ecf20Sopenharmony_ci 0xffffffff)); 18738c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_TSFTR + 4, 18748c2ecf20Sopenharmony_ci (u32)((mac->tsf >> 32) & 0xffffffff)); 18758c2ecf20Sopenharmony_ci _rtl92cu_set_bcn_ctrl_reg(hw, BIT(3), 0); 18768c2ecf20Sopenharmony_ci if (btype_ibss) 18778c2ecf20Sopenharmony_ci _rtl92cu_resume_tx_beacon(hw); 18788c2ecf20Sopenharmony_ci break; 18798c2ecf20Sopenharmony_ci } 18808c2ecf20Sopenharmony_ci case HW_VAR_MGT_FILTER: 18818c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_RXFLTMAP0, *(u16 *)val); 18828c2ecf20Sopenharmony_ci mac->rx_mgt_filter = *(u16 *)val; 18838c2ecf20Sopenharmony_ci break; 18848c2ecf20Sopenharmony_ci case HW_VAR_CTRL_FILTER: 18858c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_RXFLTMAP1, *(u16 *)val); 18868c2ecf20Sopenharmony_ci mac->rx_ctrl_filter = *(u16 *)val; 18878c2ecf20Sopenharmony_ci break; 18888c2ecf20Sopenharmony_ci case HW_VAR_DATA_FILTER: 18898c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_RXFLTMAP2, *(u16 *)val); 18908c2ecf20Sopenharmony_ci mac->rx_data_filter = *(u16 *)val; 18918c2ecf20Sopenharmony_ci break; 18928c2ecf20Sopenharmony_ci case HW_VAR_KEEP_ALIVE:{ 18938c2ecf20Sopenharmony_ci u8 array[2]; 18948c2ecf20Sopenharmony_ci 18958c2ecf20Sopenharmony_ci array[0] = 0xff; 18968c2ecf20Sopenharmony_ci array[1] = *((u8 *)val); 18978c2ecf20Sopenharmony_ci rtl92c_fill_h2c_cmd(hw, H2C_92C_KEEP_ALIVE_CTRL, 2, 18988c2ecf20Sopenharmony_ci array); 18998c2ecf20Sopenharmony_ci break; 19008c2ecf20Sopenharmony_ci } 19018c2ecf20Sopenharmony_ci default: 19028c2ecf20Sopenharmony_ci pr_err("switch case %#x not processed\n", variable); 19038c2ecf20Sopenharmony_ci break; 19048c2ecf20Sopenharmony_ci } 19058c2ecf20Sopenharmony_ci} 19068c2ecf20Sopenharmony_ci 19078c2ecf20Sopenharmony_cistatic void rtl92cu_update_hal_rate_table(struct ieee80211_hw *hw, 19088c2ecf20Sopenharmony_ci struct ieee80211_sta *sta) 19098c2ecf20Sopenharmony_ci{ 19108c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 19118c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 19128c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 19138c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 19148c2ecf20Sopenharmony_ci u32 ratr_value; 19158c2ecf20Sopenharmony_ci u8 ratr_index = 0; 19168c2ecf20Sopenharmony_ci u8 nmode = mac->ht_enable; 19178c2ecf20Sopenharmony_ci u8 mimo_ps = IEEE80211_SMPS_OFF; 19188c2ecf20Sopenharmony_ci u16 shortgi_rate; 19198c2ecf20Sopenharmony_ci u32 tmp_ratr_value; 19208c2ecf20Sopenharmony_ci u8 curtxbw_40mhz = mac->bw_40; 19218c2ecf20Sopenharmony_ci u8 curshortgi_40mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 19228c2ecf20Sopenharmony_ci 1 : 0; 19238c2ecf20Sopenharmony_ci u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 19248c2ecf20Sopenharmony_ci 1 : 0; 19258c2ecf20Sopenharmony_ci enum wireless_mode wirelessmode = mac->mode; 19268c2ecf20Sopenharmony_ci 19278c2ecf20Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_5G) 19288c2ecf20Sopenharmony_ci ratr_value = sta->supp_rates[1] << 4; 19298c2ecf20Sopenharmony_ci else 19308c2ecf20Sopenharmony_ci ratr_value = sta->supp_rates[0]; 19318c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) 19328c2ecf20Sopenharmony_ci ratr_value = 0xfff; 19338c2ecf20Sopenharmony_ci 19348c2ecf20Sopenharmony_ci ratr_value |= (sta->ht_cap.mcs.rx_mask[1] << 20 | 19358c2ecf20Sopenharmony_ci sta->ht_cap.mcs.rx_mask[0] << 12); 19368c2ecf20Sopenharmony_ci switch (wirelessmode) { 19378c2ecf20Sopenharmony_ci case WIRELESS_MODE_B: 19388c2ecf20Sopenharmony_ci if (ratr_value & 0x0000000c) 19398c2ecf20Sopenharmony_ci ratr_value &= 0x0000000d; 19408c2ecf20Sopenharmony_ci else 19418c2ecf20Sopenharmony_ci ratr_value &= 0x0000000f; 19428c2ecf20Sopenharmony_ci break; 19438c2ecf20Sopenharmony_ci case WIRELESS_MODE_G: 19448c2ecf20Sopenharmony_ci ratr_value &= 0x00000FF5; 19458c2ecf20Sopenharmony_ci break; 19468c2ecf20Sopenharmony_ci case WIRELESS_MODE_N_24G: 19478c2ecf20Sopenharmony_ci case WIRELESS_MODE_N_5G: 19488c2ecf20Sopenharmony_ci nmode = 1; 19498c2ecf20Sopenharmony_ci if (mimo_ps == IEEE80211_SMPS_STATIC) { 19508c2ecf20Sopenharmony_ci ratr_value &= 0x0007F005; 19518c2ecf20Sopenharmony_ci } else { 19528c2ecf20Sopenharmony_ci u32 ratr_mask; 19538c2ecf20Sopenharmony_ci 19548c2ecf20Sopenharmony_ci if (get_rf_type(rtlphy) == RF_1T2R || 19558c2ecf20Sopenharmony_ci get_rf_type(rtlphy) == RF_1T1R) 19568c2ecf20Sopenharmony_ci ratr_mask = 0x000ff005; 19578c2ecf20Sopenharmony_ci else 19588c2ecf20Sopenharmony_ci ratr_mask = 0x0f0ff005; 19598c2ecf20Sopenharmony_ci 19608c2ecf20Sopenharmony_ci ratr_value &= ratr_mask; 19618c2ecf20Sopenharmony_ci } 19628c2ecf20Sopenharmony_ci break; 19638c2ecf20Sopenharmony_ci default: 19648c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) 19658c2ecf20Sopenharmony_ci ratr_value &= 0x000ff0ff; 19668c2ecf20Sopenharmony_ci else 19678c2ecf20Sopenharmony_ci ratr_value &= 0x0f0ff0ff; 19688c2ecf20Sopenharmony_ci 19698c2ecf20Sopenharmony_ci break; 19708c2ecf20Sopenharmony_ci } 19718c2ecf20Sopenharmony_ci 19728c2ecf20Sopenharmony_ci ratr_value &= 0x0FFFFFFF; 19738c2ecf20Sopenharmony_ci 19748c2ecf20Sopenharmony_ci if (nmode && ((curtxbw_40mhz && 19758c2ecf20Sopenharmony_ci curshortgi_40mhz) || (!curtxbw_40mhz && 19768c2ecf20Sopenharmony_ci curshortgi_20mhz))) { 19778c2ecf20Sopenharmony_ci ratr_value |= 0x10000000; 19788c2ecf20Sopenharmony_ci tmp_ratr_value = (ratr_value >> 12); 19798c2ecf20Sopenharmony_ci 19808c2ecf20Sopenharmony_ci for (shortgi_rate = 15; shortgi_rate > 0; shortgi_rate--) { 19818c2ecf20Sopenharmony_ci if ((1 << shortgi_rate) & tmp_ratr_value) 19828c2ecf20Sopenharmony_ci break; 19838c2ecf20Sopenharmony_ci } 19848c2ecf20Sopenharmony_ci 19858c2ecf20Sopenharmony_ci shortgi_rate = (shortgi_rate << 12) | (shortgi_rate << 8) | 19868c2ecf20Sopenharmony_ci (shortgi_rate << 4) | (shortgi_rate); 19878c2ecf20Sopenharmony_ci } 19888c2ecf20Sopenharmony_ci 19898c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, REG_ARFR0 + ratr_index * 4, ratr_value); 19908c2ecf20Sopenharmony_ci 19918c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, "%x\n", 19928c2ecf20Sopenharmony_ci rtl_read_dword(rtlpriv, REG_ARFR0)); 19938c2ecf20Sopenharmony_ci} 19948c2ecf20Sopenharmony_ci 19958c2ecf20Sopenharmony_cistatic void rtl92cu_update_hal_rate_mask(struct ieee80211_hw *hw, 19968c2ecf20Sopenharmony_ci struct ieee80211_sta *sta, 19978c2ecf20Sopenharmony_ci u8 rssi_level, bool update_bw) 19988c2ecf20Sopenharmony_ci{ 19998c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 20008c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 20018c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 20028c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 20038c2ecf20Sopenharmony_ci struct rtl_sta_info *sta_entry = NULL; 20048c2ecf20Sopenharmony_ci u32 ratr_bitmap; 20058c2ecf20Sopenharmony_ci u8 ratr_index; 20068c2ecf20Sopenharmony_ci u8 curtxbw_40mhz = (sta->bandwidth >= IEEE80211_STA_RX_BW_40) ? 1 : 0; 20078c2ecf20Sopenharmony_ci u8 curshortgi_40mhz = curtxbw_40mhz && 20088c2ecf20Sopenharmony_ci (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40) ? 20098c2ecf20Sopenharmony_ci 1 : 0; 20108c2ecf20Sopenharmony_ci u8 curshortgi_20mhz = (sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20) ? 20118c2ecf20Sopenharmony_ci 1 : 0; 20128c2ecf20Sopenharmony_ci enum wireless_mode wirelessmode = 0; 20138c2ecf20Sopenharmony_ci bool shortgi = false; 20148c2ecf20Sopenharmony_ci u8 rate_mask[5]; 20158c2ecf20Sopenharmony_ci u8 macid = 0; 20168c2ecf20Sopenharmony_ci u8 mimo_ps = IEEE80211_SMPS_OFF; 20178c2ecf20Sopenharmony_ci 20188c2ecf20Sopenharmony_ci sta_entry = (struct rtl_sta_info *) sta->drv_priv; 20198c2ecf20Sopenharmony_ci wirelessmode = sta_entry->wireless_mode; 20208c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_STATION || 20218c2ecf20Sopenharmony_ci mac->opmode == NL80211_IFTYPE_MESH_POINT) 20228c2ecf20Sopenharmony_ci curtxbw_40mhz = mac->bw_40; 20238c2ecf20Sopenharmony_ci else if (mac->opmode == NL80211_IFTYPE_AP || 20248c2ecf20Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC) 20258c2ecf20Sopenharmony_ci macid = sta->aid + 1; 20268c2ecf20Sopenharmony_ci 20278c2ecf20Sopenharmony_ci if (rtlhal->current_bandtype == BAND_ON_5G) 20288c2ecf20Sopenharmony_ci ratr_bitmap = sta->supp_rates[1] << 4; 20298c2ecf20Sopenharmony_ci else 20308c2ecf20Sopenharmony_ci ratr_bitmap = sta->supp_rates[0]; 20318c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) 20328c2ecf20Sopenharmony_ci ratr_bitmap = 0xfff; 20338c2ecf20Sopenharmony_ci ratr_bitmap |= (sta->ht_cap.mcs.rx_mask[1] << 20 | 20348c2ecf20Sopenharmony_ci sta->ht_cap.mcs.rx_mask[0] << 12); 20358c2ecf20Sopenharmony_ci switch (wirelessmode) { 20368c2ecf20Sopenharmony_ci case WIRELESS_MODE_B: 20378c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_B; 20388c2ecf20Sopenharmony_ci if (ratr_bitmap & 0x0000000c) 20398c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0000000d; 20408c2ecf20Sopenharmony_ci else 20418c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0000000f; 20428c2ecf20Sopenharmony_ci break; 20438c2ecf20Sopenharmony_ci case WIRELESS_MODE_G: 20448c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_GB; 20458c2ecf20Sopenharmony_ci 20468c2ecf20Sopenharmony_ci if (rssi_level == 1) 20478c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00000f00; 20488c2ecf20Sopenharmony_ci else if (rssi_level == 2) 20498c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00000ff0; 20508c2ecf20Sopenharmony_ci else 20518c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00000ff5; 20528c2ecf20Sopenharmony_ci break; 20538c2ecf20Sopenharmony_ci case WIRELESS_MODE_A: 20548c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_A; 20558c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00000ff0; 20568c2ecf20Sopenharmony_ci break; 20578c2ecf20Sopenharmony_ci case WIRELESS_MODE_N_24G: 20588c2ecf20Sopenharmony_ci case WIRELESS_MODE_N_5G: 20598c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 20608c2ecf20Sopenharmony_ci 20618c2ecf20Sopenharmony_ci if (mimo_ps == IEEE80211_SMPS_STATIC) { 20628c2ecf20Sopenharmony_ci if (rssi_level == 1) 20638c2ecf20Sopenharmony_ci ratr_bitmap &= 0x00070000; 20648c2ecf20Sopenharmony_ci else if (rssi_level == 2) 20658c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0007f000; 20668c2ecf20Sopenharmony_ci else 20678c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0007f005; 20688c2ecf20Sopenharmony_ci } else { 20698c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R || 20708c2ecf20Sopenharmony_ci rtlphy->rf_type == RF_1T1R) { 20718c2ecf20Sopenharmony_ci if (curtxbw_40mhz) { 20728c2ecf20Sopenharmony_ci if (rssi_level == 1) 20738c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000f0000; 20748c2ecf20Sopenharmony_ci else if (rssi_level == 2) 20758c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff000; 20768c2ecf20Sopenharmony_ci else 20778c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff015; 20788c2ecf20Sopenharmony_ci } else { 20798c2ecf20Sopenharmony_ci if (rssi_level == 1) 20808c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000f0000; 20818c2ecf20Sopenharmony_ci else if (rssi_level == 2) 20828c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff000; 20838c2ecf20Sopenharmony_ci else 20848c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff005; 20858c2ecf20Sopenharmony_ci } 20868c2ecf20Sopenharmony_ci } else { 20878c2ecf20Sopenharmony_ci if (curtxbw_40mhz) { 20888c2ecf20Sopenharmony_ci if (rssi_level == 1) 20898c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0f0000; 20908c2ecf20Sopenharmony_ci else if (rssi_level == 2) 20918c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff000; 20928c2ecf20Sopenharmony_ci else 20938c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff015; 20948c2ecf20Sopenharmony_ci } else { 20958c2ecf20Sopenharmony_ci if (rssi_level == 1) 20968c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0f0000; 20978c2ecf20Sopenharmony_ci else if (rssi_level == 2) 20988c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff000; 20998c2ecf20Sopenharmony_ci else 21008c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff005; 21018c2ecf20Sopenharmony_ci } 21028c2ecf20Sopenharmony_ci } 21038c2ecf20Sopenharmony_ci } 21048c2ecf20Sopenharmony_ci 21058c2ecf20Sopenharmony_ci if ((curtxbw_40mhz && curshortgi_40mhz) || 21068c2ecf20Sopenharmony_ci (!curtxbw_40mhz && curshortgi_20mhz)) { 21078c2ecf20Sopenharmony_ci 21088c2ecf20Sopenharmony_ci if (macid == 0) 21098c2ecf20Sopenharmony_ci shortgi = true; 21108c2ecf20Sopenharmony_ci else if (macid == 1) 21118c2ecf20Sopenharmony_ci shortgi = false; 21128c2ecf20Sopenharmony_ci } 21138c2ecf20Sopenharmony_ci break; 21148c2ecf20Sopenharmony_ci default: 21158c2ecf20Sopenharmony_ci ratr_index = RATR_INX_WIRELESS_NGB; 21168c2ecf20Sopenharmony_ci 21178c2ecf20Sopenharmony_ci if (rtlphy->rf_type == RF_1T2R) 21188c2ecf20Sopenharmony_ci ratr_bitmap &= 0x000ff0ff; 21198c2ecf20Sopenharmony_ci else 21208c2ecf20Sopenharmony_ci ratr_bitmap &= 0x0f0ff0ff; 21218c2ecf20Sopenharmony_ci break; 21228c2ecf20Sopenharmony_ci } 21238c2ecf20Sopenharmony_ci sta_entry->ratr_index = ratr_index; 21248c2ecf20Sopenharmony_ci 21258c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, 21268c2ecf20Sopenharmony_ci "ratr_bitmap :%x\n", ratr_bitmap); 21278c2ecf20Sopenharmony_ci *(u32 *)&rate_mask = (ratr_bitmap & 0x0fffffff) | 21288c2ecf20Sopenharmony_ci (ratr_index << 28); 21298c2ecf20Sopenharmony_ci rate_mask[4] = macid | (shortgi ? 0x20 : 0x00) | 0x80; 21308c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, 21318c2ecf20Sopenharmony_ci "Rate_index:%x, ratr_val:%x, %5phC\n", 21328c2ecf20Sopenharmony_ci ratr_index, ratr_bitmap, rate_mask); 21338c2ecf20Sopenharmony_ci memcpy(rtlpriv->rate_mask, rate_mask, 5); 21348c2ecf20Sopenharmony_ci /* rtl92c_fill_h2c_cmd() does USB I/O and will result in a 21358c2ecf20Sopenharmony_ci * "scheduled while atomic" if called directly */ 21368c2ecf20Sopenharmony_ci schedule_work(&rtlpriv->works.fill_h2c_cmd); 21378c2ecf20Sopenharmony_ci 21388c2ecf20Sopenharmony_ci if (macid != 0) 21398c2ecf20Sopenharmony_ci sta_entry->ratr_index = ratr_index; 21408c2ecf20Sopenharmony_ci} 21418c2ecf20Sopenharmony_ci 21428c2ecf20Sopenharmony_civoid rtl92cu_update_hal_rate_tbl(struct ieee80211_hw *hw, 21438c2ecf20Sopenharmony_ci struct ieee80211_sta *sta, 21448c2ecf20Sopenharmony_ci u8 rssi_level, bool update_bw) 21458c2ecf20Sopenharmony_ci{ 21468c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 21478c2ecf20Sopenharmony_ci 21488c2ecf20Sopenharmony_ci if (rtlpriv->dm.useramask) 21498c2ecf20Sopenharmony_ci rtl92cu_update_hal_rate_mask(hw, sta, rssi_level, update_bw); 21508c2ecf20Sopenharmony_ci else 21518c2ecf20Sopenharmony_ci rtl92cu_update_hal_rate_table(hw, sta); 21528c2ecf20Sopenharmony_ci} 21538c2ecf20Sopenharmony_ci 21548c2ecf20Sopenharmony_civoid rtl92cu_update_channel_access_setting(struct ieee80211_hw *hw) 21558c2ecf20Sopenharmony_ci{ 21568c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 21578c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 21588c2ecf20Sopenharmony_ci u16 sifs_timer; 21598c2ecf20Sopenharmony_ci 21608c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SLOT_TIME, 21618c2ecf20Sopenharmony_ci &mac->slot_time); 21628c2ecf20Sopenharmony_ci if (!mac->ht_enable) 21638c2ecf20Sopenharmony_ci sifs_timer = 0x0a0a; 21648c2ecf20Sopenharmony_ci else 21658c2ecf20Sopenharmony_ci sifs_timer = 0x0e0e; 21668c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_SIFS, (u8 *)&sifs_timer); 21678c2ecf20Sopenharmony_ci} 21688c2ecf20Sopenharmony_ci 21698c2ecf20Sopenharmony_cibool rtl92cu_gpio_radio_on_off_checking(struct ieee80211_hw *hw, u8 * valid) 21708c2ecf20Sopenharmony_ci{ 21718c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 21728c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 21738c2ecf20Sopenharmony_ci enum rf_pwrstate e_rfpowerstate_toset, cur_rfstate; 21748c2ecf20Sopenharmony_ci u8 u1tmp = 0; 21758c2ecf20Sopenharmony_ci bool actuallyset = false; 21768c2ecf20Sopenharmony_ci unsigned long flag = 0; 21778c2ecf20Sopenharmony_ci /* to do - usb autosuspend */ 21788c2ecf20Sopenharmony_ci u8 usb_autosuspend = 0; 21798c2ecf20Sopenharmony_ci 21808c2ecf20Sopenharmony_ci if (ppsc->swrf_processing) 21818c2ecf20Sopenharmony_ci return false; 21828c2ecf20Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 21838c2ecf20Sopenharmony_ci if (ppsc->rfchange_inprogress) { 21848c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 21858c2ecf20Sopenharmony_ci return false; 21868c2ecf20Sopenharmony_ci } else { 21878c2ecf20Sopenharmony_ci ppsc->rfchange_inprogress = true; 21888c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 21898c2ecf20Sopenharmony_ci } 21908c2ecf20Sopenharmony_ci cur_rfstate = ppsc->rfpwr_state; 21918c2ecf20Sopenharmony_ci if (usb_autosuspend) { 21928c2ecf20Sopenharmony_ci /* to do................... */ 21938c2ecf20Sopenharmony_ci } else { 21948c2ecf20Sopenharmony_ci if (ppsc->pwrdown_mode) { 21958c2ecf20Sopenharmony_ci u1tmp = rtl_read_byte(rtlpriv, REG_HSISR); 21968c2ecf20Sopenharmony_ci e_rfpowerstate_toset = (u1tmp & BIT(7)) ? 21978c2ecf20Sopenharmony_ci ERFOFF : ERFON; 21988c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 21998c2ecf20Sopenharmony_ci "pwrdown, 0x5c(BIT7)=%02x\n", u1tmp); 22008c2ecf20Sopenharmony_ci } else { 22018c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_MAC_PINMUX_CFG, 22028c2ecf20Sopenharmony_ci rtl_read_byte(rtlpriv, 22038c2ecf20Sopenharmony_ci REG_MAC_PINMUX_CFG) & ~(BIT(3))); 22048c2ecf20Sopenharmony_ci u1tmp = rtl_read_byte(rtlpriv, REG_GPIO_IO_SEL); 22058c2ecf20Sopenharmony_ci e_rfpowerstate_toset = (u1tmp & BIT(3)) ? 22068c2ecf20Sopenharmony_ci ERFON : ERFOFF; 22078c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_DMESG, 22088c2ecf20Sopenharmony_ci "GPIO_IN=%02x\n", u1tmp); 22098c2ecf20Sopenharmony_ci } 22108c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, "N-SS RF =%x\n", 22118c2ecf20Sopenharmony_ci e_rfpowerstate_toset); 22128c2ecf20Sopenharmony_ci } 22138c2ecf20Sopenharmony_ci if ((ppsc->hwradiooff) && (e_rfpowerstate_toset == ERFON)) { 22148c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 22158c2ecf20Sopenharmony_ci "GPIOChangeRF - HW Radio ON, RF ON\n"); 22168c2ecf20Sopenharmony_ci ppsc->hwradiooff = false; 22178c2ecf20Sopenharmony_ci actuallyset = true; 22188c2ecf20Sopenharmony_ci } else if ((!ppsc->hwradiooff) && (e_rfpowerstate_toset == 22198c2ecf20Sopenharmony_ci ERFOFF)) { 22208c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 22218c2ecf20Sopenharmony_ci "GPIOChangeRF - HW Radio OFF\n"); 22228c2ecf20Sopenharmony_ci ppsc->hwradiooff = true; 22238c2ecf20Sopenharmony_ci actuallyset = true; 22248c2ecf20Sopenharmony_ci } else { 22258c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 22268c2ecf20Sopenharmony_ci "pHalData->bHwRadioOff and eRfPowerStateToSet do not match: pHalData->bHwRadioOff %x, eRfPowerStateToSet %x\n", 22278c2ecf20Sopenharmony_ci ppsc->hwradiooff, e_rfpowerstate_toset); 22288c2ecf20Sopenharmony_ci } 22298c2ecf20Sopenharmony_ci if (actuallyset) { 22308c2ecf20Sopenharmony_ci ppsc->hwradiooff = true; 22318c2ecf20Sopenharmony_ci if (e_rfpowerstate_toset == ERFON) { 22328c2ecf20Sopenharmony_ci if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) && 22338c2ecf20Sopenharmony_ci RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM)) 22348c2ecf20Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); 22358c2ecf20Sopenharmony_ci else if ((ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) 22368c2ecf20Sopenharmony_ci && RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3)) 22378c2ecf20Sopenharmony_ci RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); 22388c2ecf20Sopenharmony_ci } 22398c2ecf20Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 22408c2ecf20Sopenharmony_ci ppsc->rfchange_inprogress = false; 22418c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 22428c2ecf20Sopenharmony_ci /* For power down module, we need to enable register block 22438c2ecf20Sopenharmony_ci * contrl reg at 0x1c. Then enable power down control bit 22448c2ecf20Sopenharmony_ci * of register 0x04 BIT4 and BIT15 as 1. 22458c2ecf20Sopenharmony_ci */ 22468c2ecf20Sopenharmony_ci if (ppsc->pwrdown_mode && e_rfpowerstate_toset == ERFOFF) { 22478c2ecf20Sopenharmony_ci /* Enable register area 0x0-0xc. */ 22488c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, REG_RSV_CTRL, 0x0); 22498c2ecf20Sopenharmony_ci rtl_write_word(rtlpriv, REG_APS_FSMCO, 0x8812); 22508c2ecf20Sopenharmony_ci } 22518c2ecf20Sopenharmony_ci if (e_rfpowerstate_toset == ERFOFF) { 22528c2ecf20Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) 22538c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); 22548c2ecf20Sopenharmony_ci else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) 22558c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); 22568c2ecf20Sopenharmony_ci } 22578c2ecf20Sopenharmony_ci } else if (e_rfpowerstate_toset == ERFOFF || cur_rfstate == ERFOFF) { 22588c2ecf20Sopenharmony_ci /* Enter D3 or ASPM after GPIO had been done. */ 22598c2ecf20Sopenharmony_ci if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_ASPM) 22608c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_ASPM); 22618c2ecf20Sopenharmony_ci else if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_PCI_D3) 22628c2ecf20Sopenharmony_ci RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_PCI_D3); 22638c2ecf20Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 22648c2ecf20Sopenharmony_ci ppsc->rfchange_inprogress = false; 22658c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 22668c2ecf20Sopenharmony_ci } else { 22678c2ecf20Sopenharmony_ci spin_lock_irqsave(&rtlpriv->locks.rf_ps_lock, flag); 22688c2ecf20Sopenharmony_ci ppsc->rfchange_inprogress = false; 22698c2ecf20Sopenharmony_ci spin_unlock_irqrestore(&rtlpriv->locks.rf_ps_lock, flag); 22708c2ecf20Sopenharmony_ci } 22718c2ecf20Sopenharmony_ci *valid = 1; 22728c2ecf20Sopenharmony_ci return !ppsc->hwradiooff; 22738c2ecf20Sopenharmony_ci} 2274