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


      1// SPDX-License-Identifier: GPL-2.0
      2/* Copyright(c) 2009-2010  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 "fw.h"
     13#include "trx.h"
     14#include "../btcoexist/rtl_btc.h"
     15
     16static const u32 txscaling_tbl[TXSCALE_TABLE_SIZE] = {
     17	0x081, /* 0, -12.0dB */
     18	0x088, /* 1, -11.5dB */
     19	0x090, /* 2, -11.0dB */
     20	0x099, /* 3, -10.5dB */
     21	0x0A2, /* 4, -10.0dB */
     22	0x0AC, /* 5, -9.5dB */
     23	0x0B6, /* 6, -9.0dB */
     24	0x0C0, /* 7, -8.5dB */
     25	0x0CC, /* 8, -8.0dB */
     26	0x0D8, /* 9, -7.5dB */
     27	0x0E5, /* 10, -7.0dB */
     28	0x0F2, /* 11, -6.5dB */
     29	0x101, /* 12, -6.0dB */
     30	0x110, /* 13, -5.5dB */
     31	0x120, /* 14, -5.0dB */
     32	0x131, /* 15, -4.5dB */
     33	0x143, /* 16, -4.0dB */
     34	0x156, /* 17, -3.5dB */
     35	0x16A, /* 18, -3.0dB */
     36	0x180, /* 19, -2.5dB */
     37	0x197, /* 20, -2.0dB */
     38	0x1AF, /* 21, -1.5dB */
     39	0x1C8, /* 22, -1.0dB */
     40	0x1E3, /* 23, -0.5dB */
     41	0x200, /* 24, +0  dB */
     42	0x21E, /* 25, +0.5dB */
     43	0x23E, /* 26, +1.0dB */
     44	0x261, /* 27, +1.5dB */
     45	0x285, /* 28, +2.0dB */
     46	0x2AB, /* 29, +2.5dB */
     47	0x2D3, /* 30, +3.0dB */
     48	0x2FE, /* 31, +3.5dB */
     49	0x32B, /* 32, +4.0dB */
     50	0x35C, /* 33, +4.5dB */
     51	0x38E, /* 34, +5.0dB */
     52	0x3C4, /* 35, +5.5dB */
     53	0x3FE  /* 36, +6.0dB */
     54};
     55
     56static const u32 rtl8821ae_txscaling_table[TXSCALE_TABLE_SIZE] = {
     57	0x081, /* 0, -12.0dB */
     58	0x088, /* 1, -11.5dB */
     59	0x090, /* 2, -11.0dB */
     60	0x099, /* 3, -10.5dB */
     61	0x0A2, /* 4, -10.0dB */
     62	0x0AC, /* 5, -9.5dB */
     63	0x0B6, /* 6, -9.0dB */
     64	0x0C0, /* 7, -8.5dB */
     65	0x0CC, /* 8, -8.0dB */
     66	0x0D8, /* 9, -7.5dB */
     67	0x0E5, /* 10, -7.0dB */
     68	0x0F2, /* 11, -6.5dB */
     69	0x101, /* 12, -6.0dB */
     70	0x110, /* 13, -5.5dB */
     71	0x120, /* 14, -5.0dB */
     72	0x131, /* 15, -4.5dB */
     73	0x143, /* 16, -4.0dB */
     74	0x156, /* 17, -3.5dB */
     75	0x16A, /* 18, -3.0dB */
     76	0x180, /* 19, -2.5dB */
     77	0x197, /* 20, -2.0dB */
     78	0x1AF, /* 21, -1.5dB */
     79	0x1C8, /* 22, -1.0dB */
     80	0x1E3, /* 23, -0.5dB */
     81	0x200, /* 24, +0  dB */
     82	0x21E, /* 25, +0.5dB */
     83	0x23E, /* 26, +1.0dB */
     84	0x261, /* 27, +1.5dB */
     85	0x285, /* 28, +2.0dB */
     86	0x2AB, /* 29, +2.5dB */
     87	0x2D3, /* 30, +3.0dB */
     88	0x2FE, /* 31, +3.5dB */
     89	0x32B, /* 32, +4.0dB */
     90	0x35C, /* 33, +4.5dB */
     91	0x38E, /* 34, +5.0dB */
     92	0x3C4, /* 35, +5.5dB */
     93	0x3FE  /* 36, +6.0dB */
     94};
     95
     96static const u32 edca_setting_dl[PEER_MAX] = {
     97	0xa44f,		/* 0 UNKNOWN */
     98	0x5ea44f,	/* 1 REALTEK_90 */
     99	0x5e4322,	/* 2 REALTEK_92SE */
    100	0x5ea42b,		/* 3 BROAD	*/
    101	0xa44f,		/* 4 RAL */
    102	0xa630,		/* 5 ATH */
    103	0x5ea630,		/* 6 CISCO */
    104	0x5ea42b,		/* 7 MARVELL */
    105};
    106
    107static const u32 edca_setting_ul[PEER_MAX] = {
    108	0x5e4322,	/* 0 UNKNOWN */
    109	0xa44f,		/* 1 REALTEK_90 */
    110	0x5ea44f,	/* 2 REALTEK_92SE */
    111	0x5ea32b,	/* 3 BROAD */
    112	0x5ea422,	/* 4 RAL */
    113	0x5ea322,	/* 5 ATH */
    114	0x3ea430,	/* 6 CISCO */
    115	0x5ea44f,	/* 7 MARV */
    116};
    117
    118static const u8 rtl8818e_delta_swing_table_idx_24gb_p[] = {
    119	0, 0, 0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 4,
    120	4, 4, 4, 5, 5, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9};
    121
    122static const u8 rtl8818e_delta_swing_table_idx_24gb_n[] = {
    123	0, 0, 0, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 6,
    124	7, 7, 7, 7, 8, 8, 9, 9, 10, 10, 10, 11, 11, 11, 11};
    125
    126static const u8 rtl8812ae_delta_swing_table_idx_24gb_n[]  = {
    127	0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
    128	6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
    129
    130static const u8 rtl8812ae_delta_swing_table_idx_24gb_p[] = {
    131	0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
    132	6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
    133
    134static const u8 rtl8812ae_delta_swing_table_idx_24ga_n[] = {
    135	0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
    136	6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
    137
    138static const u8 rtl8812ae_delta_swing_table_idx_24ga_p[] = {
    139	0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
    140	6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
    141
    142static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_n[] = {
    143	0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
    144	6, 6, 7, 8, 9, 9, 9, 9, 10, 10, 10, 10, 11, 11};
    145
    146static const u8 rtl8812ae_delta_swing_table_idx_24gcckb_p[] = {
    147	0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
    148	6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
    149
    150static const u8 rtl8812ae_delta_swing_table_idx_24gccka_n[] = {
    151	0, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 5, 6,
    152	6, 6, 7, 8, 8, 9, 9, 9, 10, 10, 10, 10, 11, 11};
    153
    154static const u8 rtl8812ae_delta_swing_table_idx_24gccka_p[] = {
    155	0, 0, 1, 1, 2, 2, 2, 2, 3, 3, 3, 4, 4, 5, 5, 6,
    156	6, 6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 9, 9, 9};
    157
    158static const u8 rtl8812ae_delta_swing_table_idx_5gb_n[][DEL_SW_IDX_SZ] = {
    159	{0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7,
    160	7, 8, 8, 9, 9, 9, 10, 10, 11, 11, 12, 12, 13},
    161	{0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7,
    162	7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13},
    163	{0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 8, 9, 10, 11,
    164	12, 12, 13, 14, 14, 14, 15, 16, 17, 17, 17, 18, 18, 18},
    165};
    166
    167static const u8 rtl8812ae_delta_swing_table_idx_5gb_p[][DEL_SW_IDX_SZ] = {
    168	{0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 6, 7, 7, 8,
    169	8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
    170	{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
    171	8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
    172	{0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9,
    173	9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
    174};
    175
    176static const u8 rtl8812ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
    177	{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
    178	8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 13, 13, 13},
    179	{0, 1, 1, 2, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 9,
    180	9, 10, 10, 11, 11, 11, 12, 12, 12, 12, 12, 13, 13},
    181	{0, 1, 1, 2, 2, 3, 3, 4, 5, 6, 7, 8, 8, 9, 10, 11,
    182	12, 13, 14, 14, 15, 15, 15, 16, 16, 16, 17, 17, 18, 18},
    183};
    184
    185static const u8 rtl8812ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
    186	{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 4, 5, 5, 6, 7, 7, 8,
    187	8, 9, 9, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11},
    188	{0, 1, 1, 2, 2, 3, 3, 4, 4, 4, 5, 5, 6, 6, 7, 7, 8,
    189	9, 9, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
    190	{0, 1, 1, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 9, 9,
    191	10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11},
    192};
    193
    194static const u8 rtl8821ae_delta_swing_table_idx_24ga_n[]  = {
    195	0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
    196	6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
    197
    198static const u8 rtl8821ae_delta_swing_table_idx_24ga_p[] = {
    199	0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
    200	8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
    201
    202static const u8 rtl8821ae_delta_swing_table_idx_24gccka_n[] = {
    203	0, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6,
    204	6, 7, 7, 7, 8, 8, 8, 9, 9, 9, 10, 10, 10};
    205
    206static const u8 rtl8821ae_delta_swing_table_idx_24gccka_p[] = {
    207	0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8,
    208	8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12, 12, 12};
    209
    210static const u8 rtl8821ae_delta_swing_table_idx_5ga_n[][DEL_SW_IDX_SZ] = {
    211	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
    212	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
    213	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
    214	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
    215	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
    216	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
    217};
    218
    219static const u8 rtl8821ae_delta_swing_table_idx_5ga_p[][DEL_SW_IDX_SZ] = {
    220	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
    221	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
    222	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
    223	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
    224	{0, 0, 1, 2, 3, 3, 4, 5, 6, 6, 7, 8, 9, 9, 10, 11,
    225	12, 12, 13, 14, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16},
    226};
    227
    228void rtl8821ae_dm_txpower_track_adjust(struct ieee80211_hw *hw,
    229				       u8 type, u8 *pdirection,
    230				       u32 *poutwrite_val)
    231{
    232	struct rtl_priv *rtlpriv = rtl_priv(hw);
    233	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
    234	u8 pwr_val = 0;
    235
    236	if (type == 0) {
    237		if (rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A] <=
    238			rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A]) {
    239			*pdirection = 1;
    240			pwr_val = rtldm->swing_idx_ofdm_base[RF90_PATH_A] -
    241					rtldm->swing_idx_ofdm[RF90_PATH_A];
    242		} else {
    243			*pdirection = 2;
    244			pwr_val = rtldm->swing_idx_ofdm[RF90_PATH_A] -
    245				rtldm->swing_idx_ofdm_base[RF90_PATH_A];
    246		}
    247	} else if (type == 1) {
    248		if (rtldm->swing_idx_cck <= rtldm->swing_idx_cck_base) {
    249			*pdirection = 1;
    250			pwr_val = rtldm->swing_idx_cck_base -
    251					rtldm->swing_idx_cck;
    252		} else {
    253			*pdirection = 2;
    254			pwr_val = rtldm->swing_idx_cck -
    255				rtldm->swing_idx_cck_base;
    256		}
    257	}
    258
    259	if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
    260		pwr_val = TXPWRTRACK_MAX_IDX;
    261
    262	*poutwrite_val = pwr_val | (pwr_val << 8)|
    263				(pwr_val << 16)|
    264				(pwr_val << 24);
    265}
    266
    267void rtl8821ae_dm_clear_txpower_tracking_state(struct ieee80211_hw *hw)
    268{
    269	struct rtl_priv *rtlpriv = rtl_priv(hw);
    270	struct rtl_dm *rtldm = rtl_dm(rtlpriv);
    271	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
    272	u8 p = 0;
    273
    274	rtldm->swing_idx_cck_base = rtldm->default_cck_index;
    275	rtldm->swing_idx_cck = rtldm->default_cck_index;
    276	rtldm->cck_index = 0;
    277
    278	for (p = RF90_PATH_A; p <= RF90_PATH_B; ++p) {
    279		rtldm->swing_idx_ofdm_base[p] = rtldm->default_ofdm_index;
    280		rtldm->swing_idx_ofdm[p] = rtldm->default_ofdm_index;
    281		rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
    282
    283		rtldm->power_index_offset[p] = 0;
    284		rtldm->delta_power_index[p] = 0;
    285		rtldm->delta_power_index_last[p] = 0;
    286		/*Initial Mix mode power tracking*/
    287		rtldm->absolute_ofdm_swing_idx[p] = 0;
    288		rtldm->remnant_ofdm_swing_idx[p] = 0;
    289	}
    290	/*Initial at Modify Tx Scaling Mode*/
    291	rtldm->modify_txagc_flag_path_a = false;
    292	/*Initial at Modify Tx Scaling Mode*/
    293	rtldm->modify_txagc_flag_path_b = false;
    294	rtldm->remnant_cck_idx = 0;
    295	rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
    296	rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
    297	rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
    298}
    299
    300static u8  rtl8821ae_dm_get_swing_index(struct ieee80211_hw *hw)
    301{
    302	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
    303	u8 i = 0;
    304	u32  bb_swing;
    305
    306	bb_swing = phy_get_tx_swing_8812A(hw, rtlhal->current_bandtype,
    307					  RF90_PATH_A);
    308
    309	for (i = 0; i < TXSCALE_TABLE_SIZE; ++i)
    310		if (bb_swing == rtl8821ae_txscaling_table[i])
    311			break;
    312
    313	return i;
    314}
    315
    316void rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(
    317				struct ieee80211_hw *hw)
    318{
    319	struct rtl_priv *rtlpriv = rtl_priv(hw);
    320	struct rtl_dm *rtldm = rtl_dm(rtlpriv);
    321	struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv);
    322	u8 default_swing_index  = 0;
    323	u8 p = 0;
    324
    325	rtlpriv->dm.txpower_track_control = true;
    326	rtldm->thermalvalue = rtlefuse->eeprom_thermalmeter;
    327	rtldm->thermalvalue_iqk = rtlefuse->eeprom_thermalmeter;
    328	rtldm->thermalvalue_lck = rtlefuse->eeprom_thermalmeter;
    329	default_swing_index = rtl8821ae_dm_get_swing_index(hw);
    330
    331	rtldm->default_ofdm_index =
    332		(default_swing_index == TXSCALE_TABLE_SIZE) ?
    333		24 : default_swing_index;
    334	rtldm->default_cck_index = 24;
    335
    336	rtldm->swing_idx_cck_base = rtldm->default_cck_index;
    337	rtldm->cck_index = rtldm->default_cck_index;
    338
    339	for (p = RF90_PATH_A; p < MAX_RF_PATH; ++p) {
    340		rtldm->swing_idx_ofdm_base[p] =
    341			rtldm->default_ofdm_index;
    342		rtldm->ofdm_index[p] = rtldm->default_ofdm_index;
    343		rtldm->delta_power_index[p] = 0;
    344		rtldm->power_index_offset[p] = 0;
    345		rtldm->delta_power_index_last[p] = 0;
    346	}
    347}
    348
    349void rtl8821ae_dm_init_edca_turbo(struct ieee80211_hw *hw)
    350{
    351	struct rtl_priv *rtlpriv = rtl_priv(hw);
    352
    353	rtlpriv->dm.current_turbo_edca = false;
    354	rtlpriv->dm.is_any_nonbepkts = false;
    355	rtlpriv->dm.is_cur_rdlstate = false;
    356}
    357
    358void rtl8821ae_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
    359{
    360	struct rtl_priv *rtlpriv = rtl_priv(hw);
    361	struct rate_adaptive *p_ra = &rtlpriv->ra;
    362
    363	p_ra->ratr_state = DM_RATR_STA_INIT;
    364	p_ra->pre_ratr_state = DM_RATR_STA_INIT;
    365
    366	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
    367	if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
    368		rtlpriv->dm.useramask = true;
    369	else
    370		rtlpriv->dm.useramask = false;
    371
    372	p_ra->high_rssi_thresh_for_ra = 50;
    373	p_ra->low_rssi_thresh_for_ra40m = 20;
    374}
    375
    376static void rtl8821ae_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
    377{
    378	struct rtl_priv *rtlpriv = rtl_priv(hw);
    379
    380	rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
    381
    382	rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, BIT(11));
    383	rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
    384}
    385
    386static void rtl8821ae_dm_common_info_self_init(struct ieee80211_hw *hw)
    387{
    388	struct rtl_priv *rtlpriv = rtl_priv(hw);
    389	struct rtl_phy *rtlphy = &rtlpriv->phy;
    390	u8 tmp;
    391
    392	rtlphy->cck_high_power =
    393		(bool)rtl_get_bbreg(hw, ODM_REG_CCK_RPT_FORMAT_11AC,
    394				    ODM_BIT_CCK_RPT_FORMAT_11AC);
    395
    396	tmp = (u8)rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC,
    397				ODM_BIT_BB_RX_PATH_11AC);
    398	if (tmp & BIT(0))
    399		rtlpriv->dm.rfpath_rxenable[0] = true;
    400	if (tmp & BIT(1))
    401		rtlpriv->dm.rfpath_rxenable[1] = true;
    402}
    403
    404void rtl8821ae_dm_init(struct ieee80211_hw *hw)
    405{
    406	struct rtl_priv *rtlpriv = rtl_priv(hw);
    407	struct rtl_phy *rtlphy = &rtlpriv->phy;
    408	u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
    409
    410	spin_lock(&rtlpriv->locks.iqk_lock);
    411	rtlphy->lck_inprogress = false;
    412	spin_unlock(&rtlpriv->locks.iqk_lock);
    413
    414	rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
    415	rtl8821ae_dm_common_info_self_init(hw);
    416	rtl_dm_diginit(hw, cur_igvalue);
    417	rtl8821ae_dm_init_rate_adaptive_mask(hw);
    418	rtl8821ae_dm_init_edca_turbo(hw);
    419	rtl8821ae_dm_initialize_txpower_tracking_thermalmeter(hw);
    420	rtl8821ae_dm_init_dynamic_atc_switch(hw);
    421}
    422
    423static void rtl8821ae_dm_find_minimum_rssi(struct ieee80211_hw *hw)
    424{
    425	struct rtl_priv *rtlpriv = rtl_priv(hw);
    426	struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable;
    427	struct rtl_mac *mac = rtl_mac(rtlpriv);
    428
    429	/* Determine the minimum RSSI  */
    430	if ((mac->link_state < MAC80211_LINKED) &&
    431	    (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
    432		rtl_dm_dig->min_undec_pwdb_for_dm = 0;
    433		pr_debug("rtl8821ae: Not connected to any AP\n");
    434	}
    435	if (mac->link_state >= MAC80211_LINKED) {
    436		if (mac->opmode == NL80211_IFTYPE_AP ||
    437		    mac->opmode == NL80211_IFTYPE_ADHOC) {
    438			rtl_dm_dig->min_undec_pwdb_for_dm =
    439			    rtlpriv->dm.entry_min_undec_sm_pwdb;
    440			rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
    441				"AP Client PWDB = 0x%lx\n",
    442				rtlpriv->dm.entry_min_undec_sm_pwdb);
    443		} else {
    444			rtl_dm_dig->min_undec_pwdb_for_dm =
    445			    rtlpriv->dm.undec_sm_pwdb;
    446			rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
    447				"STA Default Port PWDB = 0x%x\n",
    448				rtl_dm_dig->min_undec_pwdb_for_dm);
    449		}
    450	} else {
    451		rtl_dm_dig->min_undec_pwdb_for_dm =
    452		    rtlpriv->dm.entry_min_undec_sm_pwdb;
    453		rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
    454			"AP Ext Port or disconnect PWDB = 0x%x\n",
    455			rtl_dm_dig->min_undec_pwdb_for_dm);
    456	}
    457	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    458		"MinUndecoratedPWDBForDM =%d\n",
    459		rtl_dm_dig->min_undec_pwdb_for_dm);
    460}
    461
    462static void  rtl8812ae_dm_rssi_dump_to_register(struct ieee80211_hw *hw)
    463{
    464	struct rtl_priv *rtlpriv = rtl_priv(hw);
    465
    466	rtl_write_byte(rtlpriv, RA_RSSI_DUMP,
    467		       rtlpriv->stats.rx_rssi_percentage[0]);
    468	rtl_write_byte(rtlpriv, RB_RSSI_DUMP,
    469		       rtlpriv->stats.rx_rssi_percentage[1]);
    470
    471	/* Rx EVM*/
    472	rtl_write_byte(rtlpriv, RS1_RX_EVM_DUMP,
    473		       rtlpriv->stats.rx_evm_dbm[0]);
    474	rtl_write_byte(rtlpriv, RS2_RX_EVM_DUMP,
    475		       rtlpriv->stats.rx_evm_dbm[1]);
    476
    477	/*Rx SNR*/
    478	rtl_write_byte(rtlpriv, RA_RX_SNR_DUMP,
    479		       (u8)(rtlpriv->stats.rx_snr_db[0]));
    480	rtl_write_byte(rtlpriv, RB_RX_SNR_DUMP,
    481		       (u8)(rtlpriv->stats.rx_snr_db[1]));
    482
    483	/*Rx Cfo_Short*/
    484	rtl_write_word(rtlpriv, RA_CFO_SHORT_DUMP,
    485		       rtlpriv->stats.rx_cfo_short[0]);
    486	rtl_write_word(rtlpriv, RB_CFO_SHORT_DUMP,
    487		       rtlpriv->stats.rx_cfo_short[1]);
    488
    489	/*Rx Cfo_Tail*/
    490	rtl_write_word(rtlpriv, RA_CFO_LONG_DUMP,
    491		       rtlpriv->stats.rx_cfo_tail[0]);
    492	rtl_write_word(rtlpriv, RB_CFO_LONG_DUMP,
    493		       rtlpriv->stats.rx_cfo_tail[1]);
    494}
    495
    496static void rtl8821ae_dm_check_rssi_monitor(struct ieee80211_hw *hw)
    497{
    498	struct rtl_priv *rtlpriv = rtl_priv(hw);
    499	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    500	struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
    501	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    502	struct rtl_sta_info *drv_priv;
    503	u8 h2c_parameter[4] = { 0 };
    504	long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
    505	u8 stbc_tx = 0;
    506	u64 cur_rxokcnt = 0;
    507	static u64 last_txokcnt = 0, last_rxokcnt;
    508
    509	cur_rxokcnt = rtlpriv->stats.rxbytesunicast - last_rxokcnt;
    510	last_txokcnt = rtlpriv->stats.txbytesunicast;
    511	last_rxokcnt = rtlpriv->stats.rxbytesunicast;
    512	if (cur_rxokcnt > (last_txokcnt * 6))
    513		h2c_parameter[3] = 0x01;
    514	else
    515		h2c_parameter[3] = 0x00;
    516
    517	/* AP & ADHOC & MESH */
    518	if (mac->opmode == NL80211_IFTYPE_AP ||
    519	    mac->opmode == NL80211_IFTYPE_ADHOC ||
    520	    mac->opmode == NL80211_IFTYPE_MESH_POINT) {
    521		spin_lock_bh(&rtlpriv->locks.entry_list_lock);
    522		list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
    523			if (drv_priv->rssi_stat.undec_sm_pwdb <
    524					tmp_entry_min_pwdb)
    525				tmp_entry_min_pwdb =
    526					drv_priv->rssi_stat.undec_sm_pwdb;
    527			if (drv_priv->rssi_stat.undec_sm_pwdb >
    528					tmp_entry_max_pwdb)
    529				tmp_entry_max_pwdb =
    530					drv_priv->rssi_stat.undec_sm_pwdb;
    531		}
    532		spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
    533
    534		/* If associated entry is found */
    535		if (tmp_entry_max_pwdb != 0) {
    536			rtlpriv->dm.entry_max_undec_sm_pwdb =
    537				tmp_entry_max_pwdb;
    538			RTPRINT(rtlpriv, FDM, DM_PWDB,
    539				"EntryMaxPWDB = 0x%lx(%ld)\n",
    540				tmp_entry_max_pwdb, tmp_entry_max_pwdb);
    541		} else {
    542			rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
    543		}
    544		/* If associated entry is found */
    545		if (tmp_entry_min_pwdb != 0xff) {
    546			rtlpriv->dm.entry_min_undec_sm_pwdb =
    547				tmp_entry_min_pwdb;
    548			RTPRINT(rtlpriv, FDM, DM_PWDB,
    549				"EntryMinPWDB = 0x%lx(%ld)\n",
    550				tmp_entry_min_pwdb, tmp_entry_min_pwdb);
    551		} else {
    552			rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
    553		}
    554	}
    555	/* Indicate Rx signal strength to FW. */
    556	if (rtlpriv->dm.useramask) {
    557		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) {
    558			if (mac->mode == WIRELESS_MODE_AC_24G ||
    559			    mac->mode == WIRELESS_MODE_AC_5G ||
    560			    mac->mode == WIRELESS_MODE_AC_ONLY)
    561				stbc_tx = (mac->vht_cur_stbc &
    562					   STBC_VHT_ENABLE_TX) ? 1 : 0;
    563			else
    564				stbc_tx = (mac->ht_cur_stbc &
    565					   STBC_HT_ENABLE_TX) ? 1 : 0;
    566			h2c_parameter[3] |= stbc_tx << 1;
    567		}
    568		h2c_parameter[2] =
    569			(u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF);
    570		h2c_parameter[1] = 0x20;
    571		h2c_parameter[0] = 0;
    572		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
    573			rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 4,
    574					       h2c_parameter);
    575		else
    576			rtl8821ae_fill_h2c_cmd(hw, H2C_RSSI_21AE_REPORT, 3,
    577					       h2c_parameter);
    578	} else {
    579		rtl_write_byte(rtlpriv, 0x4fe, rtlpriv->dm.undec_sm_pwdb);
    580	}
    581	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
    582		rtl8812ae_dm_rssi_dump_to_register(hw);
    583	rtl8821ae_dm_find_minimum_rssi(hw);
    584	dm_digtable->rssi_val_min = rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
    585}
    586
    587void rtl8821ae_dm_write_cck_cca_thres(struct ieee80211_hw *hw, u8 current_cca)
    588{
    589	struct rtl_priv *rtlpriv = rtl_priv(hw);
    590	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    591
    592	if (dm_digtable->cur_cck_cca_thres != current_cca)
    593		rtl_write_byte(rtlpriv, DM_REG_CCK_CCA_11AC, current_cca);
    594
    595	dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
    596	dm_digtable->cur_cck_cca_thres = current_cca;
    597}
    598
    599void rtl8821ae_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
    600{
    601	struct rtl_priv *rtlpriv = rtl_priv(hw);
    602	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    603
    604	if (dm_digtable->stop_dig)
    605		return;
    606
    607	if (dm_digtable->cur_igvalue != current_igi) {
    608		rtl_set_bbreg(hw, DM_REG_IGI_A_11AC,
    609			      DM_BIT_IGI_11AC, current_igi);
    610		if (rtlpriv->phy.rf_type != RF_1T1R)
    611			rtl_set_bbreg(hw, DM_REG_IGI_B_11AC,
    612				      DM_BIT_IGI_11AC, current_igi);
    613	}
    614	dm_digtable->cur_igvalue = current_igi;
    615}
    616
    617static void rtl8821ae_dm_dig(struct ieee80211_hw *hw)
    618{
    619	struct rtl_priv *rtlpriv = rtl_priv(hw);
    620	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
    621	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    622	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
    623	u8 dig_min_0;
    624	u8 dig_max_of_min;
    625	bool first_connect, first_disconnect;
    626	u8 dm_dig_max, dm_dig_min, offset;
    627	u8 current_igi = dm_digtable->cur_igvalue;
    628
    629	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "\n");
    630
    631	if (mac->act_scanning) {
    632		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    633			"Return: In Scan Progress\n");
    634		return;
    635	}
    636
    637	/*add by Neil Chen to avoid PSD is processing*/
    638	dig_min_0 = dm_digtable->dig_min_0;
    639	first_connect = (mac->link_state >= MAC80211_LINKED) &&
    640			(!dm_digtable->media_connect_0);
    641	first_disconnect = (mac->link_state < MAC80211_LINKED) &&
    642			(dm_digtable->media_connect_0);
    643
    644	/*1 Boundary Decision*/
    645
    646	dm_dig_max = 0x5A;
    647
    648	if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
    649		dm_dig_min = DM_DIG_MIN;
    650	else
    651		dm_dig_min = 0x1C;
    652
    653	dig_max_of_min = DM_DIG_MAX_AP;
    654
    655	if (mac->link_state >= MAC80211_LINKED) {
    656		if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE)
    657			offset = 20;
    658		else
    659			offset = 10;
    660
    661		if ((dm_digtable->rssi_val_min + offset) > dm_dig_max)
    662			dm_digtable->rx_gain_max = dm_dig_max;
    663		else if ((dm_digtable->rssi_val_min + offset) < dm_dig_min)
    664			dm_digtable->rx_gain_max = dm_dig_min;
    665		else
    666			dm_digtable->rx_gain_max =
    667				dm_digtable->rssi_val_min + offset;
    668
    669		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    670			"dm_digtable->rssi_val_min=0x%x,dm_digtable->rx_gain_max = 0x%x\n",
    671			dm_digtable->rssi_val_min,
    672			dm_digtable->rx_gain_max);
    673		if (rtlpriv->dm.one_entry_only) {
    674			offset = 0;
    675
    676			if (dm_digtable->rssi_val_min - offset < dm_dig_min)
    677				dig_min_0 = dm_dig_min;
    678			else if (dm_digtable->rssi_val_min -
    679				offset > dig_max_of_min)
    680				dig_min_0 = dig_max_of_min;
    681			else
    682				dig_min_0 =
    683					dm_digtable->rssi_val_min - offset;
    684
    685			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    686				"bOneEntryOnly=TRUE, dig_min_0=0x%x\n",
    687				dig_min_0);
    688		} else {
    689			dig_min_0 = dm_dig_min;
    690		}
    691	} else {
    692		dm_digtable->rx_gain_max = dm_dig_max;
    693		dig_min_0 = dm_dig_min;
    694		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n");
    695	}
    696
    697	if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
    698		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    699			"Abnormally false alarm case.\n");
    700
    701		if (dm_digtable->large_fa_hit != 3)
    702			dm_digtable->large_fa_hit++;
    703		if (dm_digtable->forbidden_igi < current_igi) {
    704			dm_digtable->forbidden_igi = current_igi;
    705			dm_digtable->large_fa_hit = 1;
    706		}
    707
    708		if (dm_digtable->large_fa_hit >= 3) {
    709			if ((dm_digtable->forbidden_igi + 1) >
    710				dm_digtable->rx_gain_max)
    711				dm_digtable->rx_gain_min =
    712					dm_digtable->rx_gain_max;
    713			else
    714				dm_digtable->rx_gain_min =
    715					(dm_digtable->forbidden_igi + 1);
    716			dm_digtable->recover_cnt = 3600;
    717		}
    718	} else {
    719		/*Recovery mechanism for IGI lower bound*/
    720		if (dm_digtable->recover_cnt != 0) {
    721			dm_digtable->recover_cnt--;
    722		} else {
    723			if (dm_digtable->large_fa_hit < 3) {
    724				if ((dm_digtable->forbidden_igi - 1) <
    725				    dig_min_0) {
    726					dm_digtable->forbidden_igi =
    727						dig_min_0;
    728					dm_digtable->rx_gain_min =
    729						dig_min_0;
    730					rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    731						"Normal Case: At Lower Bound\n");
    732				} else {
    733					dm_digtable->forbidden_igi--;
    734					dm_digtable->rx_gain_min =
    735					  (dm_digtable->forbidden_igi + 1);
    736					rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    737						"Normal Case: Approach Lower Bound\n");
    738				}
    739			} else {
    740				dm_digtable->large_fa_hit = 0;
    741			}
    742		}
    743	}
    744	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    745		"pDM_DigTable->LargeFAHit=%d\n",
    746		dm_digtable->large_fa_hit);
    747
    748	if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10)
    749		dm_digtable->rx_gain_min = dm_dig_min;
    750
    751	if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max)
    752		dm_digtable->rx_gain_min = dm_digtable->rx_gain_max;
    753
    754	/*Adjust initial gain by false alarm*/
    755	if (mac->link_state >= MAC80211_LINKED) {
    756		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    757			"DIG AfterLink\n");
    758		if (first_connect) {
    759			if (dm_digtable->rssi_val_min <= dig_max_of_min)
    760				current_igi = dm_digtable->rssi_val_min;
    761			else
    762				current_igi = dig_max_of_min;
    763			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    764				"First Connect\n");
    765		} else {
    766			if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
    767				current_igi = current_igi + 4;
    768			else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
    769				current_igi = current_igi + 2;
    770			else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
    771				current_igi = current_igi - 2;
    772
    773			if ((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) &&
    774			    (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) {
    775				current_igi = dm_digtable->rx_gain_min;
    776				rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    777					"Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n");
    778			}
    779		}
    780	} else {
    781		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    782			"DIG BeforeLink\n");
    783		if (first_disconnect) {
    784			current_igi = dm_digtable->rx_gain_min;
    785			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    786				"First DisConnect\n");
    787		} else {
    788			/* 2012.03.30 LukeLee: enable DIG before
    789			 * link but with very high thresholds
    790			 */
    791			if (rtlpriv->falsealm_cnt.cnt_all > 2000)
    792				current_igi = current_igi + 4;
    793			else if (rtlpriv->falsealm_cnt.cnt_all > 600)
    794				current_igi = current_igi + 2;
    795			else if (rtlpriv->falsealm_cnt.cnt_all < 300)
    796				current_igi = current_igi - 2;
    797
    798			if (current_igi >= 0x3e)
    799				current_igi = 0x3e;
    800
    801			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "England DIG\n");
    802		}
    803	}
    804	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    805		"DIG End Adjust IGI\n");
    806	/* Check initial gain by upper/lower bound*/
    807
    808	if (current_igi > dm_digtable->rx_gain_max)
    809		current_igi = dm_digtable->rx_gain_max;
    810	if (current_igi < dm_digtable->rx_gain_min)
    811		current_igi = dm_digtable->rx_gain_min;
    812
    813	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    814		"rx_gain_max=0x%x, rx_gain_min=0x%x\n",
    815		dm_digtable->rx_gain_max, dm_digtable->rx_gain_min);
    816	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    817		"TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all);
    818	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
    819		"CurIGValue=0x%x\n", current_igi);
    820
    821	rtl8821ae_dm_write_dig(hw, current_igi);
    822	dm_digtable->media_connect_0 =
    823		((mac->link_state >= MAC80211_LINKED) ? true : false);
    824	dm_digtable->dig_min_0 = dig_min_0;
    825}
    826
    827static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw)
    828{
    829	struct rtl_priv *rtlpriv = rtl_priv(hw);
    830	u8 cnt = 0;
    831	struct rtl_sta_info *drv_priv;
    832
    833	rtlpriv->dm.tx_rate = 0xff;
    834
    835	rtlpriv->dm.one_entry_only = false;
    836
    837	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION &&
    838	    rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
    839		rtlpriv->dm.one_entry_only = true;
    840		return;
    841	}
    842
    843	if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP ||
    844	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC ||
    845	    rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) {
    846		spin_lock_bh(&rtlpriv->locks.entry_list_lock);
    847		list_for_each_entry(drv_priv, &rtlpriv->entry_list, list)
    848			cnt++;
    849		spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
    850
    851		if (cnt == 1)
    852			rtlpriv->dm.one_entry_only = true;
    853	}
    854}
    855
    856static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw)
    857{
    858	struct rtl_priv *rtlpriv = rtl_priv(hw);
    859	struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
    860	u32 cck_enable = 0;
    861
    862	/*read OFDM FA counter*/
    863	falsealm_cnt->cnt_ofdm_fail =
    864		rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD);
    865	falsealm_cnt->cnt_cck_fail =
    866		rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD);
    867
    868	cck_enable =  rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28));
    869	if (cck_enable)  /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/
    870		falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail +
    871					falsealm_cnt->cnt_cck_fail;
    872	else
    873		falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail;
    874
    875	/*reset OFDM FA counter*/
    876	rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1);
    877	rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0);
    878	/* reset CCK FA counter*/
    879	rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0);
    880	rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1);
    881
    882	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Cnt_Cck_fail=%d\n",
    883		falsealm_cnt->cnt_cck_fail);
    884	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "cnt_ofdm_fail=%d\n",
    885		falsealm_cnt->cnt_ofdm_fail);
    886	rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Total False Alarm=%d\n",
    887		falsealm_cnt->cnt_all);
    888}
    889
    890static void rtl8812ae_dm_check_txpower_tracking_thermalmeter(
    891		struct ieee80211_hw *hw)
    892{
    893	struct rtl_priv *rtlpriv = rtl_priv(hw);
    894
    895	if (!rtlpriv->dm.tm_trigger) {
    896		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E,
    897			      BIT(17) | BIT(16), 0x03);
    898		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    899			"Trigger 8812 Thermal Meter!!\n");
    900		rtlpriv->dm.tm_trigger = 1;
    901		return;
    902	}
    903	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    904		"Schedule TxPowerTracking direct call!!\n");
    905	rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw);
    906}
    907
    908static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw)
    909{
    910	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
    911	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
    912	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
    913
    914	if (mac->link_state >= MAC80211_LINKED) {
    915		if (rtldm->linked_interval < 3)
    916			rtldm->linked_interval++;
    917
    918		if (rtldm->linked_interval == 2) {
    919			if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
    920				rtl8812ae_phy_iq_calibrate(hw, false);
    921			else
    922				rtl8821ae_phy_iq_calibrate(hw, false);
    923		}
    924	} else {
    925		rtldm->linked_interval = 0;
    926	}
    927}
    928
    929static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw,
    930					    const u8 **up_a,
    931					    const u8 **down_a,
    932					    const u8 **up_b,
    933					    const u8 **down_b)
    934{
    935	struct rtl_priv *rtlpriv = rtl_priv(hw);
    936	struct rtl_phy *rtlphy = &rtlpriv->phy;
    937	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
    938	u8 channel = rtlphy->current_channel;
    939	u8 rate = rtldm->tx_rate;
    940
    941	if (1 <= channel && channel <= 14) {
    942		if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) {
    943			*up_a = rtl8812ae_delta_swing_table_idx_24gccka_p;
    944			*down_a = rtl8812ae_delta_swing_table_idx_24gccka_n;
    945			*up_b = rtl8812ae_delta_swing_table_idx_24gcckb_p;
    946			*down_b = rtl8812ae_delta_swing_table_idx_24gcckb_n;
    947		} else {
    948			*up_a = rtl8812ae_delta_swing_table_idx_24ga_p;
    949			*down_a = rtl8812ae_delta_swing_table_idx_24ga_n;
    950			*up_b = rtl8812ae_delta_swing_table_idx_24gb_p;
    951			*down_b = rtl8812ae_delta_swing_table_idx_24gb_n;
    952		}
    953	} else if (36 <= channel && channel <= 64) {
    954		*up_a = rtl8812ae_delta_swing_table_idx_5ga_p[0];
    955		*down_a = rtl8812ae_delta_swing_table_idx_5ga_n[0];
    956		*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[0];
    957		*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[0];
    958	} else if (100 <= channel && channel <= 140) {
    959		*up_a = rtl8812ae_delta_swing_table_idx_5ga_p[1];
    960		*down_a = rtl8812ae_delta_swing_table_idx_5ga_n[1];
    961		*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[1];
    962		*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[1];
    963	} else if (149 <= channel && channel <= 173) {
    964		*up_a = rtl8812ae_delta_swing_table_idx_5ga_p[2];
    965		*down_a = rtl8812ae_delta_swing_table_idx_5ga_n[2];
    966		*up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2];
    967		*down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2];
    968	} else {
    969		*up_a = rtl8818e_delta_swing_table_idx_24gb_p;
    970		*down_a = rtl8818e_delta_swing_table_idx_24gb_n;
    971		*up_b = rtl8818e_delta_swing_table_idx_24gb_p;
    972		*down_b = rtl8818e_delta_swing_table_idx_24gb_n;
    973	}
    974}
    975
    976void rtl8821ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate)
    977{
    978	struct rtl_priv *rtlpriv = rtl_priv(hw);
    979	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
    980	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
    981	u8 p = 0;
    982
    983	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
    984		"Get C2H Command! Rate=0x%x\n", rate);
    985
    986	rtldm->tx_rate = rate;
    987
    988	if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) {
    989		rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0);
    990	} else {
    991		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
    992			rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0);
    993	}
    994}
    995
    996u8 rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate)
    997{
    998	struct rtl_priv *rtlpriv = rtl_priv(hw);
    999	u8 ret_rate = MGN_1M;
   1000
   1001	switch (rate) {
   1002	case DESC_RATE1M:
   1003		ret_rate = MGN_1M;
   1004		break;
   1005	case DESC_RATE2M:
   1006		ret_rate = MGN_2M;
   1007		break;
   1008	case DESC_RATE5_5M:
   1009		ret_rate = MGN_5_5M;
   1010		break;
   1011	case DESC_RATE11M:
   1012		ret_rate = MGN_11M;
   1013		break;
   1014	case DESC_RATE6M:
   1015		ret_rate = MGN_6M;
   1016		break;
   1017	case DESC_RATE9M:
   1018		ret_rate = MGN_9M;
   1019		break;
   1020	case DESC_RATE12M:
   1021		ret_rate = MGN_12M;
   1022		break;
   1023	case DESC_RATE18M:
   1024		ret_rate = MGN_18M;
   1025		break;
   1026	case DESC_RATE24M:
   1027		ret_rate = MGN_24M;
   1028		break;
   1029	case DESC_RATE36M:
   1030		ret_rate = MGN_36M;
   1031		break;
   1032	case DESC_RATE48M:
   1033		ret_rate = MGN_48M;
   1034		break;
   1035	case DESC_RATE54M:
   1036		ret_rate = MGN_54M;
   1037		break;
   1038	case DESC_RATEMCS0:
   1039		ret_rate = MGN_MCS0;
   1040		break;
   1041	case DESC_RATEMCS1:
   1042		ret_rate = MGN_MCS1;
   1043		break;
   1044	case DESC_RATEMCS2:
   1045		ret_rate = MGN_MCS2;
   1046		break;
   1047	case DESC_RATEMCS3:
   1048		ret_rate = MGN_MCS3;
   1049		break;
   1050	case DESC_RATEMCS4:
   1051		ret_rate = MGN_MCS4;
   1052		break;
   1053	case DESC_RATEMCS5:
   1054		ret_rate = MGN_MCS5;
   1055		break;
   1056	case DESC_RATEMCS6:
   1057		ret_rate = MGN_MCS6;
   1058		break;
   1059	case DESC_RATEMCS7:
   1060		ret_rate = MGN_MCS7;
   1061		break;
   1062	case DESC_RATEMCS8:
   1063		ret_rate = MGN_MCS8;
   1064		break;
   1065	case DESC_RATEMCS9:
   1066		ret_rate = MGN_MCS9;
   1067		break;
   1068	case DESC_RATEMCS10:
   1069		ret_rate = MGN_MCS10;
   1070		break;
   1071	case DESC_RATEMCS11:
   1072		ret_rate = MGN_MCS11;
   1073		break;
   1074	case DESC_RATEMCS12:
   1075		ret_rate = MGN_MCS12;
   1076		break;
   1077	case DESC_RATEMCS13:
   1078		ret_rate = MGN_MCS13;
   1079		break;
   1080	case DESC_RATEMCS14:
   1081		ret_rate = MGN_MCS14;
   1082		break;
   1083	case DESC_RATEMCS15:
   1084		ret_rate = MGN_MCS15;
   1085		break;
   1086	case DESC_RATEVHT1SS_MCS0:
   1087		ret_rate = MGN_VHT1SS_MCS0;
   1088		break;
   1089	case DESC_RATEVHT1SS_MCS1:
   1090		ret_rate = MGN_VHT1SS_MCS1;
   1091		break;
   1092	case DESC_RATEVHT1SS_MCS2:
   1093		ret_rate = MGN_VHT1SS_MCS2;
   1094		break;
   1095	case DESC_RATEVHT1SS_MCS3:
   1096		ret_rate = MGN_VHT1SS_MCS3;
   1097		break;
   1098	case DESC_RATEVHT1SS_MCS4:
   1099		ret_rate = MGN_VHT1SS_MCS4;
   1100		break;
   1101	case DESC_RATEVHT1SS_MCS5:
   1102		ret_rate = MGN_VHT1SS_MCS5;
   1103		break;
   1104	case DESC_RATEVHT1SS_MCS6:
   1105		ret_rate = MGN_VHT1SS_MCS6;
   1106		break;
   1107	case DESC_RATEVHT1SS_MCS7:
   1108		ret_rate = MGN_VHT1SS_MCS7;
   1109		break;
   1110	case DESC_RATEVHT1SS_MCS8:
   1111		ret_rate = MGN_VHT1SS_MCS8;
   1112		break;
   1113	case DESC_RATEVHT1SS_MCS9:
   1114		ret_rate = MGN_VHT1SS_MCS9;
   1115		break;
   1116	case DESC_RATEVHT2SS_MCS0:
   1117		ret_rate = MGN_VHT2SS_MCS0;
   1118		break;
   1119	case DESC_RATEVHT2SS_MCS1:
   1120		ret_rate = MGN_VHT2SS_MCS1;
   1121		break;
   1122	case DESC_RATEVHT2SS_MCS2:
   1123		ret_rate = MGN_VHT2SS_MCS2;
   1124		break;
   1125	case DESC_RATEVHT2SS_MCS3:
   1126		ret_rate = MGN_VHT2SS_MCS3;
   1127		break;
   1128	case DESC_RATEVHT2SS_MCS4:
   1129		ret_rate = MGN_VHT2SS_MCS4;
   1130		break;
   1131	case DESC_RATEVHT2SS_MCS5:
   1132		ret_rate = MGN_VHT2SS_MCS5;
   1133		break;
   1134	case DESC_RATEVHT2SS_MCS6:
   1135		ret_rate = MGN_VHT2SS_MCS6;
   1136		break;
   1137	case DESC_RATEVHT2SS_MCS7:
   1138		ret_rate = MGN_VHT2SS_MCS7;
   1139		break;
   1140	case DESC_RATEVHT2SS_MCS8:
   1141		ret_rate = MGN_VHT2SS_MCS8;
   1142		break;
   1143	case DESC_RATEVHT2SS_MCS9:
   1144		ret_rate = MGN_VHT2SS_MCS9;
   1145		break;
   1146	default:
   1147		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1148			"HwRateToMRate8812(): Non supported Rate [%x]!!!\n",
   1149			rate);
   1150		break;
   1151	}
   1152	return ret_rate;
   1153}
   1154
   1155/*-----------------------------------------------------------------------------
   1156 * Function:	odm_TxPwrTrackSetPwr88E()
   1157 *
   1158 * Overview:	88E change all channel tx power accordign to flag.
   1159 *				OFDM & CCK are all different.
   1160 *
   1161 * Input:		NONE
   1162 *
   1163 * Output:		NONE
   1164 *
   1165 * Return:		NONE
   1166 *
   1167 * Revised History:
   1168 *	When		Who		Remark
   1169 *	04/23/2012	MHC		Create Version 0.
   1170 *
   1171 *---------------------------------------------------------------------------
   1172 */
   1173void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
   1174				      enum pwr_track_control_method method,
   1175				      u8 rf_path, u8 channel_mapped_index)
   1176{
   1177	struct rtl_priv *rtlpriv = rtl_priv(hw);
   1178	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
   1179	struct rtl_phy *rtlphy = &rtlpriv->phy;
   1180	u32 final_swing_idx[2];
   1181	u8 pwr_tracking_limit = 26; /*+1.0dB*/
   1182	u8 tx_rate = 0xFF;
   1183	s8 final_ofdm_swing_index = 0;
   1184
   1185	if (rtldm->tx_rate != 0xFF)
   1186		tx_rate =
   1187			rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
   1188
   1189	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1190		"===>%s\n", __func__);
   1191	/*20130429 Mimic Modify High Rate BBSwing Limit.*/
   1192	if (tx_rate != 0xFF) {
   1193		/*CCK*/
   1194		if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
   1195			pwr_tracking_limit = 32; /*+4dB*/
   1196		/*OFDM*/
   1197		else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
   1198			pwr_tracking_limit = 30; /*+3dB*/
   1199		else if (tx_rate == MGN_54M)
   1200			pwr_tracking_limit = 28; /*+2dB*/
   1201		/*HT*/
   1202		 /*QPSK/BPSK*/
   1203		else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2))
   1204			pwr_tracking_limit = 34; /*+5dB*/
   1205		 /*16QAM*/
   1206		else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4))
   1207			pwr_tracking_limit = 30; /*+3dB*/
   1208		 /*64QAM*/
   1209		else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7))
   1210			pwr_tracking_limit = 28; /*+2dB*/
   1211		 /*QPSK/BPSK*/
   1212		else if ((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10))
   1213			pwr_tracking_limit = 34; /*+5dB*/
   1214		 /*16QAM*/
   1215		else if ((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12))
   1216			pwr_tracking_limit = 30; /*+3dB*/
   1217		 /*64QAM*/
   1218		else if ((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15))
   1219			pwr_tracking_limit = 28; /*+2dB*/
   1220
   1221		/*2 VHT*/
   1222		 /*QPSK/BPSK*/
   1223		else if ((tx_rate >= MGN_VHT1SS_MCS0) &&
   1224			 (tx_rate <= MGN_VHT1SS_MCS2))
   1225			pwr_tracking_limit = 34; /*+5dB*/
   1226		 /*16QAM*/
   1227		else if ((tx_rate >= MGN_VHT1SS_MCS3) &&
   1228			 (tx_rate <= MGN_VHT1SS_MCS4))
   1229			pwr_tracking_limit = 30; /*+3dB*/
   1230		 /*64QAM*/
   1231		else if ((tx_rate >= MGN_VHT1SS_MCS5) &&
   1232			 (tx_rate <= MGN_VHT1SS_MCS6))
   1233			pwr_tracking_limit = 28; /*+2dB*/
   1234		else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
   1235			pwr_tracking_limit = 26; /*+1dB*/
   1236		else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
   1237			pwr_tracking_limit = 24; /*+0dB*/
   1238		else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
   1239			pwr_tracking_limit = 22; /*-1dB*/
   1240		 /*QPSK/BPSK*/
   1241		else if ((tx_rate >= MGN_VHT2SS_MCS0) &&
   1242			 (tx_rate <= MGN_VHT2SS_MCS2))
   1243			pwr_tracking_limit = 34; /*+5dB*/
   1244		 /*16QAM*/
   1245		else if ((tx_rate >= MGN_VHT2SS_MCS3) &&
   1246			 (tx_rate <= MGN_VHT2SS_MCS4))
   1247			pwr_tracking_limit = 30; /*+3dB*/
   1248		 /*64QAM*/
   1249		else if ((tx_rate >= MGN_VHT2SS_MCS5) &&
   1250			 (tx_rate <= MGN_VHT2SS_MCS6))
   1251			pwr_tracking_limit = 28; /*+2dB*/
   1252		else if (tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/
   1253			pwr_tracking_limit = 26; /*+1dB*/
   1254		else if (tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/
   1255			pwr_tracking_limit = 24; /*+0dB*/
   1256		else if (tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/
   1257			pwr_tracking_limit = 22; /*-1dB*/
   1258		else
   1259			pwr_tracking_limit = 24;
   1260	}
   1261	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1262		"TxRate=0x%x, PwrTrackingLimit=%d\n",
   1263		tx_rate, pwr_tracking_limit);
   1264
   1265	if (method == BBSWING) {
   1266		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1267			"===>%s\n", __func__);
   1268
   1269		if (rf_path == RF90_PATH_A) {
   1270			u32 tmp;
   1271
   1272			final_swing_idx[RF90_PATH_A] =
   1273				(rtldm->ofdm_index[RF90_PATH_A] >
   1274				pwr_tracking_limit) ?
   1275				pwr_tracking_limit :
   1276				rtldm->ofdm_index[RF90_PATH_A];
   1277			tmp = final_swing_idx[RF90_PATH_A];
   1278			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1279				"pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
   1280				rtldm->ofdm_index[RF90_PATH_A],
   1281				final_swing_idx[RF90_PATH_A]);
   1282
   1283			rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
   1284				      txscaling_tbl[tmp]);
   1285		} else {
   1286			u32 tmp;
   1287
   1288			final_swing_idx[RF90_PATH_B] =
   1289				rtldm->ofdm_index[RF90_PATH_B] >
   1290				pwr_tracking_limit ?
   1291				pwr_tracking_limit :
   1292				rtldm->ofdm_index[RF90_PATH_B];
   1293			tmp = final_swing_idx[RF90_PATH_B];
   1294			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1295				"pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n",
   1296				rtldm->ofdm_index[RF90_PATH_B],
   1297				final_swing_idx[RF90_PATH_B]);
   1298
   1299			rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
   1300				      txscaling_tbl[tmp]);
   1301		}
   1302	} else if (method == MIX_MODE) {
   1303		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1304			"pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
   1305			rtldm->default_ofdm_index,
   1306			rtldm->absolute_ofdm_swing_idx[rf_path],
   1307			rf_path);
   1308
   1309		final_ofdm_swing_index = rtldm->default_ofdm_index +
   1310				rtldm->absolute_ofdm_swing_idx[rf_path];
   1311
   1312		if (rf_path == RF90_PATH_A) {
   1313			/*BBSwing higher then Limit*/
   1314			if (final_ofdm_swing_index > pwr_tracking_limit) {
   1315				rtldm->remnant_cck_idx =
   1316					final_ofdm_swing_index -
   1317					pwr_tracking_limit;
   1318				/* CCK Follow the same compensation value
   1319				 * as Path A
   1320				 */
   1321				rtldm->remnant_ofdm_swing_idx[rf_path] =
   1322					final_ofdm_swing_index -
   1323					pwr_tracking_limit;
   1324
   1325				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
   1326					      txscaling_tbl[pwr_tracking_limit]);
   1327
   1328				rtldm->modify_txagc_flag_path_a = true;
   1329
   1330				/*Set TxAGC Page C{};*/
   1331				rtl8821ae_phy_set_txpower_level_by_path(hw,
   1332					rtlphy->current_channel,
   1333					RF90_PATH_A);
   1334
   1335				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1336					"******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n",
   1337					pwr_tracking_limit,
   1338					rtldm->remnant_ofdm_swing_idx[rf_path]);
   1339			} else if (final_ofdm_swing_index < 0) {
   1340				rtldm->remnant_cck_idx = final_ofdm_swing_index;
   1341				/* CCK Follow the same compensate value as Path A*/
   1342				rtldm->remnant_ofdm_swing_idx[rf_path] =
   1343					final_ofdm_swing_index;
   1344
   1345				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
   1346					txscaling_tbl[0]);
   1347
   1348				rtldm->modify_txagc_flag_path_a = true;
   1349
   1350				/*Set TxAGC Page C{};*/
   1351				rtl8821ae_phy_set_txpower_level_by_path(hw,
   1352					rtlphy->current_channel, RF90_PATH_A);
   1353
   1354				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1355					"******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
   1356					rtldm->remnant_ofdm_swing_idx[rf_path]);
   1357			} else {
   1358				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
   1359					txscaling_tbl[(u8)final_ofdm_swing_index]);
   1360
   1361				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1362					"******Path_A Compensate with BBSwing, Final_OFDM_Swing_Index = %d\n",
   1363					final_ofdm_swing_index);
   1364				/*If TxAGC has changed, reset TxAGC again*/
   1365				if (rtldm->modify_txagc_flag_path_a) {
   1366					rtldm->remnant_cck_idx = 0;
   1367					rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
   1368
   1369					/*Set TxAGC Page C{};*/
   1370					rtl8821ae_phy_set_txpower_level_by_path(hw,
   1371						rtlphy->current_channel, RF90_PATH_A);
   1372					rtldm->modify_txagc_flag_path_a = false;
   1373
   1374					rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
   1375						DBG_LOUD,
   1376						"******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
   1377				}
   1378			}
   1379		}
   1380		/*BBSwing higher then Limit*/
   1381		if (rf_path == RF90_PATH_B) {
   1382			if (final_ofdm_swing_index > pwr_tracking_limit) {
   1383				rtldm->remnant_ofdm_swing_idx[rf_path] =
   1384					final_ofdm_swing_index -
   1385					pwr_tracking_limit;
   1386
   1387				rtl_set_bbreg(hw, RB_TXSCALE,
   1388					0xFFE00000,
   1389					txscaling_tbl[pwr_tracking_limit]);
   1390
   1391				rtldm->modify_txagc_flag_path_b = true;
   1392
   1393				/*Set TxAGC Page E{};*/
   1394				rtl8821ae_phy_set_txpower_level_by_path(hw,
   1395					rtlphy->current_channel, RF90_PATH_B);
   1396
   1397				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1398					"******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
   1399					pwr_tracking_limit,
   1400					 rtldm->remnant_ofdm_swing_idx[rf_path]);
   1401			} else if (final_ofdm_swing_index < 0) {
   1402				rtldm->remnant_ofdm_swing_idx[rf_path] =
   1403					final_ofdm_swing_index;
   1404
   1405				rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
   1406					      txscaling_tbl[0]);
   1407
   1408				rtldm->modify_txagc_flag_path_b = true;
   1409
   1410				/*Set TxAGC Page E{};*/
   1411				rtl8821ae_phy_set_txpower_level_by_path(hw,
   1412					rtlphy->current_channel, RF90_PATH_B);
   1413
   1414				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1415					"******Path_B Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
   1416					rtldm->remnant_ofdm_swing_idx[rf_path]);
   1417			} else {
   1418				rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000,
   1419					txscaling_tbl[(u8)final_ofdm_swing_index]);
   1420
   1421				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1422					"******Path_B Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
   1423					final_ofdm_swing_index);
   1424				 /*If TxAGC has changed, reset TxAGC again*/
   1425				if (rtldm->modify_txagc_flag_path_b) {
   1426					rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
   1427
   1428					/*Set TxAGC Page E{};*/
   1429					rtl8821ae_phy_set_txpower_level_by_path(hw,
   1430					rtlphy->current_channel, RF90_PATH_B);
   1431
   1432					rtldm->modify_txagc_flag_path_b =
   1433						false;
   1434
   1435					rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1436						"******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n");
   1437				}
   1438			}
   1439		}
   1440	} else {
   1441		return;
   1442	}
   1443}
   1444
   1445void rtl8812ae_dm_txpower_tracking_callback_thermalmeter(
   1446	struct ieee80211_hw *hw)
   1447{
   1448	struct rtl_priv *rtlpriv = rtl_priv(hw);
   1449	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
   1450	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
   1451	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
   1452	u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
   1453	u8 thermal_value_avg_count = 0;
   1454	u32 thermal_value_avg = 0;
   1455	/* OFDM BB Swing should be less than +3.0dB, */
   1456	u8 ofdm_min_index = 6;
   1457	 /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
   1458	u8 index_for_channel = 0;
   1459	/* 1. The following TWO tables decide
   1460	 * the final index of OFDM/CCK swing table.
   1461	 */
   1462	const u8 *delta_swing_table_idx_tup_a;
   1463	const u8 *delta_swing_table_idx_tdown_a;
   1464	const u8 *delta_swing_table_idx_tup_b;
   1465	const u8 *delta_swing_table_idx_tdown_b;
   1466
   1467	/*2. Initialization ( 7 steps in total )*/
   1468	rtl8812ae_get_delta_swing_table(hw,
   1469		&delta_swing_table_idx_tup_a,
   1470		&delta_swing_table_idx_tdown_a,
   1471		&delta_swing_table_idx_tup_b,
   1472		&delta_swing_table_idx_tdown_b);
   1473
   1474	rtldm->txpower_trackinginit = true;
   1475
   1476	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1477		"pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
   1478		rtldm->swing_idx_cck_base,
   1479		rtldm->swing_idx_ofdm_base[RF90_PATH_A],
   1480		rtldm->default_ofdm_index);
   1481
   1482	thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A,
   1483		/*0x42: RF Reg[15:10] 88E*/
   1484		RF_T_METER_8812A, 0xfc00);
   1485	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1486		"Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
   1487		thermal_value, rtlefuse->eeprom_thermalmeter);
   1488	if (!rtldm->txpower_track_control ||
   1489	    rtlefuse->eeprom_thermalmeter == 0 ||
   1490	    rtlefuse->eeprom_thermalmeter == 0xFF)
   1491		return;
   1492
   1493	/* 3. Initialize ThermalValues of RFCalibrateInfo*/
   1494
   1495	if (rtlhal->reloadtxpowerindex)
   1496		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1497			"reload ofdm index for band switch\n");
   1498
   1499	/*4. Calculate average thermal meter*/
   1500	rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
   1501	rtldm->thermalvalue_avg_index++;
   1502	if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
   1503		/*Average times =  c.AverageThermalNum*/
   1504		rtldm->thermalvalue_avg_index = 0;
   1505
   1506	for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) {
   1507		if (rtldm->thermalvalue_avg[i]) {
   1508			thermal_value_avg += rtldm->thermalvalue_avg[i];
   1509			thermal_value_avg_count++;
   1510		}
   1511	}
   1512	/*Calculate Average ThermalValue after average enough times*/
   1513	if (thermal_value_avg_count) {
   1514		thermal_value = (u8)(thermal_value_avg /
   1515				thermal_value_avg_count);
   1516		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1517			"AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
   1518			thermal_value, rtlefuse->eeprom_thermalmeter);
   1519	}
   1520
   1521	/*5. Calculate delta, delta_LCK, delta_IQK.
   1522	 *"delta" here is used to determine whether
   1523	 *thermal value changes or not.
   1524	 */
   1525	delta = (thermal_value > rtldm->thermalvalue) ?
   1526		(thermal_value - rtldm->thermalvalue) :
   1527		(rtldm->thermalvalue - thermal_value);
   1528	delta_lck = (thermal_value > rtldm->thermalvalue_lck) ?
   1529		(thermal_value - rtldm->thermalvalue_lck) :
   1530		(rtldm->thermalvalue_lck - thermal_value);
   1531	delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ?
   1532		(thermal_value - rtldm->thermalvalue_iqk) :
   1533		(rtldm->thermalvalue_iqk - thermal_value);
   1534
   1535	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1536		"(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
   1537		delta, delta_lck, delta_iqk);
   1538
   1539	/* 6. If necessary, do LCK.
   1540	 * Delta temperature is equal to or larger than 20 centigrade.
   1541	 */
   1542	if (delta_lck >= IQK_THRESHOLD) {
   1543		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1544			"delta_LCK(%d) >= Threshold_IQK(%d)\n",
   1545			delta_lck, IQK_THRESHOLD);
   1546		rtldm->thermalvalue_lck = thermal_value;
   1547		rtl8821ae_phy_lc_calibrate(hw);
   1548	}
   1549
   1550	/*7. If necessary, move the index of swing table to adjust Tx power.*/
   1551
   1552	if (delta > 0 && rtldm->txpower_track_control) {
   1553		/* "delta" here is used to record the
   1554		 * absolute value of differrence.
   1555		 */
   1556		delta = thermal_value > rtlefuse->eeprom_thermalmeter ?
   1557			(thermal_value - rtlefuse->eeprom_thermalmeter) :
   1558			(rtlefuse->eeprom_thermalmeter - thermal_value);
   1559
   1560		if (delta >= TXPWR_TRACK_TABLE_SIZE)
   1561			delta = TXPWR_TRACK_TABLE_SIZE - 1;
   1562
   1563		/*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
   1564
   1565		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
   1566			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1567				"delta_swing_table_idx_tup_a[%d] = %d\n",
   1568				delta, delta_swing_table_idx_tup_a[delta]);
   1569			rtldm->delta_power_index_last[RF90_PATH_A] =
   1570				rtldm->delta_power_index[RF90_PATH_A];
   1571			rtldm->delta_power_index[RF90_PATH_A] =
   1572				delta_swing_table_idx_tup_a[delta];
   1573
   1574			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
   1575				delta_swing_table_idx_tup_a[delta];
   1576			/*Record delta swing for mix mode power tracking*/
   1577
   1578			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1579				"******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
   1580			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
   1581
   1582			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1583				"delta_swing_table_idx_tup_b[%d] = %d\n",
   1584				delta, delta_swing_table_idx_tup_b[delta]);
   1585			rtldm->delta_power_index_last[RF90_PATH_B] =
   1586				rtldm->delta_power_index[RF90_PATH_B];
   1587			rtldm->delta_power_index[RF90_PATH_B] =
   1588				delta_swing_table_idx_tup_b[delta];
   1589
   1590			rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] =
   1591				delta_swing_table_idx_tup_b[delta];
   1592			/*Record delta swing for mix mode power tracking*/
   1593
   1594			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1595				"******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
   1596				rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]);
   1597		} else {
   1598			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1599				"delta_swing_table_idx_tdown_a[%d] = %d\n",
   1600				delta, delta_swing_table_idx_tdown_a[delta]);
   1601
   1602			rtldm->delta_power_index_last[RF90_PATH_A] =
   1603				rtldm->delta_power_index[RF90_PATH_A];
   1604			rtldm->delta_power_index[RF90_PATH_A] =
   1605				-1 * delta_swing_table_idx_tdown_a[delta];
   1606
   1607			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
   1608				-1 * delta_swing_table_idx_tdown_a[delta];
   1609			/* Record delta swing for mix mode power tracking*/
   1610			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1611				"******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
   1612				rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
   1613
   1614			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1615				"deltaSwingTableIdx_TDOWN_B[%d] = %d\n",
   1616				delta, delta_swing_table_idx_tdown_b[delta]);
   1617
   1618			rtldm->delta_power_index_last[RF90_PATH_B] =
   1619				rtldm->delta_power_index[RF90_PATH_B];
   1620			rtldm->delta_power_index[RF90_PATH_B] =
   1621				-1 * delta_swing_table_idx_tdown_b[delta];
   1622
   1623			rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] =
   1624				-1 * delta_swing_table_idx_tdown_b[delta];
   1625			/*Record delta swing for mix mode power tracking*/
   1626
   1627			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1628				"******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n",
   1629				rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]);
   1630		}
   1631
   1632		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) {
   1633			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1634				"============================= [Path-%c]Calculating PowerIndexOffset =============================\n",
   1635				(p == RF90_PATH_A ? 'A' : 'B'));
   1636
   1637			if (rtldm->delta_power_index[p] ==
   1638				rtldm->delta_power_index_last[p])
   1639				/*If Thermal value changes but lookup
   1640				table value still the same*/
   1641				rtldm->power_index_offset[p] = 0;
   1642			else
   1643				rtldm->power_index_offset[p] =
   1644					rtldm->delta_power_index[p] -
   1645					rtldm->delta_power_index_last[p];
   1646				/* Power Index Diff between 2
   1647				 * times Power Tracking
   1648				 */
   1649			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1650				"[Path-%c] PowerIndexOffset(%d) =DeltaPowerIndex(%d) -DeltaPowerIndexLast(%d)\n",
   1651				(p == RF90_PATH_A ? 'A' : 'B'),
   1652				rtldm->power_index_offset[p],
   1653				rtldm->delta_power_index[p],
   1654				rtldm->delta_power_index_last[p]);
   1655
   1656			rtldm->ofdm_index[p] =
   1657					rtldm->swing_idx_ofdm_base[p] +
   1658					rtldm->power_index_offset[p];
   1659			rtldm->cck_index =
   1660					rtldm->swing_idx_cck_base +
   1661					rtldm->power_index_offset[p];
   1662
   1663			rtldm->swing_idx_cck = rtldm->cck_index;
   1664			rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p];
   1665
   1666			/****Print BB Swing Base and Index Offset */
   1667
   1668			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1669				"The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
   1670				rtldm->swing_idx_cck,
   1671				rtldm->swing_idx_cck_base,
   1672				rtldm->power_index_offset[p]);
   1673			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1674				"The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
   1675				rtldm->swing_idx_ofdm[p],
   1676				(p == RF90_PATH_A ? 'A' : 'B'),
   1677				rtldm->swing_idx_ofdm_base[p],
   1678				rtldm->power_index_offset[p]);
   1679
   1680			/*7.1 Handle boundary conditions of index.*/
   1681
   1682			if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1)
   1683				rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1;
   1684			else if (rtldm->ofdm_index[p] < ofdm_min_index)
   1685				rtldm->ofdm_index[p] = ofdm_min_index;
   1686		}
   1687		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1688			"\n\n====================================================================================\n");
   1689		if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1)
   1690			rtldm->cck_index = TXSCALE_TABLE_SIZE - 1;
   1691		else if (rtldm->cck_index < 0)
   1692			rtldm->cck_index = 0;
   1693	} else {
   1694		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1695			"The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
   1696			rtldm->txpower_track_control,
   1697			thermal_value,
   1698			rtldm->thermalvalue);
   1699
   1700		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
   1701			rtldm->power_index_offset[p] = 0;
   1702	}
   1703	/*Print Swing base & current*/
   1704	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1705		"TxPowerTracking: [CCK] Swing Current Index: %d,Swing Base Index: %d\n",
   1706		rtldm->cck_index, rtldm->swing_idx_cck_base);
   1707	for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) {
   1708		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1709			"TxPowerTracking: [OFDM] Swing Current Index: %d,Swing Base Index[%c]: %d\n",
   1710			rtldm->ofdm_index[p],
   1711			(p == RF90_PATH_A ? 'A' : 'B'),
   1712			rtldm->swing_idx_ofdm_base[p]);
   1713	}
   1714
   1715	if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
   1716		rtldm->power_index_offset[RF90_PATH_B] != 0) &&
   1717		rtldm->txpower_track_control) {
   1718		/*7.2 Configure the Swing Table to adjust Tx Power.
   1719		 *Always TRUE after Tx Power is adjusted by power tracking.
   1720		 *
   1721		 *2012/04/23 MH According to Luke's suggestion,
   1722		 *we can not write BB digital
   1723		 *to increase TX power. Otherwise, EVM will be bad.
   1724		 *
   1725		 *2012/04/25 MH Add for tx power tracking to set
   1726		 *tx power in tx agc for 88E.
   1727		 */
   1728		if (thermal_value > rtldm->thermalvalue) {
   1729			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1730				"Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d,EFUSE_t: %d, Last_t: %d\n",
   1731				rtldm->power_index_offset[RF90_PATH_A],
   1732				delta, thermal_value,
   1733				rtlefuse->eeprom_thermalmeter,
   1734				rtldm->thermalvalue);
   1735
   1736			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1737				"Temperature Increasing(B): delta_pi: %d ,delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
   1738				rtldm->power_index_offset[RF90_PATH_B],
   1739				delta, thermal_value,
   1740				rtlefuse->eeprom_thermalmeter,
   1741				rtldm->thermalvalue);
   1742		} else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
   1743			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1744				"Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
   1745				rtldm->power_index_offset[RF90_PATH_A],
   1746				delta, thermal_value,
   1747				rtlefuse->eeprom_thermalmeter,
   1748				rtldm->thermalvalue);
   1749
   1750			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1751				"Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
   1752				rtldm->power_index_offset[RF90_PATH_B],
   1753				delta, thermal_value,
   1754				rtlefuse->eeprom_thermalmeter,
   1755				rtldm->thermalvalue);
   1756		}
   1757
   1758		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
   1759			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1760				"Temperature(%d) higher than PG value(%d)\n",
   1761				thermal_value, rtlefuse->eeprom_thermalmeter);
   1762
   1763			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1764				"**********Enter POWER Tracking MIX_MODE**********\n");
   1765			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
   1766				rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE,
   1767								 p, 0);
   1768		} else {
   1769			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1770				"Temperature(%d) lower than PG value(%d)\n",
   1771				thermal_value, rtlefuse->eeprom_thermalmeter);
   1772
   1773			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1774				"**********Enter POWER Tracking MIX_MODE**********\n");
   1775			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
   1776				rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE,
   1777								 p, index_for_channel);
   1778		}
   1779		/*Record last time Power Tracking result as base.*/
   1780		rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
   1781		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++)
   1782				rtldm->swing_idx_ofdm_base[p] =
   1783					rtldm->swing_idx_ofdm[p];
   1784
   1785		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1786			"pDM_Odm->RFCalibrateInfo.ThermalValue =%d ThermalValue= %d\n",
   1787			rtldm->thermalvalue, thermal_value);
   1788		/*Record last Power Tracking Thermal Value*/
   1789		rtldm->thermalvalue = thermal_value;
   1790	}
   1791	/*Delta temperature is equal to or larger than
   1792	20 centigrade (When threshold is 8).*/
   1793	if (delta_iqk >= IQK_THRESHOLD)
   1794		rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8);
   1795
   1796	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1797		"<===%s\n", __func__);
   1798}
   1799
   1800static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw,
   1801					    const u8 **up_a,
   1802					    const u8 **down_a)
   1803{
   1804	struct rtl_priv *rtlpriv = rtl_priv(hw);
   1805	struct rtl_phy *rtlphy = &rtlpriv->phy;
   1806	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
   1807	u8 channel = rtlphy->current_channel;
   1808	u8 rate = rtldm->tx_rate;
   1809
   1810	if (1 <= channel && channel <= 14) {
   1811		if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) {
   1812			*up_a = rtl8821ae_delta_swing_table_idx_24gccka_p;
   1813			*down_a = rtl8821ae_delta_swing_table_idx_24gccka_n;
   1814		} else {
   1815			*up_a = rtl8821ae_delta_swing_table_idx_24ga_p;
   1816			*down_a = rtl8821ae_delta_swing_table_idx_24ga_n;
   1817		}
   1818	} else if (36 <= channel && channel <= 64) {
   1819		*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0];
   1820		*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0];
   1821	} else if (100 <= channel && channel <= 140) {
   1822		*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1];
   1823		*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1];
   1824	} else if (149 <= channel && channel <= 173) {
   1825		*up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2];
   1826		*down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2];
   1827	} else {
   1828		*up_a = rtl8818e_delta_swing_table_idx_24gb_p;
   1829		*down_a = rtl8818e_delta_swing_table_idx_24gb_n;
   1830	}
   1831	return;
   1832}
   1833
   1834/*-----------------------------------------------------------------------------
   1835 * Function:	odm_TxPwrTrackSetPwr88E()
   1836 *
   1837 * Overview:	88E change all channel tx power accordign to flag.
   1838 *				OFDM & CCK are all different.
   1839 *
   1840 * Input:		NONE
   1841 *
   1842 * Output:		NONE
   1843 *
   1844 * Return:		NONE
   1845 *
   1846 * Revised History:
   1847 *	When		Who		Remark
   1848 *	04/23/2012	MHC		Create Version 0.
   1849 *
   1850 *---------------------------------------------------------------------------
   1851 */
   1852void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw,
   1853				      enum pwr_track_control_method method,
   1854				      u8 rf_path, u8 channel_mapped_index)
   1855{
   1856	struct rtl_priv *rtlpriv = rtl_priv(hw);
   1857	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
   1858	struct rtl_phy *rtlphy = &rtlpriv->phy;
   1859	u32 final_swing_idx[1];
   1860	u8 pwr_tracking_limit = 26; /*+1.0dB*/
   1861	u8 tx_rate = 0xFF;
   1862	s8 final_ofdm_swing_index = 0;
   1863
   1864	if (rtldm->tx_rate != 0xFF)
   1865		tx_rate = rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate);
   1866
   1867	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "===>%s\n", __func__);
   1868
   1869	if (tx_rate != 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/
   1870		/*CCK*/
   1871		if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M))
   1872			pwr_tracking_limit = 32; /*+4dB*/
   1873		/*OFDM*/
   1874		else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M))
   1875			pwr_tracking_limit = 30; /*+3dB*/
   1876		else if (tx_rate == MGN_54M)
   1877			pwr_tracking_limit = 28; /*+2dB*/
   1878		/*HT*/
   1879		/*QPSK/BPSK*/
   1880		else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2))
   1881			pwr_tracking_limit = 34; /*+5dB*/
   1882		/*16QAM*/
   1883		else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4))
   1884			pwr_tracking_limit = 30; /*+3dB*/
   1885		/*64QAM*/
   1886		else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7))
   1887			pwr_tracking_limit = 28; /*+2dB*/
   1888		/*2 VHT*/
   1889		/*QPSK/BPSK*/
   1890		else if ((tx_rate >= MGN_VHT1SS_MCS0) &&
   1891			(tx_rate <= MGN_VHT1SS_MCS2))
   1892			pwr_tracking_limit = 34; /*+5dB*/
   1893		/*16QAM*/
   1894		else if ((tx_rate >= MGN_VHT1SS_MCS3) &&
   1895			(tx_rate <= MGN_VHT1SS_MCS4))
   1896			pwr_tracking_limit = 30; /*+3dB*/
   1897		/*64QAM*/
   1898		else if ((tx_rate >= MGN_VHT1SS_MCS5) &&
   1899			(tx_rate <= MGN_VHT1SS_MCS6))
   1900			pwr_tracking_limit = 28; /*+2dB*/
   1901		else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/
   1902			pwr_tracking_limit = 26; /*+1dB*/
   1903		else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/
   1904			pwr_tracking_limit = 24; /*+0dB*/
   1905		else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/
   1906			pwr_tracking_limit = 22; /*-1dB*/
   1907		else
   1908			pwr_tracking_limit = 24;
   1909	}
   1910	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1911		"TxRate=0x%x, PwrTrackingLimit=%d\n",
   1912		tx_rate, pwr_tracking_limit);
   1913
   1914	if (method == BBSWING) {
   1915		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1916			"===>%s\n", __func__);
   1917		if (rf_path == RF90_PATH_A) {
   1918			final_swing_idx[RF90_PATH_A] =
   1919				(rtldm->ofdm_index[RF90_PATH_A] >
   1920				pwr_tracking_limit) ?
   1921				pwr_tracking_limit :
   1922				rtldm->ofdm_index[RF90_PATH_A];
   1923			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1924				"pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n",
   1925				rtldm->ofdm_index[RF90_PATH_A],
   1926				final_swing_idx[RF90_PATH_A]);
   1927
   1928			rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
   1929				txscaling_tbl[final_swing_idx[RF90_PATH_A]]);
   1930		}
   1931	} else if (method == MIX_MODE) {
   1932		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1933			"pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n",
   1934			rtldm->default_ofdm_index,
   1935			rtldm->absolute_ofdm_swing_idx[rf_path],
   1936			rf_path);
   1937
   1938		final_ofdm_swing_index =
   1939			rtldm->default_ofdm_index +
   1940			rtldm->absolute_ofdm_swing_idx[rf_path];
   1941		/*BBSwing higher then Limit*/
   1942		if (rf_path == RF90_PATH_A) {
   1943			if (final_ofdm_swing_index > pwr_tracking_limit) {
   1944				rtldm->remnant_cck_idx =
   1945					final_ofdm_swing_index -
   1946					pwr_tracking_limit;
   1947				/* CCK Follow the same compensate value as Path A*/
   1948				rtldm->remnant_ofdm_swing_idx[rf_path] =
   1949					final_ofdm_swing_index -
   1950					pwr_tracking_limit;
   1951
   1952				rtl_set_bbreg(hw, RA_TXSCALE,
   1953					0xFFE00000,
   1954					txscaling_tbl[pwr_tracking_limit]);
   1955
   1956				rtldm->modify_txagc_flag_path_a = true;
   1957
   1958				/*Set TxAGC Page C{};*/
   1959				rtl8821ae_phy_set_txpower_level_by_path(hw,
   1960					rtlphy->current_channel,
   1961					RF90_PATH_A);
   1962
   1963				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1964					" ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n",
   1965					pwr_tracking_limit,
   1966					rtldm->remnant_ofdm_swing_idx[rf_path]);
   1967			} else if (final_ofdm_swing_index < 0) {
   1968				rtldm->remnant_cck_idx = final_ofdm_swing_index;
   1969				/* CCK Follow the same compensate value as Path A*/
   1970				rtldm->remnant_ofdm_swing_idx[rf_path] =
   1971					final_ofdm_swing_index;
   1972
   1973				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
   1974					txscaling_tbl[0]);
   1975
   1976				rtldm->modify_txagc_flag_path_a = true;
   1977
   1978				/*Set TxAGC Page C{};*/
   1979				rtl8821ae_phy_set_txpower_level_by_path(hw,
   1980					rtlphy->current_channel, RF90_PATH_A);
   1981
   1982				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1983					"******Path_A Lower then BBSwing lower bound  0 , Remnant TxAGC Value = %d\n",
   1984					rtldm->remnant_ofdm_swing_idx[rf_path]);
   1985			} else {
   1986				rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000,
   1987					txscaling_tbl[(u8)final_ofdm_swing_index]);
   1988
   1989				rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   1990					"******Path_A Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n",
   1991					final_ofdm_swing_index);
   1992				/*If TxAGC has changed, reset TxAGC again*/
   1993				if (rtldm->modify_txagc_flag_path_a) {
   1994					rtldm->remnant_cck_idx = 0;
   1995					rtldm->remnant_ofdm_swing_idx[rf_path] = 0;
   1996
   1997					/*Set TxAGC Page C{};*/
   1998					rtl8821ae_phy_set_txpower_level_by_path(hw,
   1999						rtlphy->current_channel, RF90_PATH_A);
   2000
   2001					rtldm->modify_txagc_flag_path_a = false;
   2002
   2003					rtl_dbg(rtlpriv, COMP_POWER_TRACKING,
   2004						DBG_LOUD,
   2005						"******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n");
   2006				}
   2007			}
   2008		}
   2009	} else {
   2010		return;
   2011	}
   2012}
   2013
   2014void rtl8821ae_dm_txpower_tracking_callback_thermalmeter(
   2015	struct ieee80211_hw *hw)
   2016{
   2017	struct rtl_priv *rtlpriv = rtl_priv(hw);
   2018	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
   2019	struct rtl_dm	*rtldm = rtl_dm(rtl_priv(hw));
   2020	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
   2021	struct rtl_phy *rtlphy = &rtlpriv->phy;
   2022
   2023	u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0;
   2024	u8 thermal_value_avg_count = 0;
   2025	u32 thermal_value_avg = 0;
   2026
   2027	u8 ofdm_min_index = 6;  /*OFDM BB Swing should be less than +3.0dB */
   2028	/* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/
   2029	u8 index_for_channel = 0;
   2030
   2031	/* 1. The following TWO tables decide the final
   2032	 * index of OFDM/CCK swing table.
   2033	 */
   2034	const u8 *delta_swing_table_idx_tup_a;
   2035	const u8 *delta_swing_table_idx_tdown_a;
   2036
   2037	/*2. Initilization ( 7 steps in total )*/
   2038	rtl8821ae_get_delta_swing_table(hw,
   2039					&delta_swing_table_idx_tup_a,
   2040					&delta_swing_table_idx_tdown_a);
   2041
   2042	rtldm->txpower_trackinginit = true;
   2043
   2044	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2045		"===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n",
   2046		__func__,
   2047		rtldm->swing_idx_cck_base,
   2048		rtldm->swing_idx_ofdm_base[RF90_PATH_A],
   2049		rtldm->default_ofdm_index);
   2050	/*0x42: RF Reg[15:10] 88E*/
   2051	thermal_value = (u8)rtl_get_rfreg(hw,
   2052		RF90_PATH_A, RF_T_METER_8812A, 0xfc00);
   2053	if (!rtldm->txpower_track_control ||
   2054		rtlefuse->eeprom_thermalmeter == 0 ||
   2055		rtlefuse->eeprom_thermalmeter == 0xFF)
   2056		return;
   2057
   2058	/* 3. Initialize ThermalValues of RFCalibrateInfo*/
   2059
   2060	if (rtlhal->reloadtxpowerindex) {
   2061		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2062			"reload ofdm index for band switch\n");
   2063	}
   2064
   2065	/*4. Calculate average thermal meter*/
   2066	rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value;
   2067	rtldm->thermalvalue_avg_index++;
   2068	if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A)
   2069		/*Average times =  c.AverageThermalNum*/
   2070		rtldm->thermalvalue_avg_index = 0;
   2071
   2072	for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) {
   2073		if (rtldm->thermalvalue_avg[i]) {
   2074			thermal_value_avg += rtldm->thermalvalue_avg[i];
   2075			thermal_value_avg_count++;
   2076		}
   2077	}
   2078	/*Calculate Average ThermalValue after average enough times*/
   2079	if (thermal_value_avg_count) {
   2080		thermal_value = (u8)(thermal_value_avg /
   2081				thermal_value_avg_count);
   2082		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2083			"AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n",
   2084			thermal_value, rtlefuse->eeprom_thermalmeter);
   2085	}
   2086
   2087	/*5. Calculate delta, delta_LCK, delta_IQK.
   2088	 *"delta" here is used to determine whether
   2089	 * thermal value changes or not.
   2090	 */
   2091	delta = (thermal_value > rtldm->thermalvalue) ?
   2092		(thermal_value - rtldm->thermalvalue) :
   2093		(rtldm->thermalvalue - thermal_value);
   2094	delta_lck = (thermal_value > rtldm->thermalvalue_lck) ?
   2095		(thermal_value - rtldm->thermalvalue_lck) :
   2096		(rtldm->thermalvalue_lck - thermal_value);
   2097	delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ?
   2098		(thermal_value - rtldm->thermalvalue_iqk) :
   2099		(rtldm->thermalvalue_iqk - thermal_value);
   2100
   2101	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2102		"(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n",
   2103		delta, delta_lck, delta_iqk);
   2104
   2105	/* 6. If necessary, do LCK.	*/
   2106	/*Delta temperature is equal to or larger than 20 centigrade.*/
   2107	if (delta_lck >= IQK_THRESHOLD) {
   2108		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2109			"delta_LCK(%d) >= Threshold_IQK(%d)\n",
   2110			delta_lck, IQK_THRESHOLD);
   2111		rtldm->thermalvalue_lck = thermal_value;
   2112		rtl8821ae_phy_lc_calibrate(hw);
   2113	}
   2114
   2115	/*7. If necessary, move the index of swing table to adjust Tx power.*/
   2116
   2117	if (delta > 0 && rtldm->txpower_track_control) {
   2118		/*"delta" here is used to record the
   2119		 * absolute value of differrence.
   2120		 */
   2121		delta = thermal_value > rtlefuse->eeprom_thermalmeter ?
   2122			(thermal_value - rtlefuse->eeprom_thermalmeter) :
   2123			(rtlefuse->eeprom_thermalmeter - thermal_value);
   2124
   2125		if (delta >= TXSCALE_TABLE_SIZE)
   2126			delta = TXSCALE_TABLE_SIZE - 1;
   2127
   2128		/*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/
   2129
   2130		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
   2131			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2132				"delta_swing_table_idx_tup_a[%d] = %d\n",
   2133				delta, delta_swing_table_idx_tup_a[delta]);
   2134			rtldm->delta_power_index_last[RF90_PATH_A] =
   2135				rtldm->delta_power_index[RF90_PATH_A];
   2136			rtldm->delta_power_index[RF90_PATH_A] =
   2137				delta_swing_table_idx_tup_a[delta];
   2138
   2139			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
   2140				delta_swing_table_idx_tup_a[delta];
   2141			/*Record delta swing for mix mode power tracking*/
   2142
   2143			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2144				"******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
   2145				rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
   2146		} else {
   2147			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2148				"delta_swing_table_idx_tdown_a[%d] = %d\n",
   2149				delta, delta_swing_table_idx_tdown_a[delta]);
   2150
   2151			rtldm->delta_power_index_last[RF90_PATH_A] =
   2152				rtldm->delta_power_index[RF90_PATH_A];
   2153			rtldm->delta_power_index[RF90_PATH_A] =
   2154				-1 * delta_swing_table_idx_tdown_a[delta];
   2155
   2156			rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] =
   2157				-1 * delta_swing_table_idx_tdown_a[delta];
   2158			/* Record delta swing for mix mode power tracking*/
   2159			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2160				"******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n",
   2161				rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]);
   2162		}
   2163
   2164		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) {
   2165			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2166				"\n\n================================ [Path-%c]Calculating PowerIndexOffset ================================\n",
   2167				(p == RF90_PATH_A ? 'A' : 'B'));
   2168			/*If Thermal value changes but lookup table value
   2169			 * still the same
   2170			 */
   2171			if (rtldm->delta_power_index[p] ==
   2172				rtldm->delta_power_index_last[p])
   2173
   2174				rtldm->power_index_offset[p] = 0;
   2175			else
   2176				rtldm->power_index_offset[p] =
   2177					rtldm->delta_power_index[p] -
   2178					rtldm->delta_power_index_last[p];
   2179			/*Power Index Diff between 2 times Power Tracking*/
   2180
   2181			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2182				"[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n",
   2183				(p == RF90_PATH_A ? 'A' : 'B'),
   2184				rtldm->power_index_offset[p],
   2185				rtldm->delta_power_index[p] ,
   2186				rtldm->delta_power_index_last[p]);
   2187
   2188			rtldm->ofdm_index[p] =
   2189					rtldm->swing_idx_ofdm_base[p] +
   2190					rtldm->power_index_offset[p];
   2191			rtldm->cck_index =
   2192					rtldm->swing_idx_cck_base +
   2193					rtldm->power_index_offset[p];
   2194
   2195			rtldm->swing_idx_cck = rtldm->cck_index;
   2196			rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p];
   2197
   2198			/*********Print BB Swing Base and Index Offset********/
   2199
   2200			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2201				"The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n",
   2202				rtldm->swing_idx_cck,
   2203				rtldm->swing_idx_cck_base,
   2204				rtldm->power_index_offset[p]);
   2205			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2206				"The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n",
   2207				rtldm->swing_idx_ofdm[p],
   2208				(p == RF90_PATH_A ? 'A' : 'B'),
   2209				rtldm->swing_idx_ofdm_base[p],
   2210				rtldm->power_index_offset[p]);
   2211
   2212			/*7.1 Handle boundary conditions of index.*/
   2213
   2214			if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1)
   2215				rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1;
   2216			else if (rtldm->ofdm_index[p] < ofdm_min_index)
   2217				rtldm->ofdm_index[p] = ofdm_min_index;
   2218		}
   2219		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2220			"\n\n========================================================================================================\n");
   2221		if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1)
   2222			rtldm->cck_index = TXSCALE_TABLE_SIZE - 1;
   2223		else if (rtldm->cck_index < 0)
   2224			rtldm->cck_index = 0;
   2225	} else {
   2226		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2227			"The thermal meter is unchanged or TxPowerTracking OFF(%d):ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n",
   2228			rtldm->txpower_track_control,
   2229			thermal_value,
   2230			rtldm->thermalvalue);
   2231
   2232		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
   2233			rtldm->power_index_offset[p] = 0;
   2234	}
   2235	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2236		"TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n",
   2237		/*Print Swing base & current*/
   2238		rtldm->cck_index, rtldm->swing_idx_cck_base);
   2239	for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) {
   2240		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2241			"TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n",
   2242			rtldm->ofdm_index[p],
   2243			(p == RF90_PATH_A ? 'A' : 'B'),
   2244			rtldm->swing_idx_ofdm_base[p]);
   2245	}
   2246
   2247	if ((rtldm->power_index_offset[RF90_PATH_A] != 0 ||
   2248		rtldm->power_index_offset[RF90_PATH_B] != 0) &&
   2249		rtldm->txpower_track_control) {
   2250		/*7.2 Configure the Swing Table to adjust Tx Power.*/
   2251		/*Always TRUE after Tx Power is adjusted by power tracking.*/
   2252		/*
   2253		 *  2012/04/23 MH According to Luke's suggestion,
   2254		 *  we can not write BB digital
   2255		 *  to increase TX power. Otherwise, EVM will be bad.
   2256		 *
   2257		 *  2012/04/25 MH Add for tx power tracking to
   2258		 *  set tx power in tx agc for 88E.
   2259		 */
   2260		if (thermal_value > rtldm->thermalvalue) {
   2261			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2262				"Temperature Increasing(A): delta_pi: %d , delta_t: %d,Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
   2263				rtldm->power_index_offset[RF90_PATH_A],
   2264				delta, thermal_value,
   2265				rtlefuse->eeprom_thermalmeter,
   2266				rtldm->thermalvalue);
   2267		} else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/
   2268			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2269				"Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n",
   2270				rtldm->power_index_offset[RF90_PATH_A],
   2271				delta, thermal_value,
   2272				rtlefuse->eeprom_thermalmeter,
   2273				rtldm->thermalvalue);
   2274		}
   2275
   2276		if (thermal_value > rtlefuse->eeprom_thermalmeter) {
   2277			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2278				"Temperature(%d) higher than PG value(%d)\n",
   2279				thermal_value, rtlefuse->eeprom_thermalmeter);
   2280
   2281			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2282				"****Enter POWER Tracking MIX_MODE****\n");
   2283			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
   2284					rtl8821ae_dm_txpwr_track_set_pwr(hw,
   2285						MIX_MODE, p, index_for_channel);
   2286		} else {
   2287			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2288				"Temperature(%d) lower than PG value(%d)\n",
   2289				thermal_value, rtlefuse->eeprom_thermalmeter);
   2290
   2291			rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2292				"*****Enter POWER Tracking MIX_MODE*****\n");
   2293			for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
   2294				rtl8812ae_dm_txpwr_track_set_pwr(hw,
   2295					MIX_MODE, p, index_for_channel);
   2296		}
   2297		/*Record last time Power Tracking result as base.*/
   2298		rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
   2299		for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++)
   2300			rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p];
   2301
   2302		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2303			"pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n",
   2304			rtldm->thermalvalue, thermal_value);
   2305		/*Record last Power Tracking Thermal Value*/
   2306		rtldm->thermalvalue = thermal_value;
   2307	}
   2308	/* Delta temperature is equal to or larger than
   2309	 * 20 centigrade (When threshold is 8).
   2310	 */
   2311	if (delta_iqk >= IQK_THRESHOLD) {
   2312		if (!rtlphy->lck_inprogress) {
   2313			spin_lock(&rtlpriv->locks.iqk_lock);
   2314			rtlphy->lck_inprogress = true;
   2315			spin_unlock(&rtlpriv->locks.iqk_lock);
   2316
   2317			rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8);
   2318
   2319			spin_lock(&rtlpriv->locks.iqk_lock);
   2320			rtlphy->lck_inprogress = false;
   2321			spin_unlock(&rtlpriv->locks.iqk_lock);
   2322		}
   2323	}
   2324
   2325	rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===%s\n", __func__);
   2326}
   2327
   2328void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw)
   2329{
   2330	struct rtl_priv *rtlpriv = rtl_priv(hw);
   2331	if (!rtlpriv->dm.tm_trigger) {
   2332		rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16),
   2333			      0x03);
   2334		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2335			"Trigger 8821ae Thermal Meter!!\n");
   2336		rtlpriv->dm.tm_trigger = 1;
   2337		return;
   2338	} else {
   2339		rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
   2340			"Schedule TxPowerTracking !!\n");
   2341
   2342		rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw);
   2343		rtlpriv->dm.tm_trigger = 0;
   2344	}
   2345}
   2346
   2347static void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
   2348{
   2349	struct rtl_priv *rtlpriv = rtl_priv(hw);
   2350	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
   2351	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
   2352	struct rate_adaptive *p_ra = &rtlpriv->ra;
   2353	u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m;
   2354	u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
   2355	u8 go_up_gap = 5;
   2356	struct ieee80211_sta *sta = NULL;
   2357
   2358	if (is_hal_stop(rtlhal)) {
   2359		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
   2360			"driver is going to unload\n");
   2361		return;
   2362	}
   2363
   2364	if (!rtlpriv->dm.useramask) {
   2365		rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
   2366			"driver does not control rate adaptive mask\n");
   2367		return;
   2368	}
   2369
   2370	if (mac->link_state == MAC80211_LINKED &&
   2371		mac->opmode == NL80211_IFTYPE_STATION) {
   2372		switch (p_ra->pre_ratr_state) {
   2373		case DM_RATR_STA_MIDDLE:
   2374			high_rssithresh_for_ra += go_up_gap;
   2375			break;
   2376		case DM_RATR_STA_LOW:
   2377			high_rssithresh_for_ra += go_up_gap;
   2378			low_rssithresh_for_ra += go_up_gap;
   2379			break;
   2380		default:
   2381			break;
   2382		}
   2383
   2384		if (rtlpriv->dm.undec_sm_pwdb >
   2385		    (long)high_rssithresh_for_ra)
   2386			p_ra->ratr_state = DM_RATR_STA_HIGH;
   2387		else if (rtlpriv->dm.undec_sm_pwdb >
   2388			 (long)low_rssithresh_for_ra)
   2389			p_ra->ratr_state = DM_RATR_STA_MIDDLE;
   2390		else
   2391			p_ra->ratr_state = DM_RATR_STA_LOW;
   2392
   2393		if (p_ra->pre_ratr_state != p_ra->ratr_state) {
   2394			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
   2395				"RSSI = %ld\n",
   2396				rtlpriv->dm.undec_sm_pwdb);
   2397			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
   2398				"RSSI_LEVEL = %d\n", p_ra->ratr_state);
   2399			rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
   2400				"PreState = %d, CurState = %d\n",
   2401				p_ra->pre_ratr_state, p_ra->ratr_state);
   2402
   2403			rcu_read_lock();
   2404			sta = rtl_find_sta(hw, mac->bssid);
   2405			if (sta)
   2406				rtlpriv->cfg->ops->update_rate_tbl(hw,
   2407						sta, p_ra->ratr_state, true);
   2408			rcu_read_unlock();
   2409
   2410			p_ra->pre_ratr_state = p_ra->ratr_state;
   2411		}
   2412	}
   2413}
   2414
   2415static void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw *hw)
   2416{
   2417	struct rtl_priv *rtlpriv = rtl_priv(hw);
   2418	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
   2419	struct rtl_mac *mac = &rtlpriv->mac80211;
   2420	static u8 stage;
   2421	u8 cur_stage = 0;
   2422	u16 basic_rate = RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M | RRSR_6M;
   2423
   2424	if (mac->link_state < MAC80211_LINKED)
   2425		cur_stage = 0;
   2426	else if (dm_digtable->rssi_val_min < 25)
   2427		cur_stage = 1;
   2428	else if (dm_digtable->rssi_val_min > 30)
   2429		cur_stage = 3;
   2430	else
   2431		cur_stage = 2;
   2432
   2433	if (cur_stage != stage) {
   2434		if (cur_stage == 1) {
   2435			basic_rate &= (!(basic_rate ^ mac->basic_rates));
   2436			rtlpriv->cfg->ops->set_hw_reg(hw,
   2437				HW_VAR_BASIC_RATE, (u8 *)&basic_rate);
   2438		} else if (cur_stage == 3 && (stage == 1 || stage == 2)) {
   2439			rtlpriv->cfg->ops->set_hw_reg(hw,
   2440				HW_VAR_BASIC_RATE, (u8 *)&mac->basic_rates);
   2441		}
   2442	}
   2443	stage = cur_stage;
   2444}
   2445
   2446static void rtl8821ae_dm_edca_choose_traffic_idx(
   2447	struct ieee80211_hw *hw, u64 cur_tx_bytes,
   2448	u64 cur_rx_bytes, bool b_bias_on_rx,
   2449	bool *pb_is_cur_rdl_state)
   2450{
   2451	struct rtl_priv *rtlpriv = rtl_priv(hw);
   2452
   2453	if (b_bias_on_rx) {
   2454		if (cur_tx_bytes > (cur_rx_bytes*4)) {
   2455			*pb_is_cur_rdl_state = false;
   2456			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2457				"Uplink Traffic\n");
   2458		} else {
   2459			*pb_is_cur_rdl_state = true;
   2460			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2461				"Balance Traffic\n");
   2462		}
   2463	} else {
   2464		if (cur_rx_bytes > (cur_tx_bytes*4)) {
   2465			*pb_is_cur_rdl_state = true;
   2466			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2467				"Downlink	Traffic\n");
   2468		} else {
   2469			*pb_is_cur_rdl_state = false;
   2470			rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2471				"Balance Traffic\n");
   2472		}
   2473	}
   2474	return;
   2475}
   2476
   2477static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw)
   2478{
   2479	struct rtl_priv *rtlpriv = rtl_priv(hw);
   2480	struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
   2481	struct rtl_dm *rtldm =  rtl_dm(rtl_priv(hw));
   2482
   2483	/*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/
   2484	u64 cur_tx_ok_cnt = 0;
   2485	u64 cur_rx_ok_cnt = 0;
   2486	u32 edca_be_ul = 0x5ea42b;
   2487	u32 edca_be_dl = 0x5ea42b;
   2488	u32 edca_be = 0x5ea42b;
   2489	u8 iot_peer = 0;
   2490	bool *pb_is_cur_rdl_state = NULL;
   2491	bool b_bias_on_rx = false;
   2492	bool b_edca_turbo_on = false;
   2493
   2494	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2495		"%s=====>\n", __func__);
   2496	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2497		"Original BE PARAM: 0x%x\n",
   2498		rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N));
   2499
   2500	if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100)
   2501		rtlpriv->dm.is_any_nonbepkts = true;
   2502	rtlpriv->dm.dbginfo.num_non_be_pkt = 0;
   2503
   2504	/*===============================
   2505	 * list parameter for different platform
   2506	 *===============================
   2507	 */
   2508	pb_is_cur_rdl_state = &rtlpriv->dm.is_cur_rdlstate;
   2509
   2510	cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt;
   2511	cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt;
   2512
   2513	rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
   2514	rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
   2515
   2516	iot_peer = rtlpriv->mac80211.vendor;
   2517	b_bias_on_rx = false;
   2518	b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) &&
   2519			   (!rtlpriv->dm.disable_framebursting)) ?
   2520			   true : false;
   2521
   2522	if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8812AE) {
   2523		if ((iot_peer == PEER_CISCO) &&
   2524			(mac->mode == WIRELESS_MODE_N_24G)) {
   2525			edca_be_dl = edca_setting_dl[iot_peer];
   2526			edca_be_ul = edca_setting_ul[iot_peer];
   2527		}
   2528	}
   2529
   2530	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2531		"bIsAnyNonBEPkts : 0x%x  bDisableFrameBursting : 0x%x\n",
   2532		rtlpriv->dm.is_any_nonbepkts,
   2533		rtlpriv->dm.disable_framebursting);
   2534
   2535	rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2536		"bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n",
   2537		b_edca_turbo_on, b_bias_on_rx);
   2538
   2539	if (b_edca_turbo_on) {
   2540		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2541			"curTxOkCnt : 0x%llx\n", cur_tx_ok_cnt);
   2542		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2543			"curRxOkCnt : 0x%llx\n", cur_rx_ok_cnt);
   2544		if (b_bias_on_rx)
   2545			rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
   2546				cur_rx_ok_cnt, true, pb_is_cur_rdl_state);
   2547		else
   2548			rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt,
   2549				cur_rx_ok_cnt, false, pb_is_cur_rdl_state);
   2550
   2551		edca_be = (*pb_is_cur_rdl_state) ?  edca_be_dl : edca_be_ul;
   2552
   2553		rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be);
   2554
   2555		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2556			"EDCA Turbo on: EDCA_BE:0x%x\n", edca_be);
   2557
   2558		rtlpriv->dm.current_turbo_edca = true;
   2559
   2560		rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD,
   2561			"EDCA_BE_DL : 0x%x  EDCA_BE_UL : 0x%x  EDCA_BE : 0x%x\n",
   2562			edca_be_dl, edca_be_ul, edca_be);
   2563	} else {
   2564		if (rtlpriv->dm.current_turbo_edca) {
   2565			u8 tmp = AC0_BE;
   2566			rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM,
   2567						      (u8 *)(&tmp));
   2568		}
   2569		rtlpriv->dm.current_turbo_edca = false;
   2570	}
   2571
   2572	rtlpriv->dm.is_any_nonbepkts = false;
   2573	rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast;
   2574	rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast;
   2575}
   2576
   2577static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw)
   2578{
   2579	struct rtl_priv *rtlpriv = rtl_priv(hw);
   2580	struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
   2581	u8 cur_cck_cca_thresh;
   2582
   2583	if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) {
   2584		if (dm_digtable->rssi_val_min > 25) {
   2585			cur_cck_cca_thresh = 0xcd;
   2586		} else if ((dm_digtable->rssi_val_min <= 25) &&
   2587			   (dm_digtable->rssi_val_min > 10)) {
   2588			cur_cck_cca_thresh = 0x83;
   2589		} else {
   2590			if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
   2591				cur_cck_cca_thresh = 0x83;
   2592			else
   2593				cur_cck_cca_thresh = 0x40;
   2594		}
   2595	} else {
   2596		if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000)
   2597			cur_cck_cca_thresh = 0x83;
   2598		else
   2599			cur_cck_cca_thresh = 0x40;
   2600	}
   2601
   2602	if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh)
   2603		rtl_write_byte(rtlpriv, ODM_REG_CCK_CCA_11AC,
   2604			       cur_cck_cca_thresh);
   2605
   2606	dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres;
   2607	dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh;
   2608	rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
   2609		"CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres);
   2610}
   2611
   2612static void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw)
   2613{
   2614	struct rtl_priv *rtlpriv = rtl_priv(hw);
   2615	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
   2616	u8 crystal_cap;
   2617	u32 packet_count;
   2618	int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0;
   2619	int cfo_ave_diff;
   2620
   2621	if (rtlpriv->mac80211.link_state < MAC80211_LINKED) {
   2622		/*1.Enable ATC*/
   2623		if (rtldm->atc_status == ATC_STATUS_OFF) {
   2624			rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON);
   2625			rtldm->atc_status = ATC_STATUS_ON;
   2626		}
   2627
   2628		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No link!!\n");
   2629		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
   2630			"atc_status = %d\n", rtldm->atc_status);
   2631
   2632		if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) {
   2633			rtldm->crystal_cap = rtlpriv->efuse.crystalcap;
   2634			crystal_cap = rtldm->crystal_cap & 0x3f;
   2635			crystal_cap = crystal_cap & 0x3f;
   2636			if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE)
   2637				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
   2638					      0x7ff80000, (crystal_cap |
   2639					      (crystal_cap << 6)));
   2640			else
   2641				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
   2642					      0xfff000, (crystal_cap |
   2643					      (crystal_cap << 6)));
   2644		}
   2645		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "crystal_cap = 0x%x\n",
   2646			rtldm->crystal_cap);
   2647	} else{
   2648		/*1. Calculate CFO for path-A & path-B*/
   2649		cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280;
   2650		cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280;
   2651		packet_count = rtldm->packet_count;
   2652
   2653		/*2.No new packet*/
   2654		if (packet_count == rtldm->packet_count_pre) {
   2655			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
   2656				"packet counter doesn't change\n");
   2657			return;
   2658		}
   2659
   2660		rtldm->packet_count_pre = packet_count;
   2661		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
   2662			"packet counter = %d\n",
   2663			rtldm->packet_count);
   2664
   2665		/*3.Average CFO*/
   2666		if (rtlpriv->phy.rf_type == RF_1T1R)
   2667			cfo_ave = cfo_khz_a;
   2668		else
   2669			cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1;
   2670
   2671		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
   2672			"cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n",
   2673			cfo_khz_a, cfo_khz_b, cfo_ave);
   2674
   2675		/*4.Avoid abnormal large CFO*/
   2676		cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ?
   2677						(rtldm->cfo_ave_pre - cfo_ave) :
   2678						(cfo_ave - rtldm->cfo_ave_pre);
   2679
   2680		if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) {
   2681			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
   2682				"first large CFO hit\n");
   2683			rtldm->large_cfo_hit = true;
   2684			return;
   2685		} else
   2686			rtldm->large_cfo_hit = false;
   2687
   2688		rtldm->cfo_ave_pre = cfo_ave;
   2689
   2690		/*CFO tracking by adjusting Xtal cap.*/
   2691
   2692		/*1.Dynamic Xtal threshold*/
   2693		if (cfo_ave >= -rtldm->cfo_threshold &&
   2694			cfo_ave <= rtldm->cfo_threshold &&
   2695			rtldm->is_freeze == 0) {
   2696			if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) {
   2697				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10;
   2698				rtldm->is_freeze = 1;
   2699			} else {
   2700				rtldm->cfo_threshold = CFO_THRESHOLD_XTAL;
   2701			}
   2702		}
   2703		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
   2704			"Dynamic threshold = %d\n",
   2705			rtldm->cfo_threshold);
   2706
   2707		/* 2.Calculate Xtal offset*/
   2708		if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f)
   2709			adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1;
   2710		else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) &&
   2711			 rtlpriv->dm.crystal_cap > 0)
   2712			adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1;
   2713		rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
   2714			"Crystal cap = 0x%x, Crystal cap offset = %d\n",
   2715			rtldm->crystal_cap, adjust_xtal);
   2716
   2717		/*3.Adjudt Crystal Cap.*/
   2718		if (adjust_xtal != 0) {
   2719			rtldm->is_freeze = 0;
   2720			rtldm->crystal_cap += adjust_xtal;
   2721
   2722			if (rtldm->crystal_cap > 0x3f)
   2723				rtldm->crystal_cap = 0x3f;
   2724			else if (rtldm->crystal_cap < 0)
   2725				rtldm->crystal_cap = 0;
   2726
   2727			crystal_cap = rtldm->crystal_cap & 0x3f;
   2728			crystal_cap = crystal_cap & 0x3f;
   2729			if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE)
   2730				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
   2731					      0x7ff80000, (crystal_cap |
   2732					      (crystal_cap << 6)));
   2733			else
   2734				rtl_set_bbreg(hw, REG_MAC_PHY_CTRL,
   2735					      0xfff000, (crystal_cap |
   2736					      (crystal_cap << 6)));
   2737			rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD,
   2738				"New crystal cap = 0x%x\n",
   2739				rtldm->crystal_cap);
   2740		}
   2741	}
   2742}
   2743
   2744void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw)
   2745{
   2746	struct rtl_priv *rtlpriv = rtl_priv(hw);
   2747	struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
   2748	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
   2749	bool fw_current_inpsmode = false;
   2750	bool fw_ps_awake = true;
   2751
   2752	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS,
   2753				      (u8 *)(&fw_current_inpsmode));
   2754
   2755	rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON,
   2756				      (u8 *)(&fw_ps_awake));
   2757
   2758	if (ppsc->p2p_ps_info.p2p_ps_mode)
   2759		fw_ps_awake = false;
   2760
   2761	spin_lock(&rtlpriv->locks.rf_ps_lock);
   2762	if ((ppsc->rfpwr_state == ERFON) &&
   2763	    ((!fw_current_inpsmode) && fw_ps_awake) &&
   2764	    (!ppsc->rfchange_inprogress)) {
   2765		rtl8821ae_dm_common_info_self_update(hw);
   2766		rtl8821ae_dm_false_alarm_counter_statistics(hw);
   2767		rtl8821ae_dm_check_rssi_monitor(hw);
   2768		rtl8821ae_dm_dig(hw);
   2769		rtl8821ae_dm_cck_packet_detection_thresh(hw);
   2770		rtl8821ae_dm_refresh_rate_adaptive_mask(hw);
   2771		rtl8821ae_dm_refresh_basic_rate_mask(hw);
   2772		rtl8821ae_dm_check_edca_turbo(hw);
   2773		rtl8821ae_dm_dynamic_atc_switch(hw);
   2774		if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)
   2775			rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw);
   2776		else
   2777			rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw);
   2778		rtl8821ae_dm_iq_calibrate(hw);
   2779	}
   2780	spin_unlock(&rtlpriv->locks.rf_ps_lock);
   2781
   2782	rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0;
   2783	rtl_dbg(rtlpriv, COMP_DIG, DBG_DMESG, "\n");
   2784}
   2785
   2786void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw,
   2787					u8 *pdesc, u32 mac_id)
   2788{
   2789	struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
   2790	struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
   2791	struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
   2792	struct fast_ant_training *pfat_table = &rtldm->fat_table;
   2793	__le32 *pdesc32 = (__le32 *)pdesc;
   2794
   2795	if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE)
   2796		return;
   2797
   2798	if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV)
   2799		set_tx_desc_tx_ant(pdesc32, pfat_table->antsel_a[mac_id]);
   2800}