0001
0002
0003
0004 #include "../wifi.h"
0005 #include "../base.h"
0006 #include "../pci.h"
0007 #include "../core.h"
0008 #include "reg.h"
0009 #include "def.h"
0010 #include "phy.h"
0011 #include "dm.h"
0012 #include "../rtl8723com/dm_common.h"
0013 #include "fw.h"
0014 #include "trx.h"
0015 #include "../btcoexist/rtl_btc.h"
0016
0017 static const u32 ofdmswing_table[] = {
0018 0x0b40002d,
0019 0x0c000030,
0020 0x0cc00033,
0021 0x0d800036,
0022 0x0e400039,
0023 0x0f00003c,
0024 0x10000040,
0025 0x11000044,
0026 0x12000048,
0027 0x1300004c,
0028 0x14400051,
0029 0x15800056,
0030 0x16c0005b,
0031 0x18000060,
0032 0x19800066,
0033 0x1b00006c,
0034 0x1c800072,
0035 0x1e400079,
0036 0x20000080,
0037 0x22000088,
0038 0x24000090,
0039 0x26000098,
0040 0x288000a2,
0041 0x2ac000ab,
0042 0x2d4000b5,
0043 0x300000c0,
0044 0x32c000cb,
0045 0x35c000d7,
0046 0x390000e4,
0047 0x3c8000f2,
0048 0x40000100,
0049 0x43c0010f,
0050 0x47c0011f,
0051 0x4c000130,
0052 0x50800142,
0053 0x55400155,
0054 0x5a400169,
0055 0x5fc0017f,
0056 0x65400195,
0057 0x6b8001ae,
0058 0x71c001c7,
0059 0x788001e2,
0060 0x7f8001fe
0061 };
0062
0063 static const u8 cckswing_table_ch1ch13[CCK_TABLE_SIZE][8] = {
0064 {0x09, 0x08, 0x07, 0x06, 0x04, 0x03, 0x01, 0x01},
0065 {0x09, 0x09, 0x08, 0x06, 0x05, 0x03, 0x01, 0x01},
0066 {0x0a, 0x09, 0x08, 0x07, 0x05, 0x03, 0x02, 0x01},
0067 {0x0a, 0x0a, 0x09, 0x07, 0x05, 0x03, 0x02, 0x01},
0068 {0x0b, 0x0a, 0x09, 0x08, 0x06, 0x04, 0x02, 0x01},
0069 {0x0b, 0x0b, 0x0a, 0x08, 0x06, 0x04, 0x02, 0x01},
0070 {0x0c, 0x0c, 0x0a, 0x09, 0x06, 0x04, 0x02, 0x01},
0071 {0x0d, 0x0c, 0x0b, 0x09, 0x07, 0x04, 0x02, 0x01},
0072 {0x0d, 0x0d, 0x0c, 0x0a, 0x07, 0x05, 0x02, 0x01},
0073 {0x0e, 0x0e, 0x0c, 0x0a, 0x08, 0x05, 0x02, 0x01},
0074 {0x0f, 0x0f, 0x0d, 0x0b, 0x08, 0x05, 0x03, 0x01},
0075 {0x10, 0x10, 0x0e, 0x0b, 0x08, 0x05, 0x03, 0x01},
0076 {0x11, 0x11, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0077 {0x12, 0x12, 0x0f, 0x0c, 0x09, 0x06, 0x03, 0x01},
0078 {0x13, 0x13, 0x10, 0x0d, 0x0a, 0x06, 0x03, 0x01},
0079 {0x14, 0x14, 0x11, 0x0e, 0x0b, 0x07, 0x03, 0x02},
0080 {0x16, 0x15, 0x12, 0x0f, 0x0b, 0x07, 0x04, 0x01},
0081 {0x17, 0x16, 0x13, 0x10, 0x0c, 0x08, 0x04, 0x02},
0082 {0x18, 0x17, 0x15, 0x11, 0x0c, 0x08, 0x04, 0x02},
0083 {0x1a, 0x19, 0x16, 0x12, 0x0d, 0x09, 0x04, 0x02},
0084 {0x1b, 0x1a, 0x17, 0x13, 0x0e, 0x09, 0x04, 0x02},
0085 {0x1d, 0x1c, 0x18, 0x14, 0x0f, 0x0a, 0x05, 0x02},
0086 {0x1f, 0x1e, 0x1a, 0x15, 0x10, 0x0a, 0x05, 0x02},
0087 {0x20, 0x20, 0x1b, 0x16, 0x11, 0x08, 0x05, 0x02},
0088 {0x22, 0x21, 0x1d, 0x18, 0x11, 0x0b, 0x06, 0x02},
0089 {0x24, 0x23, 0x1f, 0x19, 0x13, 0x0c, 0x06, 0x03},
0090 {0x26, 0x25, 0x21, 0x1b, 0x14, 0x0d, 0x06, 0x03},
0091 {0x28, 0x28, 0x22, 0x1c, 0x15, 0x0d, 0x07, 0x03},
0092 {0x2b, 0x2a, 0x25, 0x1e, 0x16, 0x0e, 0x07, 0x03},
0093 {0x2d, 0x2d, 0x27, 0x1f, 0x18, 0x0f, 0x08, 0x03},
0094 {0x30, 0x2f, 0x29, 0x21, 0x19, 0x10, 0x08, 0x03},
0095 {0x33, 0x32, 0x2b, 0x23, 0x1a, 0x11, 0x08, 0x04},
0096 {0x36, 0x35, 0x2e, 0x25, 0x1c, 0x12, 0x09, 0x04}
0097 };
0098
0099 static const u8 cckswing_table_ch14[CCK_TABLE_SIZE][8] = {
0100 {0x09, 0x08, 0x07, 0x04, 0x00, 0x00, 0x00, 0x00},
0101 {0x09, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0102 {0x0a, 0x09, 0x08, 0x05, 0x00, 0x00, 0x00, 0x00},
0103 {0x0a, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0104 {0x0b, 0x0a, 0x09, 0x05, 0x00, 0x00, 0x00, 0x00},
0105 {0x0b, 0x0b, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0106 {0x0c, 0x0c, 0x0a, 0x06, 0x00, 0x00, 0x00, 0x00},
0107 {0x0d, 0x0c, 0x0b, 0x06, 0x00, 0x00, 0x00, 0x00},
0108 {0x0d, 0x0d, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0109 {0x0e, 0x0e, 0x0c, 0x07, 0x00, 0x00, 0x00, 0x00},
0110 {0x0f, 0x0f, 0x0d, 0x08, 0x00, 0x00, 0x00, 0x00},
0111 {0x10, 0x10, 0x0e, 0x08, 0x00, 0x00, 0x00, 0x00},
0112 {0x11, 0x11, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0113 {0x12, 0x12, 0x0f, 0x09, 0x00, 0x00, 0x00, 0x00},
0114 {0x13, 0x13, 0x10, 0x0a, 0x00, 0x00, 0x00, 0x00},
0115 {0x14, 0x14, 0x11, 0x0a, 0x00, 0x00, 0x00, 0x00},
0116 {0x16, 0x15, 0x12, 0x0b, 0x00, 0x00, 0x00, 0x00},
0117 {0x17, 0x16, 0x13, 0x0b, 0x00, 0x00, 0x00, 0x00},
0118 {0x18, 0x17, 0x15, 0x0c, 0x00, 0x00, 0x00, 0x00},
0119 {0x1a, 0x19, 0x16, 0x0d, 0x00, 0x00, 0x00, 0x00},
0120 {0x1b, 0x1a, 0x17, 0x0e, 0x00, 0x00, 0x00, 0x00},
0121 {0x1d, 0x1c, 0x18, 0x0e, 0x00, 0x00, 0x00, 0x00},
0122 {0x1f, 0x1e, 0x1a, 0x0f, 0x00, 0x00, 0x00, 0x00},
0123 {0x20, 0x20, 0x1b, 0x10, 0x00, 0x00, 0x00, 0x00},
0124 {0x22, 0x21, 0x1d, 0x11, 0x00, 0x00, 0x00, 0x00},
0125 {0x24, 0x23, 0x1f, 0x12, 0x00, 0x00, 0x00, 0x00},
0126 {0x26, 0x25, 0x21, 0x13, 0x00, 0x00, 0x00, 0x00},
0127 {0x28, 0x28, 0x24, 0x14, 0x00, 0x00, 0x00, 0x00},
0128 {0x2b, 0x2a, 0x25, 0x15, 0x00, 0x00, 0x00, 0x00},
0129 {0x2d, 0x2d, 0x17, 0x17, 0x00, 0x00, 0x00, 0x00},
0130 {0x30, 0x2f, 0x29, 0x18, 0x00, 0x00, 0x00, 0x00},
0131 {0x33, 0x32, 0x2b, 0x19, 0x00, 0x00, 0x00, 0x00},
0132 {0x36, 0x35, 0x2e, 0x1b, 0x00, 0x00, 0x00, 0x00}
0133 };
0134
0135 static const u32 edca_setting_dl[PEER_MAX] = {
0136 0xa44f,
0137 0x5ea44f,
0138 0x5e4322,
0139 0x5ea42b,
0140 0xa44f,
0141 0xa630,
0142 0x5ea630,
0143 0x5ea42b,
0144 };
0145
0146 static const u32 edca_setting_ul[PEER_MAX] = {
0147 0x5e4322,
0148 0xa44f,
0149 0x5ea44f,
0150 0x5ea32b,
0151 0x5ea422,
0152 0x5ea322,
0153 0x3ea430,
0154 0x5ea44f,
0155 };
0156
0157 void rtl8723be_dm_txpower_track_adjust(struct ieee80211_hw *hw, u8 type,
0158 u8 *pdirection, u32 *poutwrite_val)
0159 {
0160 struct rtl_priv *rtlpriv = rtl_priv(hw);
0161 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
0162 u8 pwr_val = 0;
0163 u8 ofdm_base = rtlpriv->dm.swing_idx_ofdm_base[RF90_PATH_A];
0164 u8 ofdm_val = rtlpriv->dm.swing_idx_ofdm[RF90_PATH_A];
0165 u8 cck_base = rtldm->swing_idx_cck_base;
0166 u8 cck_val = rtldm->swing_idx_cck;
0167
0168 if (type == 0) {
0169 if (ofdm_val <= ofdm_base) {
0170 *pdirection = 1;
0171 pwr_val = ofdm_base - ofdm_val;
0172 } else {
0173 *pdirection = 2;
0174 pwr_val = ofdm_val - ofdm_base;
0175 }
0176 } else if (type == 1) {
0177 if (cck_val <= cck_base) {
0178 *pdirection = 1;
0179 pwr_val = cck_base - cck_val;
0180 } else {
0181 *pdirection = 2;
0182 pwr_val = cck_val - cck_base;
0183 }
0184 }
0185
0186 if (pwr_val >= TXPWRTRACK_MAX_IDX && (*pdirection == 1))
0187 pwr_val = TXPWRTRACK_MAX_IDX;
0188
0189 *poutwrite_val = pwr_val | (pwr_val << 8) |
0190 (pwr_val << 16) | (pwr_val << 24);
0191 }
0192
0193 void rtl8723be_dm_init_rate_adaptive_mask(struct ieee80211_hw *hw)
0194 {
0195 struct rtl_priv *rtlpriv = rtl_priv(hw);
0196 struct rate_adaptive *p_ra = &rtlpriv->ra;
0197
0198 p_ra->ratr_state = DM_RATR_STA_INIT;
0199 p_ra->pre_ratr_state = DM_RATR_STA_INIT;
0200
0201 if (rtlpriv->dm.dm_type == DM_TYPE_BYDRIVER)
0202 rtlpriv->dm.useramask = true;
0203 else
0204 rtlpriv->dm.useramask = false;
0205
0206 p_ra->high_rssi_thresh_for_ra = 50;
0207 p_ra->low_rssi_thresh_for_ra40m = 20;
0208 }
0209
0210 static void rtl8723be_dm_init_txpower_tracking(struct ieee80211_hw *hw)
0211 {
0212 struct rtl_priv *rtlpriv = rtl_priv(hw);
0213
0214 rtlpriv->dm.txpower_tracking = true;
0215 rtlpriv->dm.txpower_track_control = true;
0216 rtlpriv->dm.thermalvalue = 0;
0217
0218 rtlpriv->dm.ofdm_index[0] = 30;
0219 rtlpriv->dm.cck_index = 20;
0220
0221 rtlpriv->dm.swing_idx_cck_base = rtlpriv->dm.cck_index;
0222
0223 rtlpriv->dm.swing_idx_ofdm_base[0] = rtlpriv->dm.ofdm_index[0];
0224 rtlpriv->dm.delta_power_index[RF90_PATH_A] = 0;
0225 rtlpriv->dm.delta_power_index_last[RF90_PATH_A] = 0;
0226 rtlpriv->dm.power_index_offset[RF90_PATH_A] = 0;
0227
0228 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0229 "rtlpriv->dm.txpower_tracking = %d\n",
0230 rtlpriv->dm.txpower_tracking);
0231 }
0232
0233 static void rtl8723be_dm_init_dynamic_atc_switch(struct ieee80211_hw *hw)
0234 {
0235 struct rtl_priv *rtlpriv = rtl_priv(hw);
0236
0237 rtlpriv->dm.crystal_cap = rtlpriv->efuse.crystalcap;
0238
0239 rtlpriv->dm.atc_status = rtl_get_bbreg(hw, ROFDM1_CFOTRACKING, 0x800);
0240 rtlpriv->dm.cfo_threshold = CFO_THRESHOLD_XTAL;
0241 }
0242
0243 void rtl8723be_dm_init(struct ieee80211_hw *hw)
0244 {
0245 struct rtl_priv *rtlpriv = rtl_priv(hw);
0246 u32 cur_igvalue = rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f);
0247
0248 rtlpriv->dm.dm_type = DM_TYPE_BYDRIVER;
0249 rtl_dm_diginit(hw, cur_igvalue);
0250 rtl8723be_dm_init_rate_adaptive_mask(hw);
0251 rtl8723_dm_init_edca_turbo(hw);
0252 rtl8723_dm_init_dynamic_bb_powersaving(hw);
0253 rtl8723_dm_init_dynamic_txpower(hw);
0254 rtl8723be_dm_init_txpower_tracking(hw);
0255 rtl8723be_dm_init_dynamic_atc_switch(hw);
0256 }
0257
0258 static void rtl8723be_dm_find_minimum_rssi(struct ieee80211_hw *hw)
0259 {
0260 struct rtl_priv *rtlpriv = rtl_priv(hw);
0261 struct dig_t *rtl_dm_dig = &rtlpriv->dm_digtable;
0262 struct rtl_mac *mac = rtl_mac(rtlpriv);
0263
0264
0265 if ((mac->link_state < MAC80211_LINKED) &&
0266 (rtlpriv->dm.entry_min_undec_sm_pwdb == 0)) {
0267 rtl_dm_dig->min_undec_pwdb_for_dm = 0;
0268 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
0269 "Not connected to any\n");
0270 }
0271 if (mac->link_state >= MAC80211_LINKED) {
0272 if (mac->opmode == NL80211_IFTYPE_AP ||
0273 mac->opmode == NL80211_IFTYPE_ADHOC) {
0274 rtl_dm_dig->min_undec_pwdb_for_dm =
0275 rtlpriv->dm.entry_min_undec_sm_pwdb;
0276 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
0277 "AP Client PWDB = 0x%lx\n",
0278 rtlpriv->dm.entry_min_undec_sm_pwdb);
0279 } else {
0280 rtl_dm_dig->min_undec_pwdb_for_dm =
0281 rtlpriv->dm.undec_sm_pwdb;
0282 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
0283 "STA Default Port PWDB = 0x%x\n",
0284 rtl_dm_dig->min_undec_pwdb_for_dm);
0285 }
0286 } else {
0287 rtl_dm_dig->min_undec_pwdb_for_dm =
0288 rtlpriv->dm.entry_min_undec_sm_pwdb;
0289 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD,
0290 "AP Ext Port or disconnect PWDB = 0x%x\n",
0291 rtl_dm_dig->min_undec_pwdb_for_dm);
0292 }
0293 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "MinUndecoratedPWDBForDM =%d\n",
0294 rtl_dm_dig->min_undec_pwdb_for_dm);
0295 }
0296
0297 static void rtl8723be_dm_check_rssi_monitor(struct ieee80211_hw *hw)
0298 {
0299 struct rtl_priv *rtlpriv = rtl_priv(hw);
0300 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0301 struct rtl_sta_info *drv_priv;
0302 u8 h2c_parameter[3] = { 0 };
0303 long tmp_entry_max_pwdb = 0, tmp_entry_min_pwdb = 0xff;
0304
0305
0306 spin_lock_bh(&rtlpriv->locks.entry_list_lock);
0307 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) {
0308 if (drv_priv->rssi_stat.undec_sm_pwdb <
0309 tmp_entry_min_pwdb)
0310 tmp_entry_min_pwdb =
0311 drv_priv->rssi_stat.undec_sm_pwdb;
0312 if (drv_priv->rssi_stat.undec_sm_pwdb >
0313 tmp_entry_max_pwdb)
0314 tmp_entry_max_pwdb =
0315 drv_priv->rssi_stat.undec_sm_pwdb;
0316 }
0317 spin_unlock_bh(&rtlpriv->locks.entry_list_lock);
0318
0319
0320 if (tmp_entry_max_pwdb != 0) {
0321 rtlpriv->dm.entry_max_undec_sm_pwdb =
0322 tmp_entry_max_pwdb;
0323 RTPRINT(rtlpriv, FDM, DM_PWDB,
0324 "EntryMaxPWDB = 0x%lx(%ld)\n",
0325 tmp_entry_max_pwdb, tmp_entry_max_pwdb);
0326 } else {
0327 rtlpriv->dm.entry_max_undec_sm_pwdb = 0;
0328 }
0329
0330 if (tmp_entry_min_pwdb != 0xff) {
0331 rtlpriv->dm.entry_min_undec_sm_pwdb =
0332 tmp_entry_min_pwdb;
0333 RTPRINT(rtlpriv, FDM, DM_PWDB,
0334 "EntryMinPWDB = 0x%lx(%ld)\n",
0335 tmp_entry_min_pwdb, tmp_entry_min_pwdb);
0336 } else {
0337 rtlpriv->dm.entry_min_undec_sm_pwdb = 0;
0338 }
0339
0340 if (rtlpriv->dm.useramask) {
0341 h2c_parameter[2] =
0342 (u8)(rtlpriv->dm.undec_sm_pwdb & 0xFF);
0343 h2c_parameter[1] = 0x20;
0344 h2c_parameter[0] = 0;
0345 rtl8723be_fill_h2c_cmd(hw, H2C_RSSIBE_REPORT, 3, h2c_parameter);
0346 } else {
0347 rtl_write_byte(rtlpriv, 0x4fe,
0348 rtlpriv->dm.undec_sm_pwdb);
0349 }
0350 rtl8723be_dm_find_minimum_rssi(hw);
0351 dm_digtable->rssi_val_min =
0352 rtlpriv->dm_digtable.min_undec_pwdb_for_dm;
0353 }
0354
0355 void rtl8723be_dm_write_dig(struct ieee80211_hw *hw, u8 current_igi)
0356 {
0357 struct rtl_priv *rtlpriv = rtl_priv(hw);
0358 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0359
0360 if (dm_digtable->stop_dig)
0361 return;
0362
0363 if (dm_digtable->cur_igvalue != current_igi) {
0364 rtl_set_bbreg(hw, ROFDM0_XAAGCCORE1, 0x7f, current_igi);
0365 if (rtlpriv->phy.rf_type != RF_1T1R)
0366 rtl_set_bbreg(hw, ROFDM0_XBAGCCORE1,
0367 0x7f, current_igi);
0368 }
0369 dm_digtable->pre_igvalue = dm_digtable->cur_igvalue;
0370 dm_digtable->cur_igvalue = current_igi;
0371 }
0372
0373 static void rtl8723be_dm_dig(struct ieee80211_hw *hw)
0374 {
0375 struct rtl_priv *rtlpriv = rtl_priv(hw);
0376 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
0377 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0378 u8 dig_min_0, dig_maxofmin;
0379 bool bfirstconnect, bfirstdisconnect;
0380 u8 dm_dig_max, dm_dig_min;
0381 u8 current_igi = dm_digtable->cur_igvalue;
0382 u8 offset;
0383
0384
0385 if (mac->act_scanning)
0386 return;
0387
0388 dig_min_0 = dm_digtable->dig_min_0;
0389 bfirstconnect = (mac->link_state >= MAC80211_LINKED) &&
0390 !dm_digtable->media_connect_0;
0391 bfirstdisconnect = (mac->link_state < MAC80211_LINKED) &&
0392 (dm_digtable->media_connect_0);
0393
0394 dm_dig_max = 0x5a;
0395 dm_dig_min = DM_DIG_MIN;
0396 dig_maxofmin = DM_DIG_MAX_AP;
0397
0398 if (mac->link_state >= MAC80211_LINKED) {
0399 if ((dm_digtable->rssi_val_min + 10) > dm_dig_max)
0400 dm_digtable->rx_gain_max = dm_dig_max;
0401 else if ((dm_digtable->rssi_val_min + 10) < dm_dig_min)
0402 dm_digtable->rx_gain_max = dm_dig_min;
0403 else
0404 dm_digtable->rx_gain_max =
0405 dm_digtable->rssi_val_min + 10;
0406
0407 if (rtlpriv->dm.one_entry_only) {
0408 offset = 12;
0409 if (dm_digtable->rssi_val_min - offset < dm_dig_min)
0410 dig_min_0 = dm_dig_min;
0411 else if (dm_digtable->rssi_val_min - offset >
0412 dig_maxofmin)
0413 dig_min_0 = dig_maxofmin;
0414 else
0415 dig_min_0 =
0416 dm_digtable->rssi_val_min - offset;
0417 } else {
0418 dig_min_0 = dm_dig_min;
0419 }
0420
0421 } else {
0422 dm_digtable->rx_gain_max = dm_dig_max;
0423 dig_min_0 = dm_dig_min;
0424 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "no link\n");
0425 }
0426
0427 if (rtlpriv->falsealm_cnt.cnt_all > 10000) {
0428 if (dm_digtable->large_fa_hit != 3)
0429 dm_digtable->large_fa_hit++;
0430 if (dm_digtable->forbidden_igi < current_igi) {
0431 dm_digtable->forbidden_igi = current_igi;
0432 dm_digtable->large_fa_hit = 1;
0433 }
0434
0435 if (dm_digtable->large_fa_hit >= 3) {
0436 if ((dm_digtable->forbidden_igi + 1) >
0437 dm_digtable->rx_gain_max)
0438 dm_digtable->rx_gain_min =
0439 dm_digtable->rx_gain_max;
0440 else
0441 dm_digtable->rx_gain_min =
0442 dm_digtable->forbidden_igi + 1;
0443 dm_digtable->recover_cnt = 3600;
0444 }
0445 } else {
0446 if (dm_digtable->recover_cnt != 0) {
0447 dm_digtable->recover_cnt--;
0448 } else {
0449 if (dm_digtable->large_fa_hit < 3) {
0450 if ((dm_digtable->forbidden_igi - 1) <
0451 dig_min_0) {
0452 dm_digtable->forbidden_igi =
0453 dig_min_0;
0454 dm_digtable->rx_gain_min =
0455 dig_min_0;
0456 } else {
0457 dm_digtable->forbidden_igi--;
0458 dm_digtable->rx_gain_min =
0459 dm_digtable->forbidden_igi + 1;
0460 }
0461 } else {
0462 dm_digtable->large_fa_hit = 0;
0463 }
0464 }
0465 }
0466 if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max)
0467 dm_digtable->rx_gain_min = dm_digtable->rx_gain_max;
0468
0469 if (mac->link_state >= MAC80211_LINKED) {
0470 if (bfirstconnect) {
0471 if (dm_digtable->rssi_val_min <= dig_maxofmin)
0472 current_igi = dm_digtable->rssi_val_min;
0473 else
0474 current_igi = dig_maxofmin;
0475
0476 dm_digtable->large_fa_hit = 0;
0477 } else {
0478 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2)
0479 current_igi += 4;
0480 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1)
0481 current_igi += 2;
0482 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0)
0483 current_igi -= 2;
0484 }
0485 } else {
0486 if (bfirstdisconnect) {
0487 current_igi = dm_digtable->rx_gain_min;
0488 } else {
0489 if (rtlpriv->falsealm_cnt.cnt_all > 10000)
0490 current_igi += 4;
0491 else if (rtlpriv->falsealm_cnt.cnt_all > 8000)
0492 current_igi += 2;
0493 else if (rtlpriv->falsealm_cnt.cnt_all < 500)
0494 current_igi -= 2;
0495 }
0496 }
0497
0498 if (current_igi > dm_digtable->rx_gain_max)
0499 current_igi = dm_digtable->rx_gain_max;
0500 else if (current_igi < dm_digtable->rx_gain_min)
0501 current_igi = dm_digtable->rx_gain_min;
0502
0503 rtl8723be_dm_write_dig(hw, current_igi);
0504 dm_digtable->media_connect_0 =
0505 ((mac->link_state >= MAC80211_LINKED) ? true : false);
0506 dm_digtable->dig_min_0 = dig_min_0;
0507 }
0508
0509 static void rtl8723be_dm_false_alarm_counter_statistics(
0510 struct ieee80211_hw *hw)
0511 {
0512 u32 ret_value;
0513 struct rtl_priv *rtlpriv = rtl_priv(hw);
0514 struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt;
0515
0516 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 1);
0517 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 1);
0518
0519 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE1_11N, MASKDWORD);
0520 falsealm_cnt->cnt_fast_fsync_fail = ret_value & 0xffff;
0521 falsealm_cnt->cnt_sb_search_fail = (ret_value & 0xffff0000) >> 16;
0522
0523 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE2_11N, MASKDWORD);
0524 falsealm_cnt->cnt_ofdm_cca = ret_value & 0xffff;
0525 falsealm_cnt->cnt_parity_fail = (ret_value & 0xffff0000) >> 16;
0526
0527 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE3_11N, MASKDWORD);
0528 falsealm_cnt->cnt_rate_illegal = ret_value & 0xffff;
0529 falsealm_cnt->cnt_crc8_fail = (ret_value & 0xffff0000) >> 16;
0530
0531 ret_value = rtl_get_bbreg(hw, DM_REG_OFDM_FA_TYPE4_11N, MASKDWORD);
0532 falsealm_cnt->cnt_mcs_fail = ret_value & 0xffff;
0533
0534 falsealm_cnt->cnt_ofdm_fail = falsealm_cnt->cnt_parity_fail +
0535 falsealm_cnt->cnt_rate_illegal +
0536 falsealm_cnt->cnt_crc8_fail +
0537 falsealm_cnt->cnt_mcs_fail +
0538 falsealm_cnt->cnt_fast_fsync_fail +
0539 falsealm_cnt->cnt_sb_search_fail;
0540
0541 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(12), 1);
0542 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(14), 1);
0543
0544 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_RST_11N, MASKBYTE0);
0545 falsealm_cnt->cnt_cck_fail = ret_value;
0546
0547 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_FA_MSB_11N, MASKBYTE3);
0548 falsealm_cnt->cnt_cck_fail += (ret_value & 0xff) << 8;
0549
0550 ret_value = rtl_get_bbreg(hw, DM_REG_CCK_CCA_CNT_11N, MASKDWORD);
0551 falsealm_cnt->cnt_cck_cca = ((ret_value & 0xff) << 8) |
0552 ((ret_value & 0xff00) >> 8);
0553
0554 falsealm_cnt->cnt_all = falsealm_cnt->cnt_fast_fsync_fail +
0555 falsealm_cnt->cnt_sb_search_fail +
0556 falsealm_cnt->cnt_parity_fail +
0557 falsealm_cnt->cnt_rate_illegal +
0558 falsealm_cnt->cnt_crc8_fail +
0559 falsealm_cnt->cnt_mcs_fail +
0560 falsealm_cnt->cnt_cck_fail;
0561
0562 falsealm_cnt->cnt_cca_all = falsealm_cnt->cnt_ofdm_cca +
0563 falsealm_cnt->cnt_cck_cca;
0564
0565 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 1);
0566 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTC_11N, BIT(31), 0);
0567 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 1);
0568 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(27), 0);
0569
0570 rtl_set_bbreg(hw, DM_REG_OFDM_FA_HOLDC_11N, BIT(31), 0);
0571 rtl_set_bbreg(hw, DM_REG_OFDM_FA_RSTD_11N, BIT(31), 0);
0572
0573 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 0);
0574 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(13) | BIT(12), 2);
0575
0576 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 0);
0577 rtl_set_bbreg(hw, DM_REG_CCK_FA_RST_11N, BIT(15) | BIT(14), 2);
0578
0579 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0580 "cnt_parity_fail = %d, cnt_rate_illegal = %d, cnt_crc8_fail = %d, cnt_mcs_fail = %d\n",
0581 falsealm_cnt->cnt_parity_fail,
0582 falsealm_cnt->cnt_rate_illegal,
0583 falsealm_cnt->cnt_crc8_fail,
0584 falsealm_cnt->cnt_mcs_fail);
0585
0586 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE,
0587 "cnt_ofdm_fail = %x, cnt_cck_fail = %x, cnt_all = %x\n",
0588 falsealm_cnt->cnt_ofdm_fail,
0589 falsealm_cnt->cnt_cck_fail,
0590 falsealm_cnt->cnt_all);
0591 }
0592
0593 static void rtl8723be_dm_dynamic_txpower(struct ieee80211_hw *hw)
0594 {
0595
0596 return;
0597 }
0598
0599 static void rtl8723be_set_iqk_matrix(struct ieee80211_hw *hw, u8 ofdm_index,
0600 u8 rfpath, long iqk_result_x,
0601 long iqk_result_y)
0602 {
0603 long ele_a = 0, ele_d, ele_c = 0, value32;
0604
0605 if (ofdm_index >= 43)
0606 ofdm_index = 43 - 1;
0607
0608 ele_d = (ofdmswing_table[ofdm_index] & 0xFFC00000) >> 22;
0609
0610 if (iqk_result_x != 0) {
0611 if ((iqk_result_x & 0x00000200) != 0)
0612 iqk_result_x = iqk_result_x | 0xFFFFFC00;
0613 ele_a = ((iqk_result_x * ele_d) >> 8) & 0x000003FF;
0614
0615 if ((iqk_result_y & 0x00000200) != 0)
0616 iqk_result_y = iqk_result_y | 0xFFFFFC00;
0617 ele_c = ((iqk_result_y * ele_d) >> 8) & 0x000003FF;
0618
0619 switch (rfpath) {
0620 case RF90_PATH_A:
0621 value32 = (ele_d << 22) |
0622 ((ele_c & 0x3F) << 16) | ele_a;
0623 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
0624 value32);
0625 value32 = (ele_c & 0x000003C0) >> 6;
0626 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, value32);
0627 value32 = ((iqk_result_x * ele_d) >> 7) & 0x01;
0628 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24),
0629 value32);
0630 break;
0631 default:
0632 break;
0633 }
0634 } else {
0635 switch (rfpath) {
0636 case RF90_PATH_A:
0637 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, MASKDWORD,
0638 ofdmswing_table[ofdm_index]);
0639 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, MASKH4BITS, 0x00);
0640 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(24), 0x00);
0641 break;
0642 default:
0643 break;
0644 }
0645 }
0646 }
0647
0648 static void rtl8723be_dm_tx_power_track_set_power(struct ieee80211_hw *hw,
0649 enum pwr_track_control_method method,
0650 u8 rfpath, u8 idx)
0651 {
0652 struct rtl_priv *rtlpriv = rtl_priv(hw);
0653 struct rtl_phy *rtlphy = &rtlpriv->phy;
0654 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
0655 u8 swing_idx_ofdm_limit = 36;
0656
0657 if (method == TXAGC) {
0658 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
0659 } else if (method == BBSWING) {
0660 if (rtldm->swing_idx_cck >= CCK_TABLE_SIZE)
0661 rtldm->swing_idx_cck = CCK_TABLE_SIZE - 1;
0662
0663 if (!rtldm->cck_inch14) {
0664 rtl_write_byte(rtlpriv, 0xa22,
0665 cckswing_table_ch1ch13[rtldm->swing_idx_cck][0]);
0666 rtl_write_byte(rtlpriv, 0xa23,
0667 cckswing_table_ch1ch13[rtldm->swing_idx_cck][1]);
0668 rtl_write_byte(rtlpriv, 0xa24,
0669 cckswing_table_ch1ch13[rtldm->swing_idx_cck][2]);
0670 rtl_write_byte(rtlpriv, 0xa25,
0671 cckswing_table_ch1ch13[rtldm->swing_idx_cck][3]);
0672 rtl_write_byte(rtlpriv, 0xa26,
0673 cckswing_table_ch1ch13[rtldm->swing_idx_cck][4]);
0674 rtl_write_byte(rtlpriv, 0xa27,
0675 cckswing_table_ch1ch13[rtldm->swing_idx_cck][5]);
0676 rtl_write_byte(rtlpriv, 0xa28,
0677 cckswing_table_ch1ch13[rtldm->swing_idx_cck][6]);
0678 rtl_write_byte(rtlpriv, 0xa29,
0679 cckswing_table_ch1ch13[rtldm->swing_idx_cck][7]);
0680 } else {
0681 rtl_write_byte(rtlpriv, 0xa22,
0682 cckswing_table_ch14[rtldm->swing_idx_cck][0]);
0683 rtl_write_byte(rtlpriv, 0xa23,
0684 cckswing_table_ch14[rtldm->swing_idx_cck][1]);
0685 rtl_write_byte(rtlpriv, 0xa24,
0686 cckswing_table_ch14[rtldm->swing_idx_cck][2]);
0687 rtl_write_byte(rtlpriv, 0xa25,
0688 cckswing_table_ch14[rtldm->swing_idx_cck][3]);
0689 rtl_write_byte(rtlpriv, 0xa26,
0690 cckswing_table_ch14[rtldm->swing_idx_cck][4]);
0691 rtl_write_byte(rtlpriv, 0xa27,
0692 cckswing_table_ch14[rtldm->swing_idx_cck][5]);
0693 rtl_write_byte(rtlpriv, 0xa28,
0694 cckswing_table_ch14[rtldm->swing_idx_cck][6]);
0695 rtl_write_byte(rtlpriv, 0xa29,
0696 cckswing_table_ch14[rtldm->swing_idx_cck][7]);
0697 }
0698
0699 if (rfpath == RF90_PATH_A) {
0700 if (rtldm->swing_idx_ofdm[RF90_PATH_A] <
0701 swing_idx_ofdm_limit)
0702 swing_idx_ofdm_limit =
0703 rtldm->swing_idx_ofdm[RF90_PATH_A];
0704
0705 rtl8723be_set_iqk_matrix(hw,
0706 rtldm->swing_idx_ofdm[rfpath], rfpath,
0707 rtlphy->iqk_matrix[idx].value[0][0],
0708 rtlphy->iqk_matrix[idx].value[0][1]);
0709 } else if (rfpath == RF90_PATH_B) {
0710 if (rtldm->swing_idx_ofdm[RF90_PATH_B] <
0711 swing_idx_ofdm_limit)
0712 swing_idx_ofdm_limit =
0713 rtldm->swing_idx_ofdm[RF90_PATH_B];
0714
0715 rtl8723be_set_iqk_matrix(hw,
0716 rtldm->swing_idx_ofdm[rfpath], rfpath,
0717 rtlphy->iqk_matrix[idx].value[0][4],
0718 rtlphy->iqk_matrix[idx].value[0][5]);
0719 }
0720 } else {
0721 return;
0722 }
0723 }
0724
0725 static void rtl8723be_dm_txpower_tracking_callback_thermalmeter(
0726 struct ieee80211_hw *hw)
0727 {
0728 struct rtl_priv *rtlpriv = rtl_priv(hw);
0729 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
0730 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw));
0731 u8 thermalvalue = 0, delta, delta_lck, delta_iqk;
0732 u8 thermalvalue_avg_count = 0;
0733 u32 thermalvalue_avg = 0;
0734 int i = 0;
0735
0736 u8 ofdm_min_index = 6;
0737 u8 index_for_channel = 0;
0738
0739 static const s8 delta_swing_table_idx_tup_a[TXSCALE_TABLE_SIZE] = {
0740 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
0741 5, 6, 6, 7, 7, 8, 8, 9, 9, 9, 10,
0742 10, 11, 11, 12, 12, 13, 14, 15};
0743 static const s8 delta_swing_table_idx_tdown_a[TXSCALE_TABLE_SIZE] = {
0744 0, 0, 1, 2, 2, 2, 3, 3, 3, 4, 5,
0745 5, 6, 6, 6, 6, 7, 7, 7, 8, 8, 9,
0746 9, 10, 10, 11, 12, 13, 14, 15};
0747
0748
0749 rtlpriv->dm.txpower_trackinginit = true;
0750 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0751 "%s\n", __func__);
0752
0753 thermalvalue = (u8)rtl_get_rfreg(hw,
0754 RF90_PATH_A, RF_T_METER, 0xfc00);
0755 if (!rtlpriv->dm.txpower_track_control || thermalvalue == 0 ||
0756 rtlefuse->eeprom_thermalmeter == 0xFF)
0757 return;
0758 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0759 "Readback Thermal Meter = 0x%x pre thermal meter 0x%x eeprom_thermalmeter 0x%x\n",
0760 thermalvalue, rtldm->thermalvalue,
0761 rtlefuse->eeprom_thermalmeter);
0762
0763 if (!rtldm->thermalvalue) {
0764 rtlpriv->dm.thermalvalue_lck = thermalvalue;
0765 rtlpriv->dm.thermalvalue_iqk = thermalvalue;
0766 }
0767
0768
0769 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermalvalue;
0770 rtldm->thermalvalue_avg_index++;
0771 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8723BE)
0772 rtldm->thermalvalue_avg_index = 0;
0773
0774 for (i = 0; i < AVG_THERMAL_NUM_8723BE; i++) {
0775 if (rtldm->thermalvalue_avg[i]) {
0776 thermalvalue_avg += rtldm->thermalvalue_avg[i];
0777 thermalvalue_avg_count++;
0778 }
0779 }
0780
0781 if (thermalvalue_avg_count)
0782 thermalvalue = (u8)(thermalvalue_avg / thermalvalue_avg_count);
0783
0784
0785 delta = (thermalvalue > rtlpriv->dm.thermalvalue) ?
0786 (thermalvalue - rtlpriv->dm.thermalvalue) :
0787 (rtlpriv->dm.thermalvalue - thermalvalue);
0788 delta_lck = (thermalvalue > rtlpriv->dm.thermalvalue_lck) ?
0789 (thermalvalue - rtlpriv->dm.thermalvalue_lck) :
0790 (rtlpriv->dm.thermalvalue_lck - thermalvalue);
0791 delta_iqk = (thermalvalue > rtlpriv->dm.thermalvalue_iqk) ?
0792 (thermalvalue - rtlpriv->dm.thermalvalue_iqk) :
0793 (rtlpriv->dm.thermalvalue_iqk - thermalvalue);
0794
0795 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0796 "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",
0797 thermalvalue, rtlpriv->dm.thermalvalue,
0798 rtlefuse->eeprom_thermalmeter, delta, delta_lck, delta_iqk);
0799
0800 if (delta_lck >= IQK_THRESHOLD) {
0801 rtlpriv->dm.thermalvalue_lck = thermalvalue;
0802 rtl8723be_phy_lc_calibrate(hw);
0803 }
0804
0805
0806
0807
0808 if (delta > 0 && rtlpriv->dm.txpower_track_control) {
0809 delta = (thermalvalue > rtlefuse->eeprom_thermalmeter) ?
0810 (thermalvalue - rtlefuse->eeprom_thermalmeter) :
0811 (rtlefuse->eeprom_thermalmeter - thermalvalue);
0812
0813 if (delta >= TXSCALE_TABLE_SIZE)
0814 delta = TXSCALE_TABLE_SIZE - 1;
0815
0816
0817
0818 if (thermalvalue > rtlefuse->eeprom_thermalmeter) {
0819 rtldm->delta_power_index_last[RF90_PATH_A] =
0820 rtldm->delta_power_index[RF90_PATH_A];
0821 rtldm->delta_power_index[RF90_PATH_A] =
0822 delta_swing_table_idx_tup_a[delta];
0823 } else {
0824 rtldm->delta_power_index_last[RF90_PATH_A] =
0825 rtldm->delta_power_index[RF90_PATH_A];
0826 rtldm->delta_power_index[RF90_PATH_A] =
0827 -1 * delta_swing_table_idx_tdown_a[delta];
0828 }
0829
0830
0831 if (rtldm->delta_power_index[RF90_PATH_A] ==
0832 rtldm->delta_power_index_last[RF90_PATH_A])
0833 rtldm->power_index_offset[RF90_PATH_A] = 0;
0834 else
0835 rtldm->power_index_offset[RF90_PATH_A] =
0836 rtldm->delta_power_index[RF90_PATH_A] -
0837 rtldm->delta_power_index_last[RF90_PATH_A];
0838
0839 rtldm->ofdm_index[0] =
0840 rtldm->swing_idx_ofdm_base[RF90_PATH_A] +
0841 rtldm->power_index_offset[RF90_PATH_A];
0842 rtldm->cck_index = rtldm->swing_idx_cck_base +
0843 rtldm->power_index_offset[RF90_PATH_A];
0844
0845 rtldm->swing_idx_cck = rtldm->cck_index;
0846 rtldm->swing_idx_ofdm[0] = rtldm->ofdm_index[0];
0847
0848 if (rtldm->ofdm_index[0] > OFDM_TABLE_SIZE - 1)
0849 rtldm->ofdm_index[0] = OFDM_TABLE_SIZE - 1;
0850 else if (rtldm->ofdm_index[0] < ofdm_min_index)
0851 rtldm->ofdm_index[0] = ofdm_min_index;
0852
0853 if (rtldm->cck_index > CCK_TABLE_SIZE - 1)
0854 rtldm->cck_index = CCK_TABLE_SIZE - 1;
0855 else if (rtldm->cck_index < 0)
0856 rtldm->cck_index = 0;
0857 } else {
0858 rtldm->power_index_offset[RF90_PATH_A] = 0;
0859 }
0860
0861 if ((rtldm->power_index_offset[RF90_PATH_A] != 0) &&
0862 (rtldm->txpower_track_control)) {
0863 rtldm->done_txpower = true;
0864 rtl8723be_dm_tx_power_track_set_power(hw, BBSWING, 0,
0865 index_for_channel);
0866
0867 rtldm->swing_idx_cck_base = rtldm->swing_idx_cck;
0868 rtldm->swing_idx_ofdm_base[RF90_PATH_A] =
0869 rtldm->swing_idx_ofdm[0];
0870 rtldm->thermalvalue = thermalvalue;
0871 }
0872
0873 if (delta_iqk >= IQK_THRESHOLD) {
0874 rtldm->thermalvalue_iqk = thermalvalue;
0875 rtl8723be_phy_iq_calibrate(hw, false);
0876 }
0877
0878 rtldm->txpowercount = 0;
0879 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "end\n");
0880
0881 }
0882
0883 void rtl8723be_dm_check_txpower_tracking(struct ieee80211_hw *hw)
0884 {
0885 struct rtl_priv *rtlpriv = rtl_priv(hw);
0886
0887 if (!rtlpriv->dm.txpower_tracking)
0888 return;
0889
0890 if (!rtlpriv->dm.tm_trigger) {
0891 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER, BIT(17) | BIT(16),
0892 0x03);
0893 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0894 "Trigger 8723be Thermal Meter!!\n");
0895 rtlpriv->dm.tm_trigger = 1;
0896 return;
0897 } else {
0898 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
0899 "Schedule TxPowerTracking !!\n");
0900 rtl8723be_dm_txpower_tracking_callback_thermalmeter(hw);
0901 rtlpriv->dm.tm_trigger = 0;
0902 }
0903 }
0904
0905 static void rtl8723be_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw)
0906 {
0907 struct rtl_priv *rtlpriv = rtl_priv(hw);
0908 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
0909 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0910 struct rate_adaptive *p_ra = &rtlpriv->ra;
0911 u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m;
0912 u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra;
0913 u8 go_up_gap = 5;
0914 struct ieee80211_sta *sta = NULL;
0915
0916 if (is_hal_stop(rtlhal)) {
0917 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0918 "driver is going to unload\n");
0919 return;
0920 }
0921
0922 if (!rtlpriv->dm.useramask) {
0923 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0924 "driver does not control rate adaptive mask\n");
0925 return;
0926 }
0927
0928 if (mac->link_state == MAC80211_LINKED &&
0929 mac->opmode == NL80211_IFTYPE_STATION) {
0930 switch (p_ra->pre_ratr_state) {
0931 case DM_RATR_STA_MIDDLE:
0932 high_rssithresh_for_ra += go_up_gap;
0933 break;
0934 case DM_RATR_STA_LOW:
0935 high_rssithresh_for_ra += go_up_gap;
0936 low_rssithresh_for_ra += go_up_gap;
0937 break;
0938 default:
0939 break;
0940 }
0941
0942 if (rtlpriv->dm.undec_sm_pwdb >
0943 (long)high_rssithresh_for_ra)
0944 p_ra->ratr_state = DM_RATR_STA_HIGH;
0945 else if (rtlpriv->dm.undec_sm_pwdb >
0946 (long)low_rssithresh_for_ra)
0947 p_ra->ratr_state = DM_RATR_STA_MIDDLE;
0948 else
0949 p_ra->ratr_state = DM_RATR_STA_LOW;
0950
0951 if (p_ra->pre_ratr_state != p_ra->ratr_state) {
0952 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0953 "RSSI = %ld\n",
0954 rtlpriv->dm.undec_sm_pwdb);
0955 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0956 "RSSI_LEVEL = %d\n", p_ra->ratr_state);
0957 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD,
0958 "PreState = %d, CurState = %d\n",
0959 p_ra->pre_ratr_state, p_ra->ratr_state);
0960
0961 rcu_read_lock();
0962 sta = rtl_find_sta(hw, mac->bssid);
0963 if (sta)
0964 rtlpriv->cfg->ops->update_rate_tbl(hw, sta,
0965 p_ra->ratr_state,
0966 true);
0967 rcu_read_unlock();
0968
0969 p_ra->pre_ratr_state = p_ra->ratr_state;
0970 }
0971 }
0972 }
0973
0974 static bool rtl8723be_dm_is_edca_turbo_disable(struct ieee80211_hw *hw)
0975 {
0976 struct rtl_priv *rtlpriv = rtl_priv(hw);
0977
0978 if (rtlpriv->mac80211.mode == WIRELESS_MODE_B)
0979 return true;
0980
0981 return false;
0982 }
0983
0984 static void rtl8723be_dm_check_edca_turbo(struct ieee80211_hw *hw)
0985 {
0986 struct rtl_priv *rtlpriv = rtl_priv(hw);
0987 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
0988
0989 static u64 last_txok_cnt;
0990 static u64 last_rxok_cnt;
0991 u64 cur_txok_cnt = 0;
0992 u64 cur_rxok_cnt = 0;
0993 u32 edca_be_ul = 0x6ea42b;
0994 u32 edca_be_dl = 0x6ea42b;
0995 u32 edca_be = 0x5ea42b;
0996 u32 iot_peer = 0;
0997 bool b_is_cur_rdlstate;
0998 bool b_bias_on_rx = false;
0999 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
1040 exit:
1041 rtlpriv->dm.is_any_nonbepkts = false;
1042 last_txok_cnt = rtlpriv->stats.txbytesunicast;
1043 last_rxok_cnt = rtlpriv->stats.rxbytesunicast;
1044 }
1045
1046 static 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
1080 static 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
1107 static 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
1210 static 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
1238 void 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 }