162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 262306a36Sopenharmony_ci/* Copyright(c) 2009-2014 Realtek Corporation.*/ 362306a36Sopenharmony_ci 462306a36Sopenharmony_ci#include "../wifi.h" 562306a36Sopenharmony_ci#include "../base.h" 662306a36Sopenharmony_ci#include "../pci.h" 762306a36Sopenharmony_ci#include "../core.h" 862306a36Sopenharmony_ci#include "reg.h" 962306a36Sopenharmony_ci#include "def.h" 1062306a36Sopenharmony_ci#include "phy.h" 1162306a36Sopenharmony_ci#include "dm.h" 1262306a36Sopenharmony_ci#include "fw.h" 1362306a36Sopenharmony_ci#include "trx.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic void rtl92ee_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) 1662306a36Sopenharmony_ci{ 1762306a36Sopenharmony_ci u32 ret_value; 1862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 1962306a36Sopenharmony_ci struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1); 2262306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1); 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD); 2562306a36Sopenharmony_ci falsealm_cnt->cnt_fast_fsync_fail = (ret_value & 0xffff); 2662306a36Sopenharmony_ci falsealm_cnt->cnt_sb_search_fail = ((ret_value & 0xffff0000) >> 16); 2762306a36Sopenharmony_ci 2862306a36Sopenharmony_ci ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD); 2962306a36Sopenharmony_ci falsealm_cnt->cnt_ofdm_cca = (ret_value & 0xffff); 3062306a36Sopenharmony_ci falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16); 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD); 3362306a36Sopenharmony_ci falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff); 3462306a36Sopenharmony_ci falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16); 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_ci ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD); 3762306a36Sopenharmony_ci falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff); 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail + 4062306a36Sopenharmony_ci falsealm_cnt->cnt_rate_illegal + 4162306a36Sopenharmony_ci falsealm_cnt->cnt_crc8_fail + 4262306a36Sopenharmony_ci falsealm_cnt->cnt_mcs_fail + 4362306a36Sopenharmony_ci falsealm_cnt->cnt_fast_fsync_fail + 4462306a36Sopenharmony_ci falsealm_cnt->cnt_sb_search_fail; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci ret_value = rtl_get_bbreg(hw, DM_REG_SC_CNT_11N, MASKDWORD); 4762306a36Sopenharmony_ci falsealm_cnt->cnt_bw_lsc = (ret_value & 0xffff); 4862306a36Sopenharmony_ci falsealm_cnt->cnt_bw_usc = ((ret_value & 0xffff0000) >> 16); 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1); 5162306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1); 5262306a36Sopenharmony_ci 5362306a36Sopenharmony_ci ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_LSB_11N, MASKBYTE0); 5462306a36Sopenharmony_ci falsealm_cnt->cnt_cck_fail = ret_value; 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3); 5762306a36Sopenharmony_ci falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8; 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD); 6062306a36Sopenharmony_ci falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) | 6162306a36Sopenharmony_ci ((ret_value & 0xFF00) >> 8); 6262306a36Sopenharmony_ci 6362306a36Sopenharmony_ci falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail + 6462306a36Sopenharmony_ci falsealm_cnt->cnt_sb_search_fail + 6562306a36Sopenharmony_ci falsealm_cnt->cnt_parity_fail + 6662306a36Sopenharmony_ci falsealm_cnt->cnt_rate_illegal + 6762306a36Sopenharmony_ci falsealm_cnt->cnt_crc8_fail + 6862306a36Sopenharmony_ci falsealm_cnt->cnt_mcs_fail + 6962306a36Sopenharmony_ci falsealm_cnt->cnt_cck_fail; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca + 7262306a36Sopenharmony_ci falsealm_cnt->cnt_cck_cca; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci /*reset false alarm counter registers*/ 7562306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1); 7662306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0); 7762306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1); 7862306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0); 7962306a36Sopenharmony_ci /*update ofdm counter*/ 8062306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0); 8162306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0); 8262306a36Sopenharmony_ci /*reset CCK CCA counter*/ 8362306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0); 8462306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2); 8562306a36Sopenharmony_ci /*reset CCK FA counter*/ 8662306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0); 8762306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2); 8862306a36Sopenharmony_ci 8962306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 9062306a36Sopenharmony_ci "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n", 9162306a36Sopenharmony_ci falsealm_cnt->cnt_parity_fail, 9262306a36Sopenharmony_ci falsealm_cnt->cnt_rate_illegal, 9362306a36Sopenharmony_ci falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail); 9462306a36Sopenharmony_ci 9562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 9662306a36Sopenharmony_ci "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n", 9762306a36Sopenharmony_ci falsealm_cnt->cnt_ofdm_fail, 9862306a36Sopenharmony_ci falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all); 9962306a36Sopenharmony_ci} 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_cistatic void rtl92ee_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) 10262306a36Sopenharmony_ci{ 10362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 10462306a36Sopenharmony_ci struct dig_t *dm_dig = &rtlpriv->dm_digtable; 10562306a36Sopenharmony_ci u8 cur_cck_cca_thresh; 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) { 10862306a36Sopenharmony_ci if (dm_dig->rssi_val_min > 25) { 10962306a36Sopenharmony_ci cur_cck_cca_thresh = 0xcd; 11062306a36Sopenharmony_ci } else if ((dm_dig->rssi_val_min <= 25) && 11162306a36Sopenharmony_ci (dm_dig->rssi_val_min > 10)) { 11262306a36Sopenharmony_ci cur_cck_cca_thresh = 0x83; 11362306a36Sopenharmony_ci } else { 11462306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) 11562306a36Sopenharmony_ci cur_cck_cca_thresh = 0x83; 11662306a36Sopenharmony_ci else 11762306a36Sopenharmony_ci cur_cck_cca_thresh = 0x40; 11862306a36Sopenharmony_ci } 11962306a36Sopenharmony_ci } else { 12062306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) 12162306a36Sopenharmony_ci cur_cck_cca_thresh = 0x83; 12262306a36Sopenharmony_ci else 12362306a36Sopenharmony_ci cur_cck_cca_thresh = 0x40; 12462306a36Sopenharmony_ci } 12562306a36Sopenharmony_ci rtl92ee_dm_write_cck_cca_thres(hw, cur_cck_cca_thresh); 12662306a36Sopenharmony_ci} 12762306a36Sopenharmony_ci 12862306a36Sopenharmony_cistatic void rtl92ee_dm_dig(struct ieee80211_hw *hw) 12962306a36Sopenharmony_ci{ 13062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 13162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 13262306a36Sopenharmony_ci struct dig_t *dm_dig = &rtlpriv->dm_digtable; 13362306a36Sopenharmony_ci u8 dig_min_0, dig_maxofmin; 13462306a36Sopenharmony_ci bool bfirstconnect , bfirstdisconnect; 13562306a36Sopenharmony_ci u8 dm_dig_max, dm_dig_min; 13662306a36Sopenharmony_ci u8 current_igi = dm_dig->cur_igvalue; 13762306a36Sopenharmony_ci u8 offset; 13862306a36Sopenharmony_ci 13962306a36Sopenharmony_ci /* AP,BT */ 14062306a36Sopenharmony_ci if (mac->act_scanning) 14162306a36Sopenharmony_ci return; 14262306a36Sopenharmony_ci 14362306a36Sopenharmony_ci dig_min_0 = dm_dig->dig_min_0; 14462306a36Sopenharmony_ci bfirstconnect = (mac->link_state >= MAC80211_LINKED) && 14562306a36Sopenharmony_ci !dm_dig->media_connect_0; 14662306a36Sopenharmony_ci bfirstdisconnect = (mac->link_state < MAC80211_LINKED) && 14762306a36Sopenharmony_ci dm_dig->media_connect_0; 14862306a36Sopenharmony_ci 14962306a36Sopenharmony_ci dm_dig_max = 0x5a; 15062306a36Sopenharmony_ci dm_dig_min = DM_DIG_MIN; 15162306a36Sopenharmony_ci dig_maxofmin = DM_DIG_MAX_AP; 15262306a36Sopenharmony_ci 15362306a36Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 15462306a36Sopenharmony_ci if ((dm_dig->rssi_val_min + 10) > dm_dig_max) 15562306a36Sopenharmony_ci dm_dig->rx_gain_max = dm_dig_max; 15662306a36Sopenharmony_ci else if ((dm_dig->rssi_val_min + 10) < dm_dig_min) 15762306a36Sopenharmony_ci dm_dig->rx_gain_max = dm_dig_min; 15862306a36Sopenharmony_ci else 15962306a36Sopenharmony_ci dm_dig->rx_gain_max = dm_dig->rssi_val_min + 10; 16062306a36Sopenharmony_ci 16162306a36Sopenharmony_ci if (rtlpriv->dm.one_entry_only) { 16262306a36Sopenharmony_ci offset = 0; 16362306a36Sopenharmony_ci if (dm_dig->rssi_val_min - offset < dm_dig_min) 16462306a36Sopenharmony_ci dig_min_0 = dm_dig_min; 16562306a36Sopenharmony_ci else if (dm_dig->rssi_val_min - offset > 16662306a36Sopenharmony_ci dig_maxofmin) 16762306a36Sopenharmony_ci dig_min_0 = dig_maxofmin; 16862306a36Sopenharmony_ci else 16962306a36Sopenharmony_ci dig_min_0 = dm_dig->rssi_val_min - offset; 17062306a36Sopenharmony_ci } else { 17162306a36Sopenharmony_ci dig_min_0 = dm_dig_min; 17262306a36Sopenharmony_ci } 17362306a36Sopenharmony_ci 17462306a36Sopenharmony_ci } else { 17562306a36Sopenharmony_ci dm_dig->rx_gain_max = dm_dig_max; 17662306a36Sopenharmony_ci dig_min_0 = dm_dig_min; 17762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n"); 17862306a36Sopenharmony_ci } 17962306a36Sopenharmony_ci 18062306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > 10000) { 18162306a36Sopenharmony_ci if (dm_dig->large_fa_hit != 3) 18262306a36Sopenharmony_ci dm_dig->large_fa_hit++; 18362306a36Sopenharmony_ci if (dm_dig->forbidden_igi < current_igi) { 18462306a36Sopenharmony_ci dm_dig->forbidden_igi = current_igi; 18562306a36Sopenharmony_ci dm_dig->large_fa_hit = 1; 18662306a36Sopenharmony_ci } 18762306a36Sopenharmony_ci 18862306a36Sopenharmony_ci if (dm_dig->large_fa_hit >= 3) { 18962306a36Sopenharmony_ci if (dm_dig->forbidden_igi + 1 > dm_dig->rx_gain_max) 19062306a36Sopenharmony_ci dm_dig->rx_gain_min = 19162306a36Sopenharmony_ci dm_dig->rx_gain_max; 19262306a36Sopenharmony_ci else 19362306a36Sopenharmony_ci dm_dig->rx_gain_min = 19462306a36Sopenharmony_ci dm_dig->forbidden_igi + 1; 19562306a36Sopenharmony_ci dm_dig->recover_cnt = 3600; 19662306a36Sopenharmony_ci } 19762306a36Sopenharmony_ci } else { 19862306a36Sopenharmony_ci if (dm_dig->recover_cnt != 0) { 19962306a36Sopenharmony_ci dm_dig->recover_cnt--; 20062306a36Sopenharmony_ci } else { 20162306a36Sopenharmony_ci if (dm_dig->large_fa_hit < 3) { 20262306a36Sopenharmony_ci if ((dm_dig->forbidden_igi - 1) < 20362306a36Sopenharmony_ci dig_min_0) { 20462306a36Sopenharmony_ci dm_dig->forbidden_igi = dig_min_0; 20562306a36Sopenharmony_ci dm_dig->rx_gain_min = 20662306a36Sopenharmony_ci dig_min_0; 20762306a36Sopenharmony_ci } else { 20862306a36Sopenharmony_ci dm_dig->forbidden_igi--; 20962306a36Sopenharmony_ci dm_dig->rx_gain_min = 21062306a36Sopenharmony_ci dm_dig->forbidden_igi + 1; 21162306a36Sopenharmony_ci } 21262306a36Sopenharmony_ci } else { 21362306a36Sopenharmony_ci dm_dig->large_fa_hit = 0; 21462306a36Sopenharmony_ci } 21562306a36Sopenharmony_ci } 21662306a36Sopenharmony_ci } 21762306a36Sopenharmony_ci 21862306a36Sopenharmony_ci if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5) 21962306a36Sopenharmony_ci dm_dig->rx_gain_min = dm_dig_min; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_ci if (dm_dig->rx_gain_min > dm_dig->rx_gain_max) 22262306a36Sopenharmony_ci dm_dig->rx_gain_min = dm_dig->rx_gain_max; 22362306a36Sopenharmony_ci 22462306a36Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 22562306a36Sopenharmony_ci if (bfirstconnect) { 22662306a36Sopenharmony_ci if (dm_dig->rssi_val_min <= dig_maxofmin) 22762306a36Sopenharmony_ci current_igi = dm_dig->rssi_val_min; 22862306a36Sopenharmony_ci else 22962306a36Sopenharmony_ci current_igi = dig_maxofmin; 23062306a36Sopenharmony_ci 23162306a36Sopenharmony_ci dm_dig->large_fa_hit = 0; 23262306a36Sopenharmony_ci } else { 23362306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2) 23462306a36Sopenharmony_ci current_igi += 4; 23562306a36Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1) 23662306a36Sopenharmony_ci current_igi += 2; 23762306a36Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) 23862306a36Sopenharmony_ci current_igi -= 2; 23962306a36Sopenharmony_ci 24062306a36Sopenharmony_ci if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 5 && 24162306a36Sopenharmony_ci rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1) 24262306a36Sopenharmony_ci current_igi = dm_dig->rx_gain_min; 24362306a36Sopenharmony_ci } 24462306a36Sopenharmony_ci } else { 24562306a36Sopenharmony_ci if (bfirstdisconnect) { 24662306a36Sopenharmony_ci current_igi = dm_dig->rx_gain_min; 24762306a36Sopenharmony_ci } else { 24862306a36Sopenharmony_ci if (rtlpriv->falsealm_cnt.cnt_all > 10000) 24962306a36Sopenharmony_ci current_igi += 4; 25062306a36Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all > 8000) 25162306a36Sopenharmony_ci current_igi += 2; 25262306a36Sopenharmony_ci else if (rtlpriv->falsealm_cnt.cnt_all < 500) 25362306a36Sopenharmony_ci current_igi -= 2; 25462306a36Sopenharmony_ci } 25562306a36Sopenharmony_ci } 25662306a36Sopenharmony_ci 25762306a36Sopenharmony_ci if (current_igi > dm_dig->rx_gain_max) 25862306a36Sopenharmony_ci current_igi = dm_dig->rx_gain_max; 25962306a36Sopenharmony_ci if (current_igi < dm_dig->rx_gain_min) 26062306a36Sopenharmony_ci current_igi = dm_dig->rx_gain_min; 26162306a36Sopenharmony_ci 26262306a36Sopenharmony_ci rtl92ee_dm_write_dig(hw , current_igi); 26362306a36Sopenharmony_ci dm_dig->media_connect_0 = ((mac->link_state >= MAC80211_LINKED) ? 26462306a36Sopenharmony_ci true : false); 26562306a36Sopenharmony_ci dm_dig->dig_min_0 = dig_min_0; 26662306a36Sopenharmony_ci} 26762306a36Sopenharmony_ci 26862306a36Sopenharmony_civoid rtl92ee_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 cur_thres) 26962306a36Sopenharmony_ci{ 27062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 27162306a36Sopenharmony_ci struct dig_t *dm_dig = &rtlpriv->dm_digtable; 27262306a36Sopenharmony_ci 27362306a36Sopenharmony_ci if (dm_dig->cur_cck_cca_thres != cur_thres) 27462306a36Sopenharmony_ci rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11N, cur_thres); 27562306a36Sopenharmony_ci 27662306a36Sopenharmony_ci dm_dig->pre_cck_cca_thres = dm_dig->cur_cck_cca_thres; 27762306a36Sopenharmony_ci dm_dig->cur_cck_cca_thres = cur_thres; 27862306a36Sopenharmony_ci} 27962306a36Sopenharmony_ci 28062306a36Sopenharmony_civoid rtl92ee_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi) 28162306a36Sopenharmony_ci{ 28262306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 28362306a36Sopenharmony_ci struct dig_t *dm_dig = &rtlpriv->dm_digtable; 28462306a36Sopenharmony_ci 28562306a36Sopenharmony_ci if (dm_dig->stop_dig) 28662306a36Sopenharmony_ci return; 28762306a36Sopenharmony_ci 28862306a36Sopenharmony_ci if (dm_dig->cur_igvalue != current_igi) { 28962306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi); 29062306a36Sopenharmony_ci if (rtlpriv->phy.rf_type != RF_1T1R) 29162306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f, current_igi); 29262306a36Sopenharmony_ci } 29362306a36Sopenharmony_ci dm_dig->pre_igvalue = dm_dig->cur_igvalue; 29462306a36Sopenharmony_ci dm_dig->cur_igvalue = current_igi; 29562306a36Sopenharmony_ci} 29662306a36Sopenharmony_ci 29762306a36Sopenharmony_cistatic void rtl92ee_rssi_dump_to_register(struct ieee80211_hw *hw) 29862306a36Sopenharmony_ci{ 29962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 30062306a36Sopenharmony_ci 30162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RA_RSSIDUMP, 30262306a36Sopenharmony_ci rtlpriv->stats.rx_rssi_percentage[0]); 30362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RB_RSSIDUMP, 30462306a36Sopenharmony_ci rtlpriv->stats.rx_rssi_percentage[1]); 30562306a36Sopenharmony_ci /*It seems the following values are not initialized. 30662306a36Sopenharmony_ci *According to Windows code, 30762306a36Sopenharmony_ci *these value will only be valid with JAGUAR chips 30862306a36Sopenharmony_ci */ 30962306a36Sopenharmony_ci /* Rx EVM */ 31062306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RS1_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[0]); 31162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RS2_RXEVMDUMP, rtlpriv->stats.rx_evm_dbm[1]); 31262306a36Sopenharmony_ci /* Rx SNR */ 31362306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RA_RXSNRDUMP, 31462306a36Sopenharmony_ci (u8)(rtlpriv->stats.rx_snr_db[0])); 31562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, RB_RXSNRDUMP, 31662306a36Sopenharmony_ci (u8)(rtlpriv->stats.rx_snr_db[1])); 31762306a36Sopenharmony_ci /* Rx Cfo_Short */ 31862306a36Sopenharmony_ci rtl_write_word(rtlpriv, RA_CFOSHORTDUMP, 31962306a36Sopenharmony_ci rtlpriv->stats.rx_cfo_short[0]); 32062306a36Sopenharmony_ci rtl_write_word(rtlpriv, RB_CFOSHORTDUMP, 32162306a36Sopenharmony_ci rtlpriv->stats.rx_cfo_short[1]); 32262306a36Sopenharmony_ci /* Rx Cfo_Tail */ 32362306a36Sopenharmony_ci rtl_write_word(rtlpriv, RA_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[0]); 32462306a36Sopenharmony_ci rtl_write_word(rtlpriv, RB_CFOLONGDUMP, rtlpriv->stats.rx_cfo_tail[1]); 32562306a36Sopenharmony_ci} 32662306a36Sopenharmony_ci 32762306a36Sopenharmony_cistatic void rtl92ee_dm_find_minimum_rssi(struct ieee80211_hw *hw) 32862306a36Sopenharmony_ci{ 32962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 33062306a36Sopenharmony_ci struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable; 33162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtlpriv); 33262306a36Sopenharmony_ci 33362306a36Sopenharmony_ci /* Determine the minimum RSSI */ 33462306a36Sopenharmony_ci if ((mac->link_state < MAC80211_LINKED) && 33562306a36Sopenharmony_ci (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) { 33662306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 0; 33762306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 33862306a36Sopenharmony_ci "Not connected to any\n"); 33962306a36Sopenharmony_ci } 34062306a36Sopenharmony_ci if (mac->link_state >= MAC80211_LINKED) { 34162306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP || 34262306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC) { 34362306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 34462306a36Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 34562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 34662306a36Sopenharmony_ci "AP Client PWDB = 0x%lx\n", 34762306a36Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb); 34862306a36Sopenharmony_ci } else { 34962306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 35062306a36Sopenharmony_ci rtlpriv->dm.undec_sm_pwdb; 35162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 35262306a36Sopenharmony_ci "STA Default Port PWDB = 0x%x\n", 35362306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm); 35462306a36Sopenharmony_ci } 35562306a36Sopenharmony_ci } else { 35662306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm = 35762306a36Sopenharmony_ci rtlpriv->dm.entry_min_undec_sm_pwdb; 35862306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 35962306a36Sopenharmony_ci "AP Ext Port or disconnect PWDB = 0x%x\n", 36062306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm); 36162306a36Sopenharmony_ci } 36262306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 36362306a36Sopenharmony_ci "MinUndecoratedPWDBForDM =%d\n", 36462306a36Sopenharmony_ci rtl_dm_dig->min_undec_pwdb_for_dm); 36562306a36Sopenharmony_ci} 36662306a36Sopenharmony_ci 36762306a36Sopenharmony_cistatic void rtl92ee_dm_check_rssi_monitor(struct ieee80211_hw *hw) 36862306a36Sopenharmony_ci{ 36962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 37062306a36Sopenharmony_ci struct dig_t *dm_dig = &rtlpriv->dm_digtable; 37162306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtlpriv); 37262306a36Sopenharmony_ci struct rtl_dm *dm = rtl_dm(rtlpriv); 37362306a36Sopenharmony_ci struct rtl_sta_info *drv_priv; 37462306a36Sopenharmony_ci u8 h2c[4] = { 0 }; 37562306a36Sopenharmony_ci long max = 0, min = 0xff; 37662306a36Sopenharmony_ci u8 i = 0; 37762306a36Sopenharmony_ci 37862306a36Sopenharmony_ci if (mac->opmode == NL80211_IFTYPE_AP || 37962306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_ADHOC || 38062306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_MESH_POINT) { 38162306a36Sopenharmony_ci /* AP & ADHOC & MESH */ 38262306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.entry_list_lock); 38362306a36Sopenharmony_ci list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { 38462306a36Sopenharmony_ci struct rssi_sta *stat = &drv_priv->rssi_stat; 38562306a36Sopenharmony_ci 38662306a36Sopenharmony_ci if (stat->undec_sm_pwdb < min) 38762306a36Sopenharmony_ci min = stat->undec_sm_pwdb; 38862306a36Sopenharmony_ci if (stat->undec_sm_pwdb > max) 38962306a36Sopenharmony_ci max = stat->undec_sm_pwdb; 39062306a36Sopenharmony_ci 39162306a36Sopenharmony_ci h2c[3] = 0; 39262306a36Sopenharmony_ci h2c[2] = (u8)(dm->undec_sm_pwdb & 0xFF); 39362306a36Sopenharmony_ci h2c[1] = 0x20; 39462306a36Sopenharmony_ci h2c[0] = ++i; 39562306a36Sopenharmony_ci rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c); 39662306a36Sopenharmony_ci } 39762306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.entry_list_lock); 39862306a36Sopenharmony_ci 39962306a36Sopenharmony_ci /* If associated entry is found */ 40062306a36Sopenharmony_ci if (max != 0) { 40162306a36Sopenharmony_ci dm->entry_max_undec_sm_pwdb = max; 40262306a36Sopenharmony_ci RTPRINT(rtlpriv, FDM, DM_PWDB, 40362306a36Sopenharmony_ci "EntryMaxPWDB = 0x%lx(%ld)\n", max, max); 40462306a36Sopenharmony_ci } else { 40562306a36Sopenharmony_ci dm->entry_max_undec_sm_pwdb = 0; 40662306a36Sopenharmony_ci } 40762306a36Sopenharmony_ci /* If associated entry is found */ 40862306a36Sopenharmony_ci if (min != 0xff) { 40962306a36Sopenharmony_ci dm->entry_min_undec_sm_pwdb = min; 41062306a36Sopenharmony_ci RTPRINT(rtlpriv, FDM, DM_PWDB, 41162306a36Sopenharmony_ci "EntryMinPWDB = 0x%lx(%ld)\n", min, min); 41262306a36Sopenharmony_ci } else { 41362306a36Sopenharmony_ci dm->entry_min_undec_sm_pwdb = 0; 41462306a36Sopenharmony_ci } 41562306a36Sopenharmony_ci } 41662306a36Sopenharmony_ci 41762306a36Sopenharmony_ci /* Indicate Rx signal strength to FW. */ 41862306a36Sopenharmony_ci if (dm->useramask) { 41962306a36Sopenharmony_ci h2c[3] = 0; 42062306a36Sopenharmony_ci h2c[2] = (u8)(dm->undec_sm_pwdb & 0xFF); 42162306a36Sopenharmony_ci h2c[1] = 0x20; 42262306a36Sopenharmony_ci h2c[0] = 0; 42362306a36Sopenharmony_ci rtl92ee_fill_h2c_cmd(hw, H2C_92E_RSSI_REPORT, 4, h2c); 42462306a36Sopenharmony_ci } else { 42562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, 0x4fe, dm->undec_sm_pwdb); 42662306a36Sopenharmony_ci } 42762306a36Sopenharmony_ci rtl92ee_rssi_dump_to_register(hw); 42862306a36Sopenharmony_ci rtl92ee_dm_find_minimum_rssi(hw); 42962306a36Sopenharmony_ci dm_dig->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm; 43062306a36Sopenharmony_ci} 43162306a36Sopenharmony_ci 43262306a36Sopenharmony_cistatic void rtl92ee_dm_init_primary_cca_check(struct ieee80211_hw *hw) 43362306a36Sopenharmony_ci{ 43462306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 43562306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 43662306a36Sopenharmony_ci struct dynamic_primary_cca *primarycca = &rtlpriv->primarycca; 43762306a36Sopenharmony_ci 43862306a36Sopenharmony_ci rtlhal->rts_en = 0; 43962306a36Sopenharmony_ci primarycca->dup_rts_flag = 0; 44062306a36Sopenharmony_ci primarycca->intf_flag = 0; 44162306a36Sopenharmony_ci primarycca->intf_type = 0; 44262306a36Sopenharmony_ci primarycca->monitor_flag = 0; 44362306a36Sopenharmony_ci primarycca->ch_offset = 0; 44462306a36Sopenharmony_ci primarycca->mf_state = 0; 44562306a36Sopenharmony_ci} 44662306a36Sopenharmony_ci 44762306a36Sopenharmony_cistatic bool rtl92ee_dm_is_edca_turbo_disable(struct ieee80211_hw *hw) 44862306a36Sopenharmony_ci{ 44962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 45062306a36Sopenharmony_ci 45162306a36Sopenharmony_ci if (rtlpriv->mac80211.mode == WIRELESS_MODE_B) 45262306a36Sopenharmony_ci return true; 45362306a36Sopenharmony_ci 45462306a36Sopenharmony_ci return false; 45562306a36Sopenharmony_ci} 45662306a36Sopenharmony_ci 45762306a36Sopenharmony_civoid rtl92ee_dm_init_edca_turbo(struct ieee80211_hw *hw) 45862306a36Sopenharmony_ci{ 45962306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 46062306a36Sopenharmony_ci 46162306a36Sopenharmony_ci rtlpriv->dm.current_turbo_edca = false; 46262306a36Sopenharmony_ci rtlpriv->dm.is_cur_rdlstate = false; 46362306a36Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = false; 46462306a36Sopenharmony_ci} 46562306a36Sopenharmony_ci 46662306a36Sopenharmony_cistatic void rtl92ee_dm_check_edca_turbo(struct ieee80211_hw *hw) 46762306a36Sopenharmony_ci{ 46862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 46962306a36Sopenharmony_ci 47062306a36Sopenharmony_ci static u64 last_txok_cnt; 47162306a36Sopenharmony_ci static u64 last_rxok_cnt; 47262306a36Sopenharmony_ci u64 cur_txok_cnt = 0; 47362306a36Sopenharmony_ci u64 cur_rxok_cnt = 0; 47462306a36Sopenharmony_ci u32 edca_be_ul = 0x5ea42b; 47562306a36Sopenharmony_ci u32 edca_be_dl = 0x5ea42b; /*not sure*/ 47662306a36Sopenharmony_ci u32 edca_be = 0x5ea42b; 47762306a36Sopenharmony_ci bool is_cur_rdlstate; 47862306a36Sopenharmony_ci bool b_edca_turbo_on = false; 47962306a36Sopenharmony_ci 48062306a36Sopenharmony_ci if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100) 48162306a36Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = true; 48262306a36Sopenharmony_ci rtlpriv->dm.dbginfo.num_non_be_pkt = 0; 48362306a36Sopenharmony_ci 48462306a36Sopenharmony_ci cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt; 48562306a36Sopenharmony_ci cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt; 48662306a36Sopenharmony_ci 48762306a36Sopenharmony_ci /*b_bias_on_rx = false;*/ 48862306a36Sopenharmony_ci b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && 48962306a36Sopenharmony_ci (!rtlpriv->dm.disable_framebursting)) ? 49062306a36Sopenharmony_ci true : false; 49162306a36Sopenharmony_ci 49262306a36Sopenharmony_ci if (rtl92ee_dm_is_edca_turbo_disable(hw)) 49362306a36Sopenharmony_ci goto check_exit; 49462306a36Sopenharmony_ci 49562306a36Sopenharmony_ci if (b_edca_turbo_on) { 49662306a36Sopenharmony_ci is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ? 49762306a36Sopenharmony_ci true : false; 49862306a36Sopenharmony_ci 49962306a36Sopenharmony_ci edca_be = is_cur_rdlstate ? edca_be_dl : edca_be_ul; 50062306a36Sopenharmony_ci rtl_write_dword(rtlpriv , REG_EDCA_BE_PARAM , edca_be); 50162306a36Sopenharmony_ci rtlpriv->dm.is_cur_rdlstate = is_cur_rdlstate; 50262306a36Sopenharmony_ci rtlpriv->dm.current_turbo_edca = true; 50362306a36Sopenharmony_ci } else { 50462306a36Sopenharmony_ci if (rtlpriv->dm.current_turbo_edca) { 50562306a36Sopenharmony_ci u8 tmp = AC0_BE; 50662306a36Sopenharmony_ci 50762306a36Sopenharmony_ci rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, 50862306a36Sopenharmony_ci (u8 *)(&tmp)); 50962306a36Sopenharmony_ci } 51062306a36Sopenharmony_ci rtlpriv->dm.current_turbo_edca = false; 51162306a36Sopenharmony_ci } 51262306a36Sopenharmony_ci 51362306a36Sopenharmony_cicheck_exit: 51462306a36Sopenharmony_ci rtlpriv->dm.is_any_nonbepkts = false; 51562306a36Sopenharmony_ci last_txok_cnt = rtlpriv->stats.txbytesunicast; 51662306a36Sopenharmony_ci last_rxok_cnt = rtlpriv->stats.rxbytesunicast; 51762306a36Sopenharmony_ci} 51862306a36Sopenharmony_ci 51962306a36Sopenharmony_cistatic void rtl92ee_dm_dynamic_edcca(struct ieee80211_hw *hw) 52062306a36Sopenharmony_ci{ 52162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 52262306a36Sopenharmony_ci u8 reg_c50 , reg_c58; 52362306a36Sopenharmony_ci bool fw_current_in_ps_mode = false; 52462306a36Sopenharmony_ci 52562306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 52662306a36Sopenharmony_ci (u8 *)(&fw_current_in_ps_mode)); 52762306a36Sopenharmony_ci if (fw_current_in_ps_mode) 52862306a36Sopenharmony_ci return; 52962306a36Sopenharmony_ci 53062306a36Sopenharmony_ci reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); 53162306a36Sopenharmony_ci reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); 53262306a36Sopenharmony_ci 53362306a36Sopenharmony_ci if (reg_c50 > 0x28 && reg_c58 > 0x28) { 53462306a36Sopenharmony_ci if (!rtlpriv->rtlhal.pre_edcca_enable) { 53562306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03); 53662306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00); 53762306a36Sopenharmony_ci rtlpriv->rtlhal.pre_edcca_enable = true; 53862306a36Sopenharmony_ci } 53962306a36Sopenharmony_ci } else if (reg_c50 < 0x25 && reg_c58 < 0x25) { 54062306a36Sopenharmony_ci if (rtlpriv->rtlhal.pre_edcca_enable) { 54162306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f); 54262306a36Sopenharmony_ci rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f); 54362306a36Sopenharmony_ci rtlpriv->rtlhal.pre_edcca_enable = false; 54462306a36Sopenharmony_ci } 54562306a36Sopenharmony_ci } 54662306a36Sopenharmony_ci} 54762306a36Sopenharmony_ci 54862306a36Sopenharmony_cistatic void rtl92ee_dm_adaptivity(struct ieee80211_hw *hw) 54962306a36Sopenharmony_ci{ 55062306a36Sopenharmony_ci rtl92ee_dm_dynamic_edcca(hw); 55162306a36Sopenharmony_ci} 55262306a36Sopenharmony_ci 55362306a36Sopenharmony_cistatic void rtl92ee_dm_write_dynamic_cca(struct ieee80211_hw *hw, 55462306a36Sopenharmony_ci u8 cur_mf_state) 55562306a36Sopenharmony_ci{ 55662306a36Sopenharmony_ci struct dynamic_primary_cca *primarycca = &rtl_priv(hw)->primarycca; 55762306a36Sopenharmony_ci 55862306a36Sopenharmony_ci if (primarycca->mf_state != cur_mf_state) 55962306a36Sopenharmony_ci rtl_set_bbreg(hw, DM_REG_L1SBD_PD_CH_11N, BIT(8) | BIT(7), 56062306a36Sopenharmony_ci cur_mf_state); 56162306a36Sopenharmony_ci 56262306a36Sopenharmony_ci primarycca->mf_state = cur_mf_state; 56362306a36Sopenharmony_ci} 56462306a36Sopenharmony_ci 56562306a36Sopenharmony_cistatic void rtl92ee_dm_dynamic_primary_cca_ckeck(struct ieee80211_hw *hw) 56662306a36Sopenharmony_ci{ 56762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 56862306a36Sopenharmony_ci struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; 56962306a36Sopenharmony_ci struct dynamic_primary_cca *primarycca = &rtlpriv->primarycca; 57062306a36Sopenharmony_ci bool is40mhz = false; 57162306a36Sopenharmony_ci u64 ofdm_cca, ofdm_fa, bw_usc_cnt, bw_lsc_cnt; 57262306a36Sopenharmony_ci u8 sec_ch_offset; 57362306a36Sopenharmony_ci u8 cur_mf_state; 57462306a36Sopenharmony_ci static u8 count_down = MONITOR_TIME; 57562306a36Sopenharmony_ci 57662306a36Sopenharmony_ci ofdm_cca = falsealm_cnt->cnt_ofdm_cca; 57762306a36Sopenharmony_ci ofdm_fa = falsealm_cnt->cnt_ofdm_fail; 57862306a36Sopenharmony_ci bw_usc_cnt = falsealm_cnt->cnt_bw_usc; 57962306a36Sopenharmony_ci bw_lsc_cnt = falsealm_cnt->cnt_bw_lsc; 58062306a36Sopenharmony_ci is40mhz = rtlpriv->mac80211.bw_40; 58162306a36Sopenharmony_ci sec_ch_offset = rtlpriv->mac80211.cur_40_prime_sc; 58262306a36Sopenharmony_ci /* NIC: 2: sec is below, 1: sec is above */ 58362306a36Sopenharmony_ci 58462306a36Sopenharmony_ci if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP) { 58562306a36Sopenharmony_ci cur_mf_state = MF_USC_LSC; 58662306a36Sopenharmony_ci rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); 58762306a36Sopenharmony_ci return; 58862306a36Sopenharmony_ci } 58962306a36Sopenharmony_ci 59062306a36Sopenharmony_ci if (rtlpriv->mac80211.link_state < MAC80211_LINKED) 59162306a36Sopenharmony_ci return; 59262306a36Sopenharmony_ci 59362306a36Sopenharmony_ci if (is40mhz) 59462306a36Sopenharmony_ci return; 59562306a36Sopenharmony_ci 59662306a36Sopenharmony_ci if (primarycca->pricca_flag == 0) { 59762306a36Sopenharmony_ci /* Primary channel is above 59862306a36Sopenharmony_ci * NOTE: duplicate CTS can remove this condition 59962306a36Sopenharmony_ci */ 60062306a36Sopenharmony_ci if (sec_ch_offset == 2) { 60162306a36Sopenharmony_ci if ((ofdm_cca > OFDMCCA_TH) && 60262306a36Sopenharmony_ci (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) && 60362306a36Sopenharmony_ci (ofdm_fa > (ofdm_cca >> 1))) { 60462306a36Sopenharmony_ci primarycca->intf_type = 1; 60562306a36Sopenharmony_ci primarycca->intf_flag = 1; 60662306a36Sopenharmony_ci cur_mf_state = MF_USC; 60762306a36Sopenharmony_ci rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); 60862306a36Sopenharmony_ci primarycca->pricca_flag = 1; 60962306a36Sopenharmony_ci } else if ((ofdm_cca > OFDMCCA_TH) && 61062306a36Sopenharmony_ci (bw_lsc_cnt > (bw_usc_cnt + BW_IND_BIAS)) && 61162306a36Sopenharmony_ci (ofdm_fa < (ofdm_cca >> 1))) { 61262306a36Sopenharmony_ci primarycca->intf_type = 2; 61362306a36Sopenharmony_ci primarycca->intf_flag = 1; 61462306a36Sopenharmony_ci cur_mf_state = MF_USC; 61562306a36Sopenharmony_ci rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); 61662306a36Sopenharmony_ci primarycca->pricca_flag = 1; 61762306a36Sopenharmony_ci primarycca->dup_rts_flag = 1; 61862306a36Sopenharmony_ci rtlpriv->rtlhal.rts_en = 1; 61962306a36Sopenharmony_ci } else { 62062306a36Sopenharmony_ci primarycca->intf_type = 0; 62162306a36Sopenharmony_ci primarycca->intf_flag = 0; 62262306a36Sopenharmony_ci cur_mf_state = MF_USC_LSC; 62362306a36Sopenharmony_ci rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); 62462306a36Sopenharmony_ci rtlpriv->rtlhal.rts_en = 0; 62562306a36Sopenharmony_ci primarycca->dup_rts_flag = 0; 62662306a36Sopenharmony_ci } 62762306a36Sopenharmony_ci } else if (sec_ch_offset == 1) { 62862306a36Sopenharmony_ci if ((ofdm_cca > OFDMCCA_TH) && 62962306a36Sopenharmony_ci (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) && 63062306a36Sopenharmony_ci (ofdm_fa > (ofdm_cca >> 1))) { 63162306a36Sopenharmony_ci primarycca->intf_type = 1; 63262306a36Sopenharmony_ci primarycca->intf_flag = 1; 63362306a36Sopenharmony_ci cur_mf_state = MF_LSC; 63462306a36Sopenharmony_ci rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); 63562306a36Sopenharmony_ci primarycca->pricca_flag = 1; 63662306a36Sopenharmony_ci } else if ((ofdm_cca > OFDMCCA_TH) && 63762306a36Sopenharmony_ci (bw_usc_cnt > (bw_lsc_cnt + BW_IND_BIAS)) && 63862306a36Sopenharmony_ci (ofdm_fa < (ofdm_cca >> 1))) { 63962306a36Sopenharmony_ci primarycca->intf_type = 2; 64062306a36Sopenharmony_ci primarycca->intf_flag = 1; 64162306a36Sopenharmony_ci cur_mf_state = MF_LSC; 64262306a36Sopenharmony_ci rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); 64362306a36Sopenharmony_ci primarycca->pricca_flag = 1; 64462306a36Sopenharmony_ci primarycca->dup_rts_flag = 1; 64562306a36Sopenharmony_ci rtlpriv->rtlhal.rts_en = 1; 64662306a36Sopenharmony_ci } else { 64762306a36Sopenharmony_ci primarycca->intf_type = 0; 64862306a36Sopenharmony_ci primarycca->intf_flag = 0; 64962306a36Sopenharmony_ci cur_mf_state = MF_USC_LSC; 65062306a36Sopenharmony_ci rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); 65162306a36Sopenharmony_ci rtlpriv->rtlhal.rts_en = 0; 65262306a36Sopenharmony_ci primarycca->dup_rts_flag = 0; 65362306a36Sopenharmony_ci } 65462306a36Sopenharmony_ci } 65562306a36Sopenharmony_ci } else {/* PrimaryCCA->PriCCA_flag==1 */ 65662306a36Sopenharmony_ci count_down--; 65762306a36Sopenharmony_ci if (count_down == 0) { 65862306a36Sopenharmony_ci count_down = MONITOR_TIME; 65962306a36Sopenharmony_ci primarycca->pricca_flag = 0; 66062306a36Sopenharmony_ci cur_mf_state = MF_USC_LSC; 66162306a36Sopenharmony_ci /* default */ 66262306a36Sopenharmony_ci rtl92ee_dm_write_dynamic_cca(hw, cur_mf_state); 66362306a36Sopenharmony_ci rtlpriv->rtlhal.rts_en = 0; 66462306a36Sopenharmony_ci primarycca->dup_rts_flag = 0; 66562306a36Sopenharmony_ci primarycca->intf_type = 0; 66662306a36Sopenharmony_ci primarycca->intf_flag = 0; 66762306a36Sopenharmony_ci } 66862306a36Sopenharmony_ci } 66962306a36Sopenharmony_ci} 67062306a36Sopenharmony_ci 67162306a36Sopenharmony_cistatic void rtl92ee_dm_dynamic_atc_switch(struct ieee80211_hw *hw) 67262306a36Sopenharmony_ci{ 67362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 67462306a36Sopenharmony_ci struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 67562306a36Sopenharmony_ci u8 crystal_cap; 67662306a36Sopenharmony_ci u32 packet_count; 67762306a36Sopenharmony_ci int cfo_khz_a , cfo_khz_b , cfo_ave = 0, adjust_xtal = 0; 67862306a36Sopenharmony_ci int cfo_ave_diff; 67962306a36Sopenharmony_ci 68062306a36Sopenharmony_ci if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { 68162306a36Sopenharmony_ci if (rtldm->atc_status == ATC_STATUS_OFF) { 68262306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), 68362306a36Sopenharmony_ci ATC_STATUS_ON); 68462306a36Sopenharmony_ci rtldm->atc_status = ATC_STATUS_ON; 68562306a36Sopenharmony_ci } 68662306a36Sopenharmony_ci /* Disable CFO tracking for BT */ 68762306a36Sopenharmony_ci if (rtlpriv->cfg->ops->get_btc_status()) { 68862306a36Sopenharmony_ci if (!rtlpriv->btcoexist.btc_ops-> 68962306a36Sopenharmony_ci btc_is_bt_disabled(rtlpriv)) { 69062306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD, 69162306a36Sopenharmony_ci "odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n"); 69262306a36Sopenharmony_ci return; 69362306a36Sopenharmony_ci } 69462306a36Sopenharmony_ci } 69562306a36Sopenharmony_ci /* Reset Crystal Cap */ 69662306a36Sopenharmony_ci if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) { 69762306a36Sopenharmony_ci rtldm->crystal_cap = rtlpriv->efuse.crystalcap; 69862306a36Sopenharmony_ci crystal_cap = rtldm->crystal_cap & 0x3f; 69962306a36Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, 70062306a36Sopenharmony_ci (crystal_cap | (crystal_cap << 6))); 70162306a36Sopenharmony_ci } 70262306a36Sopenharmony_ci } else { 70362306a36Sopenharmony_ci cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280; 70462306a36Sopenharmony_ci cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280; 70562306a36Sopenharmony_ci packet_count = rtldm->packet_count; 70662306a36Sopenharmony_ci 70762306a36Sopenharmony_ci if (packet_count == rtldm->packet_count_pre) 70862306a36Sopenharmony_ci return; 70962306a36Sopenharmony_ci 71062306a36Sopenharmony_ci rtldm->packet_count_pre = packet_count; 71162306a36Sopenharmony_ci 71262306a36Sopenharmony_ci if (rtlpriv->phy.rf_type == RF_1T1R) 71362306a36Sopenharmony_ci cfo_ave = cfo_khz_a; 71462306a36Sopenharmony_ci else 71562306a36Sopenharmony_ci cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1; 71662306a36Sopenharmony_ci 71762306a36Sopenharmony_ci cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ? 71862306a36Sopenharmony_ci (rtldm->cfo_ave_pre - cfo_ave) : 71962306a36Sopenharmony_ci (cfo_ave - rtldm->cfo_ave_pre); 72062306a36Sopenharmony_ci 72162306a36Sopenharmony_ci if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) { 72262306a36Sopenharmony_ci rtldm->large_cfo_hit = true; 72362306a36Sopenharmony_ci return; 72462306a36Sopenharmony_ci } 72562306a36Sopenharmony_ci rtldm->large_cfo_hit = false; 72662306a36Sopenharmony_ci 72762306a36Sopenharmony_ci rtldm->cfo_ave_pre = cfo_ave; 72862306a36Sopenharmony_ci 72962306a36Sopenharmony_ci if (cfo_ave >= -rtldm->cfo_threshold && 73062306a36Sopenharmony_ci cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) { 73162306a36Sopenharmony_ci if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) { 73262306a36Sopenharmony_ci rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10; 73362306a36Sopenharmony_ci rtldm->is_freeze = 1; 73462306a36Sopenharmony_ci } else { 73562306a36Sopenharmony_ci rtldm->cfo_threshold = CFO_THRESHOLD_XTAL; 73662306a36Sopenharmony_ci } 73762306a36Sopenharmony_ci } 73862306a36Sopenharmony_ci 73962306a36Sopenharmony_ci if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f) 74062306a36Sopenharmony_ci adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1; 74162306a36Sopenharmony_ci else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && 74262306a36Sopenharmony_ci rtlpriv->dm.crystal_cap > 0) 74362306a36Sopenharmony_ci adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1; 74462306a36Sopenharmony_ci 74562306a36Sopenharmony_ci if (adjust_xtal != 0) { 74662306a36Sopenharmony_ci rtldm->is_freeze = 0; 74762306a36Sopenharmony_ci rtldm->crystal_cap += adjust_xtal; 74862306a36Sopenharmony_ci 74962306a36Sopenharmony_ci if (rtldm->crystal_cap > 0x3f) 75062306a36Sopenharmony_ci rtldm->crystal_cap = 0x3f; 75162306a36Sopenharmony_ci else if (rtldm->crystal_cap < 0) 75262306a36Sopenharmony_ci rtldm->crystal_cap = 0; 75362306a36Sopenharmony_ci 75462306a36Sopenharmony_ci crystal_cap = rtldm->crystal_cap & 0x3f; 75562306a36Sopenharmony_ci rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, 75662306a36Sopenharmony_ci (crystal_cap | (crystal_cap << 6))); 75762306a36Sopenharmony_ci } 75862306a36Sopenharmony_ci 75962306a36Sopenharmony_ci if (cfo_ave < CFO_THRESHOLD_ATC && 76062306a36Sopenharmony_ci cfo_ave > -CFO_THRESHOLD_ATC) { 76162306a36Sopenharmony_ci if (rtldm->atc_status == ATC_STATUS_ON) { 76262306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), 76362306a36Sopenharmony_ci ATC_STATUS_OFF); 76462306a36Sopenharmony_ci rtldm->atc_status = ATC_STATUS_OFF; 76562306a36Sopenharmony_ci } 76662306a36Sopenharmony_ci } else { 76762306a36Sopenharmony_ci if (rtldm->atc_status == ATC_STATUS_OFF) { 76862306a36Sopenharmony_ci rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11), 76962306a36Sopenharmony_ci ATC_STATUS_ON); 77062306a36Sopenharmony_ci rtldm->atc_status = ATC_STATUS_ON; 77162306a36Sopenharmony_ci } 77262306a36Sopenharmony_ci } 77362306a36Sopenharmony_ci } 77462306a36Sopenharmony_ci} 77562306a36Sopenharmony_ci 77662306a36Sopenharmony_cistatic void rtl92ee_dm_init_txpower_tracking(struct ieee80211_hw *hw) 77762306a36Sopenharmony_ci{ 77862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 77962306a36Sopenharmony_ci struct rtl_dm *dm = rtl_dm(rtlpriv); 78062306a36Sopenharmony_ci u8 path; 78162306a36Sopenharmony_ci 78262306a36Sopenharmony_ci dm->txpower_tracking = true; 78362306a36Sopenharmony_ci dm->default_ofdm_index = 30; 78462306a36Sopenharmony_ci dm->default_cck_index = 20; 78562306a36Sopenharmony_ci 78662306a36Sopenharmony_ci dm->swing_idx_cck_base = dm->default_cck_index; 78762306a36Sopenharmony_ci dm->cck_index = dm->default_cck_index; 78862306a36Sopenharmony_ci 78962306a36Sopenharmony_ci for (path = RF90_PATH_A; path < MAX_RF_PATH; path++) { 79062306a36Sopenharmony_ci dm->swing_idx_ofdm_base[path] = dm->default_ofdm_index; 79162306a36Sopenharmony_ci dm->ofdm_index[path] = dm->default_ofdm_index; 79262306a36Sopenharmony_ci dm->delta_power_index[path] = 0; 79362306a36Sopenharmony_ci dm->delta_power_index_last[path] = 0; 79462306a36Sopenharmony_ci dm->power_index_offset[path] = 0; 79562306a36Sopenharmony_ci } 79662306a36Sopenharmony_ci} 79762306a36Sopenharmony_ci 79862306a36Sopenharmony_civoid rtl92ee_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw) 79962306a36Sopenharmony_ci{ 80062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 80162306a36Sopenharmony_ci struct rate_adaptive *p_ra = &rtlpriv->ra; 80262306a36Sopenharmony_ci 80362306a36Sopenharmony_ci p_ra->ratr_state = DM_RATR_STA_INIT; 80462306a36Sopenharmony_ci p_ra->pre_ratr_state = DM_RATR_STA_INIT; 80562306a36Sopenharmony_ci 80662306a36Sopenharmony_ci if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) 80762306a36Sopenharmony_ci rtlpriv->dm.useramask = true; 80862306a36Sopenharmony_ci else 80962306a36Sopenharmony_ci rtlpriv->dm.useramask = false; 81062306a36Sopenharmony_ci 81162306a36Sopenharmony_ci p_ra->ldpc_thres = 35; 81262306a36Sopenharmony_ci p_ra->use_ldpc = false; 81362306a36Sopenharmony_ci p_ra->high_rssi_thresh_for_ra = 50; 81462306a36Sopenharmony_ci p_ra->low_rssi_thresh_for_ra40m = 20; 81562306a36Sopenharmony_ci} 81662306a36Sopenharmony_ci 81762306a36Sopenharmony_cistatic bool _rtl92ee_dm_ra_state_check(struct ieee80211_hw *hw, 81862306a36Sopenharmony_ci s32 rssi, u8 *ratr_state) 81962306a36Sopenharmony_ci{ 82062306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 82162306a36Sopenharmony_ci struct rate_adaptive *p_ra = &rtlpriv->ra; 82262306a36Sopenharmony_ci const u8 go_up_gap = 5; 82362306a36Sopenharmony_ci u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra; 82462306a36Sopenharmony_ci u32 low_rssithresh_for_ra = p_ra->low_rssi_thresh_for_ra40m; 82562306a36Sopenharmony_ci u8 state; 82662306a36Sopenharmony_ci 82762306a36Sopenharmony_ci /* Threshold Adjustment: 82862306a36Sopenharmony_ci * when RSSI state trends to go up one or two levels, 82962306a36Sopenharmony_ci * make sure RSSI is high enough. 83062306a36Sopenharmony_ci * Here GoUpGap is added to solve 83162306a36Sopenharmony_ci * the boundary's level alternation issue. 83262306a36Sopenharmony_ci */ 83362306a36Sopenharmony_ci switch (*ratr_state) { 83462306a36Sopenharmony_ci case DM_RATR_STA_INIT: 83562306a36Sopenharmony_ci case DM_RATR_STA_HIGH: 83662306a36Sopenharmony_ci break; 83762306a36Sopenharmony_ci case DM_RATR_STA_MIDDLE: 83862306a36Sopenharmony_ci high_rssithresh_for_ra += go_up_gap; 83962306a36Sopenharmony_ci break; 84062306a36Sopenharmony_ci case DM_RATR_STA_LOW: 84162306a36Sopenharmony_ci high_rssithresh_for_ra += go_up_gap; 84262306a36Sopenharmony_ci low_rssithresh_for_ra += go_up_gap; 84362306a36Sopenharmony_ci break; 84462306a36Sopenharmony_ci default: 84562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATR, DBG_DMESG, 84662306a36Sopenharmony_ci "wrong rssi level setting %d !\n", *ratr_state); 84762306a36Sopenharmony_ci break; 84862306a36Sopenharmony_ci } 84962306a36Sopenharmony_ci 85062306a36Sopenharmony_ci /* Decide RATRState by RSSI. */ 85162306a36Sopenharmony_ci if (rssi > high_rssithresh_for_ra) 85262306a36Sopenharmony_ci state = DM_RATR_STA_HIGH; 85362306a36Sopenharmony_ci else if (rssi > low_rssithresh_for_ra) 85462306a36Sopenharmony_ci state = DM_RATR_STA_MIDDLE; 85562306a36Sopenharmony_ci else 85662306a36Sopenharmony_ci state = DM_RATR_STA_LOW; 85762306a36Sopenharmony_ci 85862306a36Sopenharmony_ci if (*ratr_state != state) { 85962306a36Sopenharmony_ci *ratr_state = state; 86062306a36Sopenharmony_ci return true; 86162306a36Sopenharmony_ci } 86262306a36Sopenharmony_ci 86362306a36Sopenharmony_ci return false; 86462306a36Sopenharmony_ci} 86562306a36Sopenharmony_ci 86662306a36Sopenharmony_cistatic void rtl92ee_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) 86762306a36Sopenharmony_ci{ 86862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 86962306a36Sopenharmony_ci struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 87062306a36Sopenharmony_ci struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 87162306a36Sopenharmony_ci struct rate_adaptive *p_ra = &rtlpriv->ra; 87262306a36Sopenharmony_ci struct ieee80211_sta *sta = NULL; 87362306a36Sopenharmony_ci 87462306a36Sopenharmony_ci if (is_hal_stop(rtlhal)) { 87562306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 87662306a36Sopenharmony_ci "driver is going to unload\n"); 87762306a36Sopenharmony_ci return; 87862306a36Sopenharmony_ci } 87962306a36Sopenharmony_ci 88062306a36Sopenharmony_ci if (!rtlpriv->dm.useramask) { 88162306a36Sopenharmony_ci rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 88262306a36Sopenharmony_ci "driver does not control rate adaptive mask\n"); 88362306a36Sopenharmony_ci return; 88462306a36Sopenharmony_ci } 88562306a36Sopenharmony_ci 88662306a36Sopenharmony_ci if (mac->link_state == MAC80211_LINKED && 88762306a36Sopenharmony_ci mac->opmode == NL80211_IFTYPE_STATION) { 88862306a36Sopenharmony_ci if (rtlpriv->dm.undec_sm_pwdb < p_ra->ldpc_thres) { 88962306a36Sopenharmony_ci p_ra->use_ldpc = true; 89062306a36Sopenharmony_ci p_ra->lower_rts_rate = true; 89162306a36Sopenharmony_ci } else if (rtlpriv->dm.undec_sm_pwdb > 89262306a36Sopenharmony_ci (p_ra->ldpc_thres - 5)) { 89362306a36Sopenharmony_ci p_ra->use_ldpc = false; 89462306a36Sopenharmony_ci p_ra->lower_rts_rate = false; 89562306a36Sopenharmony_ci } 89662306a36Sopenharmony_ci if (_rtl92ee_dm_ra_state_check(hw, rtlpriv->dm.undec_sm_pwdb, 89762306a36Sopenharmony_ci &p_ra->ratr_state)) { 89862306a36Sopenharmony_ci rcu_read_lock(); 89962306a36Sopenharmony_ci sta = rtl_find_sta(hw, mac->bssid); 90062306a36Sopenharmony_ci if (sta) 90162306a36Sopenharmony_ci rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 90262306a36Sopenharmony_ci p_ra->ratr_state, 90362306a36Sopenharmony_ci true); 90462306a36Sopenharmony_ci rcu_read_unlock(); 90562306a36Sopenharmony_ci 90662306a36Sopenharmony_ci p_ra->pre_ratr_state = p_ra->ratr_state; 90762306a36Sopenharmony_ci } 90862306a36Sopenharmony_ci } 90962306a36Sopenharmony_ci} 91062306a36Sopenharmony_ci 91162306a36Sopenharmony_cistatic void rtl92ee_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw) 91262306a36Sopenharmony_ci{ 91362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 91462306a36Sopenharmony_ci 91562306a36Sopenharmony_ci rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap; 91662306a36Sopenharmony_ci 91762306a36Sopenharmony_ci rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11)); 91862306a36Sopenharmony_ci rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL; 91962306a36Sopenharmony_ci} 92062306a36Sopenharmony_ci 92162306a36Sopenharmony_civoid rtl92ee_dm_init(struct ieee80211_hw *hw) 92262306a36Sopenharmony_ci{ 92362306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 92462306a36Sopenharmony_ci u32 cur_igvalue = rtl_get_bbreg(hw, DM_REG_IGI_A_11N, DM_BIT_IGI_11N); 92562306a36Sopenharmony_ci 92662306a36Sopenharmony_ci rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER; 92762306a36Sopenharmony_ci 92862306a36Sopenharmony_ci rtl_dm_diginit(hw, cur_igvalue); 92962306a36Sopenharmony_ci rtl92ee_dm_init_rate_adaptive_mask(hw); 93062306a36Sopenharmony_ci rtl92ee_dm_init_primary_cca_check(hw); 93162306a36Sopenharmony_ci rtl92ee_dm_init_edca_turbo(hw); 93262306a36Sopenharmony_ci rtl92ee_dm_init_txpower_tracking(hw); 93362306a36Sopenharmony_ci rtl92ee_dm_init_dynamic_atc_switch(hw); 93462306a36Sopenharmony_ci} 93562306a36Sopenharmony_ci 93662306a36Sopenharmony_cistatic void rtl92ee_dm_common_info_self_update(struct ieee80211_hw *hw) 93762306a36Sopenharmony_ci{ 93862306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 93962306a36Sopenharmony_ci struct rtl_sta_info *drv_priv; 94062306a36Sopenharmony_ci u8 cnt = 0; 94162306a36Sopenharmony_ci 94262306a36Sopenharmony_ci rtlpriv->dm.one_entry_only = false; 94362306a36Sopenharmony_ci 94462306a36Sopenharmony_ci if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION && 94562306a36Sopenharmony_ci rtlpriv->mac80211.link_state >= MAC80211_LINKED) { 94662306a36Sopenharmony_ci rtlpriv->dm.one_entry_only = true; 94762306a36Sopenharmony_ci return; 94862306a36Sopenharmony_ci } 94962306a36Sopenharmony_ci 95062306a36Sopenharmony_ci if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || 95162306a36Sopenharmony_ci rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC || 95262306a36Sopenharmony_ci rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) { 95362306a36Sopenharmony_ci spin_lock_bh(&rtlpriv->locks.entry_list_lock); 95462306a36Sopenharmony_ci list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) { 95562306a36Sopenharmony_ci cnt++; 95662306a36Sopenharmony_ci } 95762306a36Sopenharmony_ci spin_unlock_bh(&rtlpriv->locks.entry_list_lock); 95862306a36Sopenharmony_ci 95962306a36Sopenharmony_ci if (cnt == 1) 96062306a36Sopenharmony_ci rtlpriv->dm.one_entry_only = true; 96162306a36Sopenharmony_ci } 96262306a36Sopenharmony_ci} 96362306a36Sopenharmony_ci 96462306a36Sopenharmony_civoid rtl92ee_dm_dynamic_arfb_select(struct ieee80211_hw *hw, 96562306a36Sopenharmony_ci u8 rate, bool collision_state) 96662306a36Sopenharmony_ci{ 96762306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 96862306a36Sopenharmony_ci 96962306a36Sopenharmony_ci if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS12) { 97062306a36Sopenharmony_ci if (collision_state == 1) { 97162306a36Sopenharmony_ci if (rate == DESC92C_RATEMCS12) { 97262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); 97362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 97462306a36Sopenharmony_ci 0x07060501); 97562306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS11) { 97662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); 97762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 97862306a36Sopenharmony_ci 0x07070605); 97962306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS10) { 98062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); 98162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 98262306a36Sopenharmony_ci 0x08080706); 98362306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS9) { 98462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); 98562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 98662306a36Sopenharmony_ci 0x08080707); 98762306a36Sopenharmony_ci } else { 98862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 0x0); 98962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 99062306a36Sopenharmony_ci 0x09090808); 99162306a36Sopenharmony_ci } 99262306a36Sopenharmony_ci } else { /* collision_state == 0 */ 99362306a36Sopenharmony_ci if (rate == DESC92C_RATEMCS12) { 99462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 99562306a36Sopenharmony_ci 0x05010000); 99662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 99762306a36Sopenharmony_ci 0x09080706); 99862306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS11) { 99962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 100062306a36Sopenharmony_ci 0x06050000); 100162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 100262306a36Sopenharmony_ci 0x09080807); 100362306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS10) { 100462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 100562306a36Sopenharmony_ci 0x07060000); 100662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 100762306a36Sopenharmony_ci 0x0a090908); 100862306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS9) { 100962306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 101062306a36Sopenharmony_ci 0x07070000); 101162306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 101262306a36Sopenharmony_ci 0x0a090808); 101362306a36Sopenharmony_ci } else { 101462306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 101562306a36Sopenharmony_ci 0x08080000); 101662306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 101762306a36Sopenharmony_ci 0x0b0a0909); 101862306a36Sopenharmony_ci } 101962306a36Sopenharmony_ci } 102062306a36Sopenharmony_ci } else { /* MCS13~MCS15, 1SS, G-mode */ 102162306a36Sopenharmony_ci if (collision_state == 1) { 102262306a36Sopenharmony_ci if (rate == DESC92C_RATEMCS15) { 102362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 102462306a36Sopenharmony_ci 0x00000000); 102562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 102662306a36Sopenharmony_ci 0x05040302); 102762306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS14) { 102862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 102962306a36Sopenharmony_ci 0x00000000); 103062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 103162306a36Sopenharmony_ci 0x06050302); 103262306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS13) { 103362306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 103462306a36Sopenharmony_ci 0x00000000); 103562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 103662306a36Sopenharmony_ci 0x07060502); 103762306a36Sopenharmony_ci } else { 103862306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 103962306a36Sopenharmony_ci 0x00000000); 104062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 104162306a36Sopenharmony_ci 0x06050402); 104262306a36Sopenharmony_ci } 104362306a36Sopenharmony_ci } else{ /* collision_state == 0 */ 104462306a36Sopenharmony_ci if (rate == DESC92C_RATEMCS15) { 104562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 104662306a36Sopenharmony_ci 0x03020000); 104762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 104862306a36Sopenharmony_ci 0x07060504); 104962306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS14) { 105062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 105162306a36Sopenharmony_ci 0x03020000); 105262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 105362306a36Sopenharmony_ci 0x08070605); 105462306a36Sopenharmony_ci } else if (rate == DESC92C_RATEMCS13) { 105562306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 105662306a36Sopenharmony_ci 0x05020000); 105762306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 105862306a36Sopenharmony_ci 0x09080706); 105962306a36Sopenharmony_ci } else { 106062306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC, 106162306a36Sopenharmony_ci 0x04020000); 106262306a36Sopenharmony_ci rtl_write_dword(rtlpriv, REG_DARFRC + 4, 106362306a36Sopenharmony_ci 0x08070605); 106462306a36Sopenharmony_ci } 106562306a36Sopenharmony_ci } 106662306a36Sopenharmony_ci } 106762306a36Sopenharmony_ci} 106862306a36Sopenharmony_ci 106962306a36Sopenharmony_civoid rtl92ee_dm_watchdog(struct ieee80211_hw *hw) 107062306a36Sopenharmony_ci{ 107162306a36Sopenharmony_ci struct rtl_priv *rtlpriv = rtl_priv(hw); 107262306a36Sopenharmony_ci struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 107362306a36Sopenharmony_ci bool fw_current_inpsmode = false; 107462306a36Sopenharmony_ci bool fw_ps_awake = true; 107562306a36Sopenharmony_ci 107662306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 107762306a36Sopenharmony_ci (u8 *)(&fw_current_inpsmode)); 107862306a36Sopenharmony_ci rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, 107962306a36Sopenharmony_ci (u8 *)(&fw_ps_awake)); 108062306a36Sopenharmony_ci if (ppsc->p2p_ps_info.p2p_ps_mode) 108162306a36Sopenharmony_ci fw_ps_awake = false; 108262306a36Sopenharmony_ci 108362306a36Sopenharmony_ci spin_lock(&rtlpriv->locks.rf_ps_lock); 108462306a36Sopenharmony_ci if ((ppsc->rfpwr_state == ERFON) && 108562306a36Sopenharmony_ci ((!fw_current_inpsmode) && fw_ps_awake) && 108662306a36Sopenharmony_ci (!ppsc->rfchange_inprogress)) { 108762306a36Sopenharmony_ci rtl92ee_dm_common_info_self_update(hw); 108862306a36Sopenharmony_ci rtl92ee_dm_false_alarm_counter_statistics(hw); 108962306a36Sopenharmony_ci rtl92ee_dm_check_rssi_monitor(hw); 109062306a36Sopenharmony_ci rtl92ee_dm_dig(hw); 109162306a36Sopenharmony_ci rtl92ee_dm_adaptivity(hw); 109262306a36Sopenharmony_ci rtl92ee_dm_cck_packet_detection_thresh(hw); 109362306a36Sopenharmony_ci rtl92ee_dm_refresh_rate_adaptive_mask(hw); 109462306a36Sopenharmony_ci rtl92ee_dm_check_edca_turbo(hw); 109562306a36Sopenharmony_ci rtl92ee_dm_dynamic_atc_switch(hw); 109662306a36Sopenharmony_ci rtl92ee_dm_dynamic_primary_cca_ckeck(hw); 109762306a36Sopenharmony_ci } 109862306a36Sopenharmony_ci spin_unlock(&rtlpriv->locks.rf_ps_lock); 109962306a36Sopenharmony_ci} 1100