cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

dm.c (24994B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright(c) 2009-2012  Realtek Corporation.*/
      3
      4#include "../wifi.h"
      5#include "../base.h"
      6#include "../pci.h"
      7#include "../core.h"
      8#include "reg.h"
      9#include "def.h"
     10#include "phy.h"
     11#include "dm.h"
     12#include "../rtl8723com/dm_common.h"
     13#include "fw.h"
     14#include "hal_btc.h"
     15
     16static u8 rtl8723e_dm_initial_gain_min_pwdb(struct ieee80211_hw *hw)
     17{
     18	struct rtl_priv *rtlpriv = rtl_priv(hw);
     19	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
     20	struct rtl_mac *mac = rtl_mac(rtlpriv);
     21	long rssi_val_min = 0;
     22
     23	if (mac->link_state == MAC80211_LINKED &&
     24	    mac->opmode == NL80211_IFTYPE_STATION &&
     25	    rtlpriv->link_info.bcn_rx_inperiod == 0)
     26		return 0;
     27
     28	if ((dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) &&
     29	    (dm_digtable->cursta_cstate == DIG_STA_CONNECT)) {
     30		if (rtlpriv->dm.entry_min_undec_sm_pwdb != 0)
     31			rssi_val_min =
     32			    (rtlpriv->dm.entry_min_undec_sm_pwdb >
     33			     rtlpriv->dm.undec_sm_pwdb) ?
     34			    rtlpriv->dm.undec_sm_pwdb :
     35			    rtlpriv->dm.entry_min_undec_sm_pwdb;
     36		else
     37			rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
     38	} else if (dm_digtable->cursta_cstate == DIG_STA_CONNECT ||
     39		   dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT) {
     40		rssi_val_min = rtlpriv->dm.undec_sm_pwdb;
     41	} else if (dm_digtable->curmultista_cstate ==
     42		DIG_MULTISTA_CONNECT) {
     43		rssi_val_min = rtlpriv->dm.entry_min_undec_sm_pwdb;
     44	}
     45
     46	return (u8) rssi_val_min;
     47}
     48
     49static void rtl8723e_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
     50{
     51	u32 ret_value;
     52	struct rtl_priv *rtlpriv = rtl_priv(hw);
     53	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
     54
     55	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
     56	falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
     57
     58	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
     59	falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
     60	falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
     61
     62	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
     63	falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
     64	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
     65	    falsealm_cnt->cnt_rate_illegal +
     66	    falsealm_cnt->cnt_crc8_fail + falsealm_cnt->cnt_mcs_fail;
     67
     68	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, BIT(14), 1);
     69	ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERLOWER, MASKBYTE0);
     70	falsealm_cnt->cnt_cck_fail = ret_value;
     71
     72	ret_value = rtl_get_bbreg(hw, RCCK0_FACOUNTERUPPER, MASKBYTE3);
     73	falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
     74	falsealm_cnt->cnt_all = (falsealm_cnt->cnt_parity_fail +
     75				 falsealm_cnt->cnt_rate_illegal +
     76				 falsealm_cnt->cnt_crc8_fail +
     77				 falsealm_cnt->cnt_mcs_fail +
     78				 falsealm_cnt->cnt_cck_fail);
     79
     80	rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 1);
     81	rtl_set_bbreg(hw, ROFDM1_LSTF, 0x08000000, 0);
     82	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 0);
     83	rtl_set_bbreg(hw, RCCK0_FALSEALARMREPORT, 0x0000c000, 2);
     84
     85	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
     86		"cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
     87		falsealm_cnt->cnt_parity_fail,
     88		falsealm_cnt->cnt_rate_illegal,
     89		falsealm_cnt->cnt_crc8_fail, falsealm_cnt->cnt_mcs_fail);
     90
     91	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
     92		"cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
     93		falsealm_cnt->cnt_ofdm_fail,
     94		falsealm_cnt->cnt_cck_fail, falsealm_cnt->cnt_all);
     95}
     96
     97static void rtl92c_dm_ctrl_initgain_by_fa(struct ieee80211_hw *hw)
     98{
     99	struct rtl_priv *rtlpriv = rtl_priv(hw);
    100	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    101	u8 value_igi = dm_digtable->cur_igvalue;
    102
    103	if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
    104		value_igi--;
    105	else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)
    106		value_igi += 0;
    107	else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH2)
    108		value_igi++;
    109	else if (rtlpriv->falsealm_cnt.cnt_all >= DM_DIG_FA_TH2)
    110		value_igi += 2;
    111	if (value_igi > DM_DIG_FA_UPPER)
    112		value_igi = DM_DIG_FA_UPPER;
    113	else if (value_igi < DM_DIG_FA_LOWER)
    114		value_igi = DM_DIG_FA_LOWER;
    115	if (rtlpriv->falsealm_cnt.cnt_all > 10000)
    116		value_igi = 0x32;
    117
    118	dm_digtable->cur_igvalue = value_igi;
    119	rtl8723e_dm_write_dig(hw);
    120}
    121
    122static void rtl92c_dm_ctrl_initgain_by_rssi(struct ieee80211_hw *hw)
    123{
    124	struct rtl_priv *rtlpriv = rtl_priv(hw);
    125	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    126
    127	if (rtlpriv->falsealm_cnt.cnt_all > dm_digtable->fa_highthresh) {
    128		if ((dm_digtable->back_val - 2) <
    129		    dm_digtable->back_range_min)
    130			dm_digtable->back_val =
    131			    dm_digtable->back_range_min;
    132		else
    133			dm_digtable->back_val -= 2;
    134	} else if (rtlpriv->falsealm_cnt.cnt_all < dm_digtable->fa_lowthresh) {
    135		if ((dm_digtable->back_val + 2) >
    136		    dm_digtable->back_range_max)
    137			dm_digtable->back_val =
    138			    dm_digtable->back_range_max;
    139		else
    140			dm_digtable->back_val += 2;
    141	}
    142
    143	if ((dm_digtable->rssi_val_min + 10 - dm_digtable->back_val) >
    144	    dm_digtable->rx_gain_max)
    145		dm_digtable->cur_igvalue = dm_digtable->rx_gain_max;
    146	else if ((dm_digtable->rssi_val_min + 10 -
    147		  dm_digtable->back_val) < dm_digtable->rx_gain_min)
    148		dm_digtable->cur_igvalue = dm_digtable->rx_gain_min;
    149	else
    150		dm_digtable->cur_igvalue = dm_digtable->rssi_val_min + 10 -
    151		    dm_digtable->back_val;
    152
    153	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
    154		"rssi_val_min = %x back_val %x\n",
    155		dm_digtable->rssi_val_min, dm_digtable->back_val);
    156
    157	rtl8723e_dm_write_dig(hw);
    158}
    159
    160static void rtl8723e_dm_initial_gain_multi_sta(struct ieee80211_hw *hw)
    161{
    162	static u8 binitialized;
    163	struct rtl_priv *rtlpriv = rtl_priv(hw);
    164	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    165	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    166	long rssi_strength = rtlpriv->dm.entry_min_undec_sm_pwdb;
    167	bool multi_sta = false;
    168
    169	if (mac->opmode == NL80211_IFTYPE_ADHOC)
    170		multi_sta = true;
    171
    172	if (!multi_sta || (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT)) {
    173		binitialized = false;
    174		dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
    175		return;
    176	} else if (!binitialized) {
    177		binitialized = true;
    178		dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
    179		dm_digtable->cur_igvalue = 0x20;
    180		rtl8723e_dm_write_dig(hw);
    181	}
    182
    183	if (dm_digtable->curmultista_cstate == DIG_MULTISTA_CONNECT) {
    184		if ((rssi_strength < dm_digtable->rssi_lowthresh) &&
    185		    (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_1)) {
    186
    187			if (dm_digtable->dig_ext_port_stage ==
    188			    DIG_EXT_PORT_STAGE_2) {
    189				dm_digtable->cur_igvalue = 0x20;
    190				rtl8723e_dm_write_dig(hw);
    191			}
    192
    193			dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_1;
    194		} else if (rssi_strength > dm_digtable->rssi_highthresh) {
    195			dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_2;
    196			rtl92c_dm_ctrl_initgain_by_fa(hw);
    197		}
    198	} else if (dm_digtable->dig_ext_port_stage != DIG_EXT_PORT_STAGE_0) {
    199		dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_0;
    200		dm_digtable->cur_igvalue = 0x20;
    201		rtl8723e_dm_write_dig(hw);
    202	}
    203
    204	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
    205		"curmultista_cstate = %x dig_ext_port_stage %x\n",
    206		dm_digtable->curmultista_cstate,
    207		dm_digtable->dig_ext_port_stage);
    208}
    209
    210static void rtl8723e_dm_initial_gain_sta(struct ieee80211_hw *hw)
    211{
    212	struct rtl_priv *rtlpriv = rtl_priv(hw);
    213	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    214
    215	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
    216		"presta_cstate = %x, cursta_cstate = %x\n",
    217		dm_digtable->presta_cstate,
    218		dm_digtable->cursta_cstate);
    219
    220	if (dm_digtable->presta_cstate == dm_digtable->cursta_cstate ||
    221	    dm_digtable->cursta_cstate == DIG_STA_BEFORE_CONNECT ||
    222	    dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
    223		if (dm_digtable->cursta_cstate != DIG_STA_DISCONNECT) {
    224			dm_digtable->rssi_val_min =
    225			    rtl8723e_dm_initial_gain_min_pwdb(hw);
    226			rtl92c_dm_ctrl_initgain_by_rssi(hw);
    227		}
    228	} else {
    229		dm_digtable->rssi_val_min = 0;
    230		dm_digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
    231		dm_digtable->back_val = DM_DIG_BACKOFF_DEFAULT;
    232		dm_digtable->cur_igvalue = 0x20;
    233		dm_digtable->pre_igvalue = 0;
    234		rtl8723e_dm_write_dig(hw);
    235	}
    236}
    237
    238static void rtl8723e_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
    239{
    240	struct rtl_priv *rtlpriv = rtl_priv(hw);
    241	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    242
    243	if (dm_digtable->cursta_cstate == DIG_STA_CONNECT) {
    244		dm_digtable->rssi_val_min = rtl8723e_dm_initial_gain_min_pwdb(hw);
    245
    246		if (dm_digtable->pre_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
    247			if (dm_digtable->rssi_val_min <= 25)
    248				dm_digtable->cur_cck_pd_state =
    249				    CCK_PD_STAGE_LOWRSSI;
    250			else
    251				dm_digtable->cur_cck_pd_state =
    252				    CCK_PD_STAGE_HIGHRSSI;
    253		} else {
    254			if (dm_digtable->rssi_val_min <= 20)
    255				dm_digtable->cur_cck_pd_state =
    256				    CCK_PD_STAGE_LOWRSSI;
    257			else
    258				dm_digtable->cur_cck_pd_state =
    259				    CCK_PD_STAGE_HIGHRSSI;
    260		}
    261	} else {
    262		dm_digtable->cur_cck_pd_state = CCK_PD_STAGE_MAX;
    263	}
    264
    265	if (dm_digtable->pre_cck_pd_state != dm_digtable->cur_cck_pd_state) {
    266		if (dm_digtable->cur_cck_pd_state == CCK_PD_STAGE_LOWRSSI) {
    267			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 800)
    268				dm_digtable->cur_cck_fa_state =
    269				    CCK_FA_STAGE_HIGH;
    270			else
    271				dm_digtable->cur_cck_fa_state =
    272				    CCK_FA_STAGE_LOW;
    273			if (dm_digtable->pre_cck_fa_state !=
    274			    dm_digtable->cur_cck_fa_state) {
    275				if (dm_digtable->cur_cck_fa_state ==
    276				    CCK_FA_STAGE_LOW)
    277					rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
    278						      0x83);
    279				else
    280					rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2,
    281						      0xcd);
    282
    283				dm_digtable->pre_cck_fa_state =
    284				    dm_digtable->cur_cck_fa_state;
    285			}
    286
    287			rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x40);
    288
    289		} else {
    290			rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, 0xcd);
    291			rtl_set_bbreg(hw, RCCK0_SYSTEM, MASKBYTE1, 0x47);
    292			dm_digtable->pre_cck_fa_state = 0;
    293			dm_digtable->cur_cck_fa_state = 0;
    294
    295		}
    296		dm_digtable->pre_cck_pd_state = dm_digtable->cur_cck_pd_state;
    297	}
    298
    299	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
    300		"CCKPDStage=%x\n", dm_digtable->cur_cck_pd_state);
    301
    302}
    303
    304static void rtl8723e_dm_ctrl_initgain_by_twoport(struct ieee80211_hw *hw)
    305{
    306	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    307	struct rtl_priv *rtlpriv = rtl_priv(hw);
    308	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    309
    310	if (mac->act_scanning)
    311		return;
    312
    313	if (mac->link_state >= MAC80211_LINKED)
    314		dm_digtable->cursta_cstate = DIG_STA_CONNECT;
    315	else
    316		dm_digtable->cursta_cstate = DIG_STA_DISCONNECT;
    317
    318	rtl8723e_dm_initial_gain_sta(hw);
    319	rtl8723e_dm_initial_gain_multi_sta(hw);
    320	rtl8723e_dm_cck_packet_detection_thresh(hw);
    321
    322	dm_digtable->presta_cstate = dm_digtable->cursta_cstate;
    323
    324}
    325
    326static void rtl8723e_dm_dig(struct ieee80211_hw *hw)
    327{
    328	struct rtl_priv *rtlpriv = rtl_priv(hw);
    329	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    330
    331	if (!rtlpriv->dm.dm_initialgain_enable)
    332		return;
    333	if (!dm_digtable->dig_enable_flag)
    334		return;
    335
    336	rtl8723e_dm_ctrl_initgain_by_twoport(hw);
    337
    338}
    339
    340static void rtl8723e_dm_dynamic_txpower(struct ieee80211_hw *hw)
    341{
    342	struct rtl_priv *rtlpriv = rtl_priv(hw);
    343	struct rtl_phy *rtlphy = &(rtlpriv->phy);
    344	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    345	long undec_sm_pwdb;
    346
    347	if (!rtlpriv->dm.dynamic_txpower_enable)
    348		return;
    349
    350	if (rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
    351		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
    352		return;
    353	}
    354
    355	if ((mac->link_state < MAC80211_LINKED) &&
    356	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
    357		rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
    358			"Not connected to any\n");
    359
    360		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
    361
    362		rtlpriv->dm.last_dtp_lvl = TXHIGHPWRLEVEL_NORMAL;
    363		return;
    364	}
    365
    366	if (mac->link_state >= MAC80211_LINKED) {
    367		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
    368			undec_sm_pwdb =
    369			    rtlpriv->dm.entry_min_undec_sm_pwdb;
    370			rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
    371				"AP Client PWDB = 0x%lx\n",
    372				undec_sm_pwdb);
    373		} else {
    374			undec_sm_pwdb =
    375			    rtlpriv->dm.undec_sm_pwdb;
    376			rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
    377				"STA Default Port PWDB = 0x%lx\n",
    378				undec_sm_pwdb);
    379		}
    380	} else {
    381		undec_sm_pwdb =
    382		    rtlpriv->dm.entry_min_undec_sm_pwdb;
    383
    384		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
    385			"AP Ext Port PWDB = 0x%lx\n",
    386			undec_sm_pwdb);
    387	}
    388
    389	if (undec_sm_pwdb >= TX_POWER_NEAR_FIELD_THRESH_LVL2) {
    390		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
    391		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
    392			"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x0)\n");
    393	} else if ((undec_sm_pwdb <
    394		    (TX_POWER_NEAR_FIELD_THRESH_LVL2 - 3)) &&
    395		   (undec_sm_pwdb >=
    396		    TX_POWER_NEAR_FIELD_THRESH_LVL1)) {
    397		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_LEVEL1;
    398		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
    399			"TXHIGHPWRLEVEL_LEVEL1 (TxPwr=0x10)\n");
    400	} else if (undec_sm_pwdb <
    401		   (TX_POWER_NEAR_FIELD_THRESH_LVL1 - 5)) {
    402		rtlpriv->dm.dynamic_txhighpower_lvl = TXHIGHPWRLEVEL_NORMAL;
    403		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
    404			"TXHIGHPWRLEVEL_NORMAL\n");
    405	}
    406
    407	if (rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl) {
    408		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
    409			"PHY_SetTxPowerLevel8192S() Channel = %d\n",
    410			rtlphy->current_channel);
    411		rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel);
    412	}
    413
    414	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
    415}
    416
    417void rtl8723e_dm_write_dig(struct ieee80211_hw *hw)
    418{
    419	struct rtl_priv *rtlpriv = rtl_priv(hw);
    420	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    421
    422	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    423		"cur_igvalue = 0x%x, pre_igvalue = 0x%x, back_val = %d\n",
    424		dm_digtable->cur_igvalue, dm_digtable->pre_igvalue,
    425		dm_digtable->back_val);
    426
    427	if (dm_digtable->pre_igvalue != dm_digtable->cur_igvalue) {
    428		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f,
    429			      dm_digtable->cur_igvalue);
    430		rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, 0x7f,
    431			      dm_digtable->cur_igvalue);
    432
    433		dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
    434	}
    435}
    436
    437static void rtl8723e_dm_pwdb_monitor(struct ieee80211_hw *hw)
    438{
    439}
    440
    441static void rtl8723e_dm_check_edca_turbo(struct ieee80211_hw *hw)
    442{
    443	struct rtl_priv *rtlpriv = rtl_priv(hw);
    444	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    445
    446	static u64 last_txok_cnt;
    447	static u64 last_rxok_cnt;
    448	static u32 last_bt_edca_ul;
    449	static u32 last_bt_edca_dl;
    450	u64 cur_txok_cnt = 0;
    451	u64 cur_rxok_cnt = 0;
    452	u32 edca_be_ul = 0x5ea42b;
    453	u32 edca_be_dl = 0x5ea42b;
    454	bool bt_change_edca = false;
    455
    456	if ((last_bt_edca_ul != rtlpriv->btcoexist.bt_edca_ul) ||
    457	    (last_bt_edca_dl != rtlpriv->btcoexist.bt_edca_dl)) {
    458		rtlpriv->dm.current_turbo_edca = false;
    459		last_bt_edca_ul = rtlpriv->btcoexist.bt_edca_ul;
    460		last_bt_edca_dl = rtlpriv->btcoexist.bt_edca_dl;
    461	}
    462
    463	if (rtlpriv->btcoexist.bt_edca_ul != 0) {
    464		edca_be_ul = rtlpriv->btcoexist.bt_edca_ul;
    465		bt_change_edca = true;
    466	}
    467
    468	if (rtlpriv->btcoexist.bt_edca_dl != 0) {
    469		edca_be_ul = rtlpriv->btcoexist.bt_edca_dl;
    470		bt_change_edca = true;
    471	}
    472
    473	if (mac->link_state != MAC80211_LINKED) {
    474		rtlpriv->dm.current_turbo_edca = false;
    475		return;
    476	}
    477	if ((bt_change_edca) || ((!rtlpriv->dm.is_any_nonbepkts) &&
    478	     (!rtlpriv->dm.disable_framebursting))) {
    479
    480		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
    481		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
    482
    483		if (cur_rxok_cnt > 4 * cur_txok_cnt) {
    484			if (!rtlpriv->dm.is_cur_rdlstate ||
    485			    !rtlpriv->dm.current_turbo_edca) {
    486				rtl_write_dword(rtlpriv,
    487						REG_EDCA_BE_PARAM,
    488						edca_be_dl);
    489				rtlpriv->dm.is_cur_rdlstate = true;
    490			}
    491		} else {
    492			if (rtlpriv->dm.is_cur_rdlstate ||
    493			    !rtlpriv->dm.current_turbo_edca) {
    494				rtl_write_dword(rtlpriv,
    495						REG_EDCA_BE_PARAM,
    496						edca_be_ul);
    497				rtlpriv->dm.is_cur_rdlstate = false;
    498			}
    499		}
    500		rtlpriv->dm.current_turbo_edca = true;
    501	} else {
    502		if (rtlpriv->dm.current_turbo_edca) {
    503			u8 tmp = AC0_BE;
    504			rtlpriv->cfg->ops->set_hw_reg(hw,
    505						      HW_VAR_AC_PARAM,
    506						      (u8 *)(&tmp));
    507			rtlpriv->dm.current_turbo_edca = false;
    508		}
    509	}
    510
    511	rtlpriv->dm.is_any_nonbepkts = false;
    512	last_txok_cnt = rtlpriv->stats.txbytesunicast;
    513	last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
    514}
    515
    516static void rtl8723e_dm_initialize_txpower_tracking_thermalmeter(
    517				struct ieee80211_hw *hw)
    518{
    519	struct rtl_priv *rtlpriv = rtl_priv(hw);
    520
    521	rtlpriv->dm.txpower_tracking = true;
    522	rtlpriv->dm.txpower_trackinginit = false;
    523
    524	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    525		"pMgntInfo->txpower_tracking = %d\n",
    526		rtlpriv->dm.txpower_tracking);
    527}
    528
    529static void rtl8723e_dm_initialize_txpower_tracking(struct ieee80211_hw *hw)
    530{
    531	rtl8723e_dm_initialize_txpower_tracking_thermalmeter(hw);
    532}
    533
    534void rtl8723e_dm_check_txpower_tracking(struct ieee80211_hw *hw)
    535{
    536	return;
    537}
    538
    539void rtl8723e_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
    540{
    541	struct rtl_priv *rtlpriv = rtl_priv(hw);
    542	struct rate_adaptive *p_ra = &rtlpriv->ra;
    543
    544	p_ra->ratr_state = DM_RATR_STA_INIT;
    545	p_ra->pre_ratr_state = DM_RATR_STA_INIT;
    546
    547	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
    548		rtlpriv->dm.useramask = true;
    549	else
    550		rtlpriv->dm.useramask = false;
    551
    552}
    553
    554static void rtl8723e_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
    555{
    556	struct rtl_priv *rtlpriv = rtl_priv(hw);
    557	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
    558	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    559	struct rate_adaptive *p_ra = &rtlpriv->ra;
    560	u32 low_rssithresh_for_ra, high_rssithresh_for_ra;
    561	struct ieee80211_sta *sta = NULL;
    562
    563	if (is_hal_stop(rtlhal)) {
    564		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    565			" driver is going to unload\n");
    566		return;
    567	}
    568
    569	if (!rtlpriv->dm.useramask) {
    570		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    571			" driver does not control rate adaptive mask\n");
    572		return;
    573	}
    574
    575	if (mac->link_state == MAC80211_LINKED &&
    576	    mac->opmode == NL80211_IFTYPE_STATION) {
    577		switch (p_ra->pre_ratr_state) {
    578		case DM_RATR_STA_HIGH:
    579			high_rssithresh_for_ra = 50;
    580			low_rssithresh_for_ra = 20;
    581			break;
    582		case DM_RATR_STA_MIDDLE:
    583			high_rssithresh_for_ra = 55;
    584			low_rssithresh_for_ra = 20;
    585			break;
    586		case DM_RATR_STA_LOW:
    587			high_rssithresh_for_ra = 60;
    588			low_rssithresh_for_ra = 25;
    589			break;
    590		default:
    591			high_rssithresh_for_ra = 50;
    592			low_rssithresh_for_ra = 20;
    593			break;
    594		}
    595
    596		if (rtlpriv->link_info.bcn_rx_inperiod == 0)
    597			switch (p_ra->pre_ratr_state) {
    598			case DM_RATR_STA_HIGH:
    599			default:
    600				p_ra->ratr_state = DM_RATR_STA_MIDDLE;
    601				break;
    602			case DM_RATR_STA_MIDDLE:
    603			case DM_RATR_STA_LOW:
    604				p_ra->ratr_state = DM_RATR_STA_LOW;
    605				break;
    606			}
    607		else if (rtlpriv->dm.undec_sm_pwdb > high_rssithresh_for_ra)
    608			p_ra->ratr_state = DM_RATR_STA_HIGH;
    609		else if (rtlpriv->dm.undec_sm_pwdb > low_rssithresh_for_ra)
    610			p_ra->ratr_state = DM_RATR_STA_MIDDLE;
    611		else
    612			p_ra->ratr_state = DM_RATR_STA_LOW;
    613
    614		if (p_ra->pre_ratr_state != p_ra->ratr_state) {
    615			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    616				"RSSI = %ld\n",
    617				rtlpriv->dm.undec_sm_pwdb);
    618			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    619				"RSSI_LEVEL = %d\n", p_ra->ratr_state);
    620			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    621				"PreState = %d, CurState = %d\n",
    622				p_ra->pre_ratr_state, p_ra->ratr_state);
    623
    624			rcu_read_lock();
    625			sta = rtl_find_sta(hw, mac->bssid);
    626			if (sta)
    627				rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
    628							   p_ra->ratr_state,
    629								      true);
    630			rcu_read_unlock();
    631
    632			p_ra->pre_ratr_state = p_ra->ratr_state;
    633		}
    634	}
    635}
    636
    637void rtl8723e_dm_rf_saving(struct ieee80211_hw *hw, u8 bforce_in_normal)
    638{
    639	struct rtl_priv *rtlpriv = rtl_priv(hw);
    640	struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
    641	static u8 initialize;
    642	static u32 reg_874, reg_c70, reg_85c, reg_a74;
    643
    644	if (initialize == 0) {
    645		reg_874 = (rtl_get_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
    646					 MASKDWORD) & 0x1CC000) >> 14;
    647
    648		reg_c70 = (rtl_get_bbreg(hw, ROFDM0_AGCPARAMETER1,
    649					 MASKDWORD) & BIT(3)) >> 3;
    650
    651		reg_85c = (rtl_get_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
    652					 MASKDWORD) & 0xFF000000) >> 24;
    653
    654		reg_a74 = (rtl_get_bbreg(hw, 0xa74, MASKDWORD) & 0xF000) >> 12;
    655
    656		initialize = 1;
    657	}
    658
    659	if (!bforce_in_normal) {
    660		if (dm_pstable->rssi_val_min != 0) {
    661			if (dm_pstable->pre_rfstate == RF_NORMAL) {
    662				if (dm_pstable->rssi_val_min >= 30)
    663					dm_pstable->cur_rfstate = RF_SAVE;
    664				else
    665					dm_pstable->cur_rfstate = RF_NORMAL;
    666			} else {
    667				if (dm_pstable->rssi_val_min <= 25)
    668					dm_pstable->cur_rfstate = RF_NORMAL;
    669				else
    670					dm_pstable->cur_rfstate = RF_SAVE;
    671			}
    672		} else {
    673			dm_pstable->cur_rfstate = RF_MAX;
    674		}
    675	} else {
    676		dm_pstable->cur_rfstate = RF_NORMAL;
    677	}
    678
    679	if (dm_pstable->pre_rfstate != dm_pstable->cur_rfstate) {
    680		if (dm_pstable->cur_rfstate == RF_SAVE) {
    681			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
    682				      BIT(5), 0x1);
    683			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
    684				      0x1C0000, 0x2);
    685			rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3), 0);
    686			rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL,
    687				      0xFF000000, 0x63);
    688			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
    689				      0xC000, 0x2);
    690			rtl_set_bbreg(hw, 0xa74, 0xF000, 0x3);
    691			rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
    692			rtl_set_bbreg(hw, 0x818, BIT(28), 0x1);
    693		} else {
    694			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
    695				      0x1CC000, reg_874);
    696			rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, BIT(3),
    697				      reg_c70);
    698			rtl_set_bbreg(hw, RFPGA0_XCD_SWITCHCONTROL, 0xFF000000,
    699				      reg_85c);
    700			rtl_set_bbreg(hw, 0xa74, 0xF000, reg_a74);
    701			rtl_set_bbreg(hw, 0x818, BIT(28), 0x0);
    702			rtl_set_bbreg(hw, RFPGA0_XCD_RFINTERFACESW,
    703				      BIT(5), 0x0);
    704		}
    705
    706		dm_pstable->pre_rfstate = dm_pstable->cur_rfstate;
    707	}
    708}
    709
    710static void rtl8723e_dm_dynamic_bb_powersaving(struct ieee80211_hw *hw)
    711{
    712	struct rtl_priv *rtlpriv = rtl_priv(hw);
    713	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    714	struct ps_t *dm_pstable = &rtlpriv->dm_pstable;
    715
    716	if (((mac->link_state == MAC80211_NOLINK)) &&
    717	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
    718		dm_pstable->rssi_val_min = 0;
    719		rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
    720			"Not connected to any\n");
    721	}
    722
    723	if (mac->link_state == MAC80211_LINKED) {
    724		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
    725			dm_pstable->rssi_val_min =
    726			    rtlpriv->dm.entry_min_undec_sm_pwdb;
    727			rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
    728				"AP Client PWDB = 0x%lx\n",
    729				dm_pstable->rssi_val_min);
    730		} else {
    731			dm_pstable->rssi_val_min =
    732			    rtlpriv->dm.undec_sm_pwdb;
    733			rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
    734				"STA Default Port PWDB = 0x%lx\n",
    735				dm_pstable->rssi_val_min);
    736		}
    737	} else {
    738		dm_pstable->rssi_val_min =
    739		    rtlpriv->dm.entry_min_undec_sm_pwdb;
    740
    741		rtl_dbg(rtlpriv, DBG_LOUD, DBG_LOUD,
    742			"AP Ext Port PWDB = 0x%lx\n",
    743			dm_pstable->rssi_val_min);
    744	}
    745
    746	rtl8723e_dm_rf_saving(hw, false);
    747}
    748
    749void rtl8723e_dm_init(struct ieee80211_hw *hw)
    750{
    751	struct rtl_priv *rtlpriv = rtl_priv(hw);
    752
    753	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
    754	rtl_dm_diginit(hw, 0x20);
    755	rtl8723_dm_init_dynamic_txpower(hw);
    756	rtl8723_dm_init_edca_turbo(hw);
    757	rtl8723e_dm_init_rate_adaptive_mask(hw);
    758	rtl8723e_dm_initialize_txpower_tracking(hw);
    759	rtl8723_dm_init_dynamic_bb_powersaving(hw);
    760}
    761
    762void rtl8723e_dm_watchdog(struct ieee80211_hw *hw)
    763{
    764	struct rtl_priv *rtlpriv = rtl_priv(hw);
    765	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
    766	bool fw_current_inpsmode = false;
    767	bool fw_ps_awake = true;
    768	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
    769				      (u8 *)(&fw_current_inpsmode));
    770	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
    771				      (u8 *)(&fw_ps_awake));
    772
    773	if (ppsc->p2p_ps_info.p2p_ps_mode)
    774		fw_ps_awake = false;
    775
    776	spin_lock(&rtlpriv->locks.rf_ps_lock);
    777	if ((ppsc->rfpwr_state == ERFON) &&
    778	    ((!fw_current_inpsmode) && fw_ps_awake) &&
    779	    (!ppsc->rfchange_inprogress)) {
    780		rtl8723e_dm_pwdb_monitor(hw);
    781		rtl8723e_dm_dig(hw);
    782		rtl8723e_dm_false_alarm_counter_statistics(hw);
    783		rtl8723e_dm_dynamic_bb_powersaving(hw);
    784		rtl8723e_dm_dynamic_txpower(hw);
    785		rtl8723e_dm_check_txpower_tracking(hw);
    786		rtl8723e_dm_refresh_rate_adaptive_mask(hw);
    787		rtl8723e_dm_bt_coexist(hw);
    788		rtl8723e_dm_check_edca_turbo(hw);
    789	}
    790	spin_unlock(&rtlpriv->locks.rf_ps_lock);
    791	if (rtlpriv->btcoexist.init_set)
    792		rtl_write_byte(rtlpriv, 0x76e, 0xc);
    793}
    794
    795static void rtl8723e_dm_init_bt_coexist(struct ieee80211_hw *hw)
    796{
    797	struct rtl_priv *rtlpriv = rtl_priv(hw);
    798
    799	rtlpriv->btcoexist.bt_rfreg_origin_1e
    800		= rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK1, 0xfffff);
    801	rtlpriv->btcoexist.bt_rfreg_origin_1f
    802		= rtl_get_rfreg(hw, (enum radio_path)0, RF_RCK2, 0xf0);
    803
    804	rtlpriv->btcoexist.cstate = 0;
    805	rtlpriv->btcoexist.previous_state = 0;
    806	rtlpriv->btcoexist.cstate_h = 0;
    807	rtlpriv->btcoexist.previous_state_h = 0;
    808	rtlpriv->btcoexist.lps_counter = 0;
    809
    810	/*  Enable counter statistics */
    811	rtl_write_byte(rtlpriv, 0x76e, 0x4);
    812	rtl_write_byte(rtlpriv, 0x778, 0x3);
    813	rtl_write_byte(rtlpriv, 0x40, 0x20);
    814
    815	rtlpriv->btcoexist.init_set = true;
    816}
    817
    818void rtl8723e_dm_bt_coexist(struct ieee80211_hw *hw)
    819{
    820	struct rtl_priv *rtlpriv = rtl_priv(hw);
    821	u8 tmp_byte = 0;
    822	if (!rtlpriv->btcoexist.bt_coexistence) {
    823		rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
    824			"[DM]{BT], BT not exist!!\n");
    825		return;
    826	}
    827
    828	if (!rtlpriv->btcoexist.init_set) {
    829		rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
    830			"[DM][BT], %s\n", __func__);
    831		rtl8723e_dm_init_bt_coexist(hw);
    832	}
    833
    834	tmp_byte = rtl_read_byte(rtlpriv, 0x40);
    835	rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
    836		"[DM][BT], 0x40 is 0x%x\n", tmp_byte);
    837	rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_DMESG,
    838		"[DM][BT], bt_dm_coexist start\n");
    839	rtl8723e_dm_bt_coexist_8723(hw);
    840}