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 (41416B)


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright(c) 2009-2014  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 "trx.h"
     15#include "../btcoexist/rtl_btc.h"
     16
     17static const u32 ofdmswing_table[] = {
     18	0x0b40002d, /* 0,  -15.0dB */
     19	0x0c000030, /* 1,  -14.5dB */
     20	0x0cc00033, /* 2,  -14.0dB */
     21	0x0d800036, /* 3,  -13.5dB */
     22	0x0e400039, /* 4,  -13.0dB */
     23	0x0f00003c, /* 5,  -12.5dB */
     24	0x10000040, /* 6,  -12.0dB */
     25	0x11000044, /* 7,  -11.5dB */
     26	0x12000048, /* 8,  -11.0dB */
     27	0x1300004c, /* 9,  -10.5dB */
     28	0x14400051, /* 10, -10.0dB */
     29	0x15800056, /* 11, -9.5dB */
     30	0x16c0005b, /* 12, -9.0dB */
     31	0x18000060, /* 13, -8.5dB */
     32	0x19800066, /* 14, -8.0dB */
     33	0x1b00006c, /* 15, -7.5dB */
     34	0x1c800072, /* 16, -7.0dB */
     35	0x1e400079, /* 17, -6.5dB */
     36	0x20000080, /* 18, -6.0dB */
     37	0x22000088, /* 19, -5.5dB */
     38	0x24000090, /* 20, -5.0dB */
     39	0x26000098, /* 21, -4.5dB */
     40	0x288000a2, /* 22, -4.0dB */
     41	0x2ac000ab, /* 23, -3.5dB */
     42	0x2d4000b5, /* 24, -3.0dB */
     43	0x300000c0, /* 25, -2.5dB */
     44	0x32c000cb, /* 26, -2.0dB */
     45	0x35c000d7, /* 27, -1.5dB */
     46	0x390000e4, /* 28, -1.0dB */
     47	0x3c8000f2, /* 29, -0.5dB */
     48	0x40000100, /* 30, +0dB */
     49	0x43c0010f, /* 31, +0.5dB */
     50	0x47c0011f, /* 32, +1.0dB */
     51	0x4c000130, /* 33, +1.5dB */
     52	0x50800142, /* 34, +2.0dB */
     53	0x55400155, /* 35, +2.5dB */
     54	0x5a400169, /* 36, +3.0dB */
     55	0x5fc0017f, /* 37, +3.5dB */
     56	0x65400195, /* 38, +4.0dB */
     57	0x6b8001ae, /* 39, +4.5dB */
     58	0x71c001c7, /* 40, +5.0dB */
     59	0x788001e2, /* 41, +5.5dB */
     60	0x7f8001fe  /* 42, +6.0dB */
     61};
     62
     63static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
     64	{0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01}, /*  0, -16.0dB */
     65	{0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01}, /*  1, -15.5dB */
     66	{0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01}, /*  2, -15.0dB */
     67	{0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01}, /*  3, -14.5dB */
     68	{0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01}, /*  4, -14.0dB */
     69	{0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01}, /*  5, -13.5dB */
     70	{0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01}, /*  6, -13.0dB */
     71	{0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01}, /*  7, -12.5dB */
     72	{0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01}, /*  8, -12.0dB */
     73	{0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01}, /*  9, -11.5dB */
     74	{0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 10, -11.0dB */
     75	{0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01}, /* 11, -10.5dB */
     76	{0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 12, -10.0dB */
     77	{0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01}, /* 13, -9.5dB */
     78	{0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01}, /* 14, -9.0dB */
     79	{0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02}, /* 15, -8.5dB */
     80	{0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01}, /* 16, -8.0dB */
     81	{0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02}, /* 17, -7.5dB */
     82	{0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02}, /* 18, -7.0dB */
     83	{0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02}, /* 19, -6.5dB */
     84	{0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02}, /* 20, -6.0dB */
     85	{0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02}, /* 21, -5.5dB */
     86	{0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02}, /* 22, -5.0dB */
     87	{0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02}, /* 23, -4.5dB */
     88	{0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02}, /* 24, -4.0dB */
     89	{0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03}, /* 25, -3.5dB */
     90	{0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03}, /* 26, -3.0dB */
     91	{0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03}, /* 27, -2.5dB */
     92	{0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03}, /* 28, -2.0dB */
     93	{0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03}, /* 29, -1.5dB */
     94	{0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03}, /* 30, -1.0dB */
     95	{0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04}, /* 31, -0.5dB */
     96	{0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}  /* 32, +0dB */
     97};
     98
     99static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
    100	{0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00}, /*  0, -16.0dB */
    101	{0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  1, -15.5dB */
    102	{0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  2, -15.0dB */
    103	{0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  3, -14.5dB */
    104	{0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00}, /*  4, -14.0dB */
    105	{0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*  5, -13.5dB */
    106	{0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00}, /*  6, -13.0dB */
    107	{0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00}, /*  7, -12.5dB */
    108	{0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /*  8, -12.0dB */
    109	{0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00}, /*  9, -11.5dB */
    110	{0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 10, -11.0dB */
    111	{0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00}, /* 11, -10.5dB */
    112	{0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 12, -10.0dB */
    113	{0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00}, /* 13, -9.5dB */
    114	{0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 14, -9.0dB */
    115	{0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00}, /* 15, -8.5dB */
    116	{0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 16, -8.0dB */
    117	{0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00}, /* 17, -7.5dB */
    118	{0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00}, /* 18, -7.0dB */
    119	{0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00}, /* 19, -6.5dB */
    120	{0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 20, -6.0dB */
    121	{0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00}, /* 21, -5.5dB */
    122	{0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00}, /* 22, -5.0dB */
    123	{0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00}, /* 23, -4.5dB */
    124	{0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00}, /* 24, -4.0dB */
    125	{0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00}, /* 25, -3.5dB */
    126	{0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00}, /* 26, -3.0dB */
    127	{0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00}, /* 27, -2.5dB */
    128	{0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00}, /* 28, -2.0dB */
    129	{0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00}, /* 29, -1.5dB */
    130	{0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00}, /* 30, -1.0dB */
    131	{0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00}, /* 31, -0.5dB */
    132	{0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}  /* 32, +0dB */
    133};
    134
    135static const u32 edca_setting_dl[PEER_MAX] = {
    136	0xa44f,		/* 0 UNKNOWN */
    137	0x5ea44f,	/* 1 REALTEK_90 */
    138	0x5e4322,	/* 2 REALTEK_92SE */
    139	0x5ea42b,	/* 3 BROAD */
    140	0xa44f,		/* 4 RAL */
    141	0xa630,		/* 5 ATH */
    142	0x5ea630,	/* 6 CISCO */
    143	0x5ea42b,	/* 7 MARVELL */
    144};
    145
    146static const u32 edca_setting_ul[PEER_MAX] = {
    147	0x5e4322,	/* 0 UNKNOWN */
    148	0xa44f,		/* 1 REALTEK_90 */
    149	0x5ea44f,	/* 2 REALTEK_92SE */
    150	0x5ea32b,	/* 3 BROAD */
    151	0x5ea422,	/* 4 RAL */
    152	0x5ea322,	/* 5 ATH */
    153	0x3ea430,	/* 6 CISCO */
    154	0x5ea44f,	/* 7 MARV */
    155};
    156
    157void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type,
    158				       u8 *pdirection, u32 *poutwrite_val)
    159{
    160	struct rtl_priv *rtlpriv = rtl_priv(hw);
    161	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
    162	u8 pwr_val = 0;
    163	u8 ofdm_base = rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A];
    164	u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
    165	u8 cck_base = rtldm->swing_idx_cck_base;
    166	u8 cck_val = rtldm->swing_idx_cck;
    167
    168	if (type == 0) {
    169		if (ofdm_val <= ofdm_base) {
    170			*pdirection = 1;
    171			pwr_val = ofdm_base - ofdm_val;
    172		} else {
    173			*pdirection = 2;
    174			pwr_val = ofdm_val - ofdm_base;
    175		}
    176	} else if (type == 1) {
    177		if (cck_val <= cck_base) {
    178			*pdirection = 1;
    179			pwr_val = cck_base - cck_val;
    180		} else {
    181			*pdirection = 2;
    182			pwr_val = cck_val - cck_base;
    183		}
    184	}
    185
    186	if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
    187		pwr_val = TXPWRTRACK_MAX_IDX;
    188
    189	*poutwrite_val = pwr_val | (pwr_val << 8) |
    190		(pwr_val << 16) | (pwr_val << 24);
    191}
    192
    193void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
    194{
    195	struct rtl_priv *rtlpriv = rtl_priv(hw);
    196	struct rate_adaptive *p_ra = &rtlpriv->ra;
    197
    198	p_ra->ratr_state = DM_RATR_STA_INIT;
    199	p_ra->pre_ratr_state = DM_RATR_STA_INIT;
    200
    201	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
    202		rtlpriv->dm.useramask = true;
    203	else
    204		rtlpriv->dm.useramask = false;
    205
    206	p_ra->high_rssi_thresh_for_ra = 50;
    207	p_ra->low_rssi_thresh_for_ra40m = 20;
    208}
    209
    210static void rtl8723be_dm_init_txpower_tracking(struct ieee80211_hw *hw)
    211{
    212	struct rtl_priv *rtlpriv = rtl_priv(hw);
    213
    214	rtlpriv->dm.txpower_tracking = true;
    215	rtlpriv->dm.txpower_track_control = true;
    216	rtlpriv->dm.thermalvalue = 0;
    217
    218	rtlpriv->dm.ofdm_index[0] = 30;
    219	rtlpriv->dm.cck_index = 20;
    220
    221	rtlpriv->dm.swing_idx_cck_base = rtlpriv->dm.cck_index;
    222
    223	rtlpriv->dm.swing_idx_ofdm_base[0] = rtlpriv->dm.ofdm_index[0];
    224	rtlpriv->dm.delta_power_index[RF90_PATH_A] = 0;
    225	rtlpriv->dm.delta_power_index_last[RF90_PATH_A] = 0;
    226	rtlpriv->dm.power_index_offset[RF90_PATH_A] = 0;
    227
    228	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    229		"rtlpriv->dm.txpower_tracking = %d\n",
    230		rtlpriv->dm.txpower_tracking);
    231}
    232
    233static void rtl8723be_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
    234{
    235	struct rtl_priv *rtlpriv = rtl_priv(hw);
    236
    237	rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
    238
    239	rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, 0x800);
    240	rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
    241}
    242
    243void rtl8723be_dm_init(struct ieee80211_hw *hw)
    244{
    245	struct rtl_priv *rtlpriv = rtl_priv(hw);
    246	u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
    247
    248	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
    249	rtl_dm_diginit(hw, cur_igvalue);
    250	rtl8723be_dm_init_rate_adaptive_mask(hw);
    251	rtl8723_dm_init_edca_turbo(hw);
    252	rtl8723_dm_init_dynamic_bb_powersaving(hw);
    253	rtl8723_dm_init_dynamic_txpower(hw);
    254	rtl8723be_dm_init_txpower_tracking(hw);
    255	rtl8723be_dm_init_dynamic_atc_switch(hw);
    256}
    257
    258static void rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw *hw)
    259{
    260	struct rtl_priv *rtlpriv = rtl_priv(hw);
    261	struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable;
    262	struct rtl_mac *mac = rtl_mac(rtlpriv);
    263
    264	/* Determine the minimum RSSI  */
    265	if ((mac->link_state < MAC80211_LINKED) &&
    266	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
    267		rtl_dm_dig->min_undec_pwdb_for_dm = 0;
    268		rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
    269			"Not connected to any\n");
    270	}
    271	if (mac->link_state >= MAC80211_LINKED) {
    272		if (mac->opmode == NL80211_IFTYPE_AP ||
    273		    mac->opmode == NL80211_IFTYPE_ADHOC) {
    274			rtl_dm_dig->min_undec_pwdb_for_dm =
    275			    rtlpriv->dm.entry_min_undec_sm_pwdb;
    276			rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
    277				"AP Client PWDB = 0x%lx\n",
    278				rtlpriv->dm.entry_min_undec_sm_pwdb);
    279		} else {
    280			rtl_dm_dig->min_undec_pwdb_for_dm =
    281			    rtlpriv->dm.undec_sm_pwdb;
    282			rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
    283				"STA Default Port PWDB = 0x%x\n",
    284				rtl_dm_dig->min_undec_pwdb_for_dm);
    285		}
    286	} else {
    287		rtl_dm_dig->min_undec_pwdb_for_dm =
    288				rtlpriv->dm.entry_min_undec_sm_pwdb;
    289		rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
    290			"AP Ext Port or disconnect PWDB = 0x%x\n",
    291			rtl_dm_dig->min_undec_pwdb_for_dm);
    292	}
    293	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
    294		rtl_dm_dig->min_undec_pwdb_for_dm);
    295}
    296
    297static void rtl8723be_dm_check_rssi_monitor(struct ieee80211_hw *hw)
    298{
    299	struct rtl_priv *rtlpriv = rtl_priv(hw);
    300	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    301	struct rtl_sta_info *drv_priv;
    302	u8 h2c_parameter[3] = { 0 };
    303	long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
    304
    305	/* AP & ADHOC & MESH */
    306	spin_lock_bh(&rtlpriv->locks.entry_list_lock);
    307	list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
    308		if (drv_priv->rssi_stat.undec_sm_pwdb <
    309						tmp_entry_min_pwdb)
    310			tmp_entry_min_pwdb =
    311				drv_priv->rssi_stat.undec_sm_pwdb;
    312		if (drv_priv->rssi_stat.undec_sm_pwdb >
    313						tmp_entry_max_pwdb)
    314			tmp_entry_max_pwdb =
    315				drv_priv->rssi_stat.undec_sm_pwdb;
    316	}
    317	spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
    318
    319	/* If associated entry is found */
    320	if (tmp_entry_max_pwdb != 0) {
    321		rtlpriv->dm.entry_max_undec_sm_pwdb =
    322							tmp_entry_max_pwdb;
    323		RTPRINT(rtlpriv, FDM, DM_PWDB,
    324			"EntryMaxPWDB = 0x%lx(%ld)\n",
    325			 tmp_entry_max_pwdb, tmp_entry_max_pwdb);
    326	} else {
    327		rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
    328	}
    329	/* If associated entry is found */
    330	if (tmp_entry_min_pwdb != 0xff) {
    331		rtlpriv->dm.entry_min_undec_sm_pwdb =
    332							tmp_entry_min_pwdb;
    333		RTPRINT(rtlpriv, FDM, DM_PWDB,
    334			"EntryMinPWDB = 0x%lx(%ld)\n",
    335			 tmp_entry_min_pwdb, tmp_entry_min_pwdb);
    336	} else {
    337		rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
    338	}
    339	/* Indicate Rx signal strength to FW. */
    340	if (rtlpriv->dm.useramask) {
    341		h2c_parameter[2] =
    342			(u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF);
    343		h2c_parameter[1] = 0x20;
    344		h2c_parameter[0] = 0;
    345		rtl8723be_fill_h2c_cmd(hw, H2C_RSSIBE_REPORT, 3, h2c_parameter);
    346	} else {
    347		rtl_write_byte(rtlpriv, 0x4fe,
    348			       rtlpriv->dm.undec_sm_pwdb);
    349	}
    350	rtl8723be_dm_find_minimum_rssi(hw);
    351	dm_digtable->rssi_val_min =
    352			rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
    353}
    354
    355void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
    356{
    357	struct rtl_priv *rtlpriv = rtl_priv(hw);
    358	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    359
    360	if (dm_digtable->stop_dig)
    361		return;
    362
    363	if (dm_digtable->cur_igvalue != current_igi) {
    364		rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi);
    365		if (rtlpriv->phy.rf_type != RF_1T1R)
    366			rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1,
    367				      0x7f, current_igi);
    368	}
    369	dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
    370	dm_digtable->cur_igvalue = current_igi;
    371}
    372
    373static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
    374{
    375	struct rtl_priv *rtlpriv = rtl_priv(hw);
    376	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    377	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    378	u8 dig_min_0, dig_maxofmin;
    379	bool bfirstconnect, bfirstdisconnect;
    380	u8 dm_dig_max, dm_dig_min;
    381	u8 current_igi = dm_digtable->cur_igvalue;
    382	u8 offset;
    383
    384	/* AP,BT */
    385	if (mac->act_scanning)
    386		return;
    387
    388	dig_min_0 = dm_digtable->dig_min_0;
    389	bfirstconnect = (mac->link_state >= MAC80211_LINKED) &&
    390			!dm_digtable->media_connect_0;
    391	bfirstdisconnect = (mac->link_state < MAC80211_LINKED) &&
    392			(dm_digtable->media_connect_0);
    393
    394	dm_dig_max = 0x5a;
    395	dm_dig_min = DM_DIG_MIN;
    396	dig_maxofmin = DM_DIG_MAX_AP;
    397
    398	if (mac->link_state >= MAC80211_LINKED) {
    399		if ((dm_digtable->rssi_val_min + 10) > dm_dig_max)
    400			dm_digtable->rx_gain_max = dm_dig_max;
    401		else if ((dm_digtable->rssi_val_min + 10) < dm_dig_min)
    402			dm_digtable->rx_gain_max = dm_dig_min;
    403		else
    404			dm_digtable->rx_gain_max =
    405				dm_digtable->rssi_val_min + 10;
    406
    407		if (rtlpriv->dm.one_entry_only) {
    408			offset = 12;
    409			if (dm_digtable->rssi_val_min - offset < dm_dig_min)
    410				dig_min_0 = dm_dig_min;
    411			else if (dm_digtable->rssi_val_min - offset >
    412							dig_maxofmin)
    413				dig_min_0 = dig_maxofmin;
    414			else
    415				dig_min_0 =
    416					dm_digtable->rssi_val_min - offset;
    417		} else {
    418			dig_min_0 = dm_dig_min;
    419		}
    420
    421	} else {
    422		dm_digtable->rx_gain_max = dm_dig_max;
    423		dig_min_0 = dm_dig_min;
    424		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
    425	}
    426
    427	if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
    428		if (dm_digtable->large_fa_hit != 3)
    429			dm_digtable->large_fa_hit++;
    430		if (dm_digtable->forbidden_igi < current_igi) {
    431			dm_digtable->forbidden_igi = current_igi;
    432			dm_digtable->large_fa_hit = 1;
    433		}
    434
    435		if (dm_digtable->large_fa_hit >= 3) {
    436			if ((dm_digtable->forbidden_igi + 1) >
    437			     dm_digtable->rx_gain_max)
    438				dm_digtable->rx_gain_min =
    439						dm_digtable->rx_gain_max;
    440			else
    441				dm_digtable->rx_gain_min =
    442						dm_digtable->forbidden_igi + 1;
    443			dm_digtable->recover_cnt = 3600;
    444		}
    445	} else {
    446		if (dm_digtable->recover_cnt != 0) {
    447			dm_digtable->recover_cnt--;
    448		} else {
    449			if (dm_digtable->large_fa_hit < 3) {
    450				if ((dm_digtable->forbidden_igi - 1) <
    451				     dig_min_0) {
    452					dm_digtable->forbidden_igi =
    453							dig_min_0;
    454					dm_digtable->rx_gain_min =
    455							dig_min_0;
    456				} else {
    457					dm_digtable->forbidden_igi--;
    458					dm_digtable->rx_gain_min =
    459						dm_digtable->forbidden_igi + 1;
    460				}
    461			} else {
    462				dm_digtable->large_fa_hit = 0;
    463			}
    464		}
    465	}
    466	if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max)
    467		dm_digtable->rx_gain_min = dm_digtable->rx_gain_max;
    468
    469	if (mac->link_state >= MAC80211_LINKED) {
    470		if (bfirstconnect) {
    471			if (dm_digtable->rssi_val_min <= dig_maxofmin)
    472				current_igi = dm_digtable->rssi_val_min;
    473			else
    474				current_igi = dig_maxofmin;
    475
    476			dm_digtable->large_fa_hit = 0;
    477		} else {
    478			if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
    479				current_igi += 4;
    480			else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
    481				current_igi += 2;
    482			else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
    483				current_igi -= 2;
    484		}
    485	} else {
    486		if (bfirstdisconnect) {
    487			current_igi = dm_digtable->rx_gain_min;
    488		} else {
    489			if (rtlpriv->falsealm_cnt.cnt_all > 10000)
    490				current_igi += 4;
    491			else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
    492				current_igi += 2;
    493			else if (rtlpriv->falsealm_cnt.cnt_all < 500)
    494				current_igi -= 2;
    495		}
    496	}
    497
    498	if (current_igi > dm_digtable->rx_gain_max)
    499		current_igi = dm_digtable->rx_gain_max;
    500	else if (current_igi < dm_digtable->rx_gain_min)
    501		current_igi = dm_digtable->rx_gain_min;
    502
    503	rtl8723be_dm_write_dig(hw, current_igi);
    504	dm_digtable->media_connect_0 =
    505		((mac->link_state >= MAC80211_LINKED) ? true : false);
    506	dm_digtable->dig_min_0 = dig_min_0;
    507}
    508
    509static void rtl8723be_dm_false_alarm_counter_statistics(
    510					struct ieee80211_hw *hw)
    511{
    512	u32 ret_value;
    513	struct rtl_priv *rtlpriv = rtl_priv(hw);
    514	struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
    515
    516	rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
    517	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
    518
    519	ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
    520	falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff;
    521	falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16;
    522
    523	ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
    524	falsealm_cnt->cnt_ofdm_cca = ret_value & 0xffff;
    525	falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16;
    526
    527	ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
    528	falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff;
    529	falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16;
    530
    531	ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
    532	falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff;
    533
    534	falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
    535				      falsealm_cnt->cnt_rate_illegal +
    536				      falsealm_cnt->cnt_crc8_fail +
    537				      falsealm_cnt->cnt_mcs_fail +
    538				      falsealm_cnt->cnt_fast_fsync_fail +
    539				      falsealm_cnt->cnt_sb_search_fail;
    540
    541	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1);
    542	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1);
    543
    544	ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_RST_11N, MASKBYTE0);
    545	falsealm_cnt->cnt_cck_fail = ret_value;
    546
    547	ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
    548	falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
    549
    550	ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD);
    551	falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
    552				    ((ret_value & 0xff00) >> 8);
    553
    554	falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
    555				falsealm_cnt->cnt_sb_search_fail +
    556				falsealm_cnt->cnt_parity_fail +
    557				falsealm_cnt->cnt_rate_illegal +
    558				falsealm_cnt->cnt_crc8_fail +
    559				falsealm_cnt->cnt_mcs_fail +
    560				falsealm_cnt->cnt_cck_fail;
    561
    562	falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
    563				    falsealm_cnt->cnt_cck_cca;
    564
    565	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
    566	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
    567	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
    568	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
    569
    570	rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
    571	rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
    572
    573	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
    574	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
    575
    576	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
    577	rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
    578
    579	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
    580		"cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
    581		falsealm_cnt->cnt_parity_fail,
    582		falsealm_cnt->cnt_rate_illegal,
    583		falsealm_cnt->cnt_crc8_fail,
    584		falsealm_cnt->cnt_mcs_fail);
    585
    586	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
    587		"cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
    588		falsealm_cnt->cnt_ofdm_fail,
    589		falsealm_cnt->cnt_cck_fail,
    590		falsealm_cnt->cnt_all);
    591}
    592
    593static void rtl8723be_dm_dynamic_txpower(struct ieee80211_hw *hw)
    594{
    595	/* 8723BE does not support ODM_BB_DYNAMIC_TXPWR*/
    596	return;
    597}
    598
    599static void rtl8723be_set_iqk_matrix(struct ieee80211_hw *hw, u8 ofdm_index,
    600				     u8 rfpath, long iqk_result_x,
    601				     long iqk_result_y)
    602{
    603	long ele_a = 0, ele_d, ele_c = 0, value32;
    604
    605	if (ofdm_index >= 43)
    606		ofdm_index = 43 - 1;
    607
    608	ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000) >> 22;
    609
    610	if (iqk_result_x != 0) {
    611		if ((iqk_result_x & 0x00000200) != 0)
    612			iqk_result_x = iqk_result_x | 0xFFFFFC00;
    613		ele_a = ((iqk_result_x * ele_d) >> 8) & 0x000003FF;
    614
    615		if ((iqk_result_y & 0x00000200) != 0)
    616			iqk_result_y = iqk_result_y | 0xFFFFFC00;
    617		ele_c = ((iqk_result_y * ele_d) >> 8) & 0x000003FF;
    618
    619		switch (rfpath) {
    620		case RF90_PATH_A:
    621			value32 = (ele_d << 22) |
    622				((ele_c & 0x3F) << 16) | ele_a;
    623			rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
    624				      value32);
    625			value32 = (ele_c & 0x000003C0) >> 6;
    626			rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32);
    627			value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
    628			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
    629				      value32);
    630			break;
    631		default:
    632			break;
    633		}
    634	} else {
    635		switch (rfpath) {
    636		case RF90_PATH_A:
    637			rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
    638				      ofdmswing_table[ofdm_index]);
    639			rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00);
    640			rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00);
    641			break;
    642		default:
    643			break;
    644		}
    645	}
    646}
    647
    648static void rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw *hw,
    649					enum pwr_track_control_method method,
    650					u8 rfpath, u8 idx)
    651{
    652	struct rtl_priv *rtlpriv = rtl_priv(hw);
    653	struct rtl_phy *rtlphy = &rtlpriv->phy;
    654	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
    655	u8 swing_idx_ofdm_limit = 36;
    656
    657	if (method == TXAGC) {
    658		rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
    659	} else if (method == BBSWING) {
    660		if (rtldm->swing_idx_cck >= CCK_TABLE_SIZE)
    661			rtldm->swing_idx_cck = CCK_TABLE_SIZE - 1;
    662
    663		if (!rtldm->cck_inch14) {
    664			rtl_write_byte(rtlpriv, 0xa22,
    665			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][0]);
    666			rtl_write_byte(rtlpriv, 0xa23,
    667			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][1]);
    668			rtl_write_byte(rtlpriv, 0xa24,
    669			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][2]);
    670			rtl_write_byte(rtlpriv, 0xa25,
    671			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][3]);
    672			rtl_write_byte(rtlpriv, 0xa26,
    673			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][4]);
    674			rtl_write_byte(rtlpriv, 0xa27,
    675			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][5]);
    676			rtl_write_byte(rtlpriv, 0xa28,
    677			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][6]);
    678			rtl_write_byte(rtlpriv, 0xa29,
    679			    cckswing_table_ch1ch13[rtldm->swing_idx_cck][7]);
    680		} else {
    681			rtl_write_byte(rtlpriv, 0xa22,
    682			    cckswing_table_ch14[rtldm->swing_idx_cck][0]);
    683			rtl_write_byte(rtlpriv, 0xa23,
    684			    cckswing_table_ch14[rtldm->swing_idx_cck][1]);
    685			rtl_write_byte(rtlpriv, 0xa24,
    686			    cckswing_table_ch14[rtldm->swing_idx_cck][2]);
    687			rtl_write_byte(rtlpriv, 0xa25,
    688			    cckswing_table_ch14[rtldm->swing_idx_cck][3]);
    689			rtl_write_byte(rtlpriv, 0xa26,
    690			    cckswing_table_ch14[rtldm->swing_idx_cck][4]);
    691			rtl_write_byte(rtlpriv, 0xa27,
    692			    cckswing_table_ch14[rtldm->swing_idx_cck][5]);
    693			rtl_write_byte(rtlpriv, 0xa28,
    694			    cckswing_table_ch14[rtldm->swing_idx_cck][6]);
    695			rtl_write_byte(rtlpriv, 0xa29,
    696			    cckswing_table_ch14[rtldm->swing_idx_cck][7]);
    697		}
    698
    699		if (rfpath == RF90_PATH_A) {
    700			if (rtldm->swing_idx_ofdm[RF90_PATH_A] <
    701			    swing_idx_ofdm_limit)
    702				swing_idx_ofdm_limit =
    703					rtldm->swing_idx_ofdm[RF90_PATH_A];
    704
    705			rtl8723be_set_iqk_matrix(hw,
    706				rtldm->swing_idx_ofdm[rfpath], rfpath,
    707				rtlphy->iqk_matrix[idx].value[0][0],
    708				rtlphy->iqk_matrix[idx].value[0][1]);
    709		} else if (rfpath == RF90_PATH_B) {
    710			if (rtldm->swing_idx_ofdm[RF90_PATH_B] <
    711			    swing_idx_ofdm_limit)
    712				swing_idx_ofdm_limit =
    713					rtldm->swing_idx_ofdm[RF90_PATH_B];
    714
    715			rtl8723be_set_iqk_matrix(hw,
    716				rtldm->swing_idx_ofdm[rfpath], rfpath,
    717				rtlphy->iqk_matrix[idx].value[0][4],
    718				rtlphy->iqk_matrix[idx].value[0][5]);
    719		}
    720	} else {
    721		return;
    722	}
    723}
    724
    725static void rtl8723be_dm_txpower_tracking_callback_thermalmeter(
    726							struct ieee80211_hw *hw)
    727{
    728	struct rtl_priv *rtlpriv = rtl_priv(hw);
    729	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
    730	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
    731	u8 thermalvalue = 0, delta, delta_lck, delta_iqk;
    732	u8 thermalvalue_avg_count = 0;
    733	u32 thermalvalue_avg = 0;
    734	int i = 0;
    735
    736	u8 ofdm_min_index = 6;
    737	u8 index_for_channel = 0;
    738
    739	static const s8 delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = {
    740		0, 0, 1, 2, 2, 2, 3, 3, 3, 4,  5,
    741		5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10,
    742		10, 11, 11, 12, 12, 13, 14, 15};
    743	static const s8 delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = {
    744		0, 0, 1, 2, 2, 2, 3, 3, 3, 4,  5,
    745		5, 6, 6, 6, 6, 7, 7, 7, 8, 8,  9,
    746		9, 10, 10, 11, 12, 13, 14, 15};
    747
    748	/*Initilization ( 7 steps in total )*/
    749	rtlpriv->dm.txpower_trackinginit = true;
    750	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    751		"%s\n", __func__);
    752
    753	thermalvalue = (u8)rtl_get_rfreg(hw,
    754		RF90_PATH_A, RF_T_METER, 0xfc00);
    755	if (!rtlpriv->dm.txpower_track_control || thermalvalue == 0 ||
    756	    rtlefuse->eeprom_thermalmeter == 0xFF)
    757		return;
    758	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    759		"Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
    760		thermalvalue, rtldm->thermalvalue,
    761		rtlefuse->eeprom_thermalmeter);
    762	/*3 Initialize ThermalValues of RFCalibrateInfo*/
    763	if (!rtldm->thermalvalue) {
    764		rtlpriv->dm.thermalvalue_lck = thermalvalue;
    765		rtlpriv->dm.thermalvalue_iqk = thermalvalue;
    766	}
    767
    768	/*4 Calculate average thermal meter*/
    769	rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
    770	rtldm->thermalvalue_avg_index++;
    771	if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8723BE)
    772		rtldm->thermalvalue_avg_index = 0;
    773
    774	for (i = 0; i < AVG_THERMAL_NUM_8723BE; i++) {
    775		if (rtldm->thermalvalue_avg[i]) {
    776			thermalvalue_avg += rtldm->thermalvalue_avg[i];
    777			thermalvalue_avg_count++;
    778		}
    779	}
    780
    781	if (thermalvalue_avg_count)
    782		thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
    783
    784	/* 5 Calculate delta, delta_LCK, delta_IQK.*/
    785	delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
    786		(thermalvalue - rtlpriv->dm.thermalvalue) :
    787		(rtlpriv->dm.thermalvalue - thermalvalue);
    788	delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
    789		    (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
    790		    (rtlpriv->dm.thermalvalue_lck - thermalvalue);
    791	delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
    792		    (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
    793		    (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
    794
    795	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    796		"Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x delta 0x%x delta_lck 0x%x delta_iqk 0x%x\n",
    797		thermalvalue, rtlpriv->dm.thermalvalue,
    798		rtlefuse->eeprom_thermalmeter, delta, delta_lck, delta_iqk);
    799	/* 6 If necessary, do LCK.*/
    800	if (delta_lck >= IQK_THRESHOLD) {
    801		rtlpriv->dm.thermalvalue_lck = thermalvalue;
    802		rtl8723be_phy_lc_calibrate(hw);
    803	}
    804
    805	/* 7 If necessary, move the index of
    806	 * swing table to adjust Tx power.
    807	 */
    808	if (delta > 0 && rtlpriv->dm.txpower_track_control) {
    809		delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
    810			(thermalvalue - rtlefuse->eeprom_thermalmeter) :
    811			(rtlefuse->eeprom_thermalmeter - thermalvalue);
    812
    813		if (delta >= TXSCALE_TABLE_SIZE)
    814			delta = TXSCALE_TABLE_SIZE - 1;
    815		/* 7.1 Get the final CCK_index and
    816		 * OFDM_index for each swing table.
    817		 */
    818		if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
    819			rtldm->delta_power_index_last[RF90_PATH_A] =
    820					rtldm->delta_power_index[RF90_PATH_A];
    821			rtldm->delta_power_index[RF90_PATH_A] =
    822					delta_swing_table_idx_tup_a[delta];
    823		} else {
    824			rtldm->delta_power_index_last[RF90_PATH_A] =
    825					rtldm->delta_power_index[RF90_PATH_A];
    826			rtldm->delta_power_index[RF90_PATH_A] =
    827				-1 * delta_swing_table_idx_tdown_a[delta];
    828		}
    829
    830		/* 7.2 Handle boundary conditions of index.*/
    831		if (rtldm->delta_power_index[RF90_PATH_A] ==
    832		    rtldm->delta_power_index_last[RF90_PATH_A])
    833			rtldm->power_index_offset[RF90_PATH_A] = 0;
    834		else
    835			rtldm->power_index_offset[RF90_PATH_A] =
    836				rtldm->delta_power_index[RF90_PATH_A] -
    837				rtldm->delta_power_index_last[RF90_PATH_A];
    838
    839		rtldm->ofdm_index[0] =
    840			rtldm->swing_idx_ofdm_base[RF90_PATH_A] +
    841			rtldm->power_index_offset[RF90_PATH_A];
    842		rtldm->cck_index = rtldm->swing_idx_cck_base +
    843				   rtldm->power_index_offset[RF90_PATH_A];
    844
    845		rtldm->swing_idx_cck = rtldm->cck_index;
    846		rtldm->swing_idx_ofdm[0] = rtldm->ofdm_index[0];
    847
    848		if (rtldm->ofdm_index[0] > OFDM_TABLE_SIZE - 1)
    849			rtldm->ofdm_index[0] = OFDM_TABLE_SIZE - 1;
    850		else if (rtldm->ofdm_index[0] < ofdm_min_index)
    851			rtldm->ofdm_index[0] = ofdm_min_index;
    852
    853		if (rtldm->cck_index > CCK_TABLE_SIZE - 1)
    854			rtldm->cck_index = CCK_TABLE_SIZE - 1;
    855		else if (rtldm->cck_index < 0)
    856			rtldm->cck_index = 0;
    857	} else {
    858		rtldm->power_index_offset[RF90_PATH_A] = 0;
    859	}
    860
    861	if ((rtldm->power_index_offset[RF90_PATH_A] != 0) &&
    862	    (rtldm->txpower_track_control)) {
    863		rtldm->done_txpower = true;
    864		rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0,
    865						      index_for_channel);
    866
    867		rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
    868		rtldm->swing_idx_ofdm_base[RF90_PATH_A] =
    869						rtldm->swing_idx_ofdm[0];
    870		rtldm->thermalvalue = thermalvalue;
    871	}
    872
    873	if (delta_iqk >= IQK_THRESHOLD) {
    874		rtldm->thermalvalue_iqk = thermalvalue;
    875		rtl8723be_phy_iq_calibrate(hw, false);
    876	}
    877
    878	rtldm->txpowercount = 0;
    879	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
    880
    881}
    882
    883void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw)
    884{
    885	struct rtl_priv *rtlpriv = rtl_priv(hw);
    886
    887	if (!rtlpriv->dm.txpower_tracking)
    888		return;
    889
    890	if (!rtlpriv->dm.tm_trigger) {
    891		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16),
    892			      0x03);
    893		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    894			"Trigger 8723be Thermal Meter!!\n");
    895		rtlpriv->dm.tm_trigger = 1;
    896		return;
    897	} else {
    898		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    899			"Schedule TxPowerTracking !!\n");
    900		rtl8723be_dm_txpower_tracking_callback_thermalmeter(hw);
    901		rtlpriv->dm.tm_trigger = 0;
    902	}
    903}
    904
    905static void rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
    906{
    907	struct rtl_priv *rtlpriv = rtl_priv(hw);
    908	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
    909	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    910	struct rate_adaptive *p_ra = &rtlpriv->ra;
    911	u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m;
    912	u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
    913	u8 go_up_gap = 5;
    914	struct ieee80211_sta *sta = NULL;
    915
    916	if (is_hal_stop(rtlhal)) {
    917		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    918			"driver is going to unload\n");
    919		return;
    920	}
    921
    922	if (!rtlpriv->dm.useramask) {
    923		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    924			"driver does not control rate adaptive mask\n");
    925		return;
    926	}
    927
    928	if (mac->link_state == MAC80211_LINKED &&
    929		mac->opmode == NL80211_IFTYPE_STATION) {
    930		switch (p_ra->pre_ratr_state) {
    931		case DM_RATR_STA_MIDDLE:
    932			high_rssithresh_for_ra += go_up_gap;
    933			break;
    934		case DM_RATR_STA_LOW:
    935			high_rssithresh_for_ra += go_up_gap;
    936			low_rssithresh_for_ra += go_up_gap;
    937			break;
    938		default:
    939			break;
    940		}
    941
    942		if (rtlpriv->dm.undec_sm_pwdb >
    943		    (long)high_rssithresh_for_ra)
    944			p_ra->ratr_state = DM_RATR_STA_HIGH;
    945		else if (rtlpriv->dm.undec_sm_pwdb >
    946			 (long)low_rssithresh_for_ra)
    947			p_ra->ratr_state = DM_RATR_STA_MIDDLE;
    948		else
    949			p_ra->ratr_state = DM_RATR_STA_LOW;
    950
    951		if (p_ra->pre_ratr_state != p_ra->ratr_state) {
    952			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    953				"RSSI = %ld\n",
    954				 rtlpriv->dm.undec_sm_pwdb);
    955			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    956				"RSSI_LEVEL = %d\n", p_ra->ratr_state);
    957			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
    958				"PreState = %d, CurState = %d\n",
    959				p_ra->pre_ratr_state, p_ra->ratr_state);
    960
    961			rcu_read_lock();
    962			sta = rtl_find_sta(hw, mac->bssid);
    963			if (sta)
    964				rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
    965							   p_ra->ratr_state,
    966							   true);
    967			rcu_read_unlock();
    968
    969			p_ra->pre_ratr_state = p_ra->ratr_state;
    970		}
    971	}
    972}
    973
    974static bool rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
    975{
    976	struct rtl_priv *rtlpriv = rtl_priv(hw);
    977
    978	if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
    979		return true;
    980
    981	return false;
    982}
    983
    984static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw)
    985{
    986	struct rtl_priv *rtlpriv = rtl_priv(hw);
    987	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    988
    989	static u64 last_txok_cnt;
    990	static u64 last_rxok_cnt;
    991	u64 cur_txok_cnt = 0;
    992	u64 cur_rxok_cnt = 0;
    993	u32 edca_be_ul = 0x6ea42b;
    994	u32 edca_be_dl = 0x6ea42b;/*not sure*/
    995	u32 edca_be = 0x5ea42b;
    996	u32 iot_peer = 0;
    997	bool b_is_cur_rdlstate;
    998	bool b_bias_on_rx = false;
    999	bool b_edca_turbo_on = false;
   1000
   1001	cur_txok_cnt = rtlpriv->stats.txbytesunicast - last_txok_cnt;
   1002	cur_rxok_cnt = rtlpriv->stats.rxbytesunicast - last_rxok_cnt;
   1003
   1004	iot_peer = rtlpriv->mac80211.vendor;
   1005	b_bias_on_rx = (iot_peer == PEER_RAL || iot_peer == PEER_ATH) ?
   1006		       true : false;
   1007	b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
   1008			   (!rtlpriv->dm.disable_framebursting)) ?
   1009			   true : false;
   1010
   1011	if ((iot_peer == PEER_CISCO) &&
   1012	    (mac->mode == WIRELESS_MODE_N_24G)) {
   1013		edca_be_dl = edca_setting_dl[iot_peer];
   1014		edca_be_ul = edca_setting_ul[iot_peer];
   1015	}
   1016	if (rtl8723be_dm_is_edca_turbo_disable(hw))
   1017		goto exit;
   1018
   1019	if (b_edca_turbo_on) {
   1020		if (b_bias_on_rx)
   1021			b_is_cur_rdlstate = (cur_txok_cnt > cur_rxok_cnt * 4) ?
   1022					    false : true;
   1023		else
   1024			b_is_cur_rdlstate = (cur_rxok_cnt > cur_txok_cnt * 4) ?
   1025					    true : false;
   1026
   1027		edca_be = (b_is_cur_rdlstate) ? edca_be_dl : edca_be_ul;
   1028		rtl_write_dword(rtlpriv, REG_EDCA_BE_PARAM, edca_be);
   1029		rtlpriv->dm.is_cur_rdlstate = b_is_cur_rdlstate;
   1030		rtlpriv->dm.current_turbo_edca = true;
   1031	} else {
   1032		if (rtlpriv->dm.current_turbo_edca) {
   1033			u8 tmp = AC0_BE;
   1034			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
   1035						      (u8 *)(&tmp));
   1036		}
   1037		rtlpriv->dm.current_turbo_edca = false;
   1038	}
   1039
   1040exit:
   1041	rtlpriv->dm.is_any_nonbepkts = false;
   1042	last_txok_cnt = rtlpriv->stats.txbytesunicast;
   1043	last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
   1044}
   1045
   1046static void rtl8723be_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
   1047{
   1048	struct rtl_priv *rtlpriv = rtl_priv(hw);
   1049	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
   1050	u8 cur_cck_cca_thresh;
   1051
   1052	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
   1053		if (dm_digtable->rssi_val_min > 25) {
   1054			cur_cck_cca_thresh = 0xcd;
   1055		} else if ((dm_digtable->rssi_val_min <= 25) &&
   1056			   (dm_digtable->rssi_val_min > 10)) {
   1057			cur_cck_cca_thresh = 0x83;
   1058		} else {
   1059			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
   1060				cur_cck_cca_thresh = 0x83;
   1061			else
   1062				cur_cck_cca_thresh = 0x40;
   1063		}
   1064	} else {
   1065		if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
   1066			cur_cck_cca_thresh = 0x83;
   1067		else
   1068			cur_cck_cca_thresh = 0x40;
   1069	}
   1070
   1071	if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh)
   1072		rtl_set_bbreg(hw, RCCK0_CCA, MASKBYTE2, cur_cck_cca_thresh);
   1073
   1074	dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
   1075	dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh;
   1076	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
   1077		"CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres);
   1078}
   1079
   1080static void rtl8723be_dm_dynamic_edcca(struct ieee80211_hw *hw)
   1081{
   1082	struct rtl_priv *rtlpriv = rtl_priv(hw);
   1083	u8 reg_c50, reg_c58;
   1084	bool fw_current_in_ps_mode = false;
   1085
   1086	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
   1087				      (u8 *)(&fw_current_in_ps_mode));
   1088	if (fw_current_in_ps_mode)
   1089		return;
   1090
   1091	reg_c50 = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
   1092	reg_c58 = rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
   1093
   1094	if (reg_c50 > 0x28 && reg_c58 > 0x28) {
   1095		if (!rtlpriv->rtlhal.pre_edcca_enable) {
   1096			rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x03);
   1097			rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x00);
   1098		}
   1099	} else if (reg_c50 < 0x25 && reg_c58 < 0x25) {
   1100		if (rtlpriv->rtlhal.pre_edcca_enable) {
   1101			rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD, 0x7f);
   1102			rtl_write_byte(rtlpriv, ROFDM0_ECCATHRESHOLD + 2, 0x7f);
   1103		}
   1104	}
   1105}
   1106
   1107static void rtl8723be_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
   1108{
   1109	struct rtl_priv *rtlpriv = rtl_priv(hw);
   1110	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
   1111	u8 crystal_cap;
   1112	u32 packet_count;
   1113	int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
   1114	int cfo_ave_diff;
   1115
   1116	if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
   1117		if (rtldm->atc_status == ATC_STATUS_OFF) {
   1118			rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
   1119				      ATC_STATUS_ON);
   1120			rtldm->atc_status = ATC_STATUS_ON;
   1121		}
   1122		if (rtlpriv->cfg->ops->get_btc_status()) {
   1123			if (!rtlpriv->btcoexist.btc_ops->btc_is_bt_disabled(rtlpriv)) {
   1124				rtl_dbg(rtlpriv, COMP_BT_COEXIST, DBG_LOUD,
   1125					"odm_DynamicATCSwitch(): Disable CFO tracking for BT!!\n");
   1126				return;
   1127			}
   1128		}
   1129
   1130		if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
   1131			rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
   1132			crystal_cap = rtldm->crystal_cap & 0x3f;
   1133			rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
   1134				      (crystal_cap | (crystal_cap << 6)));
   1135		}
   1136	} else {
   1137		cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
   1138		cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
   1139		packet_count = rtldm->packet_count;
   1140
   1141		if (packet_count == rtldm->packet_count_pre)
   1142			return;
   1143
   1144		rtldm->packet_count_pre = packet_count;
   1145
   1146		if (rtlpriv->phy.rf_type == RF_1T1R)
   1147			cfo_ave = cfo_khz_a;
   1148		else
   1149			cfo_ave = (int)(cfo_khz_a + cfo_khz_b) >> 1;
   1150
   1151		cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
   1152			       (rtldm->cfo_ave_pre - cfo_ave) :
   1153			       (cfo_ave - rtldm->cfo_ave_pre);
   1154
   1155		if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) {
   1156			rtldm->large_cfo_hit = true;
   1157			return;
   1158		} else
   1159			rtldm->large_cfo_hit = false;
   1160
   1161		rtldm->cfo_ave_pre = cfo_ave;
   1162
   1163		if (cfo_ave >= -rtldm->cfo_threshold &&
   1164		    cfo_ave <= rtldm->cfo_threshold && rtldm->is_freeze == 0) {
   1165			if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
   1166				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
   1167				rtldm->is_freeze = 1;
   1168			} else {
   1169				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
   1170			}
   1171		}
   1172
   1173		if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
   1174			adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 1) + 1;
   1175		else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
   1176					rtlpriv->dm.crystal_cap > 0)
   1177			adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 1) - 1;
   1178
   1179		if (adjust_xtal != 0) {
   1180			rtldm->is_freeze = 0;
   1181			rtldm->crystal_cap += adjust_xtal;
   1182
   1183			if (rtldm->crystal_cap > 0x3f)
   1184				rtldm->crystal_cap = 0x3f;
   1185			else if (rtldm->crystal_cap < 0)
   1186				rtldm->crystal_cap = 0;
   1187
   1188			crystal_cap = rtldm->crystal_cap & 0x3f;
   1189			rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
   1190				      (crystal_cap | (crystal_cap << 6)));
   1191		}
   1192
   1193		if (cfo_ave < CFO_THRESHOLD_ATC &&
   1194		    cfo_ave > -CFO_THRESHOLD_ATC) {
   1195			if (rtldm->atc_status == ATC_STATUS_ON) {
   1196				rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
   1197					      ATC_STATUS_OFF);
   1198				rtldm->atc_status = ATC_STATUS_OFF;
   1199			}
   1200		} else {
   1201			if (rtldm->atc_status == ATC_STATUS_OFF) {
   1202				rtl_set_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11),
   1203					      ATC_STATUS_ON);
   1204				rtldm->atc_status = ATC_STATUS_ON;
   1205			}
   1206		}
   1207	}
   1208}
   1209
   1210static void rtl8723be_dm_common_info_self_update(struct ieee80211_hw *hw)
   1211{
   1212	struct rtl_priv *rtlpriv = rtl_priv(hw);
   1213	u8 cnt = 0;
   1214	struct rtl_sta_info *drv_priv;
   1215
   1216	rtlpriv->dm.one_entry_only = false;
   1217
   1218	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
   1219		rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
   1220		rtlpriv->dm.one_entry_only = true;
   1221		return;
   1222	}
   1223
   1224	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
   1225		rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
   1226		rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
   1227		spin_lock_bh(&rtlpriv->locks.entry_list_lock);
   1228		list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
   1229			cnt++;
   1230		}
   1231		spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
   1232
   1233		if (cnt == 1)
   1234			rtlpriv->dm.one_entry_only = true;
   1235	}
   1236}
   1237
   1238void rtl8723be_dm_watchdog(struct ieee80211_hw *hw)
   1239{
   1240	struct rtl_priv *rtlpriv = rtl_priv(hw);
   1241	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
   1242	bool fw_current_inpsmode = false;
   1243	bool fw_ps_awake = true;
   1244
   1245	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
   1246				      (u8 *)(&fw_current_inpsmode));
   1247
   1248	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
   1249				      (u8 *)(&fw_ps_awake));
   1250
   1251	if (ppsc->p2p_ps_info.p2p_ps_mode)
   1252		fw_ps_awake = false;
   1253
   1254	spin_lock(&rtlpriv->locks.rf_ps_lock);
   1255	if ((ppsc->rfpwr_state == ERFON) &&
   1256		((!fw_current_inpsmode) && fw_ps_awake) &&
   1257		(!ppsc->rfchange_inprogress)) {
   1258		rtl8723be_dm_common_info_self_update(hw);
   1259		rtl8723be_dm_false_alarm_counter_statistics(hw);
   1260		rtl8723be_dm_check_rssi_monitor(hw);
   1261		rtl8723be_dm_dig(hw);
   1262		rtl8723be_dm_dynamic_edcca(hw);
   1263		rtl8723be_dm_cck_packet_detection_thresh(hw);
   1264		rtl8723be_dm_refresh_rate_adaptive_mask(hw);
   1265		rtl8723be_dm_check_edca_turbo(hw);
   1266		rtl8723be_dm_dynamic_atc_switch(hw);
   1267		rtl8723be_dm_check_txpower_tracking(hw);
   1268		rtl8723be_dm_dynamic_txpower(hw);
   1269	}
   1270	spin_unlock(&rtlpriv->locks.rf_ps_lock);
   1271	rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
   1272}