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 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 441 "AP Client PWDB = 0x%lx\n", 442 rtlpriv->dm.entry_min_undec_sm_pwdb); 443 } else { 444 rtl_dm_dig->min_undec_pwdb_for_dm = 445 rtlpriv->dm.undec_sm_pwdb; 446 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 447 "STA Default Port PWDB = 0x%x\n", 448 rtl_dm_dig->min_undec_pwdb_for_dm); 449 } 450 } else { 451 rtl_dm_dig->min_undec_pwdb_for_dm = 452 rtlpriv->dm.entry_min_undec_sm_pwdb; 453 rtl_dbg(rtlpriv, COMP_BB_POWERSAVING, DBG_LOUD, 454 "AP Ext Port or disconnect PWDB = 0x%x\n", 455 rtl_dm_dig->min_undec_pwdb_for_dm); 456 } 457 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 458 "MinUndecoratedPWDBForDM =%d\n", 459 rtl_dm_dig->min_undec_pwdb_for_dm); 460 } 461 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 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "\n"); 630 631 if (mac->act_scanning) { 632 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 633 "Return: In Scan Progress\n"); 634 return; 635 } 636 637 /*add by Neil Chen to avoid PSD is processing*/ 638 dig_min_0 = dm_digtable->dig_min_0; 639 first_connect = (mac->link_state >= MAC80211_LINKED) && 640 (!dm_digtable->media_connect_0); 641 first_disconnect = (mac->link_state < MAC80211_LINKED) && 642 (dm_digtable->media_connect_0); 643 644 /*1 Boundary Decision*/ 645 646 dm_dig_max = 0x5A; 647 648 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE) 649 dm_dig_min = DM_DIG_MIN; 650 else 651 dm_dig_min = 0x1C; 652 653 dig_max_of_min = DM_DIG_MAX_AP; 654 655 if (mac->link_state >= MAC80211_LINKED) { 656 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8821AE) 657 offset = 20; 658 else 659 offset = 10; 660 661 if ((dm_digtable->rssi_val_min + offset) > dm_dig_max) 662 dm_digtable->rx_gain_max = dm_dig_max; 663 else if ((dm_digtable->rssi_val_min + offset) < dm_dig_min) 664 dm_digtable->rx_gain_max = dm_dig_min; 665 else 666 dm_digtable->rx_gain_max = 667 dm_digtable->rssi_val_min + offset; 668 669 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 670 "dm_digtable->rssi_val_min=0x%x,dm_digtable->rx_gain_max = 0x%x\n", 671 dm_digtable->rssi_val_min, 672 dm_digtable->rx_gain_max); 673 if (rtlpriv->dm.one_entry_only) { 674 offset = 0; 675 676 if (dm_digtable->rssi_val_min - offset < dm_dig_min) 677 dig_min_0 = dm_dig_min; 678 else if (dm_digtable->rssi_val_min - 679 offset > dig_max_of_min) 680 dig_min_0 = dig_max_of_min; 681 else 682 dig_min_0 = 683 dm_digtable->rssi_val_min - offset; 684 685 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 686 "bOneEntryOnly=TRUE, dig_min_0=0x%x\n", 687 dig_min_0); 688 } else { 689 dig_min_0 = dm_dig_min; 690 } 691 } else { 692 dm_digtable->rx_gain_max = dm_dig_max; 693 dig_min_0 = dm_dig_min; 694 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No Link\n"); 695 } 696 697 if (rtlpriv->falsealm_cnt.cnt_all > 10000) { 698 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 699 "Abnormally false alarm case.\n"); 700 701 if (dm_digtable->large_fa_hit != 3) 702 dm_digtable->large_fa_hit++; 703 if (dm_digtable->forbidden_igi < current_igi) { 704 dm_digtable->forbidden_igi = current_igi; 705 dm_digtable->large_fa_hit = 1; 706 } 707 708 if (dm_digtable->large_fa_hit >= 3) { 709 if ((dm_digtable->forbidden_igi + 1) > 710 dm_digtable->rx_gain_max) 711 dm_digtable->rx_gain_min = 712 dm_digtable->rx_gain_max; 713 else 714 dm_digtable->rx_gain_min = 715 (dm_digtable->forbidden_igi + 1); 716 dm_digtable->recover_cnt = 3600; 717 } 718 } else { 719 /*Recovery mechanism for IGI lower bound*/ 720 if (dm_digtable->recover_cnt != 0) { 721 dm_digtable->recover_cnt--; 722 } else { 723 if (dm_digtable->large_fa_hit < 3) { 724 if ((dm_digtable->forbidden_igi - 1) < 725 dig_min_0) { 726 dm_digtable->forbidden_igi = 727 dig_min_0; 728 dm_digtable->rx_gain_min = 729 dig_min_0; 730 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 731 "Normal Case: At Lower Bound\n"); 732 } else { 733 dm_digtable->forbidden_igi--; 734 dm_digtable->rx_gain_min = 735 (dm_digtable->forbidden_igi + 1); 736 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 737 "Normal Case: Approach Lower Bound\n"); 738 } 739 } else { 740 dm_digtable->large_fa_hit = 0; 741 } 742 } 743 } 744 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 745 "pDM_DigTable->LargeFAHit=%d\n", 746 dm_digtable->large_fa_hit); 747 748 if (rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) 749 dm_digtable->rx_gain_min = dm_dig_min; 750 751 if (dm_digtable->rx_gain_min > dm_digtable->rx_gain_max) 752 dm_digtable->rx_gain_min = dm_digtable->rx_gain_max; 753 754 /*Adjust initial gain by false alarm*/ 755 if (mac->link_state >= MAC80211_LINKED) { 756 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 757 "DIG AfterLink\n"); 758 if (first_connect) { 759 if (dm_digtable->rssi_val_min <= dig_max_of_min) 760 current_igi = dm_digtable->rssi_val_min; 761 else 762 current_igi = dig_max_of_min; 763 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 764 "First Connect\n"); 765 } else { 766 if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH2) 767 current_igi = current_igi + 4; 768 else if (rtlpriv->falsealm_cnt.cnt_all > DM_DIG_FA_TH1) 769 current_igi = current_igi + 2; 770 else if (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH0) 771 current_igi = current_igi - 2; 772 773 if ((rtlpriv->dm.dbginfo.num_qry_beacon_pkt < 10) && 774 (rtlpriv->falsealm_cnt.cnt_all < DM_DIG_FA_TH1)) { 775 current_igi = dm_digtable->rx_gain_min; 776 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 777 "Beacon is less than 10 and FA is less than 768, IGI GOES TO 0x1E!!!!!!!!!!!!\n"); 778 } 779 } 780 } else { 781 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 782 "DIG BeforeLink\n"); 783 if (first_disconnect) { 784 current_igi = dm_digtable->rx_gain_min; 785 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 786 "First DisConnect\n"); 787 } else { 788 /* 2012.03.30 LukeLee: enable DIG before 789 * link but with very high thresholds 790 */ 791 if (rtlpriv->falsealm_cnt.cnt_all > 2000) 792 current_igi = current_igi + 4; 793 else if (rtlpriv->falsealm_cnt.cnt_all > 600) 794 current_igi = current_igi + 2; 795 else if (rtlpriv->falsealm_cnt.cnt_all < 300) 796 current_igi = current_igi - 2; 797 798 if (current_igi >= 0x3e) 799 current_igi = 0x3e; 800 801 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "England DIG\n"); 802 } 803 } 804 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 805 "DIG End Adjust IGI\n"); 806 /* Check initial gain by upper/lower bound*/ 807 808 if (current_igi > dm_digtable->rx_gain_max) 809 current_igi = dm_digtable->rx_gain_max; 810 if (current_igi < dm_digtable->rx_gain_min) 811 current_igi = dm_digtable->rx_gain_min; 812 813 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 814 "rx_gain_max=0x%x, rx_gain_min=0x%x\n", 815 dm_digtable->rx_gain_max, dm_digtable->rx_gain_min); 816 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 817 "TotalFA=%d\n", rtlpriv->falsealm_cnt.cnt_all); 818 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 819 "CurIGValue=0x%x\n", current_igi); 820 821 rtl8821ae_dm_write_dig(hw, current_igi); 822 dm_digtable->media_connect_0 = 823 ((mac->link_state >= MAC80211_LINKED) ? true : false); 824 dm_digtable->dig_min_0 = dig_min_0; 825 } 826 827 static void rtl8821ae_dm_common_info_self_update(struct ieee80211_hw *hw) 828 { 829 struct rtl_priv *rtlpriv = rtl_priv(hw); 830 u8 cnt = 0; 831 struct rtl_sta_info *drv_priv; 832 833 rtlpriv->dm.tx_rate = 0xff; 834 835 rtlpriv->dm.one_entry_only = false; 836 837 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_STATION && 838 rtlpriv->mac80211.link_state >= MAC80211_LINKED) { 839 rtlpriv->dm.one_entry_only = true; 840 return; 841 } 842 843 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP || 844 rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC || 845 rtlpriv->mac80211.opmode == NL80211_IFTYPE_MESH_POINT) { 846 spin_lock_bh(&rtlpriv->locks.entry_list_lock); 847 list_for_each_entry(drv_priv, &rtlpriv->entry_list, list) 848 cnt++; 849 spin_unlock_bh(&rtlpriv->locks.entry_list_lock); 850 851 if (cnt == 1) 852 rtlpriv->dm.one_entry_only = true; 853 } 854 } 855 856 static void rtl8821ae_dm_false_alarm_counter_statistics(struct ieee80211_hw *hw) 857 { 858 struct rtl_priv *rtlpriv = rtl_priv(hw); 859 struct false_alarm_statistics *falsealm_cnt = &rtlpriv->falsealm_cnt; 860 u32 cck_enable = 0; 861 862 /*read OFDM FA counter*/ 863 falsealm_cnt->cnt_ofdm_fail = 864 rtl_get_bbreg(hw, ODM_REG_OFDM_FA_11AC, BMASKLWORD); 865 falsealm_cnt->cnt_cck_fail = 866 rtl_get_bbreg(hw, ODM_REG_CCK_FA_11AC, BMASKLWORD); 867 868 cck_enable = rtl_get_bbreg(hw, ODM_REG_BB_RX_PATH_11AC, BIT(28)); 869 if (cck_enable) /*if(pDM_Odm->pBandType == ODM_BAND_2_4G)*/ 870 falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail + 871 falsealm_cnt->cnt_cck_fail; 872 else 873 falsealm_cnt->cnt_all = falsealm_cnt->cnt_ofdm_fail; 874 875 /*reset OFDM FA coutner*/ 876 rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 1); 877 rtl_set_bbreg(hw, ODM_REG_OFDM_FA_RST_11AC, BIT(17), 0); 878 /* reset CCK FA counter*/ 879 rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 0); 880 rtl_set_bbreg(hw, ODM_REG_CCK_FA_RST_11AC, BIT(15), 1); 881 882 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Cnt_Cck_fail=%d\n", 883 falsealm_cnt->cnt_cck_fail); 884 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "cnt_ofdm_fail=%d\n", 885 falsealm_cnt->cnt_ofdm_fail); 886 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "Total False Alarm=%d\n", 887 falsealm_cnt->cnt_all); 888 } 889 890 static void rtl8812ae_dm_check_txpower_tracking_thermalmeter( 891 struct ieee80211_hw *hw) 892 { 893 struct rtl_priv *rtlpriv = rtl_priv(hw); 894 895 if (!rtlpriv->dm.tm_trigger) { 896 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, 897 BIT(17) | BIT(16), 0x03); 898 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 899 "Trigger 8812 Thermal Meter!!\n"); 900 rtlpriv->dm.tm_trigger = 1; 901 return; 902 } 903 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 904 "Schedule TxPowerTracking direct call!!\n"); 905 rtl8812ae_dm_txpower_tracking_callback_thermalmeter(hw); 906 } 907 908 static void rtl8821ae_dm_iq_calibrate(struct ieee80211_hw *hw) 909 { 910 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 911 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 912 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 913 914 if (mac->link_state >= MAC80211_LINKED) { 915 if (rtldm->linked_interval < 3) 916 rtldm->linked_interval++; 917 918 if (rtldm->linked_interval == 2) { 919 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 920 rtl8812ae_phy_iq_calibrate(hw, false); 921 else 922 rtl8821ae_phy_iq_calibrate(hw, false); 923 } 924 } else { 925 rtldm->linked_interval = 0; 926 } 927 } 928 929 static void rtl8812ae_get_delta_swing_table(struct ieee80211_hw *hw, 930 const u8 **up_a, 931 const u8 **down_a, 932 const u8 **up_b, 933 const u8 **down_b) 934 { 935 struct rtl_priv *rtlpriv = rtl_priv(hw); 936 struct rtl_phy *rtlphy = &rtlpriv->phy; 937 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 938 u8 channel = rtlphy->current_channel; 939 u8 rate = rtldm->tx_rate; 940 941 if (1 <= channel && channel <= 14) { 942 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) { 943 *up_a = rtl8812ae_delta_swing_table_idx_24gccka_p; 944 *down_a = rtl8812ae_delta_swing_table_idx_24gccka_n; 945 *up_b = rtl8812ae_delta_swing_table_idx_24gcckb_p; 946 *down_b = rtl8812ae_delta_swing_table_idx_24gcckb_n; 947 } else { 948 *up_a = rtl8812ae_delta_swing_table_idx_24ga_p; 949 *down_a = rtl8812ae_delta_swing_table_idx_24ga_n; 950 *up_b = rtl8812ae_delta_swing_table_idx_24gb_p; 951 *down_b = rtl8812ae_delta_swing_table_idx_24gb_n; 952 } 953 } else if (36 <= channel && channel <= 64) { 954 *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[0]; 955 *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[0]; 956 *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[0]; 957 *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[0]; 958 } else if (100 <= channel && channel <= 140) { 959 *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[1]; 960 *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[1]; 961 *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[1]; 962 *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[1]; 963 } else if (149 <= channel && channel <= 173) { 964 *up_a = rtl8812ae_delta_swing_table_idx_5ga_p[2]; 965 *down_a = rtl8812ae_delta_swing_table_idx_5ga_n[2]; 966 *up_b = rtl8812ae_delta_swing_table_idx_5gb_p[2]; 967 *down_b = rtl8812ae_delta_swing_table_idx_5gb_n[2]; 968 } else { 969 *up_a = rtl8818e_delta_swing_table_idx_24gb_p; 970 *down_a = rtl8818e_delta_swing_table_idx_24gb_n; 971 *up_b = rtl8818e_delta_swing_table_idx_24gb_p; 972 *down_b = rtl8818e_delta_swing_table_idx_24gb_n; 973 } 974 } 975 976 void rtl8821ae_dm_update_init_rate(struct ieee80211_hw *hw, u8 rate) 977 { 978 struct rtl_priv *rtlpriv = rtl_priv(hw); 979 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 980 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 981 u8 p = 0; 982 983 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 984 "Get C2H Command! Rate=0x%x\n", rate); 985 986 rtldm->tx_rate = rate; 987 988 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 989 rtl8821ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, RF90_PATH_A, 0); 990 } else { 991 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 992 rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, p, 0); 993 } 994 } 995 996 u8 rtl8821ae_hw_rate_to_mrate(struct ieee80211_hw *hw, u8 rate) 997 { 998 struct rtl_priv *rtlpriv = rtl_priv(hw); 999 u8 ret_rate = MGN_1M; 1000 1001 switch (rate) { 1002 case DESC_RATE1M: 1003 ret_rate = MGN_1M; 1004 break; 1005 case DESC_RATE2M: 1006 ret_rate = MGN_2M; 1007 break; 1008 case DESC_RATE5_5M: 1009 ret_rate = MGN_5_5M; 1010 break; 1011 case DESC_RATE11M: 1012 ret_rate = MGN_11M; 1013 break; 1014 case DESC_RATE6M: 1015 ret_rate = MGN_6M; 1016 break; 1017 case DESC_RATE9M: 1018 ret_rate = MGN_9M; 1019 break; 1020 case DESC_RATE12M: 1021 ret_rate = MGN_12M; 1022 break; 1023 case DESC_RATE18M: 1024 ret_rate = MGN_18M; 1025 break; 1026 case DESC_RATE24M: 1027 ret_rate = MGN_24M; 1028 break; 1029 case DESC_RATE36M: 1030 ret_rate = MGN_36M; 1031 break; 1032 case DESC_RATE48M: 1033 ret_rate = MGN_48M; 1034 break; 1035 case DESC_RATE54M: 1036 ret_rate = MGN_54M; 1037 break; 1038 case DESC_RATEMCS0: 1039 ret_rate = MGN_MCS0; 1040 break; 1041 case DESC_RATEMCS1: 1042 ret_rate = MGN_MCS1; 1043 break; 1044 case DESC_RATEMCS2: 1045 ret_rate = MGN_MCS2; 1046 break; 1047 case DESC_RATEMCS3: 1048 ret_rate = MGN_MCS3; 1049 break; 1050 case DESC_RATEMCS4: 1051 ret_rate = MGN_MCS4; 1052 break; 1053 case DESC_RATEMCS5: 1054 ret_rate = MGN_MCS5; 1055 break; 1056 case DESC_RATEMCS6: 1057 ret_rate = MGN_MCS6; 1058 break; 1059 case DESC_RATEMCS7: 1060 ret_rate = MGN_MCS7; 1061 break; 1062 case DESC_RATEMCS8: 1063 ret_rate = MGN_MCS8; 1064 break; 1065 case DESC_RATEMCS9: 1066 ret_rate = MGN_MCS9; 1067 break; 1068 case DESC_RATEMCS10: 1069 ret_rate = MGN_MCS10; 1070 break; 1071 case DESC_RATEMCS11: 1072 ret_rate = MGN_MCS11; 1073 break; 1074 case DESC_RATEMCS12: 1075 ret_rate = MGN_MCS12; 1076 break; 1077 case DESC_RATEMCS13: 1078 ret_rate = MGN_MCS13; 1079 break; 1080 case DESC_RATEMCS14: 1081 ret_rate = MGN_MCS14; 1082 break; 1083 case DESC_RATEMCS15: 1084 ret_rate = MGN_MCS15; 1085 break; 1086 case DESC_RATEVHT1SS_MCS0: 1087 ret_rate = MGN_VHT1SS_MCS0; 1088 break; 1089 case DESC_RATEVHT1SS_MCS1: 1090 ret_rate = MGN_VHT1SS_MCS1; 1091 break; 1092 case DESC_RATEVHT1SS_MCS2: 1093 ret_rate = MGN_VHT1SS_MCS2; 1094 break; 1095 case DESC_RATEVHT1SS_MCS3: 1096 ret_rate = MGN_VHT1SS_MCS3; 1097 break; 1098 case DESC_RATEVHT1SS_MCS4: 1099 ret_rate = MGN_VHT1SS_MCS4; 1100 break; 1101 case DESC_RATEVHT1SS_MCS5: 1102 ret_rate = MGN_VHT1SS_MCS5; 1103 break; 1104 case DESC_RATEVHT1SS_MCS6: 1105 ret_rate = MGN_VHT1SS_MCS6; 1106 break; 1107 case DESC_RATEVHT1SS_MCS7: 1108 ret_rate = MGN_VHT1SS_MCS7; 1109 break; 1110 case DESC_RATEVHT1SS_MCS8: 1111 ret_rate = MGN_VHT1SS_MCS8; 1112 break; 1113 case DESC_RATEVHT1SS_MCS9: 1114 ret_rate = MGN_VHT1SS_MCS9; 1115 break; 1116 case DESC_RATEVHT2SS_MCS0: 1117 ret_rate = MGN_VHT2SS_MCS0; 1118 break; 1119 case DESC_RATEVHT2SS_MCS1: 1120 ret_rate = MGN_VHT2SS_MCS1; 1121 break; 1122 case DESC_RATEVHT2SS_MCS2: 1123 ret_rate = MGN_VHT2SS_MCS2; 1124 break; 1125 case DESC_RATEVHT2SS_MCS3: 1126 ret_rate = MGN_VHT2SS_MCS3; 1127 break; 1128 case DESC_RATEVHT2SS_MCS4: 1129 ret_rate = MGN_VHT2SS_MCS4; 1130 break; 1131 case DESC_RATEVHT2SS_MCS5: 1132 ret_rate = MGN_VHT2SS_MCS5; 1133 break; 1134 case DESC_RATEVHT2SS_MCS6: 1135 ret_rate = MGN_VHT2SS_MCS6; 1136 break; 1137 case DESC_RATEVHT2SS_MCS7: 1138 ret_rate = MGN_VHT2SS_MCS7; 1139 break; 1140 case DESC_RATEVHT2SS_MCS8: 1141 ret_rate = MGN_VHT2SS_MCS8; 1142 break; 1143 case DESC_RATEVHT2SS_MCS9: 1144 ret_rate = MGN_VHT2SS_MCS9; 1145 break; 1146 default: 1147 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1148 "HwRateToMRate8812(): Non supported Rate [%x]!!!\n", 1149 rate); 1150 break; 1151 } 1152 return ret_rate; 1153 } 1154 1155 /*----------------------------------------------------------------------------- 1156 * Function: odm_TxPwrTrackSetPwr88E() 1157 * 1158 * Overview: 88E change all channel tx power accordign to flag. 1159 * OFDM & CCK are all different. 1160 * 1161 * Input: NONE 1162 * 1163 * Output: NONE 1164 * 1165 * Return: NONE 1166 * 1167 * Revised History: 1168 * When Who Remark 1169 * 04/23/2012 MHC Create Version 0. 1170 * 1171 *--------------------------------------------------------------------------- 1172 */ 1173 void rtl8812ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, 1174 enum pwr_track_control_method method, 1175 u8 rf_path, u8 channel_mapped_index) 1176 { 1177 struct rtl_priv *rtlpriv = rtl_priv(hw); 1178 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 1179 struct rtl_phy *rtlphy = &rtlpriv->phy; 1180 u32 final_swing_idx[2]; 1181 u8 pwr_tracking_limit = 26; /*+1.0dB*/ 1182 u8 tx_rate = 0xFF; 1183 s8 final_ofdm_swing_index = 0; 1184 1185 if (rtldm->tx_rate != 0xFF) 1186 tx_rate = 1187 rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate); 1188 1189 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1190 "===>%s\n", __func__); 1191 /*20130429 Mimic Modify High Rate BBSwing Limit.*/ 1192 if (tx_rate != 0xFF) { 1193 /*CCK*/ 1194 if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M)) 1195 pwr_tracking_limit = 32; /*+4dB*/ 1196 /*OFDM*/ 1197 else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M)) 1198 pwr_tracking_limit = 30; /*+3dB*/ 1199 else if (tx_rate == MGN_54M) 1200 pwr_tracking_limit = 28; /*+2dB*/ 1201 /*HT*/ 1202 /*QPSK/BPSK*/ 1203 else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) 1204 pwr_tracking_limit = 34; /*+5dB*/ 1205 /*16QAM*/ 1206 else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) 1207 pwr_tracking_limit = 30; /*+3dB*/ 1208 /*64QAM*/ 1209 else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) 1210 pwr_tracking_limit = 28; /*+2dB*/ 1211 /*QPSK/BPSK*/ 1212 else if ((tx_rate >= MGN_MCS8) && (tx_rate <= MGN_MCS10)) 1213 pwr_tracking_limit = 34; /*+5dB*/ 1214 /*16QAM*/ 1215 else if ((tx_rate >= MGN_MCS11) && (tx_rate <= MGN_MCS12)) 1216 pwr_tracking_limit = 30; /*+3dB*/ 1217 /*64QAM*/ 1218 else if ((tx_rate >= MGN_MCS13) && (tx_rate <= MGN_MCS15)) 1219 pwr_tracking_limit = 28; /*+2dB*/ 1220 1221 /*2 VHT*/ 1222 /*QPSK/BPSK*/ 1223 else if ((tx_rate >= MGN_VHT1SS_MCS0) && 1224 (tx_rate <= MGN_VHT1SS_MCS2)) 1225 pwr_tracking_limit = 34; /*+5dB*/ 1226 /*16QAM*/ 1227 else if ((tx_rate >= MGN_VHT1SS_MCS3) && 1228 (tx_rate <= MGN_VHT1SS_MCS4)) 1229 pwr_tracking_limit = 30; /*+3dB*/ 1230 /*64QAM*/ 1231 else if ((tx_rate >= MGN_VHT1SS_MCS5) && 1232 (tx_rate <= MGN_VHT1SS_MCS6)) 1233 pwr_tracking_limit = 28; /*+2dB*/ 1234 else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/ 1235 pwr_tracking_limit = 26; /*+1dB*/ 1236 else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/ 1237 pwr_tracking_limit = 24; /*+0dB*/ 1238 else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/ 1239 pwr_tracking_limit = 22; /*-1dB*/ 1240 /*QPSK/BPSK*/ 1241 else if ((tx_rate >= MGN_VHT2SS_MCS0) && 1242 (tx_rate <= MGN_VHT2SS_MCS2)) 1243 pwr_tracking_limit = 34; /*+5dB*/ 1244 /*16QAM*/ 1245 else if ((tx_rate >= MGN_VHT2SS_MCS3) && 1246 (tx_rate <= MGN_VHT2SS_MCS4)) 1247 pwr_tracking_limit = 30; /*+3dB*/ 1248 /*64QAM*/ 1249 else if ((tx_rate >= MGN_VHT2SS_MCS5) && 1250 (tx_rate <= MGN_VHT2SS_MCS6)) 1251 pwr_tracking_limit = 28; /*+2dB*/ 1252 else if (tx_rate == MGN_VHT2SS_MCS7) /*64QAM*/ 1253 pwr_tracking_limit = 26; /*+1dB*/ 1254 else if (tx_rate == MGN_VHT2SS_MCS8) /*256QAM*/ 1255 pwr_tracking_limit = 24; /*+0dB*/ 1256 else if (tx_rate == MGN_VHT2SS_MCS9) /*256QAM*/ 1257 pwr_tracking_limit = 22; /*-1dB*/ 1258 else 1259 pwr_tracking_limit = 24; 1260 } 1261 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1262 "TxRate=0x%x, PwrTrackingLimit=%d\n", 1263 tx_rate, pwr_tracking_limit); 1264 1265 if (method == BBSWING) { 1266 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1267 "===>%s\n", __func__); 1268 1269 if (rf_path == RF90_PATH_A) { 1270 u32 tmp; 1271 1272 final_swing_idx[RF90_PATH_A] = 1273 (rtldm->ofdm_index[RF90_PATH_A] > 1274 pwr_tracking_limit) ? 1275 pwr_tracking_limit : 1276 rtldm->ofdm_index[RF90_PATH_A]; 1277 tmp = final_swing_idx[RF90_PATH_A]; 1278 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1279 "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n", 1280 rtldm->ofdm_index[RF90_PATH_A], 1281 final_swing_idx[RF90_PATH_A]); 1282 1283 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 1284 txscaling_tbl[tmp]); 1285 } else { 1286 u32 tmp; 1287 1288 final_swing_idx[RF90_PATH_B] = 1289 rtldm->ofdm_index[RF90_PATH_B] > 1290 pwr_tracking_limit ? 1291 pwr_tracking_limit : 1292 rtldm->ofdm_index[RF90_PATH_B]; 1293 tmp = final_swing_idx[RF90_PATH_B]; 1294 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1295 "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_B]=%d, pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_B]=%d\n", 1296 rtldm->ofdm_index[RF90_PATH_B], 1297 final_swing_idx[RF90_PATH_B]); 1298 1299 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 1300 txscaling_tbl[tmp]); 1301 } 1302 } else if (method == MIX_MODE) { 1303 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1304 "pDM_Odm->DefaultOfdmIndex=%d, pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", 1305 rtldm->default_ofdm_index, 1306 rtldm->absolute_ofdm_swing_idx[rf_path], 1307 rf_path); 1308 1309 final_ofdm_swing_index = rtldm->default_ofdm_index + 1310 rtldm->absolute_ofdm_swing_idx[rf_path]; 1311 1312 if (rf_path == RF90_PATH_A) { 1313 /*BBSwing higher then Limit*/ 1314 if (final_ofdm_swing_index > pwr_tracking_limit) { 1315 rtldm->remnant_cck_idx = 1316 final_ofdm_swing_index - 1317 pwr_tracking_limit; 1318 /* CCK Follow the same compensation value 1319 * as Path A 1320 */ 1321 rtldm->remnant_ofdm_swing_idx[rf_path] = 1322 final_ofdm_swing_index - 1323 pwr_tracking_limit; 1324 1325 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 1326 txscaling_tbl[pwr_tracking_limit]); 1327 1328 rtldm->modify_txagc_flag_path_a = true; 1329 1330 /*Set TxAGC Page C{};*/ 1331 rtl8821ae_phy_set_txpower_level_by_path(hw, 1332 rtlphy->current_channel, 1333 RF90_PATH_A); 1334 1335 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1336 "******Path_A Over BBSwing Limit ,PwrTrackingLimit = %d ,Remnant TxAGC Value = %d\n", 1337 pwr_tracking_limit, 1338 rtldm->remnant_ofdm_swing_idx[rf_path]); 1339 } else if (final_ofdm_swing_index < 0) { 1340 rtldm->remnant_cck_idx = final_ofdm_swing_index; 1341 /* CCK Follow the same compensate value as Path A*/ 1342 rtldm->remnant_ofdm_swing_idx[rf_path] = 1343 final_ofdm_swing_index; 1344 1345 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 1346 txscaling_tbl[0]); 1347 1348 rtldm->modify_txagc_flag_path_a = true; 1349 1350 /*Set TxAGC Page C{};*/ 1351 rtl8821ae_phy_set_txpower_level_by_path(hw, 1352 rtlphy->current_channel, RF90_PATH_A); 1353 1354 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1355 "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", 1356 rtldm->remnant_ofdm_swing_idx[rf_path]); 1357 } else { 1358 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 1359 txscaling_tbl[(u8)final_ofdm_swing_index]); 1360 1361 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1362 "******Path_A Compensate with BBSwing, Final_OFDM_Swing_Index = %d\n", 1363 final_ofdm_swing_index); 1364 /*If TxAGC has changed, reset TxAGC again*/ 1365 if (rtldm->modify_txagc_flag_path_a) { 1366 rtldm->remnant_cck_idx = 0; 1367 rtldm->remnant_ofdm_swing_idx[rf_path] = 0; 1368 1369 /*Set TxAGC Page C{};*/ 1370 rtl8821ae_phy_set_txpower_level_by_path(hw, 1371 rtlphy->current_channel, RF90_PATH_A); 1372 rtldm->modify_txagc_flag_path_a = false; 1373 1374 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, 1375 DBG_LOUD, 1376 "******Path_A pDM_Odm->Modify_TxAGC_Flag = FALSE\n"); 1377 } 1378 } 1379 } 1380 /*BBSwing higher then Limit*/ 1381 if (rf_path == RF90_PATH_B) { 1382 if (final_ofdm_swing_index > pwr_tracking_limit) { 1383 rtldm->remnant_ofdm_swing_idx[rf_path] = 1384 final_ofdm_swing_index - 1385 pwr_tracking_limit; 1386 1387 rtl_set_bbreg(hw, RB_TXSCALE, 1388 0xFFE00000, 1389 txscaling_tbl[pwr_tracking_limit]); 1390 1391 rtldm->modify_txagc_flag_path_b = true; 1392 1393 /*Set TxAGC Page E{};*/ 1394 rtl8821ae_phy_set_txpower_level_by_path(hw, 1395 rtlphy->current_channel, RF90_PATH_B); 1396 1397 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1398 "******Path_B Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n", 1399 pwr_tracking_limit, 1400 rtldm->remnant_ofdm_swing_idx[rf_path]); 1401 } else if (final_ofdm_swing_index < 0) { 1402 rtldm->remnant_ofdm_swing_idx[rf_path] = 1403 final_ofdm_swing_index; 1404 1405 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 1406 txscaling_tbl[0]); 1407 1408 rtldm->modify_txagc_flag_path_b = true; 1409 1410 /*Set TxAGC Page E{};*/ 1411 rtl8821ae_phy_set_txpower_level_by_path(hw, 1412 rtlphy->current_channel, RF90_PATH_B); 1413 1414 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1415 "******Path_B Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", 1416 rtldm->remnant_ofdm_swing_idx[rf_path]); 1417 } else { 1418 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 1419 txscaling_tbl[(u8)final_ofdm_swing_index]); 1420 1421 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1422 "******Path_B Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n", 1423 final_ofdm_swing_index); 1424 /*If TxAGC has changed, reset TxAGC again*/ 1425 if (rtldm->modify_txagc_flag_path_b) { 1426 rtldm->remnant_ofdm_swing_idx[rf_path] = 0; 1427 1428 /*Set TxAGC Page E{};*/ 1429 rtl8821ae_phy_set_txpower_level_by_path(hw, 1430 rtlphy->current_channel, RF90_PATH_B); 1431 1432 rtldm->modify_txagc_flag_path_b = 1433 false; 1434 1435 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1436 "******Path_B pDM_Odm->Modify_TxAGC_Flag = FALSE\n"); 1437 } 1438 } 1439 } 1440 } else { 1441 return; 1442 } 1443 } 1444 1445 void rtl8812ae_dm_txpower_tracking_callback_thermalmeter( 1446 struct ieee80211_hw *hw) 1447 { 1448 struct rtl_priv *rtlpriv = rtl_priv(hw); 1449 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 1450 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 1451 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1452 u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0; 1453 u8 thermal_value_avg_count = 0; 1454 u32 thermal_value_avg = 0; 1455 /* OFDM BB Swing should be less than +3.0dB, */ 1456 u8 ofdm_min_index = 6; 1457 /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/ 1458 u8 index_for_channel = 0; 1459 /* 1. The following TWO tables decide 1460 * the final index of OFDM/CCK swing table. 1461 */ 1462 const u8 *delta_swing_table_idx_tup_a; 1463 const u8 *delta_swing_table_idx_tdown_a; 1464 const u8 *delta_swing_table_idx_tup_b; 1465 const u8 *delta_swing_table_idx_tdown_b; 1466 1467 /*2. Initilization ( 7 steps in total )*/ 1468 rtl8812ae_get_delta_swing_table(hw, 1469 &delta_swing_table_idx_tup_a, 1470 &delta_swing_table_idx_tdown_a, 1471 &delta_swing_table_idx_tup_b, 1472 &delta_swing_table_idx_tdown_b); 1473 1474 rtldm->txpower_trackinginit = true; 1475 1476 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1477 "pDM_Odm->BbSwingIdxCckBase: %d, pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", 1478 rtldm->swing_idx_cck_base, 1479 rtldm->swing_idx_ofdm_base[RF90_PATH_A], 1480 rtldm->default_ofdm_index); 1481 1482 thermal_value = (u8)rtl_get_rfreg(hw, RF90_PATH_A, 1483 /*0x42: RF Reg[15:10] 88E*/ 1484 RF_T_METER_8812A, 0xfc00); 1485 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1486 "Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", 1487 thermal_value, rtlefuse->eeprom_thermalmeter); 1488 if (!rtldm->txpower_track_control || 1489 rtlefuse->eeprom_thermalmeter == 0 || 1490 rtlefuse->eeprom_thermalmeter == 0xFF) 1491 return; 1492 1493 /* 3. Initialize ThermalValues of RFCalibrateInfo*/ 1494 1495 if (rtlhal->reloadtxpowerindex) 1496 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1497 "reload ofdm index for band switch\n"); 1498 1499 /*4. Calculate average thermal meter*/ 1500 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value; 1501 rtldm->thermalvalue_avg_index++; 1502 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A) 1503 /*Average times = c.AverageThermalNum*/ 1504 rtldm->thermalvalue_avg_index = 0; 1505 1506 for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) { 1507 if (rtldm->thermalvalue_avg[i]) { 1508 thermal_value_avg += rtldm->thermalvalue_avg[i]; 1509 thermal_value_avg_count++; 1510 } 1511 } 1512 /*Calculate Average ThermalValue after average enough times*/ 1513 if (thermal_value_avg_count) { 1514 thermal_value = (u8)(thermal_value_avg / 1515 thermal_value_avg_count); 1516 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1517 "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", 1518 thermal_value, rtlefuse->eeprom_thermalmeter); 1519 } 1520 1521 /*5. Calculate delta, delta_LCK, delta_IQK. 1522 *"delta" here is used to determine whether 1523 *thermal value changes or not. 1524 */ 1525 delta = (thermal_value > rtldm->thermalvalue) ? 1526 (thermal_value - rtldm->thermalvalue) : 1527 (rtldm->thermalvalue - thermal_value); 1528 delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? 1529 (thermal_value - rtldm->thermalvalue_lck) : 1530 (rtldm->thermalvalue_lck - thermal_value); 1531 delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? 1532 (thermal_value - rtldm->thermalvalue_iqk) : 1533 (rtldm->thermalvalue_iqk - thermal_value); 1534 1535 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1536 "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", 1537 delta, delta_lck, delta_iqk); 1538 1539 /* 6. If necessary, do LCK. 1540 * Delta temperature is equal to or larger than 20 centigrade. 1541 */ 1542 if (delta_lck >= IQK_THRESHOLD) { 1543 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1544 "delta_LCK(%d) >= Threshold_IQK(%d)\n", 1545 delta_lck, IQK_THRESHOLD); 1546 rtldm->thermalvalue_lck = thermal_value; 1547 rtl8821ae_phy_lc_calibrate(hw); 1548 } 1549 1550 /*7. If necessary, move the index of swing table to adjust Tx power.*/ 1551 1552 if (delta > 0 && rtldm->txpower_track_control) { 1553 /* "delta" here is used to record the 1554 * absolute value of differrence. 1555 */ 1556 delta = thermal_value > rtlefuse->eeprom_thermalmeter ? 1557 (thermal_value - rtlefuse->eeprom_thermalmeter) : 1558 (rtlefuse->eeprom_thermalmeter - thermal_value); 1559 1560 if (delta >= TXPWR_TRACK_TABLE_SIZE) 1561 delta = TXPWR_TRACK_TABLE_SIZE - 1; 1562 1563 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/ 1564 1565 if (thermal_value > rtlefuse->eeprom_thermalmeter) { 1566 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1567 "delta_swing_table_idx_tup_a[%d] = %d\n", 1568 delta, delta_swing_table_idx_tup_a[delta]); 1569 rtldm->delta_power_index_last[RF90_PATH_A] = 1570 rtldm->delta_power_index[RF90_PATH_A]; 1571 rtldm->delta_power_index[RF90_PATH_A] = 1572 delta_swing_table_idx_tup_a[delta]; 1573 1574 rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 1575 delta_swing_table_idx_tup_a[delta]; 1576 /*Record delta swing for mix mode power tracking*/ 1577 1578 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1579 "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 1580 rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 1581 1582 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1583 "delta_swing_table_idx_tup_b[%d] = %d\n", 1584 delta, delta_swing_table_idx_tup_b[delta]); 1585 rtldm->delta_power_index_last[RF90_PATH_B] = 1586 rtldm->delta_power_index[RF90_PATH_B]; 1587 rtldm->delta_power_index[RF90_PATH_B] = 1588 delta_swing_table_idx_tup_b[delta]; 1589 1590 rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] = 1591 delta_swing_table_idx_tup_b[delta]; 1592 /*Record delta swing for mix mode power tracking*/ 1593 1594 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1595 "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", 1596 rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); 1597 } else { 1598 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1599 "delta_swing_table_idx_tdown_a[%d] = %d\n", 1600 delta, delta_swing_table_idx_tdown_a[delta]); 1601 1602 rtldm->delta_power_index_last[RF90_PATH_A] = 1603 rtldm->delta_power_index[RF90_PATH_A]; 1604 rtldm->delta_power_index[RF90_PATH_A] = 1605 -1 * delta_swing_table_idx_tdown_a[delta]; 1606 1607 rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 1608 -1 * delta_swing_table_idx_tdown_a[delta]; 1609 /* Record delta swing for mix mode power tracking*/ 1610 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1611 "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 1612 rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 1613 1614 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1615 "deltaSwingTableIdx_TDOWN_B[%d] = %d\n", 1616 delta, delta_swing_table_idx_tdown_b[delta]); 1617 1618 rtldm->delta_power_index_last[RF90_PATH_B] = 1619 rtldm->delta_power_index[RF90_PATH_B]; 1620 rtldm->delta_power_index[RF90_PATH_B] = 1621 -1 * delta_swing_table_idx_tdown_b[delta]; 1622 1623 rtldm->absolute_ofdm_swing_idx[RF90_PATH_B] = 1624 -1 * delta_swing_table_idx_tdown_b[delta]; 1625 /*Record delta swing for mix mode power tracking*/ 1626 1627 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1628 "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_B] = %d\n", 1629 rtldm->absolute_ofdm_swing_idx[RF90_PATH_B]); 1630 } 1631 1632 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) { 1633 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1634 "============================= [Path-%c]Calculating PowerIndexOffset =============================\n", 1635 (p == RF90_PATH_A ? 'A' : 'B')); 1636 1637 if (rtldm->delta_power_index[p] == 1638 rtldm->delta_power_index_last[p]) 1639 /*If Thermal value changes but lookup 1640 table value still the same*/ 1641 rtldm->power_index_offset[p] = 0; 1642 else 1643 rtldm->power_index_offset[p] = 1644 rtldm->delta_power_index[p] - 1645 rtldm->delta_power_index_last[p]; 1646 /* Power Index Diff between 2 1647 * times Power Tracking 1648 */ 1649 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1650 "[Path-%c] PowerIndexOffset(%d) =DeltaPowerIndex(%d) -DeltaPowerIndexLast(%d)\n", 1651 (p == RF90_PATH_A ? 'A' : 'B'), 1652 rtldm->power_index_offset[p], 1653 rtldm->delta_power_index[p], 1654 rtldm->delta_power_index_last[p]); 1655 1656 rtldm->ofdm_index[p] = 1657 rtldm->swing_idx_ofdm_base[p] + 1658 rtldm->power_index_offset[p]; 1659 rtldm->cck_index = 1660 rtldm->swing_idx_cck_base + 1661 rtldm->power_index_offset[p]; 1662 1663 rtldm->swing_idx_cck = rtldm->cck_index; 1664 rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p]; 1665 1666 /****Print BB Swing Base and Index Offset */ 1667 1668 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1669 "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", 1670 rtldm->swing_idx_cck, 1671 rtldm->swing_idx_cck_base, 1672 rtldm->power_index_offset[p]); 1673 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1674 "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n", 1675 rtldm->swing_idx_ofdm[p], 1676 (p == RF90_PATH_A ? 'A' : 'B'), 1677 rtldm->swing_idx_ofdm_base[p], 1678 rtldm->power_index_offset[p]); 1679 1680 /*7.1 Handle boundary conditions of index.*/ 1681 1682 if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1) 1683 rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1; 1684 else if (rtldm->ofdm_index[p] < ofdm_min_index) 1685 rtldm->ofdm_index[p] = ofdm_min_index; 1686 } 1687 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1688 "\n\n====================================================================================\n"); 1689 if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1) 1690 rtldm->cck_index = TXSCALE_TABLE_SIZE - 1; 1691 else if (rtldm->cck_index < 0) 1692 rtldm->cck_index = 0; 1693 } else { 1694 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1695 "The thermal meter is unchanged or TxPowerTracking OFF(%d): ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n", 1696 rtldm->txpower_track_control, 1697 thermal_value, 1698 rtldm->thermalvalue); 1699 1700 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 1701 rtldm->power_index_offset[p] = 0; 1702 } 1703 /*Print Swing base & current*/ 1704 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1705 "TxPowerTracking: [CCK] Swing Current Index: %d,Swing Base Index: %d\n", 1706 rtldm->cck_index, rtldm->swing_idx_cck_base); 1707 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) { 1708 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1709 "TxPowerTracking: [OFDM] Swing Current Index: %d,Swing Base Index[%c]: %d\n", 1710 rtldm->ofdm_index[p], 1711 (p == RF90_PATH_A ? 'A' : 'B'), 1712 rtldm->swing_idx_ofdm_base[p]); 1713 } 1714 1715 if ((rtldm->power_index_offset[RF90_PATH_A] != 0 || 1716 rtldm->power_index_offset[RF90_PATH_B] != 0) && 1717 rtldm->txpower_track_control) { 1718 /*7.2 Configure the Swing Table to adjust Tx Power. 1719 *Always TRUE after Tx Power is adjusted by power tracking. 1720 * 1721 *2012/04/23 MH According to Luke's suggestion, 1722 *we can not write BB digital 1723 *to increase TX power. Otherwise, EVM will be bad. 1724 * 1725 *2012/04/25 MH Add for tx power tracking to set 1726 *tx power in tx agc for 88E. 1727 */ 1728 if (thermal_value > rtldm->thermalvalue) { 1729 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1730 "Temperature Increasing(A): delta_pi: %d , delta_t: %d, Now_t: %d,EFUSE_t: %d, Last_t: %d\n", 1731 rtldm->power_index_offset[RF90_PATH_A], 1732 delta, thermal_value, 1733 rtlefuse->eeprom_thermalmeter, 1734 rtldm->thermalvalue); 1735 1736 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1737 "Temperature Increasing(B): delta_pi: %d ,delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 1738 rtldm->power_index_offset[RF90_PATH_B], 1739 delta, thermal_value, 1740 rtlefuse->eeprom_thermalmeter, 1741 rtldm->thermalvalue); 1742 } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/ 1743 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1744 "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 1745 rtldm->power_index_offset[RF90_PATH_A], 1746 delta, thermal_value, 1747 rtlefuse->eeprom_thermalmeter, 1748 rtldm->thermalvalue); 1749 1750 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1751 "Temperature Decreasing(B): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 1752 rtldm->power_index_offset[RF90_PATH_B], 1753 delta, thermal_value, 1754 rtlefuse->eeprom_thermalmeter, 1755 rtldm->thermalvalue); 1756 } 1757 1758 if (thermal_value > rtlefuse->eeprom_thermalmeter) { 1759 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1760 "Temperature(%d) higher than PG value(%d)\n", 1761 thermal_value, rtlefuse->eeprom_thermalmeter); 1762 1763 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1764 "**********Enter POWER Tracking MIX_MODE**********\n"); 1765 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 1766 rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, 1767 p, 0); 1768 } else { 1769 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1770 "Temperature(%d) lower than PG value(%d)\n", 1771 thermal_value, rtlefuse->eeprom_thermalmeter); 1772 1773 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1774 "**********Enter POWER Tracking MIX_MODE**********\n"); 1775 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 1776 rtl8812ae_dm_txpwr_track_set_pwr(hw, MIX_MODE, 1777 p, index_for_channel); 1778 } 1779 /*Record last time Power Tracking result as base.*/ 1780 rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; 1781 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8812A; p++) 1782 rtldm->swing_idx_ofdm_base[p] = 1783 rtldm->swing_idx_ofdm[p]; 1784 1785 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1786 "pDM_Odm->RFCalibrateInfo.ThermalValue =%d ThermalValue= %d\n", 1787 rtldm->thermalvalue, thermal_value); 1788 /*Record last Power Tracking Thermal Value*/ 1789 rtldm->thermalvalue = thermal_value; 1790 } 1791 /*Delta temperature is equal to or larger than 1792 20 centigrade (When threshold is 8).*/ 1793 if (delta_iqk >= IQK_THRESHOLD) 1794 rtl8812ae_do_iqk(hw, delta_iqk, thermal_value, 8); 1795 1796 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1797 "<===%s\n", __func__); 1798 } 1799 1800 static void rtl8821ae_get_delta_swing_table(struct ieee80211_hw *hw, 1801 const u8 **up_a, 1802 const u8 **down_a) 1803 { 1804 struct rtl_priv *rtlpriv = rtl_priv(hw); 1805 struct rtl_phy *rtlphy = &rtlpriv->phy; 1806 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 1807 u8 channel = rtlphy->current_channel; 1808 u8 rate = rtldm->tx_rate; 1809 1810 if (1 <= channel && channel <= 14) { 1811 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) { 1812 *up_a = rtl8821ae_delta_swing_table_idx_24gccka_p; 1813 *down_a = rtl8821ae_delta_swing_table_idx_24gccka_n; 1814 } else { 1815 *up_a = rtl8821ae_delta_swing_table_idx_24ga_p; 1816 *down_a = rtl8821ae_delta_swing_table_idx_24ga_n; 1817 } 1818 } else if (36 <= channel && channel <= 64) { 1819 *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[0]; 1820 *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[0]; 1821 } else if (100 <= channel && channel <= 140) { 1822 *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[1]; 1823 *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[1]; 1824 } else if (149 <= channel && channel <= 173) { 1825 *up_a = rtl8821ae_delta_swing_table_idx_5ga_p[2]; 1826 *down_a = rtl8821ae_delta_swing_table_idx_5ga_n[2]; 1827 } else { 1828 *up_a = rtl8818e_delta_swing_table_idx_24gb_p; 1829 *down_a = rtl8818e_delta_swing_table_idx_24gb_n; 1830 } 1831 return; 1832 } 1833 1834 /*----------------------------------------------------------------------------- 1835 * Function: odm_TxPwrTrackSetPwr88E() 1836 * 1837 * Overview: 88E change all channel tx power accordign to flag. 1838 * OFDM & CCK are all different. 1839 * 1840 * Input: NONE 1841 * 1842 * Output: NONE 1843 * 1844 * Return: NONE 1845 * 1846 * Revised History: 1847 * When Who Remark 1848 * 04/23/2012 MHC Create Version 0. 1849 * 1850 *--------------------------------------------------------------------------- 1851 */ 1852 void rtl8821ae_dm_txpwr_track_set_pwr(struct ieee80211_hw *hw, 1853 enum pwr_track_control_method method, 1854 u8 rf_path, u8 channel_mapped_index) 1855 { 1856 struct rtl_priv *rtlpriv = rtl_priv(hw); 1857 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 1858 struct rtl_phy *rtlphy = &rtlpriv->phy; 1859 u32 final_swing_idx[1]; 1860 u8 pwr_tracking_limit = 26; /*+1.0dB*/ 1861 u8 tx_rate = 0xFF; 1862 s8 final_ofdm_swing_index = 0; 1863 1864 if (rtldm->tx_rate != 0xFF) 1865 tx_rate = rtl8821ae_hw_rate_to_mrate(hw, rtldm->tx_rate); 1866 1867 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "===>%s\n", __func__); 1868 1869 if (tx_rate != 0xFF) { /* Mimic Modify High Rate BBSwing Limit.*/ 1870 /*CCK*/ 1871 if ((tx_rate >= MGN_1M) && (tx_rate <= MGN_11M)) 1872 pwr_tracking_limit = 32; /*+4dB*/ 1873 /*OFDM*/ 1874 else if ((tx_rate >= MGN_6M) && (tx_rate <= MGN_48M)) 1875 pwr_tracking_limit = 30; /*+3dB*/ 1876 else if (tx_rate == MGN_54M) 1877 pwr_tracking_limit = 28; /*+2dB*/ 1878 /*HT*/ 1879 /*QPSK/BPSK*/ 1880 else if ((tx_rate >= MGN_MCS0) && (tx_rate <= MGN_MCS2)) 1881 pwr_tracking_limit = 34; /*+5dB*/ 1882 /*16QAM*/ 1883 else if ((tx_rate >= MGN_MCS3) && (tx_rate <= MGN_MCS4)) 1884 pwr_tracking_limit = 30; /*+3dB*/ 1885 /*64QAM*/ 1886 else if ((tx_rate >= MGN_MCS5) && (tx_rate <= MGN_MCS7)) 1887 pwr_tracking_limit = 28; /*+2dB*/ 1888 /*2 VHT*/ 1889 /*QPSK/BPSK*/ 1890 else if ((tx_rate >= MGN_VHT1SS_MCS0) && 1891 (tx_rate <= MGN_VHT1SS_MCS2)) 1892 pwr_tracking_limit = 34; /*+5dB*/ 1893 /*16QAM*/ 1894 else if ((tx_rate >= MGN_VHT1SS_MCS3) && 1895 (tx_rate <= MGN_VHT1SS_MCS4)) 1896 pwr_tracking_limit = 30; /*+3dB*/ 1897 /*64QAM*/ 1898 else if ((tx_rate >= MGN_VHT1SS_MCS5) && 1899 (tx_rate <= MGN_VHT1SS_MCS6)) 1900 pwr_tracking_limit = 28; /*+2dB*/ 1901 else if (tx_rate == MGN_VHT1SS_MCS7) /*64QAM*/ 1902 pwr_tracking_limit = 26; /*+1dB*/ 1903 else if (tx_rate == MGN_VHT1SS_MCS8) /*256QAM*/ 1904 pwr_tracking_limit = 24; /*+0dB*/ 1905 else if (tx_rate == MGN_VHT1SS_MCS9) /*256QAM*/ 1906 pwr_tracking_limit = 22; /*-1dB*/ 1907 else 1908 pwr_tracking_limit = 24; 1909 } 1910 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1911 "TxRate=0x%x, PwrTrackingLimit=%d\n", 1912 tx_rate, pwr_tracking_limit); 1913 1914 if (method == BBSWING) { 1915 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1916 "===>%s\n", __func__); 1917 if (rf_path == RF90_PATH_A) { 1918 final_swing_idx[RF90_PATH_A] = 1919 (rtldm->ofdm_index[RF90_PATH_A] > 1920 pwr_tracking_limit) ? 1921 pwr_tracking_limit : 1922 rtldm->ofdm_index[RF90_PATH_A]; 1923 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1924 "pDM_Odm->RFCalibrateInfo.OFDM_index[ODM_RF_PATH_A]=%d,pDM_Odm->RealBbSwingIdx[ODM_RF_PATH_A]=%d\n", 1925 rtldm->ofdm_index[RF90_PATH_A], 1926 final_swing_idx[RF90_PATH_A]); 1927 1928 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 1929 txscaling_tbl[final_swing_idx[RF90_PATH_A]]); 1930 } 1931 } else if (method == MIX_MODE) { 1932 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1933 "pDM_Odm->DefaultOfdmIndex=%d,pDM_Odm->Absolute_OFDMSwingIdx[RFPath]=%d, RF_Path = %d\n", 1934 rtldm->default_ofdm_index, 1935 rtldm->absolute_ofdm_swing_idx[rf_path], 1936 rf_path); 1937 1938 final_ofdm_swing_index = 1939 rtldm->default_ofdm_index + 1940 rtldm->absolute_ofdm_swing_idx[rf_path]; 1941 /*BBSwing higher then Limit*/ 1942 if (rf_path == RF90_PATH_A) { 1943 if (final_ofdm_swing_index > pwr_tracking_limit) { 1944 rtldm->remnant_cck_idx = 1945 final_ofdm_swing_index - 1946 pwr_tracking_limit; 1947 /* CCK Follow the same compensate value as Path A*/ 1948 rtldm->remnant_ofdm_swing_idx[rf_path] = 1949 final_ofdm_swing_index - 1950 pwr_tracking_limit; 1951 1952 rtl_set_bbreg(hw, RA_TXSCALE, 1953 0xFFE00000, 1954 txscaling_tbl[pwr_tracking_limit]); 1955 1956 rtldm->modify_txagc_flag_path_a = true; 1957 1958 /*Set TxAGC Page C{};*/ 1959 rtl8821ae_phy_set_txpower_level_by_path(hw, 1960 rtlphy->current_channel, 1961 RF90_PATH_A); 1962 1963 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1964 " ******Path_A Over BBSwing Limit , PwrTrackingLimit = %d , Remnant TxAGC Value = %d\n", 1965 pwr_tracking_limit, 1966 rtldm->remnant_ofdm_swing_idx[rf_path]); 1967 } else if (final_ofdm_swing_index < 0) { 1968 rtldm->remnant_cck_idx = final_ofdm_swing_index; 1969 /* CCK Follow the same compensate value as Path A*/ 1970 rtldm->remnant_ofdm_swing_idx[rf_path] = 1971 final_ofdm_swing_index; 1972 1973 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 1974 txscaling_tbl[0]); 1975 1976 rtldm->modify_txagc_flag_path_a = true; 1977 1978 /*Set TxAGC Page C{};*/ 1979 rtl8821ae_phy_set_txpower_level_by_path(hw, 1980 rtlphy->current_channel, RF90_PATH_A); 1981 1982 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1983 "******Path_A Lower then BBSwing lower bound 0 , Remnant TxAGC Value = %d\n", 1984 rtldm->remnant_ofdm_swing_idx[rf_path]); 1985 } else { 1986 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 1987 txscaling_tbl[(u8)final_ofdm_swing_index]); 1988 1989 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 1990 "******Path_A Compensate with BBSwing ,Final_OFDM_Swing_Index = %d\n", 1991 final_ofdm_swing_index); 1992 /*If TxAGC has changed, reset TxAGC again*/ 1993 if (rtldm->modify_txagc_flag_path_a) { 1994 rtldm->remnant_cck_idx = 0; 1995 rtldm->remnant_ofdm_swing_idx[rf_path] = 0; 1996 1997 /*Set TxAGC Page C{};*/ 1998 rtl8821ae_phy_set_txpower_level_by_path(hw, 1999 rtlphy->current_channel, RF90_PATH_A); 2000 2001 rtldm->modify_txagc_flag_path_a = false; 2002 2003 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, 2004 DBG_LOUD, 2005 "******Path_A pDM_Odm->Modify_TxAGC_Flag= FALSE\n"); 2006 } 2007 } 2008 } 2009 } else { 2010 return; 2011 } 2012 } 2013 2014 void rtl8821ae_dm_txpower_tracking_callback_thermalmeter( 2015 struct ieee80211_hw *hw) 2016 { 2017 struct rtl_priv *rtlpriv = rtl_priv(hw); 2018 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 2019 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 2020 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 2021 struct rtl_phy *rtlphy = &rtlpriv->phy; 2022 2023 u8 thermal_value = 0, delta, delta_lck, delta_iqk, p = 0, i = 0; 2024 u8 thermal_value_avg_count = 0; 2025 u32 thermal_value_avg = 0; 2026 2027 u8 ofdm_min_index = 6; /*OFDM BB Swing should be less than +3.0dB */ 2028 /* GetRightChnlPlaceforIQK(pHalData->CurrentChannel)*/ 2029 u8 index_for_channel = 0; 2030 2031 /* 1. The following TWO tables decide the final 2032 * index of OFDM/CCK swing table. 2033 */ 2034 const u8 *delta_swing_table_idx_tup_a; 2035 const u8 *delta_swing_table_idx_tdown_a; 2036 2037 /*2. Initilization ( 7 steps in total )*/ 2038 rtl8821ae_get_delta_swing_table(hw, 2039 &delta_swing_table_idx_tup_a, 2040 &delta_swing_table_idx_tdown_a); 2041 2042 rtldm->txpower_trackinginit = true; 2043 2044 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2045 "===>%s,\n pDM_Odm->BbSwingIdxCckBase: %d,pDM_Odm->BbSwingIdxOfdmBase[A]:%d, pDM_Odm->DefaultOfdmIndex: %d\n", 2046 __func__, 2047 rtldm->swing_idx_cck_base, 2048 rtldm->swing_idx_ofdm_base[RF90_PATH_A], 2049 rtldm->default_ofdm_index); 2050 /*0x42: RF Reg[15:10] 88E*/ 2051 thermal_value = (u8)rtl_get_rfreg(hw, 2052 RF90_PATH_A, RF_T_METER_8812A, 0xfc00); 2053 if (!rtldm->txpower_track_control || 2054 rtlefuse->eeprom_thermalmeter == 0 || 2055 rtlefuse->eeprom_thermalmeter == 0xFF) 2056 return; 2057 2058 /* 3. Initialize ThermalValues of RFCalibrateInfo*/ 2059 2060 if (rtlhal->reloadtxpowerindex) { 2061 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2062 "reload ofdm index for band switch\n"); 2063 } 2064 2065 /*4. Calculate average thermal meter*/ 2066 rtldm->thermalvalue_avg[rtldm->thermalvalue_avg_index] = thermal_value; 2067 rtldm->thermalvalue_avg_index++; 2068 if (rtldm->thermalvalue_avg_index == AVG_THERMAL_NUM_8812A) 2069 /*Average times = c.AverageThermalNum*/ 2070 rtldm->thermalvalue_avg_index = 0; 2071 2072 for (i = 0; i < AVG_THERMAL_NUM_8812A; i++) { 2073 if (rtldm->thermalvalue_avg[i]) { 2074 thermal_value_avg += rtldm->thermalvalue_avg[i]; 2075 thermal_value_avg_count++; 2076 } 2077 } 2078 /*Calculate Average ThermalValue after average enough times*/ 2079 if (thermal_value_avg_count) { 2080 thermal_value = (u8)(thermal_value_avg / 2081 thermal_value_avg_count); 2082 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2083 "AVG Thermal Meter = 0x%X, EFUSE Thermal Base = 0x%X\n", 2084 thermal_value, rtlefuse->eeprom_thermalmeter); 2085 } 2086 2087 /*5. Calculate delta, delta_LCK, delta_IQK. 2088 *"delta" here is used to determine whether 2089 * thermal value changes or not. 2090 */ 2091 delta = (thermal_value > rtldm->thermalvalue) ? 2092 (thermal_value - rtldm->thermalvalue) : 2093 (rtldm->thermalvalue - thermal_value); 2094 delta_lck = (thermal_value > rtldm->thermalvalue_lck) ? 2095 (thermal_value - rtldm->thermalvalue_lck) : 2096 (rtldm->thermalvalue_lck - thermal_value); 2097 delta_iqk = (thermal_value > rtldm->thermalvalue_iqk) ? 2098 (thermal_value - rtldm->thermalvalue_iqk) : 2099 (rtldm->thermalvalue_iqk - thermal_value); 2100 2101 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2102 "(delta, delta_LCK, delta_IQK) = (%d, %d, %d)\n", 2103 delta, delta_lck, delta_iqk); 2104 2105 /* 6. If necessary, do LCK. */ 2106 /*Delta temperature is equal to or larger than 20 centigrade.*/ 2107 if (delta_lck >= IQK_THRESHOLD) { 2108 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2109 "delta_LCK(%d) >= Threshold_IQK(%d)\n", 2110 delta_lck, IQK_THRESHOLD); 2111 rtldm->thermalvalue_lck = thermal_value; 2112 rtl8821ae_phy_lc_calibrate(hw); 2113 } 2114 2115 /*7. If necessary, move the index of swing table to adjust Tx power.*/ 2116 2117 if (delta > 0 && rtldm->txpower_track_control) { 2118 /*"delta" here is used to record the 2119 * absolute value of differrence. 2120 */ 2121 delta = thermal_value > rtlefuse->eeprom_thermalmeter ? 2122 (thermal_value - rtlefuse->eeprom_thermalmeter) : 2123 (rtlefuse->eeprom_thermalmeter - thermal_value); 2124 2125 if (delta >= TXSCALE_TABLE_SIZE) 2126 delta = TXSCALE_TABLE_SIZE - 1; 2127 2128 /*7.1 The Final Power Index = BaseIndex + PowerIndexOffset*/ 2129 2130 if (thermal_value > rtlefuse->eeprom_thermalmeter) { 2131 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2132 "delta_swing_table_idx_tup_a[%d] = %d\n", 2133 delta, delta_swing_table_idx_tup_a[delta]); 2134 rtldm->delta_power_index_last[RF90_PATH_A] = 2135 rtldm->delta_power_index[RF90_PATH_A]; 2136 rtldm->delta_power_index[RF90_PATH_A] = 2137 delta_swing_table_idx_tup_a[delta]; 2138 2139 rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 2140 delta_swing_table_idx_tup_a[delta]; 2141 /*Record delta swing for mix mode power tracking*/ 2142 2143 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2144 "******Temp is higher and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 2145 rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 2146 } else { 2147 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2148 "delta_swing_table_idx_tdown_a[%d] = %d\n", 2149 delta, delta_swing_table_idx_tdown_a[delta]); 2150 2151 rtldm->delta_power_index_last[RF90_PATH_A] = 2152 rtldm->delta_power_index[RF90_PATH_A]; 2153 rtldm->delta_power_index[RF90_PATH_A] = 2154 -1 * delta_swing_table_idx_tdown_a[delta]; 2155 2156 rtldm->absolute_ofdm_swing_idx[RF90_PATH_A] = 2157 -1 * delta_swing_table_idx_tdown_a[delta]; 2158 /* Record delta swing for mix mode power tracking*/ 2159 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2160 "******Temp is lower and pDM_Odm->Absolute_OFDMSwingIdx[ODM_RF_PATH_A] = %d\n", 2161 rtldm->absolute_ofdm_swing_idx[RF90_PATH_A]); 2162 } 2163 2164 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) { 2165 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2166 "\n\n================================ [Path-%c]Calculating PowerIndexOffset ================================\n", 2167 (p == RF90_PATH_A ? 'A' : 'B')); 2168 /*If Thermal value changes but lookup table value 2169 * still the same 2170 */ 2171 if (rtldm->delta_power_index[p] == 2172 rtldm->delta_power_index_last[p]) 2173 2174 rtldm->power_index_offset[p] = 0; 2175 else 2176 rtldm->power_index_offset[p] = 2177 rtldm->delta_power_index[p] - 2178 rtldm->delta_power_index_last[p]; 2179 /*Power Index Diff between 2 times Power Tracking*/ 2180 2181 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2182 "[Path-%c] PowerIndexOffset(%d) = DeltaPowerIndex(%d) - DeltaPowerIndexLast(%d)\n", 2183 (p == RF90_PATH_A ? 'A' : 'B'), 2184 rtldm->power_index_offset[p], 2185 rtldm->delta_power_index[p] , 2186 rtldm->delta_power_index_last[p]); 2187 2188 rtldm->ofdm_index[p] = 2189 rtldm->swing_idx_ofdm_base[p] + 2190 rtldm->power_index_offset[p]; 2191 rtldm->cck_index = 2192 rtldm->swing_idx_cck_base + 2193 rtldm->power_index_offset[p]; 2194 2195 rtldm->swing_idx_cck = rtldm->cck_index; 2196 rtldm->swing_idx_ofdm[p] = rtldm->ofdm_index[p]; 2197 2198 /*********Print BB Swing Base and Index Offset********/ 2199 2200 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2201 "The 'CCK' final index(%d) = BaseIndex(%d) + PowerIndexOffset(%d)\n", 2202 rtldm->swing_idx_cck, 2203 rtldm->swing_idx_cck_base, 2204 rtldm->power_index_offset[p]); 2205 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2206 "The 'OFDM' final index(%d) = BaseIndex[%c](%d) + PowerIndexOffset(%d)\n", 2207 rtldm->swing_idx_ofdm[p], 2208 (p == RF90_PATH_A ? 'A' : 'B'), 2209 rtldm->swing_idx_ofdm_base[p], 2210 rtldm->power_index_offset[p]); 2211 2212 /*7.1 Handle boundary conditions of index.*/ 2213 2214 if (rtldm->ofdm_index[p] > TXSCALE_TABLE_SIZE - 1) 2215 rtldm->ofdm_index[p] = TXSCALE_TABLE_SIZE - 1; 2216 else if (rtldm->ofdm_index[p] < ofdm_min_index) 2217 rtldm->ofdm_index[p] = ofdm_min_index; 2218 } 2219 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2220 "\n\n========================================================================================================\n"); 2221 if (rtldm->cck_index > TXSCALE_TABLE_SIZE - 1) 2222 rtldm->cck_index = TXSCALE_TABLE_SIZE - 1; 2223 else if (rtldm->cck_index < 0) 2224 rtldm->cck_index = 0; 2225 } else { 2226 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2227 "The thermal meter is unchanged or TxPowerTracking OFF(%d):ThermalValue: %d , pDM_Odm->RFCalibrateInfo.ThermalValue: %d\n", 2228 rtldm->txpower_track_control, 2229 thermal_value, 2230 rtldm->thermalvalue); 2231 2232 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 2233 rtldm->power_index_offset[p] = 0; 2234 } 2235 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2236 "TxPowerTracking: [CCK] Swing Current Index: %d, Swing Base Index: %d\n", 2237 /*Print Swing base & current*/ 2238 rtldm->cck_index, rtldm->swing_idx_cck_base); 2239 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) { 2240 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2241 "TxPowerTracking: [OFDM] Swing Current Index: %d, Swing Base Index[%c]: %d\n", 2242 rtldm->ofdm_index[p], 2243 (p == RF90_PATH_A ? 'A' : 'B'), 2244 rtldm->swing_idx_ofdm_base[p]); 2245 } 2246 2247 if ((rtldm->power_index_offset[RF90_PATH_A] != 0 || 2248 rtldm->power_index_offset[RF90_PATH_B] != 0) && 2249 rtldm->txpower_track_control) { 2250 /*7.2 Configure the Swing Table to adjust Tx Power.*/ 2251 /*Always TRUE after Tx Power is adjusted by power tracking.*/ 2252 /* 2253 * 2012/04/23 MH According to Luke's suggestion, 2254 * we can not write BB digital 2255 * to increase TX power. Otherwise, EVM will be bad. 2256 * 2257 * 2012/04/25 MH Add for tx power tracking to 2258 * set tx power in tx agc for 88E. 2259 */ 2260 if (thermal_value > rtldm->thermalvalue) { 2261 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2262 "Temperature Increasing(A): delta_pi: %d , delta_t: %d,Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 2263 rtldm->power_index_offset[RF90_PATH_A], 2264 delta, thermal_value, 2265 rtlefuse->eeprom_thermalmeter, 2266 rtldm->thermalvalue); 2267 } else if (thermal_value < rtldm->thermalvalue) { /*Low temperature*/ 2268 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2269 "Temperature Decreasing(A): delta_pi: %d , delta_t: %d, Now_t: %d, EFUSE_t: %d, Last_t: %d\n", 2270 rtldm->power_index_offset[RF90_PATH_A], 2271 delta, thermal_value, 2272 rtlefuse->eeprom_thermalmeter, 2273 rtldm->thermalvalue); 2274 } 2275 2276 if (thermal_value > rtlefuse->eeprom_thermalmeter) { 2277 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2278 "Temperature(%d) higher than PG value(%d)\n", 2279 thermal_value, rtlefuse->eeprom_thermalmeter); 2280 2281 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2282 "****Enter POWER Tracking MIX_MODE****\n"); 2283 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 2284 rtl8821ae_dm_txpwr_track_set_pwr(hw, 2285 MIX_MODE, p, index_for_channel); 2286 } else { 2287 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2288 "Temperature(%d) lower than PG value(%d)\n", 2289 thermal_value, rtlefuse->eeprom_thermalmeter); 2290 2291 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2292 "*****Enter POWER Tracking MIX_MODE*****\n"); 2293 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 2294 rtl8812ae_dm_txpwr_track_set_pwr(hw, 2295 MIX_MODE, p, index_for_channel); 2296 } 2297 /*Record last time Power Tracking result as base.*/ 2298 rtldm->swing_idx_cck_base = rtldm->swing_idx_cck; 2299 for (p = RF90_PATH_A; p < MAX_PATH_NUM_8821A; p++) 2300 rtldm->swing_idx_ofdm_base[p] = rtldm->swing_idx_ofdm[p]; 2301 2302 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2303 "pDM_Odm->RFCalibrateInfo.ThermalValue = %d ThermalValue= %d\n", 2304 rtldm->thermalvalue, thermal_value); 2305 /*Record last Power Tracking Thermal Value*/ 2306 rtldm->thermalvalue = thermal_value; 2307 } 2308 /* Delta temperature is equal to or larger than 2309 * 20 centigrade (When threshold is 8). 2310 */ 2311 if (delta_iqk >= IQK_THRESHOLD) { 2312 if (!rtlphy->lck_inprogress) { 2313 spin_lock(&rtlpriv->locks.iqk_lock); 2314 rtlphy->lck_inprogress = true; 2315 spin_unlock(&rtlpriv->locks.iqk_lock); 2316 2317 rtl8821ae_do_iqk(hw, delta_iqk, thermal_value, 8); 2318 2319 spin_lock(&rtlpriv->locks.iqk_lock); 2320 rtlphy->lck_inprogress = false; 2321 spin_unlock(&rtlpriv->locks.iqk_lock); 2322 } 2323 } 2324 2325 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "<===%s\n", __func__); 2326 } 2327 2328 void rtl8821ae_dm_check_txpower_tracking_thermalmeter(struct ieee80211_hw *hw) 2329 { 2330 struct rtl_priv *rtlpriv = rtl_priv(hw); 2331 if (!rtlpriv->dm.tm_trigger) { 2332 rtl_set_rfreg(hw, RF90_PATH_A, RF_T_METER_88E, BIT(17)|BIT(16), 2333 0x03); 2334 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2335 "Trigger 8821ae Thermal Meter!!\n"); 2336 rtlpriv->dm.tm_trigger = 1; 2337 return; 2338 } else { 2339 rtl_dbg(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2340 "Schedule TxPowerTracking !!\n"); 2341 2342 rtl8821ae_dm_txpower_tracking_callback_thermalmeter(hw); 2343 rtlpriv->dm.tm_trigger = 0; 2344 } 2345 } 2346 2347 static void rtl8821ae_dm_refresh_rate_adaptive_mask(struct ieee80211_hw *hw) 2348 { 2349 struct rtl_priv *rtlpriv = rtl_priv(hw); 2350 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 2351 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 2352 struct rate_adaptive *p_ra = &rtlpriv->ra; 2353 u32 low_rssithresh_for_ra = p_ra->low2high_rssi_thresh_for_ra40m; 2354 u32 high_rssithresh_for_ra = p_ra->high_rssi_thresh_for_ra; 2355 u8 go_up_gap = 5; 2356 struct ieee80211_sta *sta = NULL; 2357 2358 if (is_hal_stop(rtlhal)) { 2359 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 2360 "driver is going to unload\n"); 2361 return; 2362 } 2363 2364 if (!rtlpriv->dm.useramask) { 2365 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 2366 "driver does not control rate adaptive mask\n"); 2367 return; 2368 } 2369 2370 if (mac->link_state == MAC80211_LINKED && 2371 mac->opmode == NL80211_IFTYPE_STATION) { 2372 switch (p_ra->pre_ratr_state) { 2373 case DM_RATR_STA_MIDDLE: 2374 high_rssithresh_for_ra += go_up_gap; 2375 break; 2376 case DM_RATR_STA_LOW: 2377 high_rssithresh_for_ra += go_up_gap; 2378 low_rssithresh_for_ra += go_up_gap; 2379 break; 2380 default: 2381 break; 2382 } 2383 2384 if (rtlpriv->dm.undec_sm_pwdb > 2385 (long)high_rssithresh_for_ra) 2386 p_ra->ratr_state = DM_RATR_STA_HIGH; 2387 else if (rtlpriv->dm.undec_sm_pwdb > 2388 (long)low_rssithresh_for_ra) 2389 p_ra->ratr_state = DM_RATR_STA_MIDDLE; 2390 else 2391 p_ra->ratr_state = DM_RATR_STA_LOW; 2392 2393 if (p_ra->pre_ratr_state != p_ra->ratr_state) { 2394 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 2395 "RSSI = %ld\n", 2396 rtlpriv->dm.undec_sm_pwdb); 2397 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 2398 "RSSI_LEVEL = %d\n", p_ra->ratr_state); 2399 rtl_dbg(rtlpriv, COMP_RATE, DBG_LOUD, 2400 "PreState = %d, CurState = %d\n", 2401 p_ra->pre_ratr_state, p_ra->ratr_state); 2402 2403 rcu_read_lock(); 2404 sta = rtl_find_sta(hw, mac->bssid); 2405 if (sta) 2406 rtlpriv->cfg->ops->update_rate_tbl(hw, 2407 sta, p_ra->ratr_state, true); 2408 rcu_read_unlock(); 2409 2410 p_ra->pre_ratr_state = p_ra->ratr_state; 2411 } 2412 } 2413 } 2414 2415 static void rtl8821ae_dm_refresh_basic_rate_mask(struct ieee80211_hw *hw) 2416 { 2417 struct rtl_priv *rtlpriv = rtl_priv(hw); 2418 struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 2419 struct rtl_mac *mac = &rtlpriv->mac80211; 2420 static u8 stage; 2421 u8 cur_stage = 0; 2422 u16 basic_rate = RRSR_1M | RRSR_2M | RRSR_5_5M | RRSR_11M | RRSR_6M; 2423 2424 if (mac->link_state < MAC80211_LINKED) 2425 cur_stage = 0; 2426 else if (dm_digtable->rssi_val_min < 25) 2427 cur_stage = 1; 2428 else if (dm_digtable->rssi_val_min > 30) 2429 cur_stage = 3; 2430 else 2431 cur_stage = 2; 2432 2433 if (cur_stage != stage) { 2434 if (cur_stage == 1) { 2435 basic_rate &= (!(basic_rate ^ mac->basic_rates)); 2436 rtlpriv->cfg->ops->set_hw_reg(hw, 2437 HW_VAR_BASIC_RATE, (u8 *)&basic_rate); 2438 } else if (cur_stage == 3 && (stage == 1 || stage == 2)) { 2439 rtlpriv->cfg->ops->set_hw_reg(hw, 2440 HW_VAR_BASIC_RATE, (u8 *)&mac->basic_rates); 2441 } 2442 } 2443 stage = cur_stage; 2444 } 2445 2446 static void rtl8821ae_dm_edca_choose_traffic_idx( 2447 struct ieee80211_hw *hw, u64 cur_tx_bytes, 2448 u64 cur_rx_bytes, bool b_bias_on_rx, 2449 bool *pb_is_cur_rdl_state) 2450 { 2451 struct rtl_priv *rtlpriv = rtl_priv(hw); 2452 2453 if (b_bias_on_rx) { 2454 if (cur_tx_bytes > (cur_rx_bytes*4)) { 2455 *pb_is_cur_rdl_state = false; 2456 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2457 "Uplink Traffic\n"); 2458 } else { 2459 *pb_is_cur_rdl_state = true; 2460 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2461 "Balance Traffic\n"); 2462 } 2463 } else { 2464 if (cur_rx_bytes > (cur_tx_bytes*4)) { 2465 *pb_is_cur_rdl_state = true; 2466 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2467 "Downlink Traffic\n"); 2468 } else { 2469 *pb_is_cur_rdl_state = false; 2470 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2471 "Balance Traffic\n"); 2472 } 2473 } 2474 return; 2475 } 2476 2477 static void rtl8821ae_dm_check_edca_turbo(struct ieee80211_hw *hw) 2478 { 2479 struct rtl_priv *rtlpriv = rtl_priv(hw); 2480 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 2481 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 2482 2483 /*Keep past Tx/Rx packet count for RT-to-RT EDCA turbo.*/ 2484 u64 cur_tx_ok_cnt = 0; 2485 u64 cur_rx_ok_cnt = 0; 2486 u32 edca_be_ul = 0x5ea42b; 2487 u32 edca_be_dl = 0x5ea42b; 2488 u32 edca_be = 0x5ea42b; 2489 u8 iot_peer = 0; 2490 bool *pb_is_cur_rdl_state = NULL; 2491 bool b_bias_on_rx = false; 2492 bool b_edca_turbo_on = false; 2493 2494 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2495 "%s=====>\n", __func__); 2496 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2497 "Original BE PARAM: 0x%x\n", 2498 rtl_read_dword(rtlpriv, DM_REG_EDCA_BE_11N)); 2499 2500 if (rtlpriv->dm.dbginfo.num_non_be_pkt > 0x100) 2501 rtlpriv->dm.is_any_nonbepkts = true; 2502 rtlpriv->dm.dbginfo.num_non_be_pkt = 0; 2503 2504 /*=============================== 2505 * list paramter for different platform 2506 *=============================== 2507 */ 2508 pb_is_cur_rdl_state = &rtlpriv->dm.is_cur_rdlstate; 2509 2510 cur_tx_ok_cnt = rtlpriv->stats.txbytesunicast - rtldm->last_tx_ok_cnt; 2511 cur_rx_ok_cnt = rtlpriv->stats.rxbytesunicast - rtldm->last_rx_ok_cnt; 2512 2513 rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast; 2514 rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast; 2515 2516 iot_peer = rtlpriv->mac80211.vendor; 2517 b_bias_on_rx = false; 2518 b_edca_turbo_on = ((!rtlpriv->dm.is_any_nonbepkts) && 2519 (!rtlpriv->dm.disable_framebursting)) ? 2520 true : false; 2521 2522 if (rtlpriv->rtlhal.hw_type != HARDWARE_TYPE_RTL8812AE) { 2523 if ((iot_peer == PEER_CISCO) && 2524 (mac->mode == WIRELESS_MODE_N_24G)) { 2525 edca_be_dl = edca_setting_dl[iot_peer]; 2526 edca_be_ul = edca_setting_ul[iot_peer]; 2527 } 2528 } 2529 2530 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2531 "bIsAnyNonBEPkts : 0x%x bDisableFrameBursting : 0x%x\n", 2532 rtlpriv->dm.is_any_nonbepkts, 2533 rtlpriv->dm.disable_framebursting); 2534 2535 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2536 "bEdcaTurboOn : 0x%x bBiasOnRx : 0x%x\n", 2537 b_edca_turbo_on, b_bias_on_rx); 2538 2539 if (b_edca_turbo_on) { 2540 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2541 "curTxOkCnt : 0x%llx\n", cur_tx_ok_cnt); 2542 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2543 "curRxOkCnt : 0x%llx\n", cur_rx_ok_cnt); 2544 if (b_bias_on_rx) 2545 rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt, 2546 cur_rx_ok_cnt, true, pb_is_cur_rdl_state); 2547 else 2548 rtl8821ae_dm_edca_choose_traffic_idx(hw, cur_tx_ok_cnt, 2549 cur_rx_ok_cnt, false, pb_is_cur_rdl_state); 2550 2551 edca_be = (*pb_is_cur_rdl_state) ? edca_be_dl : edca_be_ul; 2552 2553 rtl_write_dword(rtlpriv, DM_REG_EDCA_BE_11N, edca_be); 2554 2555 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2556 "EDCA Turbo on: EDCA_BE:0x%x\n", edca_be); 2557 2558 rtlpriv->dm.current_turbo_edca = true; 2559 2560 rtl_dbg(rtlpriv, COMP_TURBO, DBG_LOUD, 2561 "EDCA_BE_DL : 0x%x EDCA_BE_UL : 0x%x EDCA_BE : 0x%x\n", 2562 edca_be_dl, edca_be_ul, edca_be); 2563 } else { 2564 if (rtlpriv->dm.current_turbo_edca) { 2565 u8 tmp = AC0_BE; 2566 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_AC_PARAM, 2567 (u8 *)(&tmp)); 2568 } 2569 rtlpriv->dm.current_turbo_edca = false; 2570 } 2571 2572 rtlpriv->dm.is_any_nonbepkts = false; 2573 rtldm->last_tx_ok_cnt = rtlpriv->stats.txbytesunicast; 2574 rtldm->last_rx_ok_cnt = rtlpriv->stats.rxbytesunicast; 2575 } 2576 2577 static void rtl8821ae_dm_cck_packet_detection_thresh(struct ieee80211_hw *hw) 2578 { 2579 struct rtl_priv *rtlpriv = rtl_priv(hw); 2580 struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 2581 u8 cur_cck_cca_thresh; 2582 2583 if (rtlpriv->mac80211.link_state >= MAC80211_LINKED) { 2584 if (dm_digtable->rssi_val_min > 25) { 2585 cur_cck_cca_thresh = 0xcd; 2586 } else if ((dm_digtable->rssi_val_min <= 25) && 2587 (dm_digtable->rssi_val_min > 10)) { 2588 cur_cck_cca_thresh = 0x83; 2589 } else { 2590 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) 2591 cur_cck_cca_thresh = 0x83; 2592 else 2593 cur_cck_cca_thresh = 0x40; 2594 } 2595 } else { 2596 if (rtlpriv->falsealm_cnt.cnt_cck_fail > 1000) 2597 cur_cck_cca_thresh = 0x83; 2598 else 2599 cur_cck_cca_thresh = 0x40; 2600 } 2601 2602 if (dm_digtable->cur_cck_cca_thres != cur_cck_cca_thresh) 2603 rtl_write_byte(rtlpriv, ODM_REG_CCK_CCA_11AC, 2604 cur_cck_cca_thresh); 2605 2606 dm_digtable->pre_cck_cca_thres = dm_digtable->cur_cck_cca_thres; 2607 dm_digtable->cur_cck_cca_thres = cur_cck_cca_thresh; 2608 rtl_dbg(rtlpriv, COMP_DIG, DBG_TRACE, 2609 "CCK cca thresh hold =%x\n", dm_digtable->cur_cck_cca_thres); 2610 } 2611 2612 static void rtl8821ae_dm_dynamic_atc_switch(struct ieee80211_hw *hw) 2613 { 2614 struct rtl_priv *rtlpriv = rtl_priv(hw); 2615 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 2616 u8 crystal_cap; 2617 u32 packet_count; 2618 int cfo_khz_a, cfo_khz_b, cfo_ave = 0, adjust_xtal = 0; 2619 int cfo_ave_diff; 2620 2621 if (rtlpriv->mac80211.link_state < MAC80211_LINKED) { 2622 /*1.Enable ATC*/ 2623 if (rtldm->atc_status == ATC_STATUS_OFF) { 2624 rtl_set_bbreg(hw, RFC_AREA, BIT(14), ATC_STATUS_ON); 2625 rtldm->atc_status = ATC_STATUS_ON; 2626 } 2627 2628 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "No link!!\n"); 2629 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 2630 "atc_status = %d\n", rtldm->atc_status); 2631 2632 if (rtldm->crystal_cap != rtlpriv->efuse.crystalcap) { 2633 rtldm->crystal_cap = rtlpriv->efuse.crystalcap; 2634 crystal_cap = rtldm->crystal_cap & 0x3f; 2635 crystal_cap = crystal_cap & 0x3f; 2636 if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) 2637 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 2638 0x7ff80000, (crystal_cap | 2639 (crystal_cap << 6))); 2640 else 2641 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 2642 0xfff000, (crystal_cap | 2643 (crystal_cap << 6))); 2644 } 2645 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, "crystal_cap = 0x%x\n", 2646 rtldm->crystal_cap); 2647 } else{ 2648 /*1. Calculate CFO for path-A & path-B*/ 2649 cfo_khz_a = (int)(rtldm->cfo_tail[0] * 3125) / 1280; 2650 cfo_khz_b = (int)(rtldm->cfo_tail[1] * 3125) / 1280; 2651 packet_count = rtldm->packet_count; 2652 2653 /*2.No new packet*/ 2654 if (packet_count == rtldm->packet_count_pre) { 2655 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 2656 "packet counter doesn't change\n"); 2657 return; 2658 } 2659 2660 rtldm->packet_count_pre = packet_count; 2661 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 2662 "packet counter = %d\n", 2663 rtldm->packet_count); 2664 2665 /*3.Average CFO*/ 2666 if (rtlpriv->phy.rf_type == RF_1T1R) 2667 cfo_ave = cfo_khz_a; 2668 else 2669 cfo_ave = (cfo_khz_a + cfo_khz_b) >> 1; 2670 2671 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 2672 "cfo_khz_a = %dkHz, cfo_khz_b = %dkHz, cfo_ave = %dkHz\n", 2673 cfo_khz_a, cfo_khz_b, cfo_ave); 2674 2675 /*4.Avoid abnormal large CFO*/ 2676 cfo_ave_diff = (rtldm->cfo_ave_pre >= cfo_ave) ? 2677 (rtldm->cfo_ave_pre - cfo_ave) : 2678 (cfo_ave - rtldm->cfo_ave_pre); 2679 2680 if (cfo_ave_diff > 20 && !rtldm->large_cfo_hit) { 2681 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 2682 "first large CFO hit\n"); 2683 rtldm->large_cfo_hit = true; 2684 return; 2685 } else 2686 rtldm->large_cfo_hit = false; 2687 2688 rtldm->cfo_ave_pre = cfo_ave; 2689 2690 /*CFO tracking by adjusting Xtal cap.*/ 2691 2692 /*1.Dynamic Xtal threshold*/ 2693 if (cfo_ave >= -rtldm->cfo_threshold && 2694 cfo_ave <= rtldm->cfo_threshold && 2695 rtldm->is_freeze == 0) { 2696 if (rtldm->cfo_threshold == CFO_THRESHOLD_XTAL) { 2697 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL + 10; 2698 rtldm->is_freeze = 1; 2699 } else { 2700 rtldm->cfo_threshold = CFO_THRESHOLD_XTAL; 2701 } 2702 } 2703 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 2704 "Dynamic threshold = %d\n", 2705 rtldm->cfo_threshold); 2706 2707 /* 2.Calculate Xtal offset*/ 2708 if (cfo_ave > rtldm->cfo_threshold && rtldm->crystal_cap < 0x3f) 2709 adjust_xtal = ((cfo_ave - CFO_THRESHOLD_XTAL) >> 2) + 1; 2710 else if ((cfo_ave < -rtlpriv->dm.cfo_threshold) && 2711 rtlpriv->dm.crystal_cap > 0) 2712 adjust_xtal = ((cfo_ave + CFO_THRESHOLD_XTAL) >> 2) - 1; 2713 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 2714 "Crystal cap = 0x%x, Crystal cap offset = %d\n", 2715 rtldm->crystal_cap, adjust_xtal); 2716 2717 /*3.Adjudt Crystal Cap.*/ 2718 if (adjust_xtal != 0) { 2719 rtldm->is_freeze = 0; 2720 rtldm->crystal_cap += adjust_xtal; 2721 2722 if (rtldm->crystal_cap > 0x3f) 2723 rtldm->crystal_cap = 0x3f; 2724 else if (rtldm->crystal_cap < 0) 2725 rtldm->crystal_cap = 0; 2726 2727 crystal_cap = rtldm->crystal_cap & 0x3f; 2728 crystal_cap = crystal_cap & 0x3f; 2729 if (rtlpriv->rtlhal.hw_type == HARDWARE_TYPE_RTL8812AE) 2730 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 2731 0x7ff80000, (crystal_cap | 2732 (crystal_cap << 6))); 2733 else 2734 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 2735 0xfff000, (crystal_cap | 2736 (crystal_cap << 6))); 2737 rtl_dbg(rtlpriv, COMP_DIG, DBG_LOUD, 2738 "New crystal cap = 0x%x\n", 2739 rtldm->crystal_cap); 2740 } 2741 } 2742 } 2743 2744 void rtl8821ae_dm_watchdog(struct ieee80211_hw *hw) 2745 { 2746 struct rtl_priv *rtlpriv = rtl_priv(hw); 2747 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 2748 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 2749 bool fw_current_inpsmode = false; 2750 bool fw_ps_awake = true; 2751 2752 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FW_PSMODE_STATUS, 2753 (u8 *)(&fw_current_inpsmode)); 2754 2755 rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_FWLPS_RF_ON, 2756 (u8 *)(&fw_ps_awake)); 2757 2758 if (ppsc->p2p_ps_info.p2p_ps_mode) 2759 fw_ps_awake = false; 2760 2761 spin_lock(&rtlpriv->locks.rf_ps_lock); 2762 if ((ppsc->rfpwr_state == ERFON) && 2763 ((!fw_current_inpsmode) && fw_ps_awake) && 2764 (!ppsc->rfchange_inprogress)) { 2765 rtl8821ae_dm_common_info_self_update(hw); 2766 rtl8821ae_dm_false_alarm_counter_statistics(hw); 2767 rtl8821ae_dm_check_rssi_monitor(hw); 2768 rtl8821ae_dm_dig(hw); 2769 rtl8821ae_dm_cck_packet_detection_thresh(hw); 2770 rtl8821ae_dm_refresh_rate_adaptive_mask(hw); 2771 rtl8821ae_dm_refresh_basic_rate_mask(hw); 2772 rtl8821ae_dm_check_edca_turbo(hw); 2773 rtl8821ae_dm_dynamic_atc_switch(hw); 2774 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) 2775 rtl8812ae_dm_check_txpower_tracking_thermalmeter(hw); 2776 else 2777 rtl8821ae_dm_check_txpower_tracking_thermalmeter(hw); 2778 rtl8821ae_dm_iq_calibrate(hw); 2779 } 2780 spin_unlock(&rtlpriv->locks.rf_ps_lock); 2781 2782 rtlpriv->dm.dbginfo.num_qry_beacon_pkt = 0; 2783 rtl_dbg(rtlpriv, COMP_DIG, DBG_DMESG, "\n"); 2784 } 2785 2786 void rtl8821ae_dm_set_tx_ant_by_tx_info(struct ieee80211_hw *hw, 2787 u8 *pdesc, u32 mac_id) 2788 { 2789 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 2790 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 2791 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 2792 struct fast_ant_training *pfat_table = &rtldm->fat_table; 2793 __le32 *pdesc32 = (__le32 *)pdesc; 2794 2795 if (rtlhal->hw_type != HARDWARE_TYPE_RTL8812AE) 2796 return; 2797 2798 if (rtlefuse->antenna_div_type == CG_TRX_HW_ANTDIV) 2799 set_tx_desc_tx_ant(pdesc32, pfat_table->antsel_a[mac_id]); 2800 } 2801