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 "../base.h" 68c2ecf20Sopenharmony_ci#include "../pci.h" 78c2ecf20Sopenharmony_ci#include "../core.h" 88c2ecf20Sopenharmony_ci#include "reg.h" 98c2ecf20Sopenharmony_ci#include "def.h" 108c2ecf20Sopenharmony_ci#include "phy.h" 118c2ecf20Sopenharmony_ci#include "dm.h" 128c2ecf20Sopenharmony_ci#include "../rtl8723com/dm_common.h" 138c2ecf20Sopenharmony_ci#include "fw.h" 148c2ecf20Sopenharmony_ci#include "hal_btc.h" 158c2ecf20Sopenharmony_ci 168c2ecf20Sopenharmony_cistatic u8 rtl8723e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw) 178c2ecf20Sopenharmony_ci{ 188c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 198c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 208c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtlpriv); 218c2ecf20Sopenharmony_ci long rssi_val_min = 0; 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci if (mac->link_state == MAC80211_LINKED && 248c2ecf20Sopenharmony_ci mac->opmode == NL80211_IFTYPE_STATION && 258c2ecf20Sopenharmony_ci rtlpriv->link_info.bcn_rx_inperiod == 0) 268c2ecf20Sopenharmony_ci return 0; 278c2ecf20Sopenharmony_ci 288c2ecf20Sopenharmony_ci if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) && 298c2ecf20Sopenharmony_ci (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) { 308c2ecf20Sopenharmony_ci if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0) 318c2ecf20Sopenharmony_ci rssi_val_min = 328c2ecf20Sopenharmony_ci (rtlpriv->dm.entry_min_undec_sm_pwdb > 338c2ecf20Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb) ? 348c2ecf20Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb : 358c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 368c2ecf20Sopenharmony_ci else 378c2ecf20Sopenharmony_ci rssi_val_min = rtlpriv->dm.undec_sm_pwdb; 388c2ecf20Sopenharmony_ci } else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT || 398c2ecf20Sopenharmony_ci dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) { 408c2ecf20Sopenharmony_ci rssi_val_min = rtlpriv->dm.undec_sm_pwdb; 418c2ecf20Sopenharmony_ci } else if (dm_digtable->curmultista_cstate == 428c2ecf20Sopenharmony_ci DIG_MULTISTA_CONNECT) { 438c2ecf20Sopenharmony_ci rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb; 448c2ecf20Sopenharmony_ci } 458c2ecf20Sopenharmony_ci 468c2ecf20Sopenharmony_ci return (u8) rssi_val_min; 478c2ecf20Sopenharmony_ci} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_cistatic void rtl8723e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) 508c2ecf20Sopenharmony_ci{ 518c2ecf20Sopenharmony_ci u32 ret_value; 528c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 538c2ecf20Sopenharmony_ci struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt); 548c2ecf20Sopenharmony_ci 558c2ecf20Sopenharmony_ci ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD); 568c2ecf20Sopenharmony_ci falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); 578c2ecf20Sopenharmony_ci 588c2ecf20Sopenharmony_ci ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD); 598c2ecf20Sopenharmony_ci falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); 608c2ecf20Sopenharmony_ci falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); 618c2ecf20Sopenharmony_ci 628c2ecf20Sopenharmony_ci ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD); 638c2ecf20Sopenharmony_ci falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); 648c2ecf20Sopenharmony_ci falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + 658c2ecf20Sopenharmony_ci falsealm_cnt->cnt_rate_illegal + 668c2ecf20Sopenharmony_ci falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail; 678c2ecf20Sopenharmony_ci 688c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1); 698c2ecf20Sopenharmony_ci ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0); 708c2ecf20Sopenharmony_ci falsealm_cnt->cnt_cck_fail = ret_value; 718c2ecf20Sopenharmony_ci 728c2ecf20Sopenharmony_ci ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3); 738c2ecf20Sopenharmony_ci falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; 748c2ecf20Sopenharmony_ci falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail + 758c2ecf20Sopenharmony_ci falsealm_cnt->cnt_rate_illegal + 768c2ecf20Sopenharmony_ci falsealm_cnt->cnt_crc8_fail + 778c2ecf20Sopenharmony_ci falsealm_cnt->cnt_mcs_fail + 788c2ecf20Sopenharmony_ci falsealm_cnt->cnt_cck_fail); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1); 818c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0); 828c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0); 838c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2); 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 868c2ecf20Sopenharmony_ci "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", 878c2ecf20Sopenharmony_ci falsealm_cnt->cnt_parity_fail, 888c2ecf20Sopenharmony_ci falsealm_cnt->cnt_rate_illegal, 898c2ecf20Sopenharmony_ci falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); 908c2ecf20Sopenharmony_ci 918c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 928c2ecf20Sopenharmony_ci "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", 938c2ecf20Sopenharmony_ci falsealm_cnt->cnt_ofdm_fail, 948c2ecf20Sopenharmony_ci falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); 958c2ecf20Sopenharmony_ci} 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_cistatic void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw) 988c2ecf20Sopenharmony_ci{ 998c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1008c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 1018c2ecf20Sopenharmony_ci u8 value_igi = dm_digtable->cur_igvalue; 1028c2ecf20Sopenharmony_ci 1038c2ecf20Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) 1048c2ecf20Sopenharmony_ci value_igi--; 1058c2ecf20Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) 1068c2ecf20Sopenharmony_ci value_igi += 0; 1078c2ecf20Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2) 1088c2ecf20Sopenharmony_ci value_igi++; 1098c2ecf20Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2) 1108c2ecf20Sopenharmony_ci value_igi += 2; 1118c2ecf20Sopenharmony_ci if (value_igi > DM_DIG_FA_UPPER) 1128c2ecf20Sopenharmony_ci value_igi = DM_DIG_FA_UPPER; 1138c2ecf20Sopenharmony_ci else if (value_igi < DM_DIG_FA_LOWER) 1148c2ecf20Sopenharmony_ci value_igi = DM_DIG_FA_LOWER; 1158c2ecf20Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > 10000) 1168c2ecf20Sopenharmony_ci value_igi = 0x32; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue = value_igi; 1198c2ecf20Sopenharmony_ci rtl8723e_dm_write_dig(hw); 1208c2ecf20Sopenharmony_ci} 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cistatic void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw) 1238c2ecf20Sopenharmony_ci{ 1248c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1258c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 1268c2ecf20Sopenharmony_ci 1278c2ecf20Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable->fa_highthresh) { 1288c2ecf20Sopenharmony_ci if ((dm_digtable->back_val - 2) < 1298c2ecf20Sopenharmony_ci dm_digtable->back_range_min) 1308c2ecf20Sopenharmony_ci dm_digtable->back_val = 1318c2ecf20Sopenharmony_ci dm_digtable->back_range_min; 1328c2ecf20Sopenharmony_ci else 1338c2ecf20Sopenharmony_ci dm_digtable->back_val -= 2; 1348c2ecf20Sopenharmony_ci } else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable->fa_lowthresh) { 1358c2ecf20Sopenharmony_ci if ((dm_digtable->back_val + 2) > 1368c2ecf20Sopenharmony_ci dm_digtable->back_range_max) 1378c2ecf20Sopenharmony_ci dm_digtable->back_val = 1388c2ecf20Sopenharmony_ci dm_digtable->back_range_max; 1398c2ecf20Sopenharmony_ci else 1408c2ecf20Sopenharmony_ci dm_digtable->back_val += 2; 1418c2ecf20Sopenharmony_ci } 1428c2ecf20Sopenharmony_ci 1438c2ecf20Sopenharmony_ci if ((dm_digtable->rssi_val_min + 10 - dm_digtable->back_val) > 1448c2ecf20Sopenharmony_ci dm_digtable->rx_gain_max) 1458c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue = dm_digtable->rx_gain_max; 1468c2ecf20Sopenharmony_ci else if ((dm_digtable->rssi_val_min + 10 - 1478c2ecf20Sopenharmony_ci dm_digtable->back_val) < dm_digtable->rx_gain_min) 1488c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue = dm_digtable->rx_gain_min; 1498c2ecf20Sopenharmony_ci else 1508c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue = dm_digtable->rssi_val_min + 10 - 1518c2ecf20Sopenharmony_ci dm_digtable->back_val; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 1548c2ecf20Sopenharmony_ci "rssi_val_min = %x back_val %x\n", 1558c2ecf20Sopenharmony_ci dm_digtable->rssi_val_min, dm_digtable->back_val); 1568c2ecf20Sopenharmony_ci 1578c2ecf20Sopenharmony_ci rtl8723e_dm_write_dig(hw); 1588c2ecf20Sopenharmony_ci} 1598c2ecf20Sopenharmony_ci 1608c2ecf20Sopenharmony_cistatic void rtl8723e_dm_initial_gain_multi_sta(struct ieee80211_hw *hw) 1618c2ecf20Sopenharmony_ci{ 1628c2ecf20Sopenharmony_ci static u8 binitialized; 1638c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1648c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 1658c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 1668c2ecf20Sopenharmony_ci long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb; 1678c2ecf20Sopenharmony_ci bool multi_sta = false; 1688c2ecf20Sopenharmony_ci 1698c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) 1708c2ecf20Sopenharmony_ci multi_sta = true; 1718c2ecf20Sopenharmony_ci 1728c2ecf20Sopenharmony_ci if (!multi_sta || (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) { 1738c2ecf20Sopenharmony_ci binitialized = false; 1748c2ecf20Sopenharmony_ci dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; 1758c2ecf20Sopenharmony_ci return; 1768c2ecf20Sopenharmony_ci } else if (!binitialized) { 1778c2ecf20Sopenharmony_ci binitialized = true; 1788c2ecf20Sopenharmony_ci dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; 1798c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue = 0x20; 1808c2ecf20Sopenharmony_ci rtl8723e_dm_write_dig(hw); 1818c2ecf20Sopenharmony_ci } 1828c2ecf20Sopenharmony_ci 1838c2ecf20Sopenharmony_ci if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) { 1848c2ecf20Sopenharmony_ci if ((rssi_strength < dm_digtable->rssi_lowthresh) && 1858c2ecf20Sopenharmony_ci (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) { 1868c2ecf20Sopenharmony_ci 1878c2ecf20Sopenharmony_ci if (dm_digtable->dig_ext_port_stage == 1888c2ecf20Sopenharmony_ci DIG_EXT_PORT_STAGE_2) { 1898c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue = 0x20; 1908c2ecf20Sopenharmony_ci rtl8723e_dm_write_dig(hw); 1918c2ecf20Sopenharmony_ci } 1928c2ecf20Sopenharmony_ci 1938c2ecf20Sopenharmony_ci dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1; 1948c2ecf20Sopenharmony_ci } else if (rssi_strength > dm_digtable->rssi_highthresh) { 1958c2ecf20Sopenharmony_ci dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2; 1968c2ecf20Sopenharmony_ci rtl92c_dm_ctrl_initgain_by_fa(hw); 1978c2ecf20Sopenharmony_ci } 1988c2ecf20Sopenharmony_ci } else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) { 1998c2ecf20Sopenharmony_ci dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0; 2008c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue = 0x20; 2018c2ecf20Sopenharmony_ci rtl8723e_dm_write_dig(hw); 2028c2ecf20Sopenharmony_ci } 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 2058c2ecf20Sopenharmony_ci "curmultista_cstate = %x dig_ext_port_stage %x\n", 2068c2ecf20Sopenharmony_ci dm_digtable->curmultista_cstate, 2078c2ecf20Sopenharmony_ci dm_digtable->dig_ext_port_stage); 2088c2ecf20Sopenharmony_ci} 2098c2ecf20Sopenharmony_ci 2108c2ecf20Sopenharmony_cistatic void rtl8723e_dm_initial_gain_sta(struct ieee80211_hw *hw) 2118c2ecf20Sopenharmony_ci{ 2128c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2138c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 2168c2ecf20Sopenharmony_ci "presta_cstate = %x, cursta_cstate = %x\n", 2178c2ecf20Sopenharmony_ci dm_digtable->presta_cstate, 2188c2ecf20Sopenharmony_ci dm_digtable->cursta_cstate); 2198c2ecf20Sopenharmony_ci 2208c2ecf20Sopenharmony_ci if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate || 2218c2ecf20Sopenharmony_ci dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT || 2228c2ecf20Sopenharmony_ci dm_digtable->cursta_cstate == DIG_STA_CONNECT) { 2238c2ecf20Sopenharmony_ci if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) { 2248c2ecf20Sopenharmony_ci dm_digtable->rssi_val_min = 2258c2ecf20Sopenharmony_ci rtl8723e_dm_initial_gain_min_pwdb(hw); 2268c2ecf20Sopenharmony_ci rtl92c_dm_ctrl_initgain_by_rssi(hw); 2278c2ecf20Sopenharmony_ci } 2288c2ecf20Sopenharmony_ci } else { 2298c2ecf20Sopenharmony_ci dm_digtable->rssi_val_min = 0; 2308c2ecf20Sopenharmony_ci dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX; 2318c2ecf20Sopenharmony_ci dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT; 2328c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue = 0x20; 2338c2ecf20Sopenharmony_ci dm_digtable->pre_igvalue = 0; 2348c2ecf20Sopenharmony_ci rtl8723e_dm_write_dig(hw); 2358c2ecf20Sopenharmony_ci } 2368c2ecf20Sopenharmony_ci} 2378c2ecf20Sopenharmony_ci 2388c2ecf20Sopenharmony_cistatic void rtl8723e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) 2398c2ecf20Sopenharmony_ci{ 2408c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 2418c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 2428c2ecf20Sopenharmony_ci 2438c2ecf20Sopenharmony_ci if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) { 2448c2ecf20Sopenharmony_ci dm_digtable->rssi_val_min = rtl8723e_dm_initial_gain_min_pwdb(hw); 2458c2ecf20Sopenharmony_ci 2468c2ecf20Sopenharmony_ci if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { 2478c2ecf20Sopenharmony_ci if (dm_digtable->rssi_val_min <= 25) 2488c2ecf20Sopenharmony_ci dm_digtable->cur_cck_pd_state = 2498c2ecf20Sopenharmony_ci CCK_PD_STAGE_LOWRSSI; 2508c2ecf20Sopenharmony_ci else 2518c2ecf20Sopenharmony_ci dm_digtable->cur_cck_pd_state = 2528c2ecf20Sopenharmony_ci CCK_PD_STAGE_HIGHRSSI; 2538c2ecf20Sopenharmony_ci } else { 2548c2ecf20Sopenharmony_ci if (dm_digtable->rssi_val_min <= 20) 2558c2ecf20Sopenharmony_ci dm_digtable->cur_cck_pd_state = 2568c2ecf20Sopenharmony_ci CCK_PD_STAGE_LOWRSSI; 2578c2ecf20Sopenharmony_ci else 2588c2ecf20Sopenharmony_ci dm_digtable->cur_cck_pd_state = 2598c2ecf20Sopenharmony_ci CCK_PD_STAGE_HIGHRSSI; 2608c2ecf20Sopenharmony_ci } 2618c2ecf20Sopenharmony_ci } else { 2628c2ecf20Sopenharmony_ci dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX; 2638c2ecf20Sopenharmony_ci } 2648c2ecf20Sopenharmony_ci 2658c2ecf20Sopenharmony_ci if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) { 2668c2ecf20Sopenharmony_ci if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) { 2678c2ecf20Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800) 2688c2ecf20Sopenharmony_ci dm_digtable->cur_cck_fa_state = 2698c2ecf20Sopenharmony_ci CCK_FA_STAGE_HIGH; 2708c2ecf20Sopenharmony_ci else 2718c2ecf20Sopenharmony_ci dm_digtable->cur_cck_fa_state = 2728c2ecf20Sopenharmony_ci CCK_FA_STAGE_LOW; 2738c2ecf20Sopenharmony_ci if (dm_digtable->pre_cck_fa_state != 2748c2ecf20Sopenharmony_ci dm_digtable->cur_cck_fa_state) { 2758c2ecf20Sopenharmony_ci if (dm_digtable->cur_cck_fa_state == 2768c2ecf20Sopenharmony_ci CCK_FA_STAGE_LOW) 2778c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 2788c2ecf20Sopenharmony_ci 0x83); 2798c2ecf20Sopenharmony_ci else 2808c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 2818c2ecf20Sopenharmony_ci 0xcd); 2828c2ecf20Sopenharmony_ci 2838c2ecf20Sopenharmony_ci dm_digtable->pre_cck_fa_state = 2848c2ecf20Sopenharmony_ci dm_digtable->cur_cck_fa_state; 2858c2ecf20Sopenharmony_ci } 2868c2ecf20Sopenharmony_ci 2878c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40); 2888c2ecf20Sopenharmony_ci 2898c2ecf20Sopenharmony_ci } else { 2908c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd); 2918c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47); 2928c2ecf20Sopenharmony_ci dm_digtable->pre_cck_fa_state = 0; 2938c2ecf20Sopenharmony_ci dm_digtable->cur_cck_fa_state = 0; 2948c2ecf20Sopenharmony_ci 2958c2ecf20Sopenharmony_ci } 2968c2ecf20Sopenharmony_ci dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state; 2978c2ecf20Sopenharmony_ci } 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 3008c2ecf20Sopenharmony_ci "CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state); 3018c2ecf20Sopenharmony_ci 3028c2ecf20Sopenharmony_ci} 3038c2ecf20Sopenharmony_ci 3048c2ecf20Sopenharmony_cistatic void rtl8723e_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw) 3058c2ecf20Sopenharmony_ci{ 3068c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 3078c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3088c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 3098c2ecf20Sopenharmony_ci 3108c2ecf20Sopenharmony_ci if (mac->act_scanning) 3118c2ecf20Sopenharmony_ci return; 3128c2ecf20Sopenharmony_ci 3138c2ecf20Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) 3148c2ecf20Sopenharmony_ci dm_digtable->cursta_cstate = DIG_STA_CONNECT; 3158c2ecf20Sopenharmony_ci else 3168c2ecf20Sopenharmony_ci dm_digtable->cursta_cstate = DIG_STA_DISCONNECT; 3178c2ecf20Sopenharmony_ci 3188c2ecf20Sopenharmony_ci rtl8723e_dm_initial_gain_sta(hw); 3198c2ecf20Sopenharmony_ci rtl8723e_dm_initial_gain_multi_sta(hw); 3208c2ecf20Sopenharmony_ci rtl8723e_dm_cck_packet_detection_thresh(hw); 3218c2ecf20Sopenharmony_ci 3228c2ecf20Sopenharmony_ci dm_digtable->presta_cstate = dm_digtable->cursta_cstate; 3238c2ecf20Sopenharmony_ci 3248c2ecf20Sopenharmony_ci} 3258c2ecf20Sopenharmony_ci 3268c2ecf20Sopenharmony_cistatic void rtl8723e_dm_dig(struct ieee80211_hw *hw) 3278c2ecf20Sopenharmony_ci{ 3288c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3298c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 3308c2ecf20Sopenharmony_ci 3318c2ecf20Sopenharmony_ci if (!rtlpriv->dm.dm_initialgain_enable) 3328c2ecf20Sopenharmony_ci return; 3338c2ecf20Sopenharmony_ci if (!dm_digtable->dig_enable_flag) 3348c2ecf20Sopenharmony_ci return; 3358c2ecf20Sopenharmony_ci 3368c2ecf20Sopenharmony_ci rtl8723e_dm_ctrl_initgain_by_twoport(hw); 3378c2ecf20Sopenharmony_ci 3388c2ecf20Sopenharmony_ci} 3398c2ecf20Sopenharmony_ci 3408c2ecf20Sopenharmony_cistatic void rtl8723e_dm_dynamic_txpower(struct ieee80211_hw *hw) 3418c2ecf20Sopenharmony_ci{ 3428c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 3438c2ecf20Sopenharmony_ci struct rtl_phy *rtlphy = &(rtlpriv->phy); 3448c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 3458c2ecf20Sopenharmony_ci long undec_sm_pwdb; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ci if (!rtlpriv->dm.dynamic_txpower_enable) 3488c2ecf20Sopenharmony_ci return; 3498c2ecf20Sopenharmony_ci 3508c2ecf20Sopenharmony_ci if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) { 3518c2ecf20Sopenharmony_ci rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; 3528c2ecf20Sopenharmony_ci return; 3538c2ecf20Sopenharmony_ci } 3548c2ecf20Sopenharmony_ci 3558c2ecf20Sopenharmony_ci if ((mac->link_state < MAC80211_LINKED) && 3568c2ecf20Sopenharmony_ci (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { 3578c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE, 3588c2ecf20Sopenharmony_ci "Not connected to any\n"); 3598c2ecf20Sopenharmony_ci 3608c2ecf20Sopenharmony_ci rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; 3618c2ecf20Sopenharmony_ci 3628c2ecf20Sopenharmony_ci rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL; 3638c2ecf20Sopenharmony_ci return; 3648c2ecf20Sopenharmony_ci } 3658c2ecf20Sopenharmony_ci 3668c2ecf20Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 3678c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) { 3688c2ecf20Sopenharmony_ci undec_sm_pwdb = 3698c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 3708c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 3718c2ecf20Sopenharmony_ci "AP Client PWDB = 0x%lx\n", 3728c2ecf20Sopenharmony_ci undec_sm_pwdb); 3738c2ecf20Sopenharmony_ci } else { 3748c2ecf20Sopenharmony_ci undec_sm_pwdb = 3758c2ecf20Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb; 3768c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 3778c2ecf20Sopenharmony_ci "STA Default Port PWDB = 0x%lx\n", 3788c2ecf20Sopenharmony_ci undec_sm_pwdb); 3798c2ecf20Sopenharmony_ci } 3808c2ecf20Sopenharmony_ci } else { 3818c2ecf20Sopenharmony_ci undec_sm_pwdb = 3828c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 3838c2ecf20Sopenharmony_ci 3848c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 3858c2ecf20Sopenharmony_ci "AP Ext Port PWDB = 0x%lx\n", 3868c2ecf20Sopenharmony_ci undec_sm_pwdb); 3878c2ecf20Sopenharmony_ci } 3888c2ecf20Sopenharmony_ci 3898c2ecf20Sopenharmony_ci if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) { 3908c2ecf20Sopenharmony_ci rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; 3918c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 3928c2ecf20Sopenharmony_ci "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n"); 3938c2ecf20Sopenharmony_ci } else if ((undec_sm_pwdb < 3948c2ecf20Sopenharmony_ci (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) && 3958c2ecf20Sopenharmony_ci (undec_sm_pwdb >= 3968c2ecf20Sopenharmony_ci TX_POWER_NEAR_FIELD_THRESH_LVL1)) { 3978c2ecf20Sopenharmony_ci rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1; 3988c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 3998c2ecf20Sopenharmony_ci "TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n"); 4008c2ecf20Sopenharmony_ci } else if (undec_sm_pwdb < 4018c2ecf20Sopenharmony_ci (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) { 4028c2ecf20Sopenharmony_ci rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL; 4038c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 4048c2ecf20Sopenharmony_ci "TXHIGHPWRLEVEL_NORMAL\n"); 4058c2ecf20Sopenharmony_ci } 4068c2ecf20Sopenharmony_ci 4078c2ecf20Sopenharmony_ci if (rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl) { 4088c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD, 4098c2ecf20Sopenharmony_ci "PHY_SetTxPowerLevel8192S() Channel = %d\n", 4108c2ecf20Sopenharmony_ci rtlphy->current_channel); 4118c2ecf20Sopenharmony_ci rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel); 4128c2ecf20Sopenharmony_ci } 4138c2ecf20Sopenharmony_ci 4148c2ecf20Sopenharmony_ci rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl; 4158c2ecf20Sopenharmony_ci} 4168c2ecf20Sopenharmony_ci 4178c2ecf20Sopenharmony_civoid rtl8723e_dm_write_dig(struct ieee80211_hw *hw) 4188c2ecf20Sopenharmony_ci{ 4198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4208c2ecf20Sopenharmony_ci struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 4218c2ecf20Sopenharmony_ci 4228c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 4238c2ecf20Sopenharmony_ci "cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n", 4248c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue, dm_digtable->pre_igvalue, 4258c2ecf20Sopenharmony_ci dm_digtable->back_val); 4268c2ecf20Sopenharmony_ci 4278c2ecf20Sopenharmony_ci if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) { 4288c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, 4298c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue); 4308c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, 4318c2ecf20Sopenharmony_ci dm_digtable->cur_igvalue); 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_ci dm_digtable->pre_igvalue = dm_digtable->cur_igvalue; 4348c2ecf20Sopenharmony_ci } 4358c2ecf20Sopenharmony_ci} 4368c2ecf20Sopenharmony_ci 4378c2ecf20Sopenharmony_cistatic void rtl8723e_dm_pwdb_monitor(struct ieee80211_hw *hw) 4388c2ecf20Sopenharmony_ci{ 4398c2ecf20Sopenharmony_ci} 4408c2ecf20Sopenharmony_ci 4418c2ecf20Sopenharmony_cistatic void rtl8723e_dm_check_edca_turbo(struct ieee80211_hw *hw) 4428c2ecf20Sopenharmony_ci{ 4438c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 4448c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 4458c2ecf20Sopenharmony_ci 4468c2ecf20Sopenharmony_ci static u64 last_txok_cnt; 4478c2ecf20Sopenharmony_ci static u64 last_rxok_cnt; 4488c2ecf20Sopenharmony_ci static u32 last_bt_edca_ul; 4498c2ecf20Sopenharmony_ci static u32 last_bt_edca_dl; 4508c2ecf20Sopenharmony_ci u64 cur_txok_cnt = 0; 4518c2ecf20Sopenharmony_ci u64 cur_rxok_cnt = 0; 4528c2ecf20Sopenharmony_ci u32 edca_be_ul = 0x5ea42b; 4538c2ecf20Sopenharmony_ci u32 edca_be_dl = 0x5ea42b; 4548c2ecf20Sopenharmony_ci bool bt_change_edca = false; 4558c2ecf20Sopenharmony_ci 4568c2ecf20Sopenharmony_ci if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) || 4578c2ecf20Sopenharmony_ci (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) { 4588c2ecf20Sopenharmony_ci rtlpriv->dm.current_turbo_edca = false; 4598c2ecf20Sopenharmony_ci last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul; 4608c2ecf20Sopenharmony_ci last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl; 4618c2ecf20Sopenharmony_ci } 4628c2ecf20Sopenharmony_ci 4638c2ecf20Sopenharmony_ci if (rtlpriv->btcoexist.bt_edca_ul != 0) { 4648c2ecf20Sopenharmony_ci edca_be_ul = rtlpriv->btcoexist.bt_edca_ul; 4658c2ecf20Sopenharmony_ci bt_change_edca = true; 4668c2ecf20Sopenharmony_ci } 4678c2ecf20Sopenharmony_ci 4688c2ecf20Sopenharmony_ci if (rtlpriv->btcoexist.bt_edca_dl != 0) { 4698c2ecf20Sopenharmony_ci edca_be_dl = rtlpriv->btcoexist.bt_edca_dl; 4708c2ecf20Sopenharmony_ci bt_change_edca = true; 4718c2ecf20Sopenharmony_ci } 4728c2ecf20Sopenharmony_ci 4738c2ecf20Sopenharmony_ci if (mac->link_state != MAC80211_LINKED) { 4748c2ecf20Sopenharmony_ci rtlpriv->dm.current_turbo_edca = false; 4758c2ecf20Sopenharmony_ci return; 4768c2ecf20Sopenharmony_ci } 4778c2ecf20Sopenharmony_ci if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) && 4788c2ecf20Sopenharmony_ci (!rtlpriv->dm.disable_framebursting))) { 4798c2ecf20Sopenharmony_ci 4808c2ecf20Sopenharmony_ci cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; 4818c2ecf20Sopenharmony_ci cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; 4828c2ecf20Sopenharmony_ci 4838c2ecf20Sopenharmony_ci if (cur_rxok_cnt > 4 * cur_txok_cnt) { 4848c2ecf20Sopenharmony_ci if (!rtlpriv->dm.is_cur_rdlstate || 4858c2ecf20Sopenharmony_ci !rtlpriv->dm.current_turbo_edca) { 4868c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, 4878c2ecf20Sopenharmony_ci REG_EDCA_BE_PARAM, 4888c2ecf20Sopenharmony_ci edca_be_dl); 4898c2ecf20Sopenharmony_ci rtlpriv->dm.is_cur_rdlstate = true; 4908c2ecf20Sopenharmony_ci } 4918c2ecf20Sopenharmony_ci } else { 4928c2ecf20Sopenharmony_ci if (rtlpriv->dm.is_cur_rdlstate || 4938c2ecf20Sopenharmony_ci !rtlpriv->dm.current_turbo_edca) { 4948c2ecf20Sopenharmony_ci rtl_write_dword(rtlpriv, 4958c2ecf20Sopenharmony_ci REG_EDCA_BE_PARAM, 4968c2ecf20Sopenharmony_ci edca_be_ul); 4978c2ecf20Sopenharmony_ci rtlpriv->dm.is_cur_rdlstate = false; 4988c2ecf20Sopenharmony_ci } 4998c2ecf20Sopenharmony_ci } 5008c2ecf20Sopenharmony_ci rtlpriv->dm.current_turbo_edca = true; 5018c2ecf20Sopenharmony_ci } else { 5028c2ecf20Sopenharmony_ci if (rtlpriv->dm.current_turbo_edca) { 5038c2ecf20Sopenharmony_ci u8 tmp = AC0_BE; 5048c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, 5058c2ecf20Sopenharmony_ci HW_VAR_AC_PARAM, 5068c2ecf20Sopenharmony_ci (u8 *)(&tmp)); 5078c2ecf20Sopenharmony_ci rtlpriv->dm.current_turbo_edca = false; 5088c2ecf20Sopenharmony_ci } 5098c2ecf20Sopenharmony_ci } 5108c2ecf20Sopenharmony_ci 5118c2ecf20Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = false; 5128c2ecf20Sopenharmony_ci last_txok_cnt = rtlpriv->stats.txbytesunicast; 5138c2ecf20Sopenharmony_ci last_rxok_cnt = rtlpriv->stats.rxbytesunicast; 5148c2ecf20Sopenharmony_ci} 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_cistatic void rtl8723e_dm_initialize_txpower_tracking_thermalmeter( 5178c2ecf20Sopenharmony_ci struct ieee80211_hw *hw) 5188c2ecf20Sopenharmony_ci{ 5198c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5208c2ecf20Sopenharmony_ci 5218c2ecf20Sopenharmony_ci rtlpriv->dm.txpower_tracking = true; 5228c2ecf20Sopenharmony_ci rtlpriv->dm.txpower_trackinginit = false; 5238c2ecf20Sopenharmony_ci 5248c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 5258c2ecf20Sopenharmony_ci "pMgntInfo->txpower_tracking = %d\n", 5268c2ecf20Sopenharmony_ci rtlpriv->dm.txpower_tracking); 5278c2ecf20Sopenharmony_ci} 5288c2ecf20Sopenharmony_ci 5298c2ecf20Sopenharmony_cistatic void rtl8723e_dm_initialize_txpower_tracking(struct ieee80211_hw *hw) 5308c2ecf20Sopenharmony_ci{ 5318c2ecf20Sopenharmony_ci rtl8723e_dm_initialize_txpower_tracking_thermalmeter(hw); 5328c2ecf20Sopenharmony_ci} 5338c2ecf20Sopenharmony_ci 5348c2ecf20Sopenharmony_civoid rtl8723e_dm_check_txpower_tracking(struct ieee80211_hw *hw) 5358c2ecf20Sopenharmony_ci{ 5368c2ecf20Sopenharmony_ci return; 5378c2ecf20Sopenharmony_ci} 5388c2ecf20Sopenharmony_ci 5398c2ecf20Sopenharmony_civoid rtl8723e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) 5408c2ecf20Sopenharmony_ci{ 5418c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5428c2ecf20Sopenharmony_ci struct rate_adaptive *p_ra = &rtlpriv->ra; 5438c2ecf20Sopenharmony_ci 5448c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_INIT; 5458c2ecf20Sopenharmony_ci p_ra->pre_ratr_state = DM_RATR_STA_INIT; 5468c2ecf20Sopenharmony_ci 5478c2ecf20Sopenharmony_ci if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) 5488c2ecf20Sopenharmony_ci rtlpriv->dm.useramask = true; 5498c2ecf20Sopenharmony_ci else 5508c2ecf20Sopenharmony_ci rtlpriv->dm.useramask = false; 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ci} 5538c2ecf20Sopenharmony_ci 5548c2ecf20Sopenharmony_cistatic void rtl8723e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) 5558c2ecf20Sopenharmony_ci{ 5568c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 5578c2ecf20Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 5588c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 5598c2ecf20Sopenharmony_ci struct rate_adaptive *p_ra = &rtlpriv->ra; 5608c2ecf20Sopenharmony_ci u32 low_rssithresh_for_ra, high_rssithresh_for_ra; 5618c2ecf20Sopenharmony_ci struct ieee80211_sta *sta = NULL; 5628c2ecf20Sopenharmony_ci 5638c2ecf20Sopenharmony_ci if (is_hal_stop(rtlhal)) { 5648c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 5658c2ecf20Sopenharmony_ci " driver is going to unload\n"); 5668c2ecf20Sopenharmony_ci return; 5678c2ecf20Sopenharmony_ci } 5688c2ecf20Sopenharmony_ci 5698c2ecf20Sopenharmony_ci if (!rtlpriv->dm.useramask) { 5708c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 5718c2ecf20Sopenharmony_ci " driver does not control rate adaptive mask\n"); 5728c2ecf20Sopenharmony_ci return; 5738c2ecf20Sopenharmony_ci } 5748c2ecf20Sopenharmony_ci 5758c2ecf20Sopenharmony_ci if (mac->link_state == MAC80211_LINKED && 5768c2ecf20Sopenharmony_ci mac->opmode == NL80211_IFTYPE_STATION) { 5778c2ecf20Sopenharmony_ci switch (p_ra->pre_ratr_state) { 5788c2ecf20Sopenharmony_ci case DM_RATR_STA_HIGH: 5798c2ecf20Sopenharmony_ci high_rssithresh_for_ra = 50; 5808c2ecf20Sopenharmony_ci low_rssithresh_for_ra = 20; 5818c2ecf20Sopenharmony_ci break; 5828c2ecf20Sopenharmony_ci case DM_RATR_STA_MIDDLE: 5838c2ecf20Sopenharmony_ci high_rssithresh_for_ra = 55; 5848c2ecf20Sopenharmony_ci low_rssithresh_for_ra = 20; 5858c2ecf20Sopenharmony_ci break; 5868c2ecf20Sopenharmony_ci case DM_RATR_STA_LOW: 5878c2ecf20Sopenharmony_ci high_rssithresh_for_ra = 60; 5888c2ecf20Sopenharmony_ci low_rssithresh_for_ra = 25; 5898c2ecf20Sopenharmony_ci break; 5908c2ecf20Sopenharmony_ci default: 5918c2ecf20Sopenharmony_ci high_rssithresh_for_ra = 50; 5928c2ecf20Sopenharmony_ci low_rssithresh_for_ra = 20; 5938c2ecf20Sopenharmony_ci break; 5948c2ecf20Sopenharmony_ci } 5958c2ecf20Sopenharmony_ci 5968c2ecf20Sopenharmony_ci if (rtlpriv->link_info.bcn_rx_inperiod == 0) 5978c2ecf20Sopenharmony_ci switch (p_ra->pre_ratr_state) { 5988c2ecf20Sopenharmony_ci case DM_RATR_STA_HIGH: 5998c2ecf20Sopenharmony_ci default: 6008c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_MIDDLE; 6018c2ecf20Sopenharmony_ci break; 6028c2ecf20Sopenharmony_ci case DM_RATR_STA_MIDDLE: 6038c2ecf20Sopenharmony_ci case DM_RATR_STA_LOW: 6048c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_LOW; 6058c2ecf20Sopenharmony_ci break; 6068c2ecf20Sopenharmony_ci } 6078c2ecf20Sopenharmony_ci else if (rtlpriv->dm.undec_sm_pwdb > high_rssithresh_for_ra) 6088c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_HIGH; 6098c2ecf20Sopenharmony_ci else if (rtlpriv->dm.undec_sm_pwdb > low_rssithresh_for_ra) 6108c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_MIDDLE; 6118c2ecf20Sopenharmony_ci else 6128c2ecf20Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_LOW; 6138c2ecf20Sopenharmony_ci 6148c2ecf20Sopenharmony_ci if (p_ra->pre_ratr_state != p_ra->ratr_state) { 6158c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 6168c2ecf20Sopenharmony_ci "RSSI = %ld\n", 6178c2ecf20Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb); 6188c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 6198c2ecf20Sopenharmony_ci "RSSI_LEVEL = %d\n", p_ra->ratr_state); 6208c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 6218c2ecf20Sopenharmony_ci "PreState = %d, CurState = %d\n", 6228c2ecf20Sopenharmony_ci p_ra->pre_ratr_state, p_ra->ratr_state); 6238c2ecf20Sopenharmony_ci 6248c2ecf20Sopenharmony_ci rcu_read_lock(); 6258c2ecf20Sopenharmony_ci sta = rtl_find_sta(hw, mac->bssid); 6268c2ecf20Sopenharmony_ci if (sta) 6278c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 6288c2ecf20Sopenharmony_ci p_ra->ratr_state, 6298c2ecf20Sopenharmony_ci true); 6308c2ecf20Sopenharmony_ci rcu_read_unlock(); 6318c2ecf20Sopenharmony_ci 6328c2ecf20Sopenharmony_ci p_ra->pre_ratr_state = p_ra->ratr_state; 6338c2ecf20Sopenharmony_ci } 6348c2ecf20Sopenharmony_ci } 6358c2ecf20Sopenharmony_ci} 6368c2ecf20Sopenharmony_ci 6378c2ecf20Sopenharmony_civoid rtl8723e_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal) 6388c2ecf20Sopenharmony_ci{ 6398c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 6408c2ecf20Sopenharmony_ci struct ps_t *dm_pstable = &rtlpriv->dm_pstable; 6418c2ecf20Sopenharmony_ci static u8 initialize; 6428c2ecf20Sopenharmony_ci static u32 reg_874, reg_c70, reg_85c, reg_a74; 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_ci if (initialize == 0) { 6458c2ecf20Sopenharmony_ci reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 6468c2ecf20Sopenharmony_ci MASKDWORD) & 0x1CC000) >> 14; 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1, 6498c2ecf20Sopenharmony_ci MASKDWORD) & BIT(3)) >> 3; 6508c2ecf20Sopenharmony_ci 6518c2ecf20Sopenharmony_ci reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 6528c2ecf20Sopenharmony_ci MASKDWORD) & 0xFF000000) >> 24; 6538c2ecf20Sopenharmony_ci 6548c2ecf20Sopenharmony_ci reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12; 6558c2ecf20Sopenharmony_ci 6568c2ecf20Sopenharmony_ci initialize = 1; 6578c2ecf20Sopenharmony_ci } 6588c2ecf20Sopenharmony_ci 6598c2ecf20Sopenharmony_ci if (!bforce_in_normal) { 6608c2ecf20Sopenharmony_ci if (dm_pstable->rssi_val_min != 0) { 6618c2ecf20Sopenharmony_ci if (dm_pstable->pre_rfstate == RF_NORMAL) { 6628c2ecf20Sopenharmony_ci if (dm_pstable->rssi_val_min >= 30) 6638c2ecf20Sopenharmony_ci dm_pstable->cur_rfstate = RF_SAVE; 6648c2ecf20Sopenharmony_ci else 6658c2ecf20Sopenharmony_ci dm_pstable->cur_rfstate = RF_NORMAL; 6668c2ecf20Sopenharmony_ci } else { 6678c2ecf20Sopenharmony_ci if (dm_pstable->rssi_val_min <= 25) 6688c2ecf20Sopenharmony_ci dm_pstable->cur_rfstate = RF_NORMAL; 6698c2ecf20Sopenharmony_ci else 6708c2ecf20Sopenharmony_ci dm_pstable->cur_rfstate = RF_SAVE; 6718c2ecf20Sopenharmony_ci } 6728c2ecf20Sopenharmony_ci } else { 6738c2ecf20Sopenharmony_ci dm_pstable->cur_rfstate = RF_MAX; 6748c2ecf20Sopenharmony_ci } 6758c2ecf20Sopenharmony_ci } else { 6768c2ecf20Sopenharmony_ci dm_pstable->cur_rfstate = RF_NORMAL; 6778c2ecf20Sopenharmony_ci } 6788c2ecf20Sopenharmony_ci 6798c2ecf20Sopenharmony_ci if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) { 6808c2ecf20Sopenharmony_ci if (dm_pstable->cur_rfstate == RF_SAVE) { 6818c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 6828c2ecf20Sopenharmony_ci BIT(5), 0x1); 6838c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 6848c2ecf20Sopenharmony_ci 0x1C0000, 0x2); 6858c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0); 6868c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 6878c2ecf20Sopenharmony_ci 0xFF000000, 0x63); 6888c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 6898c2ecf20Sopenharmony_ci 0xC000, 0x2); 6908c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3); 6918c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); 6928c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0x818, BIT(28), 0x1); 6938c2ecf20Sopenharmony_ci } else { 6948c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 6958c2ecf20Sopenharmony_ci 0x1CC000, reg_874); 6968c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 6978c2ecf20Sopenharmony_ci reg_c70); 6988c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000, 6998c2ecf20Sopenharmony_ci reg_85c); 7008c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74); 7018c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, 0x818, BIT(28), 0x0); 7028c2ecf20Sopenharmony_ci rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW, 7038c2ecf20Sopenharmony_ci BIT(5), 0x0); 7048c2ecf20Sopenharmony_ci } 7058c2ecf20Sopenharmony_ci 7068c2ecf20Sopenharmony_ci dm_pstable->pre_rfstate = dm_pstable->cur_rfstate; 7078c2ecf20Sopenharmony_ci } 7088c2ecf20Sopenharmony_ci} 7098c2ecf20Sopenharmony_ci 7108c2ecf20Sopenharmony_cistatic void rtl8723e_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw) 7118c2ecf20Sopenharmony_ci{ 7128c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7138c2ecf20Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 7148c2ecf20Sopenharmony_ci struct ps_t *dm_pstable = &rtlpriv->dm_pstable; 7158c2ecf20Sopenharmony_ci 7168c2ecf20Sopenharmony_ci if (((mac->link_state == MAC80211_NOLINK)) && 7178c2ecf20Sopenharmony_ci (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { 7188c2ecf20Sopenharmony_ci dm_pstable->rssi_val_min = 0; 7198c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, 7208c2ecf20Sopenharmony_ci "Not connected to any\n"); 7218c2ecf20Sopenharmony_ci } 7228c2ecf20Sopenharmony_ci 7238c2ecf20Sopenharmony_ci if (mac->link_state == MAC80211_LINKED) { 7248c2ecf20Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_ADHOC) { 7258c2ecf20Sopenharmony_ci dm_pstable->rssi_val_min = 7268c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 7278c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, 7288c2ecf20Sopenharmony_ci "AP Client PWDB = 0x%lx\n", 7298c2ecf20Sopenharmony_ci dm_pstable->rssi_val_min); 7308c2ecf20Sopenharmony_ci } else { 7318c2ecf20Sopenharmony_ci dm_pstable->rssi_val_min = 7328c2ecf20Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb; 7338c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, 7348c2ecf20Sopenharmony_ci "STA Default Port PWDB = 0x%lx\n", 7358c2ecf20Sopenharmony_ci dm_pstable->rssi_val_min); 7368c2ecf20Sopenharmony_ci } 7378c2ecf20Sopenharmony_ci } else { 7388c2ecf20Sopenharmony_ci dm_pstable->rssi_val_min = 7398c2ecf20Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 7408c2ecf20Sopenharmony_ci 7418c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD, 7428c2ecf20Sopenharmony_ci "AP Ext Port PWDB = 0x%lx\n", 7438c2ecf20Sopenharmony_ci dm_pstable->rssi_val_min); 7448c2ecf20Sopenharmony_ci } 7458c2ecf20Sopenharmony_ci 7468c2ecf20Sopenharmony_ci rtl8723e_dm_rf_saving(hw, false); 7478c2ecf20Sopenharmony_ci} 7488c2ecf20Sopenharmony_ci 7498c2ecf20Sopenharmony_civoid rtl8723e_dm_init(struct ieee80211_hw *hw) 7508c2ecf20Sopenharmony_ci{ 7518c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7528c2ecf20Sopenharmony_ci 7538c2ecf20Sopenharmony_ci rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 7548c2ecf20Sopenharmony_ci rtl_dm_diginit(hw, 0x20); 7558c2ecf20Sopenharmony_ci rtl8723_dm_init_dynamic_txpower(hw); 7568c2ecf20Sopenharmony_ci rtl8723_dm_init_edca_turbo(hw); 7578c2ecf20Sopenharmony_ci rtl8723e_dm_init_rate_adaptive_mask(hw); 7588c2ecf20Sopenharmony_ci rtl8723e_dm_initialize_txpower_tracking(hw); 7598c2ecf20Sopenharmony_ci rtl8723_dm_init_dynamic_bb_powersaving(hw); 7608c2ecf20Sopenharmony_ci} 7618c2ecf20Sopenharmony_ci 7628c2ecf20Sopenharmony_civoid rtl8723e_dm_watchdog(struct ieee80211_hw *hw) 7638c2ecf20Sopenharmony_ci{ 7648c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7658c2ecf20Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 7668c2ecf20Sopenharmony_ci bool fw_current_inpsmode = false; 7678c2ecf20Sopenharmony_ci bool fw_ps_awake = true; 7688c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 7698c2ecf20Sopenharmony_ci (u8 *)(&fw_current_inpsmode)); 7708c2ecf20Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, 7718c2ecf20Sopenharmony_ci (u8 *)(&fw_ps_awake)); 7728c2ecf20Sopenharmony_ci 7738c2ecf20Sopenharmony_ci if (ppsc->p2p_ps_info.p2p_ps_mode) 7748c2ecf20Sopenharmony_ci fw_ps_awake = false; 7758c2ecf20Sopenharmony_ci 7768c2ecf20Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_ps_lock); 7778c2ecf20Sopenharmony_ci if ((ppsc->rfpwr_state == ERFON) && 7788c2ecf20Sopenharmony_ci ((!fw_current_inpsmode) && fw_ps_awake) && 7798c2ecf20Sopenharmony_ci (!ppsc->rfchange_inprogress)) { 7808c2ecf20Sopenharmony_ci rtl8723e_dm_pwdb_monitor(hw); 7818c2ecf20Sopenharmony_ci rtl8723e_dm_dig(hw); 7828c2ecf20Sopenharmony_ci rtl8723e_dm_false_alarm_counter_statistics(hw); 7838c2ecf20Sopenharmony_ci rtl8723e_dm_dynamic_bb_powersaving(hw); 7848c2ecf20Sopenharmony_ci rtl8723e_dm_dynamic_txpower(hw); 7858c2ecf20Sopenharmony_ci rtl8723e_dm_check_txpower_tracking(hw); 7868c2ecf20Sopenharmony_ci rtl8723e_dm_refresh_rate_adaptive_mask(hw); 7878c2ecf20Sopenharmony_ci rtl8723e_dm_bt_coexist(hw); 7888c2ecf20Sopenharmony_ci rtl8723e_dm_check_edca_turbo(hw); 7898c2ecf20Sopenharmony_ci } 7908c2ecf20Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_ps_lock); 7918c2ecf20Sopenharmony_ci if (rtlpriv->btcoexist.init_set) 7928c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x76e, 0xc); 7938c2ecf20Sopenharmony_ci} 7948c2ecf20Sopenharmony_ci 7958c2ecf20Sopenharmony_cistatic void rtl8723e_dm_init_bt_coexist(struct ieee80211_hw *hw) 7968c2ecf20Sopenharmony_ci{ 7978c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 7988c2ecf20Sopenharmony_ci 7998c2ecf20Sopenharmony_ci rtlpriv->btcoexist.bt_rfreg_origin_1e 8008c2ecf20Sopenharmony_ci = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff); 8018c2ecf20Sopenharmony_ci rtlpriv->btcoexist.bt_rfreg_origin_1f 8028c2ecf20Sopenharmony_ci = rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0); 8038c2ecf20Sopenharmony_ci 8048c2ecf20Sopenharmony_ci rtlpriv->btcoexist.cstate = 0; 8058c2ecf20Sopenharmony_ci rtlpriv->btcoexist.previous_state = 0; 8068c2ecf20Sopenharmony_ci rtlpriv->btcoexist.cstate_h = 0; 8078c2ecf20Sopenharmony_ci rtlpriv->btcoexist.previous_state_h = 0; 8088c2ecf20Sopenharmony_ci rtlpriv->btcoexist.lps_counter = 0; 8098c2ecf20Sopenharmony_ci 8108c2ecf20Sopenharmony_ci /* Enable counter statistics */ 8118c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x76e, 0x4); 8128c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x778, 0x3); 8138c2ecf20Sopenharmony_ci rtl_write_byte(rtlpriv, 0x40, 0x20); 8148c2ecf20Sopenharmony_ci 8158c2ecf20Sopenharmony_ci rtlpriv->btcoexist.init_set = true; 8168c2ecf20Sopenharmony_ci} 8178c2ecf20Sopenharmony_ci 8188c2ecf20Sopenharmony_civoid rtl8723e_dm_bt_coexist(struct ieee80211_hw *hw) 8198c2ecf20Sopenharmony_ci{ 8208c2ecf20Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 8218c2ecf20Sopenharmony_ci u8 tmp_byte = 0; 8228c2ecf20Sopenharmony_ci if (!rtlpriv->btcoexist.bt_coexistence) { 8238c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 8248c2ecf20Sopenharmony_ci "[DM]{BT], BT not exist!!\n"); 8258c2ecf20Sopenharmony_ci return; 8268c2ecf20Sopenharmony_ci } 8278c2ecf20Sopenharmony_ci 8288c2ecf20Sopenharmony_ci if (!rtlpriv->btcoexist.init_set) { 8298c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 8308c2ecf20Sopenharmony_ci "[DM][BT], %s\n", __func__); 8318c2ecf20Sopenharmony_ci rtl8723e_dm_init_bt_coexist(hw); 8328c2ecf20Sopenharmony_ci } 8338c2ecf20Sopenharmony_ci 8348c2ecf20Sopenharmony_ci tmp_byte = rtl_read_byte(rtlpriv, 0x40); 8358c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 8368c2ecf20Sopenharmony_ci "[DM][BT], 0x40 is 0x%x\n", tmp_byte); 8378c2ecf20Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG, 8388c2ecf20Sopenharmony_ci "[DM][BT], bt_dm_coexist start\n"); 8398c2ecf20Sopenharmony_ci rtl8723e_dm_bt_coexist_8723(hw); 8408c2ecf20Sopenharmony_ci} 841