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