162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/* Copyright(c) 2009-2012  Realtek Corporation.*/
362306a36Sopenharmony_ci
462306a36Sopenharmony_ci#include "../wifi.h"
562306a36Sopenharmony_ci#include "../base.h"
662306a36Sopenharmony_ci#include "../core.h"
762306a36Sopenharmony_ci#include "reg.h"
862306a36Sopenharmony_ci#include "def.h"
962306a36Sopenharmony_ci#include "phy.h"
1062306a36Sopenharmony_ci#include "dm.h"
1162306a36Sopenharmony_ci#include "fw.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_cistatic const u32 edca_setting_dl[PEER_MAX] = {
1462306a36Sopenharmony_ci	0xa44f,		/* 0 UNKNOWN */
1562306a36Sopenharmony_ci	0x5ea44f,	/* 1 REALTEK_90 */
1662306a36Sopenharmony_ci	0x5ea44f,	/* 2 REALTEK_92SE */
1762306a36Sopenharmony_ci	0xa630,		/* 3 BROAD	*/
1862306a36Sopenharmony_ci	0xa44f,		/* 4 RAL */
1962306a36Sopenharmony_ci	0xa630,		/* 5 ATH */
2062306a36Sopenharmony_ci	0xa630,		/* 6 CISCO */
2162306a36Sopenharmony_ci	0xa42b,		/* 7 MARV */
2262306a36Sopenharmony_ci};
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_cistatic const u32 edca_setting_dl_gmode[PEER_MAX] = {
2562306a36Sopenharmony_ci	0x4322,		/* 0 UNKNOWN */
2662306a36Sopenharmony_ci	0xa44f,		/* 1 REALTEK_90 */
2762306a36Sopenharmony_ci	0x5ea44f,	/* 2 REALTEK_92SE */
2862306a36Sopenharmony_ci	0xa42b,		/* 3 BROAD */
2962306a36Sopenharmony_ci	0x5e4322,	/* 4 RAL */
3062306a36Sopenharmony_ci	0x4322,		/* 5 ATH */
3162306a36Sopenharmony_ci	0xa430,		/* 6 CISCO */
3262306a36Sopenharmony_ci	0x5ea44f,	/* 7 MARV */
3362306a36Sopenharmony_ci};
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic const u32 edca_setting_ul[PEER_MAX] = {
3662306a36Sopenharmony_ci	0x5e4322,	/* 0 UNKNOWN */
3762306a36Sopenharmony_ci	0xa44f,		/* 1 REALTEK_90 */
3862306a36Sopenharmony_ci	0x5ea44f,	/* 2 REALTEK_92SE */
3962306a36Sopenharmony_ci	0x5ea322,	/* 3 BROAD */
4062306a36Sopenharmony_ci	0x5ea422,	/* 4 RAL */
4162306a36Sopenharmony_ci	0x5ea322,	/* 5 ATH */
4262306a36Sopenharmony_ci	0x3ea44f,	/* 6 CISCO */
4362306a36Sopenharmony_ci	0x5ea44f,	/* 7 MARV */
4462306a36Sopenharmony_ci};
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_cistatic void _rtl92s_dm_check_edca_turbo(struct ieee80211_hw *hw)
4762306a36Sopenharmony_ci{
4862306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
4962306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
5062306a36Sopenharmony_ci
5162306a36Sopenharmony_ci	static u64 last_txok_cnt;
5262306a36Sopenharmony_ci	static u64 last_rxok_cnt;
5362306a36Sopenharmony_ci	u64 cur_txok_cnt = 0;
5462306a36Sopenharmony_ci	u64 cur_rxok_cnt = 0;
5562306a36Sopenharmony_ci
5662306a36Sopenharmony_ci	u32 edca_be_ul = edca_setting_ul[mac->vendor];
5762306a36Sopenharmony_ci	u32 edca_be_dl = edca_setting_dl[mac->vendor];
5862306a36Sopenharmony_ci	u32 edca_gmode = edca_setting_dl_gmode[mac->vendor];
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_ci	if (mac->link_state != MAC80211_LINKED) {
6162306a36Sopenharmony_ci		rtlpriv->dm.current_turbo_edca = false;
6262306a36Sopenharmony_ci		goto dm_checkedcaturbo_exit;
6362306a36Sopenharmony_ci	}
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	if ((!rtlpriv->dm.is_any_nonbepkts) &&
6662306a36Sopenharmony_ci	    (!rtlpriv->dm.disable_framebursting)) {
6762306a36Sopenharmony_ci		cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
6862306a36Sopenharmony_ci		cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci		if (rtlpriv->phy.rf_type == RF_1T2R) {
7162306a36Sopenharmony_ci			if (cur_txok_cnt > 4 * cur_rxok_cnt) {
7262306a36Sopenharmony_ci				/* Uplink TP is present. */
7362306a36Sopenharmony_ci				if (rtlpriv->dm.is_cur_rdlstate ||
7462306a36Sopenharmony_ci					!rtlpriv->dm.current_turbo_edca) {
7562306a36Sopenharmony_ci					rtl_write_dword(rtlpriv, EDCAPARA_BE,
7662306a36Sopenharmony_ci							edca_be_ul);
7762306a36Sopenharmony_ci					rtlpriv->dm.is_cur_rdlstate = false;
7862306a36Sopenharmony_ci				}
7962306a36Sopenharmony_ci			} else {/* Balance TP is present. */
8062306a36Sopenharmony_ci				if (!rtlpriv->dm.is_cur_rdlstate ||
8162306a36Sopenharmony_ci					!rtlpriv->dm.current_turbo_edca) {
8262306a36Sopenharmony_ci					if (mac->mode == WIRELESS_MODE_G ||
8362306a36Sopenharmony_ci					    mac->mode == WIRELESS_MODE_B)
8462306a36Sopenharmony_ci						rtl_write_dword(rtlpriv,
8562306a36Sopenharmony_ci								EDCAPARA_BE,
8662306a36Sopenharmony_ci								edca_gmode);
8762306a36Sopenharmony_ci					else
8862306a36Sopenharmony_ci						rtl_write_dword(rtlpriv,
8962306a36Sopenharmony_ci								EDCAPARA_BE,
9062306a36Sopenharmony_ci								edca_be_dl);
9162306a36Sopenharmony_ci					rtlpriv->dm.is_cur_rdlstate = true;
9262306a36Sopenharmony_ci				}
9362306a36Sopenharmony_ci			}
9462306a36Sopenharmony_ci			rtlpriv->dm.current_turbo_edca = true;
9562306a36Sopenharmony_ci		} else {
9662306a36Sopenharmony_ci			if (cur_rxok_cnt > 4 * cur_txok_cnt) {
9762306a36Sopenharmony_ci				if (!rtlpriv->dm.is_cur_rdlstate ||
9862306a36Sopenharmony_ci					!rtlpriv->dm.current_turbo_edca) {
9962306a36Sopenharmony_ci					if (mac->mode == WIRELESS_MODE_G ||
10062306a36Sopenharmony_ci					    mac->mode == WIRELESS_MODE_B)
10162306a36Sopenharmony_ci						rtl_write_dword(rtlpriv,
10262306a36Sopenharmony_ci								EDCAPARA_BE,
10362306a36Sopenharmony_ci								edca_gmode);
10462306a36Sopenharmony_ci					else
10562306a36Sopenharmony_ci						rtl_write_dword(rtlpriv,
10662306a36Sopenharmony_ci								EDCAPARA_BE,
10762306a36Sopenharmony_ci								edca_be_dl);
10862306a36Sopenharmony_ci					rtlpriv->dm.is_cur_rdlstate = true;
10962306a36Sopenharmony_ci				}
11062306a36Sopenharmony_ci			} else {
11162306a36Sopenharmony_ci				if (rtlpriv->dm.is_cur_rdlstate ||
11262306a36Sopenharmony_ci					!rtlpriv->dm.current_turbo_edca) {
11362306a36Sopenharmony_ci					rtl_write_dword(rtlpriv, EDCAPARA_BE,
11462306a36Sopenharmony_ci							edca_be_ul);
11562306a36Sopenharmony_ci					rtlpriv->dm.is_cur_rdlstate = false;
11662306a36Sopenharmony_ci				}
11762306a36Sopenharmony_ci			}
11862306a36Sopenharmony_ci			rtlpriv->dm.current_turbo_edca = true;
11962306a36Sopenharmony_ci		}
12062306a36Sopenharmony_ci	} else {
12162306a36Sopenharmony_ci		if (rtlpriv->dm.current_turbo_edca) {
12262306a36Sopenharmony_ci			u8 tmp = AC0_BE;
12362306a36Sopenharmony_ci			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
12462306a36Sopenharmony_ci						      &tmp);
12562306a36Sopenharmony_ci			rtlpriv->dm.current_turbo_edca = false;
12662306a36Sopenharmony_ci		}
12762306a36Sopenharmony_ci	}
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_cidm_checkedcaturbo_exit:
13062306a36Sopenharmony_ci	rtlpriv->dm.is_any_nonbepkts = false;
13162306a36Sopenharmony_ci	last_txok_cnt = rtlpriv->stats.txbytesunicast;
13262306a36Sopenharmony_ci	last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
13362306a36Sopenharmony_ci}
13462306a36Sopenharmony_ci
13562306a36Sopenharmony_cistatic void _rtl92s_dm_txpowertracking_callback_thermalmeter(
13662306a36Sopenharmony_ci					struct ieee80211_hw *hw)
13762306a36Sopenharmony_ci{
13862306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
13962306a36Sopenharmony_ci	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
14062306a36Sopenharmony_ci	u8 thermalvalue = 0;
14162306a36Sopenharmony_ci	u32 fw_cmd = 0;
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	rtlpriv->dm.txpower_trackinginit = true;
14462306a36Sopenharmony_ci
14562306a36Sopenharmony_ci	thermalvalue = (u8)rtl_get_rfreg(hw, RF90_PATH_A, RF_T_METER, 0x1f);
14662306a36Sopenharmony_ci
14762306a36Sopenharmony_ci	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
14862306a36Sopenharmony_ci		"Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermal meter 0x%x\n",
14962306a36Sopenharmony_ci		thermalvalue,
15062306a36Sopenharmony_ci		rtlpriv->dm.thermalvalue, rtlefuse->eeprom_thermalmeter);
15162306a36Sopenharmony_ci
15262306a36Sopenharmony_ci	if (thermalvalue) {
15362306a36Sopenharmony_ci		rtlpriv->dm.thermalvalue = thermalvalue;
15462306a36Sopenharmony_ci		if (hal_get_firmwareversion(rtlpriv) >= 0x35) {
15562306a36Sopenharmony_ci			rtl92s_phy_set_fw_cmd(hw, FW_CMD_TXPWR_TRACK_THERMAL);
15662306a36Sopenharmony_ci		} else {
15762306a36Sopenharmony_ci			fw_cmd = (FW_TXPWR_TRACK_THERMAL |
15862306a36Sopenharmony_ci				 (rtlpriv->efuse.thermalmeter[0] << 8) |
15962306a36Sopenharmony_ci				 (thermalvalue << 16));
16062306a36Sopenharmony_ci
16162306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
16262306a36Sopenharmony_ci				"Write to FW Thermal Val = 0x%x\n", fw_cmd);
16362306a36Sopenharmony_ci
16462306a36Sopenharmony_ci			rtl_write_dword(rtlpriv, WFM5, fw_cmd);
16562306a36Sopenharmony_ci			rtl92s_phy_chk_fwcmd_iodone(hw);
16662306a36Sopenharmony_ci		}
16762306a36Sopenharmony_ci	}
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci	rtlpriv->dm.txpowercount = 0;
17062306a36Sopenharmony_ci}
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_cistatic void _rtl92s_dm_check_txpowertracking_thermalmeter(
17362306a36Sopenharmony_ci					struct ieee80211_hw *hw)
17462306a36Sopenharmony_ci{
17562306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
17662306a36Sopenharmony_ci	struct rtl_phy *rtlphy = &(rtlpriv->phy);
17762306a36Sopenharmony_ci	u8 tx_power_checkcnt = 5;
17862306a36Sopenharmony_ci
17962306a36Sopenharmony_ci	/* 2T2R TP issue */
18062306a36Sopenharmony_ci	if (rtlphy->rf_type == RF_2T2R)
18162306a36Sopenharmony_ci		return;
18262306a36Sopenharmony_ci
18362306a36Sopenharmony_ci	if (!rtlpriv->dm.txpower_tracking)
18462306a36Sopenharmony_ci		return;
18562306a36Sopenharmony_ci
18662306a36Sopenharmony_ci	if (rtlpriv->dm.txpowercount <= tx_power_checkcnt) {
18762306a36Sopenharmony_ci		rtlpriv->dm.txpowercount++;
18862306a36Sopenharmony_ci		return;
18962306a36Sopenharmony_ci	}
19062306a36Sopenharmony_ci
19162306a36Sopenharmony_ci	if (!rtlpriv->dm.tm_trigger) {
19262306a36Sopenharmony_ci		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER,
19362306a36Sopenharmony_ci			      RFREG_OFFSET_MASK, 0x60);
19462306a36Sopenharmony_ci		rtlpriv->dm.tm_trigger = 1;
19562306a36Sopenharmony_ci	} else {
19662306a36Sopenharmony_ci		_rtl92s_dm_txpowertracking_callback_thermalmeter(hw);
19762306a36Sopenharmony_ci		rtlpriv->dm.tm_trigger = 0;
19862306a36Sopenharmony_ci	}
19962306a36Sopenharmony_ci}
20062306a36Sopenharmony_ci
20162306a36Sopenharmony_cistatic void _rtl92s_dm_refresh_rateadaptive_mask(struct ieee80211_hw *hw)
20262306a36Sopenharmony_ci{
20362306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
20462306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
20562306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
20662306a36Sopenharmony_ci	struct rate_adaptive *ra = &(rtlpriv->ra);
20762306a36Sopenharmony_ci	struct ieee80211_sta *sta = NULL;
20862306a36Sopenharmony_ci	u32 low_rssi_thresh = 0;
20962306a36Sopenharmony_ci	u32 middle_rssi_thresh = 0;
21062306a36Sopenharmony_ci	u32 high_rssi_thresh = 0;
21162306a36Sopenharmony_ci
21262306a36Sopenharmony_ci	if (is_hal_stop(rtlhal))
21362306a36Sopenharmony_ci		return;
21462306a36Sopenharmony_ci
21562306a36Sopenharmony_ci	if (!rtlpriv->dm.useramask)
21662306a36Sopenharmony_ci		return;
21762306a36Sopenharmony_ci
21862306a36Sopenharmony_ci	if (hal_get_firmwareversion(rtlpriv) >= 61 &&
21962306a36Sopenharmony_ci	    !rtlpriv->dm.inform_fw_driverctrldm) {
22062306a36Sopenharmony_ci		rtl92s_phy_set_fw_cmd(hw, FW_CMD_CTRL_DM_BY_DRIVER);
22162306a36Sopenharmony_ci		rtlpriv->dm.inform_fw_driverctrldm = true;
22262306a36Sopenharmony_ci	}
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	if ((mac->link_state == MAC80211_LINKED) &&
22562306a36Sopenharmony_ci	    (mac->opmode == NL80211_IFTYPE_STATION)) {
22662306a36Sopenharmony_ci		switch (ra->pre_ratr_state) {
22762306a36Sopenharmony_ci		case DM_RATR_STA_HIGH:
22862306a36Sopenharmony_ci			high_rssi_thresh = 40;
22962306a36Sopenharmony_ci			middle_rssi_thresh = 30;
23062306a36Sopenharmony_ci			low_rssi_thresh = 20;
23162306a36Sopenharmony_ci			break;
23262306a36Sopenharmony_ci		case DM_RATR_STA_MIDDLE:
23362306a36Sopenharmony_ci			high_rssi_thresh = 44;
23462306a36Sopenharmony_ci			middle_rssi_thresh = 30;
23562306a36Sopenharmony_ci			low_rssi_thresh = 20;
23662306a36Sopenharmony_ci			break;
23762306a36Sopenharmony_ci		case DM_RATR_STA_LOW:
23862306a36Sopenharmony_ci			high_rssi_thresh = 44;
23962306a36Sopenharmony_ci			middle_rssi_thresh = 34;
24062306a36Sopenharmony_ci			low_rssi_thresh = 20;
24162306a36Sopenharmony_ci			break;
24262306a36Sopenharmony_ci		case DM_RATR_STA_ULTRALOW:
24362306a36Sopenharmony_ci			high_rssi_thresh = 44;
24462306a36Sopenharmony_ci			middle_rssi_thresh = 34;
24562306a36Sopenharmony_ci			low_rssi_thresh = 24;
24662306a36Sopenharmony_ci			break;
24762306a36Sopenharmony_ci		default:
24862306a36Sopenharmony_ci			high_rssi_thresh = 44;
24962306a36Sopenharmony_ci			middle_rssi_thresh = 34;
25062306a36Sopenharmony_ci			low_rssi_thresh = 24;
25162306a36Sopenharmony_ci			break;
25262306a36Sopenharmony_ci		}
25362306a36Sopenharmony_ci
25462306a36Sopenharmony_ci		if (rtlpriv->dm.undec_sm_pwdb > (long)high_rssi_thresh) {
25562306a36Sopenharmony_ci			ra->ratr_state = DM_RATR_STA_HIGH;
25662306a36Sopenharmony_ci		} else if (rtlpriv->dm.undec_sm_pwdb >
25762306a36Sopenharmony_ci			   (long)middle_rssi_thresh) {
25862306a36Sopenharmony_ci			ra->ratr_state = DM_RATR_STA_LOW;
25962306a36Sopenharmony_ci		} else if (rtlpriv->dm.undec_sm_pwdb >
26062306a36Sopenharmony_ci			   (long)low_rssi_thresh) {
26162306a36Sopenharmony_ci			ra->ratr_state = DM_RATR_STA_LOW;
26262306a36Sopenharmony_ci		} else {
26362306a36Sopenharmony_ci			ra->ratr_state = DM_RATR_STA_ULTRALOW;
26462306a36Sopenharmony_ci		}
26562306a36Sopenharmony_ci
26662306a36Sopenharmony_ci		if (ra->pre_ratr_state != ra->ratr_state) {
26762306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
26862306a36Sopenharmony_ci				"RSSI = %ld RSSI_LEVEL = %d PreState = %d, CurState = %d\n",
26962306a36Sopenharmony_ci				rtlpriv->dm.undec_sm_pwdb, ra->ratr_state,
27062306a36Sopenharmony_ci				ra->pre_ratr_state, ra->ratr_state);
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci			rcu_read_lock();
27362306a36Sopenharmony_ci			sta = rtl_find_sta(hw, mac->bssid);
27462306a36Sopenharmony_ci			if (sta)
27562306a36Sopenharmony_ci				rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
27662306a36Sopenharmony_ci							   ra->ratr_state,
27762306a36Sopenharmony_ci							   true);
27862306a36Sopenharmony_ci			rcu_read_unlock();
27962306a36Sopenharmony_ci
28062306a36Sopenharmony_ci			ra->pre_ratr_state = ra->ratr_state;
28162306a36Sopenharmony_ci		}
28262306a36Sopenharmony_ci	}
28362306a36Sopenharmony_ci}
28462306a36Sopenharmony_ci
28562306a36Sopenharmony_cistatic void _rtl92s_dm_switch_baseband_mrc(struct ieee80211_hw *hw)
28662306a36Sopenharmony_ci{
28762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
28862306a36Sopenharmony_ci	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
28962306a36Sopenharmony_ci	struct rtl_phy *rtlphy = &(rtlpriv->phy);
29062306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
29162306a36Sopenharmony_ci	bool current_mrc;
29262306a36Sopenharmony_ci	bool enable_mrc = true;
29362306a36Sopenharmony_ci	long tmpentry_maxpwdb = 0;
29462306a36Sopenharmony_ci	u8 rssi_a = 0;
29562306a36Sopenharmony_ci	u8 rssi_b = 0;
29662306a36Sopenharmony_ci
29762306a36Sopenharmony_ci	if (is_hal_stop(rtlhal))
29862306a36Sopenharmony_ci		return;
29962306a36Sopenharmony_ci
30062306a36Sopenharmony_ci	if ((rtlphy->rf_type == RF_1T1R) || (rtlphy->rf_type == RF_2T2R))
30162306a36Sopenharmony_ci		return;
30262306a36Sopenharmony_ci
30362306a36Sopenharmony_ci	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_MRC, (u8 *)(&current_mrc));
30462306a36Sopenharmony_ci
30562306a36Sopenharmony_ci	if (mac->link_state >= MAC80211_LINKED) {
30662306a36Sopenharmony_ci		if (rtlpriv->dm.undec_sm_pwdb > tmpentry_maxpwdb) {
30762306a36Sopenharmony_ci			rssi_a = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_A];
30862306a36Sopenharmony_ci			rssi_b = rtlpriv->stats.rx_rssi_percentage[RF90_PATH_B];
30962306a36Sopenharmony_ci		}
31062306a36Sopenharmony_ci	}
31162306a36Sopenharmony_ci
31262306a36Sopenharmony_ci	/* MRC settings would NOT affect TP on Wireless B mode. */
31362306a36Sopenharmony_ci	if (mac->mode != WIRELESS_MODE_B) {
31462306a36Sopenharmony_ci		if ((rssi_a == 0) && (rssi_b == 0)) {
31562306a36Sopenharmony_ci			enable_mrc = true;
31662306a36Sopenharmony_ci		} else if (rssi_b > 30) {
31762306a36Sopenharmony_ci			/* Turn on B-Path */
31862306a36Sopenharmony_ci			enable_mrc = true;
31962306a36Sopenharmony_ci		} else if (rssi_b < 5) {
32062306a36Sopenharmony_ci			/* Turn off B-path  */
32162306a36Sopenharmony_ci			enable_mrc = false;
32262306a36Sopenharmony_ci		/* Take care of RSSI differentiation. */
32362306a36Sopenharmony_ci		} else if (rssi_a > 15 && (rssi_a >= rssi_b)) {
32462306a36Sopenharmony_ci			if ((rssi_a - rssi_b) > 15)
32562306a36Sopenharmony_ci				/* Turn off B-path  */
32662306a36Sopenharmony_ci				enable_mrc = false;
32762306a36Sopenharmony_ci			else if ((rssi_a - rssi_b) < 10)
32862306a36Sopenharmony_ci				/* Turn on B-Path */
32962306a36Sopenharmony_ci				enable_mrc = true;
33062306a36Sopenharmony_ci			else
33162306a36Sopenharmony_ci				enable_mrc = current_mrc;
33262306a36Sopenharmony_ci		} else {
33362306a36Sopenharmony_ci			/* Turn on B-Path */
33462306a36Sopenharmony_ci			enable_mrc = true;
33562306a36Sopenharmony_ci		}
33662306a36Sopenharmony_ci	}
33762306a36Sopenharmony_ci
33862306a36Sopenharmony_ci	/* Update MRC settings if needed. */
33962306a36Sopenharmony_ci	if (enable_mrc != current_mrc)
34062306a36Sopenharmony_ci		rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_MRC,
34162306a36Sopenharmony_ci					      (u8 *)&enable_mrc);
34262306a36Sopenharmony_ci
34362306a36Sopenharmony_ci}
34462306a36Sopenharmony_ci
34562306a36Sopenharmony_civoid rtl92s_dm_init_edca_turbo(struct ieee80211_hw *hw)
34662306a36Sopenharmony_ci{
34762306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
34862306a36Sopenharmony_ci
34962306a36Sopenharmony_ci	rtlpriv->dm.current_turbo_edca = false;
35062306a36Sopenharmony_ci	rtlpriv->dm.is_any_nonbepkts = false;
35162306a36Sopenharmony_ci	rtlpriv->dm.is_cur_rdlstate = false;
35262306a36Sopenharmony_ci}
35362306a36Sopenharmony_ci
35462306a36Sopenharmony_cistatic void _rtl92s_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
35562306a36Sopenharmony_ci{
35662306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
35762306a36Sopenharmony_ci	struct rate_adaptive *ra = &(rtlpriv->ra);
35862306a36Sopenharmony_ci
35962306a36Sopenharmony_ci	ra->ratr_state = DM_RATR_STA_MAX;
36062306a36Sopenharmony_ci	ra->pre_ratr_state = DM_RATR_STA_MAX;
36162306a36Sopenharmony_ci
36262306a36Sopenharmony_ci	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER &&
36362306a36Sopenharmony_ci	    hal_get_firmwareversion(rtlpriv) >= 60)
36462306a36Sopenharmony_ci		rtlpriv->dm.useramask = true;
36562306a36Sopenharmony_ci	else
36662306a36Sopenharmony_ci		rtlpriv->dm.useramask = false;
36762306a36Sopenharmony_ci
36862306a36Sopenharmony_ci	rtlpriv->dm.useramask = false;
36962306a36Sopenharmony_ci	rtlpriv->dm.inform_fw_driverctrldm = false;
37062306a36Sopenharmony_ci}
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_cistatic void _rtl92s_dm_init_txpowertracking_thermalmeter(
37362306a36Sopenharmony_ci				struct ieee80211_hw *hw)
37462306a36Sopenharmony_ci{
37562306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
37662306a36Sopenharmony_ci
37762306a36Sopenharmony_ci	rtlpriv->dm.txpower_tracking = true;
37862306a36Sopenharmony_ci	rtlpriv->dm.txpowercount = 0;
37962306a36Sopenharmony_ci	rtlpriv->dm.txpower_trackinginit = false;
38062306a36Sopenharmony_ci}
38162306a36Sopenharmony_ci
38262306a36Sopenharmony_cistatic void _rtl92s_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
38362306a36Sopenharmony_ci{
38462306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
38562306a36Sopenharmony_ci	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
38662306a36Sopenharmony_ci	u32 ret_value;
38762306a36Sopenharmony_ci
38862306a36Sopenharmony_ci	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER1, MASKDWORD);
38962306a36Sopenharmony_ci	falsealm_cnt->cnt_parity_fail = ((ret_value & 0xffff0000) >> 16);
39062306a36Sopenharmony_ci
39162306a36Sopenharmony_ci	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER2, MASKDWORD);
39262306a36Sopenharmony_ci	falsealm_cnt->cnt_rate_illegal = (ret_value & 0xffff);
39362306a36Sopenharmony_ci	falsealm_cnt->cnt_crc8_fail = ((ret_value & 0xffff0000) >> 16);
39462306a36Sopenharmony_ci	ret_value = rtl_get_bbreg(hw, ROFDM_PHYCOUNTER3, MASKDWORD);
39562306a36Sopenharmony_ci	falsealm_cnt->cnt_mcs_fail = (ret_value & 0xffff);
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
39862306a36Sopenharmony_ci		falsealm_cnt->cnt_rate_illegal + falsealm_cnt->cnt_crc8_fail +
39962306a36Sopenharmony_ci		falsealm_cnt->cnt_mcs_fail;
40062306a36Sopenharmony_ci
40162306a36Sopenharmony_ci	/* read CCK false alarm */
40262306a36Sopenharmony_ci	ret_value = rtl_get_bbreg(hw, 0xc64, MASKDWORD);
40362306a36Sopenharmony_ci	falsealm_cnt->cnt_cck_fail = (ret_value & 0xffff);
40462306a36Sopenharmony_ci	falsealm_cnt->cnt_all =	falsealm_cnt->cnt_ofdm_fail +
40562306a36Sopenharmony_ci		falsealm_cnt->cnt_cck_fail;
40662306a36Sopenharmony_ci}
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_cistatic void rtl92s_backoff_enable_flag(struct ieee80211_hw *hw)
40962306a36Sopenharmony_ci{
41062306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
41162306a36Sopenharmony_ci	struct dig_t *digtable = &rtlpriv->dm_digtable;
41262306a36Sopenharmony_ci	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
41362306a36Sopenharmony_ci
41462306a36Sopenharmony_ci	if (falsealm_cnt->cnt_all > digtable->fa_highthresh) {
41562306a36Sopenharmony_ci		if ((digtable->back_val - 6) <
41662306a36Sopenharmony_ci			digtable->backoffval_range_min)
41762306a36Sopenharmony_ci			digtable->back_val = digtable->backoffval_range_min;
41862306a36Sopenharmony_ci		else
41962306a36Sopenharmony_ci			digtable->back_val -= 6;
42062306a36Sopenharmony_ci	} else if (falsealm_cnt->cnt_all < digtable->fa_lowthresh) {
42162306a36Sopenharmony_ci		if ((digtable->back_val + 6) >
42262306a36Sopenharmony_ci			digtable->backoffval_range_max)
42362306a36Sopenharmony_ci			digtable->back_val =
42462306a36Sopenharmony_ci				 digtable->backoffval_range_max;
42562306a36Sopenharmony_ci		else
42662306a36Sopenharmony_ci			digtable->back_val += 6;
42762306a36Sopenharmony_ci	}
42862306a36Sopenharmony_ci}
42962306a36Sopenharmony_ci
43062306a36Sopenharmony_cistatic void _rtl92s_dm_initial_gain_sta_beforeconnect(struct ieee80211_hw *hw)
43162306a36Sopenharmony_ci{
43262306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
43362306a36Sopenharmony_ci	struct dig_t *digtable = &rtlpriv->dm_digtable;
43462306a36Sopenharmony_ci	struct false_alarm_statistics *falsealm_cnt = &(rtlpriv->falsealm_cnt);
43562306a36Sopenharmony_ci	static u8 initialized, force_write;
43662306a36Sopenharmony_ci	u8 initial_gain = 0;
43762306a36Sopenharmony_ci
43862306a36Sopenharmony_ci	if ((digtable->pre_sta_cstate == digtable->cur_sta_cstate) ||
43962306a36Sopenharmony_ci	    (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT)) {
44062306a36Sopenharmony_ci		if (digtable->cur_sta_cstate == DIG_STA_BEFORE_CONNECT) {
44162306a36Sopenharmony_ci			if (rtlpriv->psc.rfpwr_state != ERFON)
44262306a36Sopenharmony_ci				return;
44362306a36Sopenharmony_ci
44462306a36Sopenharmony_ci			if (digtable->backoff_enable_flag)
44562306a36Sopenharmony_ci				rtl92s_backoff_enable_flag(hw);
44662306a36Sopenharmony_ci			else
44762306a36Sopenharmony_ci				digtable->back_val = DM_DIG_BACKOFF_MAX;
44862306a36Sopenharmony_ci
44962306a36Sopenharmony_ci			if ((digtable->rssi_val + 10 - digtable->back_val) >
45062306a36Sopenharmony_ci				digtable->rx_gain_max)
45162306a36Sopenharmony_ci				digtable->cur_igvalue =
45262306a36Sopenharmony_ci						digtable->rx_gain_max;
45362306a36Sopenharmony_ci			else if ((digtable->rssi_val + 10 - digtable->back_val)
45462306a36Sopenharmony_ci				 < digtable->rx_gain_min)
45562306a36Sopenharmony_ci				digtable->cur_igvalue =
45662306a36Sopenharmony_ci						digtable->rx_gain_min;
45762306a36Sopenharmony_ci			else
45862306a36Sopenharmony_ci				digtable->cur_igvalue = digtable->rssi_val + 10
45962306a36Sopenharmony_ci					- digtable->back_val;
46062306a36Sopenharmony_ci
46162306a36Sopenharmony_ci			if (falsealm_cnt->cnt_all > 10000)
46262306a36Sopenharmony_ci				digtable->cur_igvalue =
46362306a36Sopenharmony_ci					 (digtable->cur_igvalue > 0x33) ?
46462306a36Sopenharmony_ci					 digtable->cur_igvalue : 0x33;
46562306a36Sopenharmony_ci
46662306a36Sopenharmony_ci			if (falsealm_cnt->cnt_all > 16000)
46762306a36Sopenharmony_ci				digtable->cur_igvalue =
46862306a36Sopenharmony_ci						 digtable->rx_gain_max;
46962306a36Sopenharmony_ci		/* connected -> connected or disconnected -> disconnected  */
47062306a36Sopenharmony_ci		} else {
47162306a36Sopenharmony_ci			/* Firmware control DIG, do nothing in driver dm */
47262306a36Sopenharmony_ci			return;
47362306a36Sopenharmony_ci		}
47462306a36Sopenharmony_ci		/* disconnected -> connected or connected ->
47562306a36Sopenharmony_ci		 * disconnected or beforeconnect->(dis)connected */
47662306a36Sopenharmony_ci	} else {
47762306a36Sopenharmony_ci		/* Enable FW DIG */
47862306a36Sopenharmony_ci		digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
47962306a36Sopenharmony_ci		rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_ENABLE);
48062306a36Sopenharmony_ci
48162306a36Sopenharmony_ci		digtable->back_val = DM_DIG_BACKOFF_MAX;
48262306a36Sopenharmony_ci		digtable->cur_igvalue = rtlpriv->phy.default_initialgain[0];
48362306a36Sopenharmony_ci		digtable->pre_igvalue = 0;
48462306a36Sopenharmony_ci		return;
48562306a36Sopenharmony_ci	}
48662306a36Sopenharmony_ci
48762306a36Sopenharmony_ci	/* Forced writing to prevent from fw-dig overwriting. */
48862306a36Sopenharmony_ci	if (digtable->pre_igvalue != rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1,
48962306a36Sopenharmony_ci						  MASKBYTE0))
49062306a36Sopenharmony_ci		force_write = 1;
49162306a36Sopenharmony_ci
49262306a36Sopenharmony_ci	if ((digtable->pre_igvalue != digtable->cur_igvalue) ||
49362306a36Sopenharmony_ci	    !initialized || force_write) {
49462306a36Sopenharmony_ci		/* Disable FW DIG */
49562306a36Sopenharmony_ci		rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_DISABLE);
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci		initial_gain = (u8)digtable->cur_igvalue;
49862306a36Sopenharmony_ci
49962306a36Sopenharmony_ci		/* Set initial gain. */
50062306a36Sopenharmony_ci		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0, initial_gain);
50162306a36Sopenharmony_ci		rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0, initial_gain);
50262306a36Sopenharmony_ci		digtable->pre_igvalue = digtable->cur_igvalue;
50362306a36Sopenharmony_ci		initialized = 1;
50462306a36Sopenharmony_ci		force_write = 0;
50562306a36Sopenharmony_ci	}
50662306a36Sopenharmony_ci}
50762306a36Sopenharmony_ci
50862306a36Sopenharmony_cistatic void _rtl92s_dm_ctrl_initgain_bytwoport(struct ieee80211_hw *hw)
50962306a36Sopenharmony_ci{
51062306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
51162306a36Sopenharmony_ci	struct dig_t *dig = &rtlpriv->dm_digtable;
51262306a36Sopenharmony_ci
51362306a36Sopenharmony_ci	if (rtlpriv->mac80211.act_scanning)
51462306a36Sopenharmony_ci		return;
51562306a36Sopenharmony_ci
51662306a36Sopenharmony_ci	/* Decide the current status and if modify initial gain or not */
51762306a36Sopenharmony_ci	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED ||
51862306a36Sopenharmony_ci	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC)
51962306a36Sopenharmony_ci		dig->cur_sta_cstate = DIG_STA_CONNECT;
52062306a36Sopenharmony_ci	else
52162306a36Sopenharmony_ci		dig->cur_sta_cstate = DIG_STA_DISCONNECT;
52262306a36Sopenharmony_ci
52362306a36Sopenharmony_ci	dig->rssi_val = rtlpriv->dm.undec_sm_pwdb;
52462306a36Sopenharmony_ci
52562306a36Sopenharmony_ci	/* Change dig mode to rssi */
52662306a36Sopenharmony_ci	if (dig->cur_sta_cstate != DIG_STA_DISCONNECT) {
52762306a36Sopenharmony_ci		if (dig->dig_twoport_algorithm ==
52862306a36Sopenharmony_ci		    DIG_TWO_PORT_ALGO_FALSE_ALARM) {
52962306a36Sopenharmony_ci			dig->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
53062306a36Sopenharmony_ci			rtl92s_phy_set_fw_cmd(hw, FW_CMD_DIG_MODE_SS);
53162306a36Sopenharmony_ci		}
53262306a36Sopenharmony_ci	}
53362306a36Sopenharmony_ci
53462306a36Sopenharmony_ci	_rtl92s_dm_false_alarm_counter_statistics(hw);
53562306a36Sopenharmony_ci	_rtl92s_dm_initial_gain_sta_beforeconnect(hw);
53662306a36Sopenharmony_ci
53762306a36Sopenharmony_ci	dig->pre_sta_cstate = dig->cur_sta_cstate;
53862306a36Sopenharmony_ci}
53962306a36Sopenharmony_ci
54062306a36Sopenharmony_cistatic void _rtl92s_dm_ctrl_initgain_byrssi(struct ieee80211_hw *hw)
54162306a36Sopenharmony_ci{
54262306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
54362306a36Sopenharmony_ci	struct rtl_phy *rtlphy = &(rtlpriv->phy);
54462306a36Sopenharmony_ci	struct dig_t *digtable = &rtlpriv->dm_digtable;
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	/* 2T2R TP issue */
54762306a36Sopenharmony_ci	if (rtlphy->rf_type == RF_2T2R)
54862306a36Sopenharmony_ci		return;
54962306a36Sopenharmony_ci
55062306a36Sopenharmony_ci	if (!rtlpriv->dm.dm_initialgain_enable)
55162306a36Sopenharmony_ci		return;
55262306a36Sopenharmony_ci
55362306a36Sopenharmony_ci	if (digtable->dig_enable_flag == false)
55462306a36Sopenharmony_ci		return;
55562306a36Sopenharmony_ci
55662306a36Sopenharmony_ci	_rtl92s_dm_ctrl_initgain_bytwoport(hw);
55762306a36Sopenharmony_ci}
55862306a36Sopenharmony_ci
55962306a36Sopenharmony_cistatic void _rtl92s_dm_dynamic_txpower(struct ieee80211_hw *hw)
56062306a36Sopenharmony_ci{
56162306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
56262306a36Sopenharmony_ci	struct rtl_phy *rtlphy = &(rtlpriv->phy);
56362306a36Sopenharmony_ci	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
56462306a36Sopenharmony_ci	long undec_sm_pwdb;
56562306a36Sopenharmony_ci	long txpwr_threshold_lv1, txpwr_threshold_lv2;
56662306a36Sopenharmony_ci
56762306a36Sopenharmony_ci	/* 2T2R TP issue */
56862306a36Sopenharmony_ci	if (rtlphy->rf_type == RF_2T2R)
56962306a36Sopenharmony_ci		return;
57062306a36Sopenharmony_ci
57162306a36Sopenharmony_ci	if (!rtlpriv->dm.dynamic_txpower_enable ||
57262306a36Sopenharmony_ci	    rtlpriv->dm.dm_flag & HAL_DM_HIPWR_DISABLE) {
57362306a36Sopenharmony_ci		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
57462306a36Sopenharmony_ci		return;
57562306a36Sopenharmony_ci	}
57662306a36Sopenharmony_ci
57762306a36Sopenharmony_ci	if ((mac->link_state < MAC80211_LINKED) &&
57862306a36Sopenharmony_ci	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
57962306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,
58062306a36Sopenharmony_ci			"Not connected to any\n");
58162306a36Sopenharmony_ci
58262306a36Sopenharmony_ci		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
58362306a36Sopenharmony_ci
58462306a36Sopenharmony_ci		rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
58562306a36Sopenharmony_ci		return;
58662306a36Sopenharmony_ci	}
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	if (mac->link_state >= MAC80211_LINKED) {
58962306a36Sopenharmony_ci		if (mac->opmode == NL80211_IFTYPE_ADHOC) {
59062306a36Sopenharmony_ci			undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
59162306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
59262306a36Sopenharmony_ci				"AP Client PWDB = 0x%lx\n",
59362306a36Sopenharmony_ci				undec_sm_pwdb);
59462306a36Sopenharmony_ci		} else {
59562306a36Sopenharmony_ci			undec_sm_pwdb = rtlpriv->dm.undec_sm_pwdb;
59662306a36Sopenharmony_ci			rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
59762306a36Sopenharmony_ci				"STA Default Port PWDB = 0x%lx\n",
59862306a36Sopenharmony_ci				undec_sm_pwdb);
59962306a36Sopenharmony_ci		}
60062306a36Sopenharmony_ci	} else {
60162306a36Sopenharmony_ci		undec_sm_pwdb = rtlpriv->dm.entry_min_undec_sm_pwdb;
60262306a36Sopenharmony_ci
60362306a36Sopenharmony_ci		rtl_dbg(rtlpriv, COMP_POWER, DBG_LOUD,
60462306a36Sopenharmony_ci			"AP Ext Port PWDB = 0x%lx\n",
60562306a36Sopenharmony_ci			undec_sm_pwdb);
60662306a36Sopenharmony_ci	}
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci	txpwr_threshold_lv2 = TX_POWER_NEAR_FIELD_THRESH_LVL2;
60962306a36Sopenharmony_ci	txpwr_threshold_lv1 = TX_POWER_NEAR_FIELD_THRESH_LVL1;
61062306a36Sopenharmony_ci
61162306a36Sopenharmony_ci	if (rtl_get_bbreg(hw, 0xc90, MASKBYTE0) == 1)
61262306a36Sopenharmony_ci		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
61362306a36Sopenharmony_ci	else if (undec_sm_pwdb >= txpwr_threshold_lv2)
61462306a36Sopenharmony_ci		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL2;
61562306a36Sopenharmony_ci	else if ((undec_sm_pwdb < (txpwr_threshold_lv2 - 3)) &&
61662306a36Sopenharmony_ci		(undec_sm_pwdb >= txpwr_threshold_lv1))
61762306a36Sopenharmony_ci		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL1;
61862306a36Sopenharmony_ci	else if (undec_sm_pwdb < (txpwr_threshold_lv1 - 3))
61962306a36Sopenharmony_ci		rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
62062306a36Sopenharmony_ci
62162306a36Sopenharmony_ci	if ((rtlpriv->dm.dynamic_txhighpower_lvl != rtlpriv->dm.last_dtp_lvl))
62262306a36Sopenharmony_ci		rtl92s_phy_set_txpower(hw, rtlphy->current_channel);
62362306a36Sopenharmony_ci
62462306a36Sopenharmony_ci	rtlpriv->dm.last_dtp_lvl = rtlpriv->dm.dynamic_txhighpower_lvl;
62562306a36Sopenharmony_ci}
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_cistatic void _rtl92s_dm_init_dig(struct ieee80211_hw *hw)
62862306a36Sopenharmony_ci{
62962306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
63062306a36Sopenharmony_ci	struct dig_t *digtable = &rtlpriv->dm_digtable;
63162306a36Sopenharmony_ci
63262306a36Sopenharmony_ci	/* Disable DIG scheme now.*/
63362306a36Sopenharmony_ci	digtable->dig_enable_flag = true;
63462306a36Sopenharmony_ci	digtable->backoff_enable_flag = true;
63562306a36Sopenharmony_ci
63662306a36Sopenharmony_ci	if ((rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER) &&
63762306a36Sopenharmony_ci	    (hal_get_firmwareversion(rtlpriv) >= 0x3c))
63862306a36Sopenharmony_ci		digtable->dig_algorithm = DIG_ALGO_BY_TOW_PORT;
63962306a36Sopenharmony_ci	else
64062306a36Sopenharmony_ci		digtable->dig_algorithm =
64162306a36Sopenharmony_ci			 DIG_ALGO_BEFORE_CONNECT_BY_RSSI_AND_ALARM;
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_ci	digtable->dig_twoport_algorithm = DIG_TWO_PORT_ALGO_RSSI;
64462306a36Sopenharmony_ci	digtable->dig_ext_port_stage = DIG_EXT_PORT_STAGE_MAX;
64562306a36Sopenharmony_ci	/* off=by real rssi value, on=by digtable->rssi_val for new dig */
64662306a36Sopenharmony_ci	digtable->dig_dbgmode = DM_DBG_OFF;
64762306a36Sopenharmony_ci	digtable->dig_slgorithm_switch = 0;
64862306a36Sopenharmony_ci
64962306a36Sopenharmony_ci	/* 2007/10/04 MH Define init gain threshol. */
65062306a36Sopenharmony_ci	digtable->dig_state = DM_STA_DIG_MAX;
65162306a36Sopenharmony_ci	digtable->dig_highpwrstate = DM_STA_DIG_MAX;
65262306a36Sopenharmony_ci
65362306a36Sopenharmony_ci	digtable->cur_sta_cstate = DIG_STA_DISCONNECT;
65462306a36Sopenharmony_ci	digtable->pre_sta_cstate = DIG_STA_DISCONNECT;
65562306a36Sopenharmony_ci	digtable->cur_ap_cstate = DIG_AP_DISCONNECT;
65662306a36Sopenharmony_ci	digtable->pre_ap_cstate = DIG_AP_DISCONNECT;
65762306a36Sopenharmony_ci
65862306a36Sopenharmony_ci	digtable->rssi_lowthresh = DM_DIG_THRESH_LOW;
65962306a36Sopenharmony_ci	digtable->rssi_highthresh = DM_DIG_THRESH_HIGH;
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	digtable->fa_lowthresh = DM_FALSEALARM_THRESH_LOW;
66262306a36Sopenharmony_ci	digtable->fa_highthresh = DM_FALSEALARM_THRESH_HIGH;
66362306a36Sopenharmony_ci
66462306a36Sopenharmony_ci	digtable->rssi_highpower_lowthresh = DM_DIG_HIGH_PWR_THRESH_LOW;
66562306a36Sopenharmony_ci	digtable->rssi_highpower_highthresh = DM_DIG_HIGH_PWR_THRESH_HIGH;
66662306a36Sopenharmony_ci
66762306a36Sopenharmony_ci	/* for dig debug rssi value */
66862306a36Sopenharmony_ci	digtable->rssi_val = 50;
66962306a36Sopenharmony_ci	digtable->back_val = DM_DIG_BACKOFF_MAX;
67062306a36Sopenharmony_ci	digtable->rx_gain_max = DM_DIG_MAX;
67162306a36Sopenharmony_ci
67262306a36Sopenharmony_ci	digtable->rx_gain_min = DM_DIG_MIN;
67362306a36Sopenharmony_ci
67462306a36Sopenharmony_ci	digtable->backoffval_range_max = DM_DIG_BACKOFF_MAX;
67562306a36Sopenharmony_ci	digtable->backoffval_range_min = DM_DIG_BACKOFF_MIN;
67662306a36Sopenharmony_ci}
67762306a36Sopenharmony_ci
67862306a36Sopenharmony_cistatic void _rtl92s_dm_init_dynamic_txpower(struct ieee80211_hw *hw)
67962306a36Sopenharmony_ci{
68062306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
68162306a36Sopenharmony_ci
68262306a36Sopenharmony_ci	if ((hal_get_firmwareversion(rtlpriv) >= 60) &&
68362306a36Sopenharmony_ci	    (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER))
68462306a36Sopenharmony_ci		rtlpriv->dm.dynamic_txpower_enable = true;
68562306a36Sopenharmony_ci	else
68662306a36Sopenharmony_ci		rtlpriv->dm.dynamic_txpower_enable = false;
68762306a36Sopenharmony_ci
68862306a36Sopenharmony_ci	rtlpriv->dm.last_dtp_lvl = TX_HIGHPWR_LEVEL_NORMAL;
68962306a36Sopenharmony_ci	rtlpriv->dm.dynamic_txhighpower_lvl = TX_HIGHPWR_LEVEL_NORMAL;
69062306a36Sopenharmony_ci}
69162306a36Sopenharmony_ci
69262306a36Sopenharmony_civoid rtl92s_dm_init(struct ieee80211_hw *hw)
69362306a36Sopenharmony_ci{
69462306a36Sopenharmony_ci	struct rtl_priv *rtlpriv = rtl_priv(hw);
69562306a36Sopenharmony_ci
69662306a36Sopenharmony_ci	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
69762306a36Sopenharmony_ci	rtlpriv->dm.undec_sm_pwdb = -1;
69862306a36Sopenharmony_ci
69962306a36Sopenharmony_ci	_rtl92s_dm_init_dynamic_txpower(hw);
70062306a36Sopenharmony_ci	rtl92s_dm_init_edca_turbo(hw);
70162306a36Sopenharmony_ci	_rtl92s_dm_init_rate_adaptive_mask(hw);
70262306a36Sopenharmony_ci	_rtl92s_dm_init_txpowertracking_thermalmeter(hw);
70362306a36Sopenharmony_ci	_rtl92s_dm_init_dig(hw);
70462306a36Sopenharmony_ci
70562306a36Sopenharmony_ci	rtl_write_dword(rtlpriv, WFM5, FW_CCA_CHK_ENABLE);
70662306a36Sopenharmony_ci}
70762306a36Sopenharmony_ci
70862306a36Sopenharmony_civoid rtl92s_dm_watchdog(struct ieee80211_hw *hw)
70962306a36Sopenharmony_ci{
71062306a36Sopenharmony_ci	_rtl92s_dm_check_edca_turbo(hw);
71162306a36Sopenharmony_ci	_rtl92s_dm_check_txpowertracking_thermalmeter(hw);
71262306a36Sopenharmony_ci	_rtl92s_dm_ctrl_initgain_byrssi(hw);
71362306a36Sopenharmony_ci	_rtl92s_dm_dynamic_txpower(hw);
71462306a36Sopenharmony_ci	_rtl92s_dm_refresh_rateadaptive_mask(hw);
71562306a36Sopenharmony_ci	_rtl92s_dm_switch_baseband_mrc(hw);
71662306a36Sopenharmony_ci}
71762306a36Sopenharmony_ci
718