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