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