File Index
Files and directories
Sign in
FILE

dm.c

File preview with syntax highlighting.

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