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