1/****************************************************************************** 2 * 3 * Copyright(c) 2009-2010 Realtek Corporation. 4 * 5 * This program is free software; you can redistribute it and/or modify it 6 * under the terms of version 2 of the GNU General Public License as 7 * published by the Free Software Foundation. 8 * 9 * This program is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 12 * more details. 13 * 14 * The full GNU General Public License is included in this distribution in the 15 * file called LICENSE. 16 * 17 * Contact Information: 18 * wlanfae <wlanfae@realtek.com> 19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 20 * Hsinchu 300, Taiwan. 21 * 22 * Larry Finger <Larry.Finger@lwfinger.net> 23 * 24 *****************************************************************************/ 25 26#include "../wifi.h" 27#include "../pci.h" 28#include "../ps.h" 29#include "reg.h" 30#include "def.h" 31#include "phy.h" 32#include "rf.h" 33#include "dm.h" 34#include "table.h" 35#include "trx.h" 36#include "../btcoexist/halbt_precomp.h" 37#include "hw.h" 38#include "../efuse.h" 39 40#define READ_NEXT_PAIR(array_table, v1, v2, i) \ 41 do { \ 42 i += 2; \ 43 v1 = array_table[i]; \ 44 v2 = array_table[i+1]; \ 45 } while (0) 46 47static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw, 48 enum radio_path rfpath, u32 offset); 49static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw, 50 enum radio_path rfpath, u32 offset, 51 u32 data); 52static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask); 53static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw); 54/*static bool _rtl8812ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);*/ 55static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); 56static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, 57 u8 configtype); 58static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, 59 u8 configtype); 60static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw); 61 62static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, 63 enum wireless_mode wirelessmode, 64 u8 txpwridx); 65static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw); 66static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw); 67 68static void rtl8812ae_fixspur(struct ieee80211_hw *hw, 69 enum ht_channel_width band_width, u8 channel) 70{ 71 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 72 73 /*C cut Item12 ADC FIFO CLOCK*/ 74 if (IS_VENDOR_8812A_C_CUT(rtlhal->version)) { 75 if (band_width == HT_CHANNEL_WIDTH_20_40 && channel == 11) 76 rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x3); 77 /* 0x8AC[11:10] = 2'b11*/ 78 else 79 rtl_set_bbreg(hw, RRFMOD, 0xC00, 0x2); 80 /* 0x8AC[11:10] = 2'b10*/ 81 82 /* <20120914, Kordan> A workarould to resolve 83 * 2480Mhz spur by setting ADC clock as 160M. (Asked by Binson) 84 */ 85 if (band_width == HT_CHANNEL_WIDTH_20 && 86 (channel == 13 || channel == 14)) { 87 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3); 88 /*0x8AC[9:8] = 2'b11*/ 89 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1); 90 /* 0x8C4[30] = 1*/ 91 } else if (band_width == HT_CHANNEL_WIDTH_20_40 && 92 channel == 11) { 93 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1); 94 /*0x8C4[30] = 1*/ 95 } else if (band_width != HT_CHANNEL_WIDTH_80) { 96 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2); 97 /*0x8AC[9:8] = 2'b10*/ 98 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0); 99 /*0x8C4[30] = 0*/ 100 } 101 } else if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 102 /* <20120914, Kordan> A workarould to resolve 103 * 2480Mhz spur by setting ADC clock as 160M. 104 */ 105 if (band_width == HT_CHANNEL_WIDTH_20 && 106 (channel == 13 || channel == 14)) 107 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x3); 108 /*0x8AC[9:8] = 11*/ 109 else if (channel <= 14) /*2.4G only*/ 110 rtl_set_bbreg(hw, RRFMOD, 0x300, 0x2); 111 /*0x8AC[9:8] = 10*/ 112 } 113} 114 115u32 rtl8821ae_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, 116 u32 bitmask) 117{ 118 struct rtl_priv *rtlpriv = rtl_priv(hw); 119 u32 returnvalue, originalvalue, bitshift; 120 121 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 122 "regaddr(%#x), bitmask(%#x)\n", 123 regaddr, bitmask); 124 originalvalue = rtl_read_dword(rtlpriv, regaddr); 125 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask); 126 returnvalue = (originalvalue & bitmask) >> bitshift; 127 128 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 129 "BBR MASK=0x%x Addr[0x%x]=0x%x\n", 130 bitmask, regaddr, originalvalue); 131 return returnvalue; 132} 133 134void rtl8821ae_phy_set_bb_reg(struct ieee80211_hw *hw, 135 u32 regaddr, u32 bitmask, u32 data) 136{ 137 struct rtl_priv *rtlpriv = rtl_priv(hw); 138 u32 originalvalue, bitshift; 139 140 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 141 "regaddr(%#x), bitmask(%#x), data(%#x)\n", 142 regaddr, bitmask, data); 143 144 if (bitmask != MASKDWORD) { 145 originalvalue = rtl_read_dword(rtlpriv, regaddr); 146 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask); 147 data = ((originalvalue & (~bitmask)) | 148 ((data << bitshift) & bitmask)); 149 } 150 151 rtl_write_dword(rtlpriv, regaddr, data); 152 153 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 154 "regaddr(%#x), bitmask(%#x), data(%#x)\n", 155 regaddr, bitmask, data); 156} 157 158u32 rtl8821ae_phy_query_rf_reg(struct ieee80211_hw *hw, 159 enum radio_path rfpath, u32 regaddr, 160 u32 bitmask) 161{ 162 struct rtl_priv *rtlpriv = rtl_priv(hw); 163 u32 original_value, readback_value, bitshift; 164 unsigned long flags; 165 166 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 167 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n", 168 regaddr, rfpath, bitmask); 169 170 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); 171 172 original_value = _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr); 173 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask); 174 readback_value = (original_value & bitmask) >> bitshift; 175 176 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); 177 178 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 179 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", 180 regaddr, rfpath, bitmask, original_value); 181 182 return readback_value; 183} 184 185void rtl8821ae_phy_set_rf_reg(struct ieee80211_hw *hw, 186 enum radio_path rfpath, 187 u32 regaddr, u32 bitmask, u32 data) 188{ 189 struct rtl_priv *rtlpriv = rtl_priv(hw); 190 u32 original_value, bitshift; 191 unsigned long flags; 192 193 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 194 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 195 regaddr, bitmask, data, rfpath); 196 197 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags); 198 199 if (bitmask != RFREG_OFFSET_MASK) { 200 original_value = 201 _rtl8821ae_phy_rf_serial_read(hw, rfpath, regaddr); 202 bitshift = _rtl8821ae_phy_calculate_bit_shift(bitmask); 203 data = ((original_value & (~bitmask)) | (data << bitshift)); 204 } 205 206 _rtl8821ae_phy_rf_serial_write(hw, rfpath, regaddr, data); 207 208 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); 209 210 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 211 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", 212 regaddr, bitmask, data, rfpath); 213} 214 215static u32 _rtl8821ae_phy_rf_serial_read(struct ieee80211_hw *hw, 216 enum radio_path rfpath, u32 offset) 217{ 218 struct rtl_priv *rtlpriv = rtl_priv(hw); 219 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 220 bool is_pi_mode = false; 221 u32 retvalue = 0; 222 223 /* 2009/06/17 MH We can not execute IO for power 224 save or other accident mode.*/ 225 if (RT_CANNOT_IO(hw)) { 226 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); 227 return 0xFFFFFFFF; 228 } 229 /* <20120809, Kordan> CCA OFF(when entering), 230 asked by James to avoid reading the wrong value. 231 <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it!*/ 232 if (offset != 0x0 && 233 !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) || 234 (IS_VENDOR_8812A_C_CUT(rtlhal->version)))) 235 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 1); 236 offset &= 0xff; 237 238 if (rfpath == RF90_PATH_A) 239 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xC00, 0x4); 240 else if (rfpath == RF90_PATH_B) 241 is_pi_mode = (bool)rtl_get_bbreg(hw, 0xE00, 0x4); 242 243 rtl_set_bbreg(hw, RHSSIREAD_8821AE, 0xff, offset); 244 245 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) || 246 (IS_VENDOR_8812A_C_CUT(rtlhal->version))) 247 udelay(20); 248 249 if (is_pi_mode) { 250 if (rfpath == RF90_PATH_A) 251 retvalue = 252 rtl_get_bbreg(hw, RA_PIREAD_8821A, BLSSIREADBACKDATA); 253 else if (rfpath == RF90_PATH_B) 254 retvalue = 255 rtl_get_bbreg(hw, RB_PIREAD_8821A, BLSSIREADBACKDATA); 256 } else { 257 if (rfpath == RF90_PATH_A) 258 retvalue = 259 rtl_get_bbreg(hw, RA_SIREAD_8821A, BLSSIREADBACKDATA); 260 else if (rfpath == RF90_PATH_B) 261 retvalue = 262 rtl_get_bbreg(hw, RB_SIREAD_8821A, BLSSIREADBACKDATA); 263 } 264 265 /*<20120809, Kordan> CCA ON(when exiting), 266 * asked by James to avoid reading the wrong value. 267 * <20120828, Kordan> Toggling CCA would affect RF 0x0, skip it! 268 */ 269 if (offset != 0x0 && 270 !((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) || 271 (IS_VENDOR_8812A_C_CUT(rtlhal->version)))) 272 rtl_set_bbreg(hw, RCCAONSEC, 0x8, 0); 273 return retvalue; 274} 275 276static void _rtl8821ae_phy_rf_serial_write(struct ieee80211_hw *hw, 277 enum radio_path rfpath, u32 offset, 278 u32 data) 279{ 280 struct rtl_priv *rtlpriv = rtl_priv(hw); 281 struct rtl_phy *rtlphy = &rtlpriv->phy; 282 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 283 u32 data_and_addr; 284 u32 newoffset; 285 286 if (RT_CANNOT_IO(hw)) { 287 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); 288 return; 289 } 290 offset &= 0xff; 291 newoffset = offset; 292 data_and_addr = ((newoffset << 20) | 293 (data & 0x000fffff)) & 0x0fffffff; 294 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); 295 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 296 "RFW-%d Addr[0x%x]=0x%x\n", 297 rfpath, pphyreg->rf3wire_offset, data_and_addr); 298} 299 300static u32 _rtl8821ae_phy_calculate_bit_shift(u32 bitmask) 301{ 302 u32 i; 303 304 for (i = 0; i <= 31; i++) { 305 if (((bitmask >> i) & 0x1) == 1) 306 break; 307 } 308 return i; 309} 310 311bool rtl8821ae_phy_mac_config(struct ieee80211_hw *hw) 312{ 313 bool rtstatus = 0; 314 315 rtstatus = _rtl8821ae_phy_config_mac_with_headerfile(hw); 316 317 return rtstatus; 318} 319 320bool rtl8821ae_phy_bb_config(struct ieee80211_hw *hw) 321{ 322 bool rtstatus = true; 323 struct rtl_priv *rtlpriv = rtl_priv(hw); 324 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 325 struct rtl_phy *rtlphy = &rtlpriv->phy; 326 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 327 u8 regval; 328 u8 crystal_cap; 329 330 phy_init_bb_rf_register_definition(hw); 331 332 regval = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN); 333 regval |= FEN_PCIEA; 334 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, regval); 335 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 336 regval | FEN_BB_GLB_RSTN | FEN_BBRSTB); 337 338 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x7); 339 rtl_write_byte(rtlpriv, REG_OPT_CTRL + 2, 0x7); 340 341 rtstatus = _rtl8821ae_phy_bb8821a_config_parafile(hw); 342 343 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 344 crystal_cap = rtlefuse->crystalcap & 0x3F; 345 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0x7FF80000, 346 (crystal_cap | (crystal_cap << 6))); 347 } else { 348 crystal_cap = rtlefuse->crystalcap & 0x3F; 349 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000, 350 (crystal_cap | (crystal_cap << 6))); 351 } 352 rtlphy->reg_837 = rtl_read_byte(rtlpriv, 0x837); 353 354 return rtstatus; 355} 356 357bool rtl8821ae_phy_rf_config(struct ieee80211_hw *hw) 358{ 359 return rtl8821ae_phy_rf6052_config(hw); 360} 361 362u32 phy_get_tx_swing_8812A(struct ieee80211_hw *hw, u8 band, 363 u8 rf_path) 364{ 365 struct rtl_priv *rtlpriv = rtl_priv(hw); 366 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 367 struct rtl_dm *rtldm = rtl_dm(rtlpriv); 368 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 369 char reg_swing_2g = -1;/* 0xff; */ 370 char reg_swing_5g = -1;/* 0xff; */ 371 char swing_2g = -1 * reg_swing_2g; 372 char swing_5g = -1 * reg_swing_5g; 373 u32 out = 0x200; 374 const char auto_temp = -1; 375 376 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, 377 "===> PHY_GetTxBBSwing_8812A, bbSwing_2G: %d, bbSwing_5G: %d,autoload_failflag=%d.\n", 378 (int)swing_2g, (int)swing_5g, 379 (int)rtlefuse->autoload_failflag); 380 381 if (rtlefuse->autoload_failflag) { 382 if (band == BAND_ON_2_4G) { 383 rtldm->swing_diff_2g = swing_2g; 384 if (swing_2g == 0) { 385 out = 0x200; /* 0 dB */ 386 } else if (swing_2g == -3) { 387 out = 0x16A; /* -3 dB */ 388 } else if (swing_2g == -6) { 389 out = 0x101; /* -6 dB */ 390 } else if (swing_2g == -9) { 391 out = 0x0B6; /* -9 dB */ 392 } else { 393 rtldm->swing_diff_2g = 0; 394 out = 0x200; 395 } 396 } else if (band == BAND_ON_5G) { 397 rtldm->swing_diff_5g = swing_5g; 398 if (swing_5g == 0) { 399 out = 0x200; /* 0 dB */ 400 } else if (swing_5g == -3) { 401 out = 0x16A; /* -3 dB */ 402 } else if (swing_5g == -6) { 403 out = 0x101; /* -6 dB */ 404 } else if (swing_5g == -9) { 405 out = 0x0B6; /* -9 dB */ 406 } else { 407 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 408 rtldm->swing_diff_5g = -3; 409 out = 0x16A; 410 } else { 411 rtldm->swing_diff_5g = 0; 412 out = 0x200; 413 } 414 } 415 } else { 416 rtldm->swing_diff_2g = -3; 417 rtldm->swing_diff_5g = -3; 418 out = 0x16A; /* -3 dB */ 419 } 420 } else { 421 u32 swing = 0, swing_a = 0, swing_b = 0; 422 423 if (band == BAND_ON_2_4G) { 424 if (reg_swing_2g == auto_temp) { 425 efuse_shadow_read(hw, 1, 0xC6, (u32 *)&swing); 426 swing = (swing == 0xFF) ? 0x00 : swing; 427 } else if (swing_2g == 0) { 428 swing = 0x00; /* 0 dB */ 429 } else if (swing_2g == -3) { 430 swing = 0x05; /* -3 dB */ 431 } else if (swing_2g == -6) { 432 swing = 0x0A; /* -6 dB */ 433 } else if (swing_2g == -9) { 434 swing = 0xFF; /* -9 dB */ 435 } else { 436 swing = 0x00; 437 } 438 } else { 439 if (reg_swing_5g == auto_temp) { 440 efuse_shadow_read(hw, 1, 0xC7, (u32 *)&swing); 441 swing = (swing == 0xFF) ? 0x00 : swing; 442 } else if (swing_5g == 0) { 443 swing = 0x00; /* 0 dB */ 444 } else if (swing_5g == -3) { 445 swing = 0x05; /* -3 dB */ 446 } else if (swing_5g == -6) { 447 swing = 0x0A; /* -6 dB */ 448 } else if (swing_5g == -9) { 449 swing = 0xFF; /* -9 dB */ 450 } else { 451 swing = 0x00; 452 } 453 } 454 455 swing_a = (swing & 0x3) >> 0; /* 0xC6/C7[1:0] */ 456 swing_b = (swing & 0xC) >> 2; /* 0xC6/C7[3:2] */ 457 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, 458 "===> PHY_GetTxBBSwing_8812A, swingA: 0x%X, swingB: 0x%X\n", 459 swing_a, swing_b); 460 461 /* 3 Path-A */ 462 if (swing_a == 0x0) { 463 if (band == BAND_ON_2_4G) 464 rtldm->swing_diff_2g = 0; 465 else 466 rtldm->swing_diff_5g = 0; 467 out = 0x200; /* 0 dB */ 468 } else if (swing_a == 0x1) { 469 if (band == BAND_ON_2_4G) 470 rtldm->swing_diff_2g = -3; 471 else 472 rtldm->swing_diff_5g = -3; 473 out = 0x16A; /* -3 dB */ 474 } else if (swing_a == 0x2) { 475 if (band == BAND_ON_2_4G) 476 rtldm->swing_diff_2g = -6; 477 else 478 rtldm->swing_diff_5g = -6; 479 out = 0x101; /* -6 dB */ 480 } else if (swing_a == 0x3) { 481 if (band == BAND_ON_2_4G) 482 rtldm->swing_diff_2g = -9; 483 else 484 rtldm->swing_diff_5g = -9; 485 out = 0x0B6; /* -9 dB */ 486 } 487 /* 3 Path-B */ 488 if (swing_b == 0x0) { 489 if (band == BAND_ON_2_4G) 490 rtldm->swing_diff_2g = 0; 491 else 492 rtldm->swing_diff_5g = 0; 493 out = 0x200; /* 0 dB */ 494 } else if (swing_b == 0x1) { 495 if (band == BAND_ON_2_4G) 496 rtldm->swing_diff_2g = -3; 497 else 498 rtldm->swing_diff_5g = -3; 499 out = 0x16A; /* -3 dB */ 500 } else if (swing_b == 0x2) { 501 if (band == BAND_ON_2_4G) 502 rtldm->swing_diff_2g = -6; 503 else 504 rtldm->swing_diff_5g = -6; 505 out = 0x101; /* -6 dB */ 506 } else if (swing_b == 0x3) { 507 if (band == BAND_ON_2_4G) 508 rtldm->swing_diff_2g = -9; 509 else 510 rtldm->swing_diff_5g = -9; 511 out = 0x0B6; /* -9 dB */ 512 } 513 } 514 515 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, 516 "<=== PHY_GetTxBBSwing_8812A, out = 0x%X\n", out); 517 return out; 518} 519 520void rtl8821ae_phy_switch_wirelessband(struct ieee80211_hw *hw, u8 band) 521{ 522 struct rtl_priv *rtlpriv = rtl_priv(hw); 523 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 524 struct rtl_dm *rtldm = rtl_dm(rtlpriv); 525 u8 current_band = rtlhal->current_bandtype; 526 u32 txpath, rxpath; 527 char bb_diff_between_band; 528 529 txpath = rtl8821ae_phy_query_bb_reg(hw, RTXPATH, 0xf0); 530 rxpath = rtl8821ae_phy_query_bb_reg(hw, RCCK_RX, 0x0f000000); 531 rtlhal->current_bandtype = (enum band_type) band; 532 /* reconfig BB/RF according to wireless mode */ 533 if (rtlhal->current_bandtype == BAND_ON_2_4G) { 534 /* BB & RF Config */ 535 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03); 536 537 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 538 /* 0xCB0[15:12] = 0x7 (LNA_On)*/ 539 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x7); 540 /* 0xCB0[7:4] = 0x7 (PAPE_A)*/ 541 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x7); 542 } 543 544 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 545 /*0x834[1:0] = 0x1*/ 546 rtl_set_bbreg(hw, 0x834, 0x3, 0x1); 547 } 548 549 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 550 /* 0xC1C[11:8] = 0 */ 551 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 0); 552 } else { 553 /* 0x82C[1:0] = 2b'00 */ 554 rtl_set_bbreg(hw, 0x82c, 0x3, 0); 555 } 556 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 557 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 558 0x77777777); 559 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 560 0x77777777); 561 rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x000); 562 rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x000); 563 } 564 565 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0x1); 566 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0x1); 567 568 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x0); 569 } else {/* 5G band */ 570 u16 count, reg_41a; 571 572 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 573 /*0xCB0[15:12] = 0x5 (LNA_On)*/ 574 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF000, 0x5); 575 /*0xCB0[7:4] = 0x4 (PAPE_A)*/ 576 rtl_set_bbreg(hw, RA_RFE_PINMUX, 0xF0, 0x4); 577 } 578 /*CCK_CHECK_en*/ 579 rtl_write_byte(rtlpriv, REG_CCK_CHECK, 0x80); 580 581 count = 0; 582 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY); 583 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, 584 "Reg41A value %d", reg_41a); 585 reg_41a &= 0x30; 586 while ((reg_41a != 0x30) && (count < 50)) { 587 udelay(50); 588 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "Delay 50us\n"); 589 590 reg_41a = rtl_read_word(rtlpriv, REG_TXPKT_EMPTY); 591 reg_41a &= 0x30; 592 count++; 593 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, 594 "Reg41A value %d", reg_41a); 595 } 596 if (count != 0) 597 RT_TRACE(rtlpriv, COMP_MLME, DBG_LOUD, 598 "PHY_SwitchWirelessBand8812(): Switch to 5G Band. Count = %d reg41A=0x%x\n", 599 count, reg_41a); 600 601 /* 2012/02/01, Sinda add registry to switch workaround 602 without long-run verification for scan issue. */ 603 rtl_set_bbreg(hw, ROFDMCCKEN, BOFDMEN|BCCKEN, 0x03); 604 605 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 606 /*0x834[1:0] = 0x2*/ 607 rtl_set_bbreg(hw, 0x834, 0x3, 0x2); 608 } 609 610 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 611 /* AGC table select */ 612 /* 0xC1C[11:8] = 1*/ 613 rtl_set_bbreg(hw, RA_TXSCALE, 0xF00, 1); 614 } else 615 /* 0x82C[1:0] = 2'b00 */ 616 rtl_set_bbreg(hw, 0x82c, 0x3, 1); 617 618 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 619 rtl_set_bbreg(hw, RA_RFE_PINMUX, BMASKDWORD, 620 0x77337777); 621 rtl_set_bbreg(hw, RB_RFE_PINMUX, BMASKDWORD, 622 0x77337777); 623 rtl_set_bbreg(hw, RA_RFE_INV, 0x3ff00000, 0x010); 624 rtl_set_bbreg(hw, RB_RFE_INV, 0x3ff00000, 0x010); 625 } 626 627 rtl_set_bbreg(hw, RTXPATH, 0xf0, 0); 628 rtl_set_bbreg(hw, RCCK_RX, 0x0f000000, 0xf); 629 630 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, 631 "==>PHY_SwitchWirelessBand8812() BAND_ON_5G settings OFDM index 0x%x\n", 632 rtlpriv->dm.ofdm_index[RF90_PATH_A]); 633 } 634 635 if ((rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) || 636 (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE)) { 637 /* 0xC1C[31:21] */ 638 rtl_set_bbreg(hw, RA_TXSCALE, 0xFFE00000, 639 phy_get_tx_swing_8812A(hw, band, RF90_PATH_A)); 640 /* 0xE1C[31:21] */ 641 rtl_set_bbreg(hw, RB_TXSCALE, 0xFFE00000, 642 phy_get_tx_swing_8812A(hw, band, RF90_PATH_B)); 643 644 /* <20121005, Kordan> When TxPowerTrack is ON, 645 * we should take care of the change of BB swing. 646 * That is, reset all info to trigger Tx power tracking. 647 */ 648 if (band != current_band) { 649 bb_diff_between_band = 650 (rtldm->swing_diff_2g - rtldm->swing_diff_5g); 651 bb_diff_between_band = (band == BAND_ON_2_4G) ? 652 bb_diff_between_band : 653 (-1 * bb_diff_between_band); 654 rtldm->default_ofdm_index += bb_diff_between_band * 2; 655 } 656 rtl8821ae_dm_clear_txpower_tracking_state(hw); 657 } 658 659 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, 660 "<==rtl8821ae_phy_switch_wirelessband():Switch Band OK.\n"); 661 return; 662} 663 664static bool _rtl8821ae_check_condition(struct ieee80211_hw *hw, 665 const u32 condition) 666{ 667 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 668 u32 _board = rtlefuse->board_type; /*need efuse define*/ 669 u32 _interface = 0x01; /* ODM_ITRF_PCIE */ 670 u32 _platform = 0x08;/* ODM_WIN */ 671 u32 cond = condition; 672 673 if (condition == 0xCDCDCDCD) 674 return true; 675 676 cond = condition & 0xFF; 677 if ((_board != cond) && cond != 0xFF) 678 return false; 679 680 cond = condition & 0xFF00; 681 cond = cond >> 8; 682 if ((_interface & cond) == 0 && cond != 0x07) 683 return false; 684 685 cond = condition & 0xFF0000; 686 cond = cond >> 16; 687 if ((_platform & cond) == 0 && cond != 0x0F) 688 return false; 689 return true; 690} 691 692static void _rtl8821ae_config_rf_reg(struct ieee80211_hw *hw, 693 u32 addr, u32 data, 694 enum radio_path rfpath, u32 regaddr) 695{ 696 if (addr == 0xfe || addr == 0xffe) { 697 /* In order not to disturb BT music when 698 * wifi init.(1ant NIC only) 699 */ 700 mdelay(50); 701 } else { 702 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data); 703 udelay(1); 704 } 705} 706 707static void _rtl8821ae_config_rf_radio_a(struct ieee80211_hw *hw, 708 u32 addr, u32 data) 709{ 710 u32 content = 0x1000; /*RF Content: radio_a_txt*/ 711 u32 maskforphyset = (u32)(content & 0xE000); 712 713 _rtl8821ae_config_rf_reg(hw, addr, data, 714 RF90_PATH_A, addr | maskforphyset); 715} 716 717static void _rtl8821ae_config_rf_radio_b(struct ieee80211_hw *hw, 718 u32 addr, u32 data) 719{ 720 u32 content = 0x1001; /*RF Content: radio_b_txt*/ 721 u32 maskforphyset = (u32)(content & 0xE000); 722 723 _rtl8821ae_config_rf_reg(hw, addr, data, 724 RF90_PATH_B, addr | maskforphyset); 725} 726 727static void _rtl8821ae_config_bb_reg(struct ieee80211_hw *hw, 728 u32 addr, u32 data) 729{ 730 if (addr == 0xfe) 731 mdelay(50); 732 else if (addr == 0xfd) 733 mdelay(5); 734 else if (addr == 0xfc) 735 mdelay(1); 736 else if (addr == 0xfb) 737 udelay(50); 738 else if (addr == 0xfa) 739 udelay(5); 740 else if (addr == 0xf9) 741 udelay(1); 742 else 743 rtl_set_bbreg(hw, addr, MASKDWORD, data); 744 745 udelay(1); 746} 747 748static void _rtl8821ae_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) 749{ 750 struct rtl_priv *rtlpriv = rtl_priv(hw); 751 struct rtl_phy *rtlphy = &rtlpriv->phy; 752 u8 band, rfpath, txnum, rate_section; 753 754 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band) 755 for (rfpath = 0; rfpath < TX_PWR_BY_RATE_NUM_RF; ++rfpath) 756 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum) 757 for (rate_section = 0; 758 rate_section < TX_PWR_BY_RATE_NUM_SECTION; 759 ++rate_section) 760 rtlphy->tx_power_by_rate_offset[band] 761 [rfpath][txnum][rate_section] = 0; 762} 763 764static void _rtl8821ae_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, 765 u8 band, u8 path, 766 u8 rate_section, 767 u8 txnum, u8 value) 768{ 769 struct rtl_priv *rtlpriv = rtl_priv(hw); 770 struct rtl_phy *rtlphy = &rtlpriv->phy; 771 772 if (path > RF90_PATH_D) { 773 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 774 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n", path); 775 return; 776 } 777 778 if (band == BAND_ON_2_4G) { 779 switch (rate_section) { 780 case CCK: 781 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value; 782 break; 783 case OFDM: 784 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value; 785 break; 786 case HT_MCS0_MCS7: 787 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value; 788 break; 789 case HT_MCS8_MCS15: 790 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value; 791 break; 792 case VHT_1SSMCS0_1SSMCS9: 793 rtlphy->txpwr_by_rate_base_24g[path][txnum][4] = value; 794 break; 795 case VHT_2SSMCS0_2SSMCS9: 796 rtlphy->txpwr_by_rate_base_24g[path][txnum][5] = value; 797 break; 798 default: 799 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 800 "Invalid RateSection %d in Band 2.4G,Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n", 801 rate_section, path, txnum); 802 break; 803 } 804 } else if (band == BAND_ON_5G) { 805 switch (rate_section) { 806 case OFDM: 807 rtlphy->txpwr_by_rate_base_5g[path][txnum][0] = value; 808 break; 809 case HT_MCS0_MCS7: 810 rtlphy->txpwr_by_rate_base_5g[path][txnum][1] = value; 811 break; 812 case HT_MCS8_MCS15: 813 rtlphy->txpwr_by_rate_base_5g[path][txnum][2] = value; 814 break; 815 case VHT_1SSMCS0_1SSMCS9: 816 rtlphy->txpwr_by_rate_base_5g[path][txnum][3] = value; 817 break; 818 case VHT_2SSMCS0_2SSMCS9: 819 rtlphy->txpwr_by_rate_base_5g[path][txnum][4] = value; 820 break; 821 default: 822 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 823 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n", 824 rate_section, path, txnum); 825 break; 826 } 827 } else { 828 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 829 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", band); 830 } 831} 832 833static u8 _rtl8821ae_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, 834 u8 band, u8 path, 835 u8 txnum, u8 rate_section) 836{ 837 struct rtl_priv *rtlpriv = rtl_priv(hw); 838 struct rtl_phy *rtlphy = &rtlpriv->phy; 839 u8 value = 0; 840 841 if (path > RF90_PATH_D) { 842 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 843 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n", 844 path); 845 return 0; 846 } 847 848 if (band == BAND_ON_2_4G) { 849 switch (rate_section) { 850 case CCK: 851 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0]; 852 break; 853 case OFDM: 854 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1]; 855 break; 856 case HT_MCS0_MCS7: 857 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2]; 858 break; 859 case HT_MCS8_MCS15: 860 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3]; 861 break; 862 case VHT_1SSMCS0_1SSMCS9: 863 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][4]; 864 break; 865 case VHT_2SSMCS0_2SSMCS9: 866 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][5]; 867 break; 868 default: 869 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 870 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", 871 rate_section, path, txnum); 872 break; 873 } 874 } else if (band == BAND_ON_5G) { 875 switch (rate_section) { 876 case OFDM: 877 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][0]; 878 break; 879 case HT_MCS0_MCS7: 880 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][1]; 881 break; 882 case HT_MCS8_MCS15: 883 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][2]; 884 break; 885 case VHT_1SSMCS0_1SSMCS9: 886 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][3]; 887 break; 888 case VHT_2SSMCS0_2SSMCS9: 889 value = rtlphy->txpwr_by_rate_base_5g[path][txnum][4]; 890 break; 891 default: 892 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 893 "Invalid RateSection %d in Band 5G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", 894 rate_section, path, txnum); 895 break; 896 } 897 } else { 898 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 899 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", band); 900 } 901 902 return value; 903} 904 905static void _rtl8821ae_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) 906{ 907 struct rtl_priv *rtlpriv = rtl_priv(hw); 908 struct rtl_phy *rtlphy = &rtlpriv->phy; 909 u16 rawValue = 0; 910 u8 base = 0, path = 0; 911 912 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { 913 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][0] >> 24) & 0xFF; 914 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 915 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, CCK, RF_1TX, base); 916 917 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][2] >> 24) & 0xFF; 918 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 919 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, base); 920 921 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][4] >> 24) & 0xFF; 922 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 923 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, RF_1TX, base); 924 925 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][6] >> 24) & 0xFF; 926 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 927 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS8_MCS15, RF_2TX, base); 928 929 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_1TX][8] >> 24) & 0xFF; 930 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 931 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base); 932 933 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][path][RF_2TX][11] >> 8) & 0xFF; 934 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 935 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base); 936 937 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][2] >> 24) & 0xFF; 938 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 939 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, OFDM, RF_1TX, base); 940 941 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][4] >> 24) & 0xFF; 942 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 943 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS0_MCS7, RF_1TX, base); 944 945 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][6] >> 24) & 0xFF; 946 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 947 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, HT_MCS8_MCS15, RF_2TX, base); 948 949 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_1TX][8] >> 24) & 0xFF; 950 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 951 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_1SSMCS0_1SSMCS9, RF_1TX, base); 952 953 rawValue = (u16)(rtlphy->tx_power_by_rate_offset[BAND_ON_5G][path][RF_2TX][11] >> 8) & 0xFF; 954 base = (rawValue >> 4) * 10 + (rawValue & 0xF); 955 _rtl8821ae_phy_set_txpower_by_rate_base(hw, BAND_ON_5G, path, VHT_2SSMCS0_2SSMCS9, RF_2TX, base); 956 } 957} 958 959static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start, 960 u8 end, u8 base_val) 961{ 962 char i = 0; 963 u8 temp_value = 0; 964 u32 temp_data = 0; 965 966 for (i = 3; i >= 0; --i) { 967 if (i >= start && i <= end) { 968 /* Get the exact value */ 969 temp_value = (u8)(*data >> (i * 8)) & 0xF; 970 temp_value += ((u8)((*data >> (i * 8 + 4)) & 0xF)) * 10; 971 972 /* Change the value to a relative value */ 973 temp_value = (temp_value > base_val) ? temp_value - 974 base_val : base_val - temp_value; 975 } else { 976 temp_value = (u8)(*data >> (i * 8)) & 0xFF; 977 } 978 temp_data <<= 8; 979 temp_data |= temp_value; 980 } 981 *data = temp_data; 982} 983 984static void _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(struct ieee80211_hw *hw) 985{ 986 struct rtl_priv *rtlpriv = rtl_priv(hw); 987 struct rtl_phy *rtlphy = &rtlpriv->phy; 988 u8 regulation, bw, channel, rate_section; 989 char temp_pwrlmt = 0; 990 991 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { 992 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) { 993 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) { 994 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) { 995 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation] 996 [bw][rate_section][channel][RF90_PATH_A]; 997 if (temp_pwrlmt == MAX_POWER_INDEX) { 998 if (bw == 0 || bw == 1) { /*5G 20M 40M VHT and HT can cross reference*/ 999 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1000 "No power limit table of the specified band %d, bandwidth %d, ratesection %d, channel %d, rf path %d\n", 1001 1, bw, rate_section, channel, RF90_PATH_A); 1002 if (rate_section == 2) { 1003 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A] = 1004 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A]; 1005 } else if (rate_section == 4) { 1006 rtlphy->txpwr_limit_5g[regulation][bw][4][channel][RF90_PATH_A] = 1007 rtlphy->txpwr_limit_5g[regulation][bw][2][channel][RF90_PATH_A]; 1008 } else if (rate_section == 3) { 1009 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A] = 1010 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A]; 1011 } else if (rate_section == 5) { 1012 rtlphy->txpwr_limit_5g[regulation][bw][5][channel][RF90_PATH_A] = 1013 rtlphy->txpwr_limit_5g[regulation][bw][3][channel][RF90_PATH_A]; 1014 } 1015 1016 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "use other value %d", temp_pwrlmt); 1017 } 1018 } 1019 } 1020 } 1021 } 1022 } 1023} 1024 1025static u8 _rtl8812ae_phy_get_txpower_by_rate_base_index(struct ieee80211_hw *hw, 1026 enum band_type band, u8 rate) 1027{ 1028 struct rtl_priv *rtlpriv = rtl_priv(hw); 1029 u8 index = 0; 1030 if (band == BAND_ON_2_4G) { 1031 switch (rate) { 1032 case MGN_1M: 1033 case MGN_2M: 1034 case MGN_5_5M: 1035 case MGN_11M: 1036 index = 0; 1037 break; 1038 1039 case MGN_6M: 1040 case MGN_9M: 1041 case MGN_12M: 1042 case MGN_18M: 1043 case MGN_24M: 1044 case MGN_36M: 1045 case MGN_48M: 1046 case MGN_54M: 1047 index = 1; 1048 break; 1049 1050 case MGN_MCS0: 1051 case MGN_MCS1: 1052 case MGN_MCS2: 1053 case MGN_MCS3: 1054 case MGN_MCS4: 1055 case MGN_MCS5: 1056 case MGN_MCS6: 1057 case MGN_MCS7: 1058 index = 2; 1059 break; 1060 1061 case MGN_MCS8: 1062 case MGN_MCS9: 1063 case MGN_MCS10: 1064 case MGN_MCS11: 1065 case MGN_MCS12: 1066 case MGN_MCS13: 1067 case MGN_MCS14: 1068 case MGN_MCS15: 1069 index = 3; 1070 break; 1071 1072 default: 1073 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 1074 "Wrong rate 0x%x to obtain index in 2.4G in PHY_GetTxPowerByRateBaseIndex()\n", 1075 rate); 1076 break; 1077 } 1078 } else if (band == BAND_ON_5G) { 1079 switch (rate) { 1080 case MGN_6M: 1081 case MGN_9M: 1082 case MGN_12M: 1083 case MGN_18M: 1084 case MGN_24M: 1085 case MGN_36M: 1086 case MGN_48M: 1087 case MGN_54M: 1088 index = 0; 1089 break; 1090 1091 case MGN_MCS0: 1092 case MGN_MCS1: 1093 case MGN_MCS2: 1094 case MGN_MCS3: 1095 case MGN_MCS4: 1096 case MGN_MCS5: 1097 case MGN_MCS6: 1098 case MGN_MCS7: 1099 index = 1; 1100 break; 1101 1102 case MGN_MCS8: 1103 case MGN_MCS9: 1104 case MGN_MCS10: 1105 case MGN_MCS11: 1106 case MGN_MCS12: 1107 case MGN_MCS13: 1108 case MGN_MCS14: 1109 case MGN_MCS15: 1110 index = 2; 1111 break; 1112 1113 case MGN_VHT1SS_MCS0: 1114 case MGN_VHT1SS_MCS1: 1115 case MGN_VHT1SS_MCS2: 1116 case MGN_VHT1SS_MCS3: 1117 case MGN_VHT1SS_MCS4: 1118 case MGN_VHT1SS_MCS5: 1119 case MGN_VHT1SS_MCS6: 1120 case MGN_VHT1SS_MCS7: 1121 case MGN_VHT1SS_MCS8: 1122 case MGN_VHT1SS_MCS9: 1123 index = 3; 1124 break; 1125 1126 case MGN_VHT2SS_MCS0: 1127 case MGN_VHT2SS_MCS1: 1128 case MGN_VHT2SS_MCS2: 1129 case MGN_VHT2SS_MCS3: 1130 case MGN_VHT2SS_MCS4: 1131 case MGN_VHT2SS_MCS5: 1132 case MGN_VHT2SS_MCS6: 1133 case MGN_VHT2SS_MCS7: 1134 case MGN_VHT2SS_MCS8: 1135 case MGN_VHT2SS_MCS9: 1136 index = 4; 1137 break; 1138 1139 default: 1140 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 1141 "Wrong rate 0x%x to obtain index in 5G in PHY_GetTxPowerByRateBaseIndex()\n", 1142 rate); 1143 break; 1144 } 1145 } 1146 1147 return index; 1148} 1149 1150static void _rtl8812ae_phy_convert_txpower_limit_to_power_index(struct ieee80211_hw *hw) 1151{ 1152 struct rtl_priv *rtlpriv = rtl_priv(hw); 1153 struct rtl_phy *rtlphy = &rtlpriv->phy; 1154 u8 bw40_pwr_base_dbm2_4G, bw40_pwr_base_dbm5G; 1155 u8 regulation, bw, channel, rate_section; 1156 u8 base_index2_4G = 0; 1157 u8 base_index5G = 0; 1158 char temp_value = 0, temp_pwrlmt = 0; 1159 u8 rf_path = 0; 1160 1161 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1162 "=====> _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n"); 1163 1164 _rtl8812ae_phy_cross_reference_ht_and_vht_txpower_limit(hw); 1165 1166 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { 1167 for (bw = 0; bw < MAX_2_4G_BANDWITH_NUM; ++bw) { 1168 for (channel = 0; channel < CHANNEL_MAX_NUMBER_2G; ++channel) { 1169 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) { 1170 /* obtain the base dBm values in 2.4G band 1171 CCK => 11M, OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15*/ 1172 if (rate_section == 0) { /*CCK*/ 1173 base_index2_4G = 1174 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, 1175 BAND_ON_2_4G, MGN_11M); 1176 } else if (rate_section == 1) { /*OFDM*/ 1177 base_index2_4G = 1178 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, 1179 BAND_ON_2_4G, MGN_54M); 1180 } else if (rate_section == 2) { /*HT IT*/ 1181 base_index2_4G = 1182 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, 1183 BAND_ON_2_4G, MGN_MCS7); 1184 } else if (rate_section == 3) { /*HT 2T*/ 1185 base_index2_4G = 1186 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, 1187 BAND_ON_2_4G, MGN_MCS15); 1188 } 1189 1190 temp_pwrlmt = rtlphy->txpwr_limit_2_4g[regulation] 1191 [bw][rate_section][channel][RF90_PATH_A]; 1192 1193 for (rf_path = RF90_PATH_A; 1194 rf_path < MAX_RF_PATH_NUM; 1195 ++rf_path) { 1196 if (rate_section == 3) 1197 bw40_pwr_base_dbm2_4G = 1198 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_2TX][base_index2_4G]; 1199 else 1200 bw40_pwr_base_dbm2_4G = 1201 rtlphy->txpwr_by_rate_base_24g[rf_path][RF_1TX][base_index2_4G]; 1202 1203 if (temp_pwrlmt != MAX_POWER_INDEX) { 1204 temp_value = temp_pwrlmt - bw40_pwr_base_dbm2_4G; 1205 rtlphy->txpwr_limit_2_4g[regulation] 1206 [bw][rate_section][channel][rf_path] = 1207 temp_value; 1208 } 1209 1210 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1211 "TxPwrLimit_2_4G[regulation %d][bw %d][rateSection %d][channel %d] = %d\n(TxPwrLimit in dBm %d - BW40PwrLmt2_4G[channel %d][rfPath %d] %d)\n", 1212 regulation, bw, rate_section, channel, 1213 rtlphy->txpwr_limit_2_4g[regulation][bw] 1214 [rate_section][channel][rf_path], (temp_pwrlmt == 63) 1215 ? 0 : temp_pwrlmt/2, channel, rf_path, 1216 bw40_pwr_base_dbm2_4G); 1217 } 1218 } 1219 } 1220 } 1221 } 1222 for (regulation = 0; regulation < MAX_REGULATION_NUM; ++regulation) { 1223 for (bw = 0; bw < MAX_5G_BANDWITH_NUM; ++bw) { 1224 for (channel = 0; channel < CHANNEL_MAX_NUMBER_5G; ++channel) { 1225 for (rate_section = 0; rate_section < MAX_RATE_SECTION_NUM; ++rate_section) { 1226 /* obtain the base dBm values in 5G band 1227 OFDM => 54M, HT 1T => MCS7, HT 2T => MCS15, 1228 VHT => 1SSMCS7, VHT 2T => 2SSMCS7*/ 1229 if (rate_section == 1) { /*OFDM*/ 1230 base_index5G = 1231 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, 1232 BAND_ON_5G, MGN_54M); 1233 } else if (rate_section == 2) { /*HT 1T*/ 1234 base_index5G = 1235 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, 1236 BAND_ON_5G, MGN_MCS7); 1237 } else if (rate_section == 3) { /*HT 2T*/ 1238 base_index5G = 1239 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, 1240 BAND_ON_5G, MGN_MCS15); 1241 } else if (rate_section == 4) { /*VHT 1T*/ 1242 base_index5G = 1243 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, 1244 BAND_ON_5G, MGN_VHT1SS_MCS7); 1245 } else if (rate_section == 5) { /*VHT 2T*/ 1246 base_index5G = 1247 _rtl8812ae_phy_get_txpower_by_rate_base_index(hw, 1248 BAND_ON_5G, MGN_VHT2SS_MCS7); 1249 } 1250 1251 temp_pwrlmt = rtlphy->txpwr_limit_5g[regulation] 1252 [bw][rate_section][channel] 1253 [RF90_PATH_A]; 1254 1255 for (rf_path = RF90_PATH_A; 1256 rf_path < MAX_RF_PATH_NUM; 1257 ++rf_path) { 1258 if (rate_section == 3 || rate_section == 5) 1259 bw40_pwr_base_dbm5G = 1260 rtlphy->txpwr_by_rate_base_5g[rf_path] 1261 [RF_2TX][base_index5G]; 1262 else 1263 bw40_pwr_base_dbm5G = 1264 rtlphy->txpwr_by_rate_base_5g[rf_path] 1265 [RF_1TX][base_index5G]; 1266 1267 if (temp_pwrlmt != MAX_POWER_INDEX) { 1268 temp_value = 1269 temp_pwrlmt - bw40_pwr_base_dbm5G; 1270 rtlphy->txpwr_limit_5g[regulation] 1271 [bw][rate_section][channel] 1272 [rf_path] = temp_value; 1273 } 1274 1275 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1276 "TxPwrLimit_5G[regulation %d][bw %d][rateSection %d][channel %d] =%d\n(TxPwrLimit in dBm %d - BW40PwrLmt5G[chnl group %d][rfPath %d] %d)\n", 1277 regulation, bw, rate_section, 1278 channel, rtlphy->txpwr_limit_5g[regulation] 1279 [bw][rate_section][channel][rf_path], 1280 temp_pwrlmt, channel, rf_path, bw40_pwr_base_dbm5G); 1281 } 1282 } 1283 } 1284 } 1285 } 1286 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1287 "<===== _rtl8812ae_phy_convert_txpower_limit_to_power_index()\n"); 1288} 1289 1290static void _rtl8821ae_phy_init_txpower_limit(struct ieee80211_hw *hw) 1291{ 1292 struct rtl_priv *rtlpriv = rtl_priv(hw); 1293 struct rtl_phy *rtlphy = &rtlpriv->phy; 1294 u8 i, j, k, l, m; 1295 1296 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 1297 "=====> _rtl8821ae_phy_init_txpower_limit()!\n"); 1298 1299 for (i = 0; i < MAX_REGULATION_NUM; ++i) { 1300 for (j = 0; j < MAX_2_4G_BANDWITH_NUM; ++j) 1301 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) 1302 for (m = 0; m < CHANNEL_MAX_NUMBER_2G; ++m) 1303 for (l = 0; l < MAX_RF_PATH_NUM; ++l) 1304 rtlphy->txpwr_limit_2_4g 1305 [i][j][k][m][l] 1306 = MAX_POWER_INDEX; 1307 } 1308 for (i = 0; i < MAX_REGULATION_NUM; ++i) { 1309 for (j = 0; j < MAX_5G_BANDWITH_NUM; ++j) 1310 for (k = 0; k < MAX_RATE_SECTION_NUM; ++k) 1311 for (m = 0; m < CHANNEL_MAX_NUMBER_5G; ++m) 1312 for (l = 0; l < MAX_RF_PATH_NUM; ++l) 1313 rtlphy->txpwr_limit_5g 1314 [i][j][k][m][l] 1315 = MAX_POWER_INDEX; 1316 } 1317 1318 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 1319 "<===== _rtl8821ae_phy_init_txpower_limit()!\n"); 1320} 1321 1322static void _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(struct ieee80211_hw *hw) 1323{ 1324 struct rtl_priv *rtlpriv = rtl_priv(hw); 1325 struct rtl_phy *rtlphy = &rtlpriv->phy; 1326 u8 base = 0, rfPath = 0; 1327 1328 for (rfPath = RF90_PATH_A; rfPath <= RF90_PATH_B; ++rfPath) { 1329 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, CCK); 1330 _phy_convert_txpower_dbm_to_relative_value( 1331 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][0], 1332 0, 3, base); 1333 1334 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, OFDM); 1335 _phy_convert_txpower_dbm_to_relative_value( 1336 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][1], 1337 0, 3, base); 1338 _phy_convert_txpower_dbm_to_relative_value( 1339 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][2], 1340 0, 3, base); 1341 1342 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, HT_MCS0_MCS7); 1343 _phy_convert_txpower_dbm_to_relative_value( 1344 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][3], 1345 0, 3, base); 1346 _phy_convert_txpower_dbm_to_relative_value( 1347 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][4], 1348 0, 3, base); 1349 1350 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, HT_MCS8_MCS15); 1351 1352 _phy_convert_txpower_dbm_to_relative_value( 1353 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][5], 1354 0, 3, base); 1355 1356 _phy_convert_txpower_dbm_to_relative_value( 1357 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][6], 1358 0, 3, base); 1359 1360 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9); 1361 _phy_convert_txpower_dbm_to_relative_value( 1362 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][7], 1363 0, 3, base); 1364 _phy_convert_txpower_dbm_to_relative_value( 1365 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][8], 1366 0, 3, base); 1367 _phy_convert_txpower_dbm_to_relative_value( 1368 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9], 1369 0, 1, base); 1370 1371 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9); 1372 _phy_convert_txpower_dbm_to_relative_value( 1373 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_1TX][9], 1374 2, 3, base); 1375 _phy_convert_txpower_dbm_to_relative_value( 1376 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][10], 1377 0, 3, base); 1378 _phy_convert_txpower_dbm_to_relative_value( 1379 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfPath][RF_2TX][11], 1380 0, 3, base); 1381 1382 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, OFDM); 1383 _phy_convert_txpower_dbm_to_relative_value( 1384 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][1], 1385 0, 3, base); 1386 _phy_convert_txpower_dbm_to_relative_value( 1387 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][2], 1388 0, 3, base); 1389 1390 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, HT_MCS0_MCS7); 1391 _phy_convert_txpower_dbm_to_relative_value( 1392 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][3], 1393 0, 3, base); 1394 _phy_convert_txpower_dbm_to_relative_value( 1395 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][4], 1396 0, 3, base); 1397 1398 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, HT_MCS8_MCS15); 1399 _phy_convert_txpower_dbm_to_relative_value( 1400 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][5], 1401 0, 3, base); 1402 _phy_convert_txpower_dbm_to_relative_value( 1403 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][6], 1404 0, 3, base); 1405 1406 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_1TX, VHT_1SSMCS0_1SSMCS9); 1407 _phy_convert_txpower_dbm_to_relative_value( 1408 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][7], 1409 0, 3, base); 1410 _phy_convert_txpower_dbm_to_relative_value( 1411 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][8], 1412 0, 3, base); 1413 _phy_convert_txpower_dbm_to_relative_value( 1414 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9], 1415 0, 1, base); 1416 1417 base = _rtl8821ae_phy_get_txpower_by_rate_base(hw, BAND_ON_5G, rfPath, RF_2TX, VHT_2SSMCS0_2SSMCS9); 1418 _phy_convert_txpower_dbm_to_relative_value( 1419 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_1TX][9], 1420 2, 3, base); 1421 _phy_convert_txpower_dbm_to_relative_value( 1422 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][10], 1423 0, 3, base); 1424 _phy_convert_txpower_dbm_to_relative_value( 1425 &rtlphy->tx_power_by_rate_offset[BAND_ON_5G][rfPath][RF_2TX][11], 1426 0, 3, base); 1427 } 1428 1429 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, 1430 "<===_rtl8821ae_phy_convert_txpower_dbm_to_relative_value()\n"); 1431} 1432 1433static void _rtl8821ae_phy_txpower_by_rate_configuration(struct ieee80211_hw *hw) 1434{ 1435 _rtl8821ae_phy_store_txpower_by_rate_base(hw); 1436 _rtl8821ae_phy_convert_txpower_dbm_to_relative_value(hw); 1437} 1438 1439/* string is in decimal */ 1440static bool _rtl8812ae_get_integer_from_string(char *str, u8 *pint) 1441{ 1442 u16 i = 0; 1443 *pint = 0; 1444 1445 while (str[i] != '\0') { 1446 if (str[i] >= '0' && str[i] <= '9') { 1447 *pint *= 10; 1448 *pint += (str[i] - '0'); 1449 } else { 1450 return false; 1451 } 1452 ++i; 1453 } 1454 1455 return true; 1456} 1457 1458static bool _rtl8812ae_eq_n_byte(u8 *str1, u8 *str2, u32 num) 1459{ 1460 if (num == 0) 1461 return false; 1462 while (num > 0) { 1463 num--; 1464 if (str1[num] != str2[num]) 1465 return false; 1466 } 1467 return true; 1468} 1469 1470static char _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(struct ieee80211_hw *hw, 1471 u8 band, u8 channel) 1472{ 1473 struct rtl_priv *rtlpriv = rtl_priv(hw); 1474 char channel_index = -1; 1475 u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = { 1476 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 64, 1477 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 120, 122, 1478 124, 126, 128, 130, 132, 134, 136, 138, 140, 142, 144, 149, 1479 151, 153, 155, 157, 159, 161, 163, 165, 167, 168, 169, 171, 1480 173, 175, 177}; 1481 u8 i = 0; 1482 if (band == BAND_ON_2_4G) 1483 channel_index = channel - 1; 1484 else if (band == BAND_ON_5G) { 1485 for (i = 0; i < sizeof(channel_5g)/sizeof(u8); ++i) { 1486 if (channel_5g[i] == channel) 1487 channel_index = i; 1488 } 1489 } else 1490 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Band %d in %s", 1491 band, __func__); 1492 1493 if (channel_index == -1) 1494 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 1495 "Invalid Channel %d of Band %d in %s", channel, 1496 band, __func__); 1497 1498 return channel_index; 1499} 1500 1501static void _rtl8812ae_phy_set_txpower_limit(struct ieee80211_hw *hw, u8 *pregulation, 1502 u8 *pband, u8 *pbandwidth, 1503 u8 *prate_section, u8 *prf_path, 1504 u8 *pchannel, u8 *ppower_limit) 1505{ 1506 struct rtl_priv *rtlpriv = rtl_priv(hw); 1507 struct rtl_phy *rtlphy = &rtlpriv->phy; 1508 u8 regulation = 0, bandwidth = 0, rate_section = 0, channel; 1509 u8 channel_index; 1510 char power_limit = 0, prev_power_limit, ret; 1511 1512 if (!_rtl8812ae_get_integer_from_string((char *)pchannel, &channel) || 1513 !_rtl8812ae_get_integer_from_string((char *)ppower_limit, 1514 &power_limit)) { 1515 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1516 "Illegal index of pwr_lmt table [chnl %d][val %d]\n", 1517 channel, power_limit); 1518 } 1519 1520 power_limit = power_limit > MAX_POWER_INDEX ? 1521 MAX_POWER_INDEX : power_limit; 1522 1523 if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("FCC"), 3)) 1524 regulation = 0; 1525 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("MKK"), 3)) 1526 regulation = 1; 1527 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("ETSI"), 4)) 1528 regulation = 2; 1529 else if (_rtl8812ae_eq_n_byte(pregulation, (u8 *)("WW13"), 4)) 1530 regulation = 3; 1531 1532 if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("CCK"), 3)) 1533 rate_section = 0; 1534 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("OFDM"), 4)) 1535 rate_section = 1; 1536 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) && 1537 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2)) 1538 rate_section = 2; 1539 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("HT"), 2) && 1540 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2)) 1541 rate_section = 3; 1542 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && 1543 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("1T"), 2)) 1544 rate_section = 4; 1545 else if (_rtl8812ae_eq_n_byte(prate_section, (u8 *)("VHT"), 3) && 1546 _rtl8812ae_eq_n_byte(prf_path, (u8 *)("2T"), 2)) 1547 rate_section = 5; 1548 1549 if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("20M"), 3)) 1550 bandwidth = 0; 1551 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("40M"), 3)) 1552 bandwidth = 1; 1553 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("80M"), 3)) 1554 bandwidth = 2; 1555 else if (_rtl8812ae_eq_n_byte(pbandwidth, (u8 *)("160M"), 4)) 1556 bandwidth = 3; 1557 1558 if (_rtl8812ae_eq_n_byte(pband, (u8 *)("2.4G"), 4)) { 1559 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, 1560 BAND_ON_2_4G, 1561 channel); 1562 1563 if (ret == -1) 1564 return; 1565 1566 channel_index = ret; 1567 1568 prev_power_limit = rtlphy->txpwr_limit_2_4g[regulation] 1569 [bandwidth][rate_section] 1570 [channel_index][RF90_PATH_A]; 1571 1572 if (power_limit < prev_power_limit) 1573 rtlphy->txpwr_limit_2_4g[regulation][bandwidth] 1574 [rate_section][channel_index][RF90_PATH_A] = 1575 power_limit; 1576 1577 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1578 "2.4G [regula %d][bw %d][sec %d][chnl %d][val %d]\n", 1579 regulation, bandwidth, rate_section, channel_index, 1580 rtlphy->txpwr_limit_2_4g[regulation][bandwidth] 1581 [rate_section][channel_index][RF90_PATH_A]); 1582 } else if (_rtl8812ae_eq_n_byte(pband, (u8 *)("5G"), 2)) { 1583 ret = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, 1584 BAND_ON_5G, 1585 channel); 1586 1587 if (ret == -1) 1588 return; 1589 1590 channel_index = ret; 1591 1592 prev_power_limit = rtlphy->txpwr_limit_5g[regulation][bandwidth] 1593 [rate_section][channel_index] 1594 [RF90_PATH_A]; 1595 1596 if (power_limit < prev_power_limit) 1597 rtlphy->txpwr_limit_5g[regulation][bandwidth] 1598 [rate_section][channel_index][RF90_PATH_A] = power_limit; 1599 1600 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1601 "5G: [regul %d][bw %d][sec %d][chnl %d][val %d]\n", 1602 regulation, bandwidth, rate_section, channel, 1603 rtlphy->txpwr_limit_5g[regulation][bandwidth] 1604 [rate_section][channel_index][RF90_PATH_A]); 1605 } else { 1606 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1607 "Cannot recognize the band info in %s\n", pband); 1608 return; 1609 } 1610} 1611 1612static void _rtl8812ae_phy_config_bb_txpwr_lmt(struct ieee80211_hw *hw, 1613 u8 *regulation, u8 *band, 1614 u8 *bandwidth, u8 *rate_section, 1615 u8 *rf_path, u8 *channel, 1616 u8 *power_limit) 1617{ 1618 _rtl8812ae_phy_set_txpower_limit(hw, regulation, band, bandwidth, 1619 rate_section, rf_path, channel, 1620 power_limit); 1621} 1622 1623static void _rtl8821ae_phy_read_and_config_txpwr_lmt(struct ieee80211_hw *hw) 1624{ 1625 struct rtl_priv *rtlpriv = rtl_priv(hw); 1626 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 1627 u32 i = 0; 1628 u32 array_len; 1629 u8 **array; 1630 1631 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 1632 array_len = RTL8812AE_TXPWR_LMT_ARRAY_LEN; 1633 array = RTL8812AE_TXPWR_LMT; 1634 } else { 1635 array_len = RTL8821AE_TXPWR_LMT_ARRAY_LEN; 1636 array = RTL8821AE_TXPWR_LMT; 1637 } 1638 1639 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1640 "\n"); 1641 1642 for (i = 0; i < array_len; i += 7) { 1643 u8 *regulation = array[i]; 1644 u8 *band = array[i+1]; 1645 u8 *bandwidth = array[i+2]; 1646 u8 *rate = array[i+3]; 1647 u8 *rf_path = array[i+4]; 1648 u8 *chnl = array[i+5]; 1649 u8 *val = array[i+6]; 1650 1651 _rtl8812ae_phy_config_bb_txpwr_lmt(hw, regulation, band, 1652 bandwidth, rate, rf_path, 1653 chnl, val); 1654 } 1655} 1656 1657static bool _rtl8821ae_phy_bb8821a_config_parafile(struct ieee80211_hw *hw) 1658{ 1659 struct rtl_priv *rtlpriv = rtl_priv(hw); 1660 struct rtl_phy *rtlphy = &rtlpriv->phy; 1661 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 1662 bool rtstatus; 1663 1664 _rtl8821ae_phy_init_txpower_limit(hw); 1665 1666 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */ 1667 if (rtlefuse->eeprom_regulatory != 2) 1668 _rtl8821ae_phy_read_and_config_txpwr_lmt(hw); 1669 1670 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw, 1671 BASEBAND_CONFIG_PHY_REG); 1672 if (rtstatus != true) { 1673 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!"); 1674 return false; 1675 } 1676 _rtl8821ae_phy_init_tx_power_by_rate(hw); 1677 if (rtlefuse->autoload_failflag == false) { 1678 rtstatus = _rtl8821ae_phy_config_bb_with_pgheaderfile(hw, 1679 BASEBAND_CONFIG_PHY_REG); 1680 } 1681 if (rtstatus != true) { 1682 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!"); 1683 return false; 1684 } 1685 1686 _rtl8821ae_phy_txpower_by_rate_configuration(hw); 1687 1688 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */ 1689 if (rtlefuse->eeprom_regulatory != 2) 1690 _rtl8812ae_phy_convert_txpower_limit_to_power_index(hw); 1691 1692 rtstatus = _rtl8821ae_phy_config_bb_with_headerfile(hw, 1693 BASEBAND_CONFIG_AGC_TAB); 1694 1695 if (rtstatus != true) { 1696 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); 1697 return false; 1698 } 1699 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw, 1700 RFPGA0_XA_HSSIPARAMETER2, 0x200)); 1701 return true; 1702} 1703 1704static bool _rtl8821ae_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) 1705{ 1706 struct rtl_priv *rtlpriv = rtl_priv(hw); 1707 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 1708 u32 i, v1, v2; 1709 u32 arraylength; 1710 u32 *ptrarray; 1711 1712 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read MAC_REG_Array\n"); 1713 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 1714 arraylength = RTL8821AEMAC_1T_ARRAYLEN; 1715 ptrarray = RTL8821AE_MAC_REG_ARRAY; 1716 } else { 1717 arraylength = RTL8812AEMAC_1T_ARRAYLEN; 1718 ptrarray = RTL8812AE_MAC_REG_ARRAY; 1719 } 1720 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 1721 "Img: MAC_REG_ARRAY LEN %d\n", arraylength); 1722 for (i = 0; i < arraylength; i += 2) { 1723 v1 = ptrarray[i]; 1724 v2 = (u8)ptrarray[i + 1]; 1725 if (v1 < 0xCDCDCDCD) { 1726 rtl_write_byte(rtlpriv, v1, (u8)v2); 1727 continue; 1728 } else { 1729 if (!_rtl8821ae_check_condition(hw, v1)) { 1730 /*Discard the following (offset, data) pairs*/ 1731 READ_NEXT_PAIR(ptrarray, v1, v2, i); 1732 while (v2 != 0xDEAD && 1733 v2 != 0xCDEF && 1734 v2 != 0xCDCD && i < arraylength - 2) { 1735 READ_NEXT_PAIR(ptrarray, v1, v2, i); 1736 } 1737 i -= 2; /* prevent from for-loop += 2*/ 1738 } else {/*Configure matched pairs and skip to end of if-else.*/ 1739 READ_NEXT_PAIR(ptrarray, v1, v2, i); 1740 while (v2 != 0xDEAD && 1741 v2 != 0xCDEF && 1742 v2 != 0xCDCD && i < arraylength - 2) { 1743 rtl_write_byte(rtlpriv, v1, v2); 1744 READ_NEXT_PAIR(ptrarray, v1, v2, i); 1745 } 1746 1747 while (v2 != 0xDEAD && i < arraylength - 2) 1748 READ_NEXT_PAIR(ptrarray, v1, v2, i); 1749 } 1750 } 1751 } 1752 return true; 1753} 1754 1755static bool _rtl8821ae_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, 1756 u8 configtype) 1757{ 1758 struct rtl_priv *rtlpriv = rtl_priv(hw); 1759 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 1760 int i; 1761 u32 *array_table; 1762 u16 arraylen; 1763 u32 v1 = 0, v2 = 0; 1764 1765 if (configtype == BASEBAND_CONFIG_PHY_REG) { 1766 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 1767 arraylen = RTL8812AEPHY_REG_1TARRAYLEN; 1768 array_table = RTL8812AE_PHY_REG_ARRAY; 1769 } else { 1770 arraylen = RTL8821AEPHY_REG_1TARRAYLEN; 1771 array_table = RTL8821AE_PHY_REG_ARRAY; 1772 } 1773 1774 for (i = 0; i < arraylen; i += 2) { 1775 v1 = array_table[i]; 1776 v2 = array_table[i + 1]; 1777 if (v1 < 0xCDCDCDCD) { 1778 _rtl8821ae_config_bb_reg(hw, v1, v2); 1779 continue; 1780 } else {/*This line is the start line of branch.*/ 1781 if (!_rtl8821ae_check_condition(hw, v1)) { 1782 /*Discard the following (offset, data) pairs*/ 1783 READ_NEXT_PAIR(array_table, v1, v2, i); 1784 while (v2 != 0xDEAD && 1785 v2 != 0xCDEF && 1786 v2 != 0xCDCD && 1787 i < arraylen - 2) { 1788 READ_NEXT_PAIR(array_table, v1, 1789 v2, i); 1790 } 1791 1792 i -= 2; /* prevent from for-loop += 2*/ 1793 } else {/*Configure matched pairs and skip to end of if-else.*/ 1794 READ_NEXT_PAIR(array_table, v1, v2, i); 1795 while (v2 != 0xDEAD && 1796 v2 != 0xCDEF && 1797 v2 != 0xCDCD && 1798 i < arraylen - 2) { 1799 _rtl8821ae_config_bb_reg(hw, v1, 1800 v2); 1801 READ_NEXT_PAIR(array_table, v1, 1802 v2, i); 1803 } 1804 1805 while (v2 != 0xDEAD && 1806 i < arraylen - 2) { 1807 READ_NEXT_PAIR(array_table, v1, 1808 v2, i); 1809 } 1810 } 1811 } 1812 } 1813 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { 1814 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 1815 arraylen = RTL8812AEAGCTAB_1TARRAYLEN; 1816 array_table = RTL8812AE_AGC_TAB_ARRAY; 1817 } else { 1818 arraylen = RTL8821AEAGCTAB_1TARRAYLEN; 1819 array_table = RTL8821AE_AGC_TAB_ARRAY; 1820 } 1821 1822 for (i = 0; i < arraylen; i = i + 2) { 1823 v1 = array_table[i]; 1824 v2 = array_table[i+1]; 1825 if (v1 < 0xCDCDCDCD) { 1826 rtl_set_bbreg(hw, v1, MASKDWORD, v2); 1827 udelay(1); 1828 continue; 1829 } else {/*This line is the start line of branch.*/ 1830 if (!_rtl8821ae_check_condition(hw, v1)) { 1831 /*Discard the following (offset, data) pairs*/ 1832 READ_NEXT_PAIR(array_table, v1, v2, i); 1833 while (v2 != 0xDEAD && 1834 v2 != 0xCDEF && 1835 v2 != 0xCDCD && 1836 i < arraylen - 2) { 1837 READ_NEXT_PAIR(array_table, v1, 1838 v2, i); 1839 } 1840 i -= 2; /* prevent from for-loop += 2*/ 1841 } else {/*Configure matched pairs and skip to end of if-else.*/ 1842 READ_NEXT_PAIR(array_table, v1, v2, i); 1843 while (v2 != 0xDEAD && 1844 v2 != 0xCDEF && 1845 v2 != 0xCDCD && 1846 i < arraylen - 2) { 1847 rtl_set_bbreg(hw, v1, MASKDWORD, 1848 v2); 1849 udelay(1); 1850 READ_NEXT_PAIR(array_table, v1, 1851 v2, i); 1852 } 1853 1854 while (v2 != 0xDEAD && 1855 i < arraylen - 2) { 1856 READ_NEXT_PAIR(array_table, v1, 1857 v2, i); 1858 } 1859 } 1860 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 1861 "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n", 1862 array_table[i], array_table[i + 1]); 1863 } 1864 } 1865 } 1866 return true; 1867} 1868 1869static u8 _rtl8821ae_get_rate_section_index(u32 regaddr) 1870{ 1871 u8 index = 0; 1872 regaddr &= 0xFFF; 1873 if (regaddr >= 0xC20 && regaddr <= 0xC4C) 1874 index = (u8)((regaddr - 0xC20) / 4); 1875 else if (regaddr >= 0xE20 && regaddr <= 0xE4C) 1876 index = (u8)((regaddr - 0xE20) / 4); 1877 else 1878 RT_ASSERT(!COMP_INIT, 1879 "Invalid RegAddr 0x%x\n", regaddr); 1880 return index; 1881} 1882 1883static void _rtl8821ae_store_tx_power_by_rate(struct ieee80211_hw *hw, 1884 u32 band, u32 rfpath, 1885 u32 txnum, u32 regaddr, 1886 u32 bitmask, u32 data) 1887{ 1888 struct rtl_priv *rtlpriv = rtl_priv(hw); 1889 struct rtl_phy *rtlphy = &rtlpriv->phy; 1890 u8 rate_section = _rtl8821ae_get_rate_section_index(regaddr); 1891 1892 if (band != BAND_ON_2_4G && band != BAND_ON_5G) { 1893 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid Band %d\n", band); 1894 band = BAND_ON_2_4G; 1895 } 1896 if (rfpath >= MAX_RF_PATH) { 1897 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid RfPath %d\n", rfpath); 1898 rfpath = MAX_RF_PATH - 1; 1899 } 1900 if (txnum >= MAX_RF_PATH) { 1901 RT_TRACE(rtlpriv, COMP_INIT, DBG_WARNING, "Invalid TxNum %d\n", txnum); 1902 txnum = MAX_RF_PATH - 1; 1903 } 1904 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data; 1905 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 1906 "TxPwrByRateOffset[Band %d][RfPath %d][TxNum %d][RateSection %d] = 0x%x\n", 1907 band, rfpath, txnum, rate_section, 1908 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section]); 1909} 1910 1911static bool _rtl8821ae_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, 1912 u8 configtype) 1913{ 1914 struct rtl_priv *rtlpriv = rtl_priv(hw); 1915 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 1916 int i; 1917 u32 *array; 1918 u16 arraylen; 1919 u32 v1, v2, v3, v4, v5, v6; 1920 1921 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE) { 1922 arraylen = RTL8812AEPHY_REG_ARRAY_PGLEN; 1923 array = RTL8812AE_PHY_REG_ARRAY_PG; 1924 } else { 1925 arraylen = RTL8821AEPHY_REG_ARRAY_PGLEN; 1926 array = RTL8821AE_PHY_REG_ARRAY_PG; 1927 } 1928 1929 if (configtype != BASEBAND_CONFIG_PHY_REG) { 1930 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE, 1931 "configtype != BaseBand_Config_PHY_REG\n"); 1932 return true; 1933 } 1934 for (i = 0; i < arraylen; i += 6) { 1935 v1 = array[i]; 1936 v2 = array[i+1]; 1937 v3 = array[i+2]; 1938 v4 = array[i+3]; 1939 v5 = array[i+4]; 1940 v6 = array[i+5]; 1941 1942 if (v1 < 0xCDCDCDCD) { 1943 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8812AE && 1944 (v4 == 0xfe || v4 == 0xffe)) { 1945 msleep(50); 1946 continue; 1947 } 1948 1949 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 1950 if (v4 == 0xfe) 1951 msleep(50); 1952 else if (v4 == 0xfd) 1953 mdelay(5); 1954 else if (v4 == 0xfc) 1955 mdelay(1); 1956 else if (v4 == 0xfb) 1957 udelay(50); 1958 else if (v4 == 0xfa) 1959 udelay(5); 1960 else if (v4 == 0xf9) 1961 udelay(1); 1962 } 1963 _rtl8821ae_store_tx_power_by_rate(hw, v1, v2, v3, 1964 v4, v5, v6); 1965 continue; 1966 } else { 1967 /*don't need the hw_body*/ 1968 if (!_rtl8821ae_check_condition(hw, v1)) { 1969 i += 2; /* skip the pair of expression*/ 1970 v1 = array[i]; 1971 v2 = array[i+1]; 1972 v3 = array[i+2]; 1973 while (v2 != 0xDEAD) { 1974 i += 3; 1975 v1 = array[i]; 1976 v2 = array[i+1]; 1977 v3 = array[i+2]; 1978 } 1979 } 1980 } 1981 } 1982 1983 return true; 1984} 1985 1986bool rtl8812ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, 1987 enum radio_path rfpath) 1988{ 1989 int i; 1990 bool rtstatus = true; 1991 u32 *radioa_array_table_a, *radioa_array_table_b; 1992 u16 radioa_arraylen_a, radioa_arraylen_b; 1993 struct rtl_priv *rtlpriv = rtl_priv(hw); 1994 u32 v1 = 0, v2 = 0; 1995 1996 radioa_arraylen_a = RTL8812AE_RADIOA_1TARRAYLEN; 1997 radioa_array_table_a = RTL8812AE_RADIOA_ARRAY; 1998 radioa_arraylen_b = RTL8812AE_RADIOB_1TARRAYLEN; 1999 radioa_array_table_b = RTL8812AE_RADIOB_ARRAY; 2000 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 2001 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen_a); 2002 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); 2003 rtstatus = true; 2004 switch (rfpath) { 2005 case RF90_PATH_A: 2006 for (i = 0; i < radioa_arraylen_a; i = i + 2) { 2007 v1 = radioa_array_table_a[i]; 2008 v2 = radioa_array_table_a[i+1]; 2009 if (v1 < 0xcdcdcdcd) { 2010 _rtl8821ae_config_rf_radio_a(hw, v1, v2); 2011 continue; 2012 } else{/*This line is the start line of branch.*/ 2013 if (!_rtl8821ae_check_condition(hw, v1)) { 2014 /*Discard the following (offset, data) pairs*/ 2015 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i); 2016 while (v2 != 0xDEAD && 2017 v2 != 0xCDEF && 2018 v2 != 0xCDCD && i < radioa_arraylen_a-2) 2019 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i); 2020 2021 i -= 2; /* prevent from for-loop += 2*/ 2022 } else {/*Configure matched pairs and skip to end of if-else.*/ 2023 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i); 2024 while (v2 != 0xDEAD && 2025 v2 != 0xCDEF && 2026 v2 != 0xCDCD && i < radioa_arraylen_a - 2) { 2027 _rtl8821ae_config_rf_radio_a(hw, v1, v2); 2028 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i); 2029 } 2030 2031 while (v2 != 0xDEAD && i < radioa_arraylen_a-2) 2032 READ_NEXT_PAIR(radioa_array_table_a, v1, v2, i); 2033 2034 } 2035 } 2036 } 2037 break; 2038 case RF90_PATH_B: 2039 for (i = 0; i < radioa_arraylen_b; i = i + 2) { 2040 v1 = radioa_array_table_b[i]; 2041 v2 = radioa_array_table_b[i+1]; 2042 if (v1 < 0xcdcdcdcd) { 2043 _rtl8821ae_config_rf_radio_b(hw, v1, v2); 2044 continue; 2045 } else{/*This line is the start line of branch.*/ 2046 if (!_rtl8821ae_check_condition(hw, v1)) { 2047 /*Discard the following (offset, data) pairs*/ 2048 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i); 2049 while (v2 != 0xDEAD && 2050 v2 != 0xCDEF && 2051 v2 != 0xCDCD && i < radioa_arraylen_b-2) 2052 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i); 2053 2054 i -= 2; /* prevent from for-loop += 2*/ 2055 } else {/*Configure matched pairs and skip to end of if-else.*/ 2056 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i); 2057 while (v2 != 0xDEAD && 2058 v2 != 0xCDEF && 2059 v2 != 0xCDCD && i < radioa_arraylen_b-2) { 2060 _rtl8821ae_config_rf_radio_b(hw, v1, v2); 2061 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i); 2062 } 2063 2064 while (v2 != 0xDEAD && i < radioa_arraylen_b-2) 2065 READ_NEXT_PAIR(radioa_array_table_b, v1, v2, i); 2066 } 2067 } 2068 } 2069 break; 2070 case RF90_PATH_C: 2071 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 2072 "switch case not process\n"); 2073 break; 2074 case RF90_PATH_D: 2075 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 2076 "switch case not process\n"); 2077 break; 2078 } 2079 return true; 2080} 2081 2082bool rtl8821ae_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, 2083 enum radio_path rfpath) 2084{ 2085 #define READ_NEXT_RF_PAIR(v1, v2, i) \ 2086 do { \ 2087 i += 2; \ 2088 v1 = radioa_array_table[i]; \ 2089 v2 = radioa_array_table[i+1]; \ 2090 } \ 2091 while (0) 2092 2093 int i; 2094 bool rtstatus = true; 2095 u32 *radioa_array_table; 2096 u16 radioa_arraylen; 2097 struct rtl_priv *rtlpriv = rtl_priv(hw); 2098 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */ 2099 u32 v1 = 0, v2 = 0; 2100 2101 radioa_arraylen = RTL8821AE_RADIOA_1TARRAYLEN; 2102 radioa_array_table = RTL8821AE_RADIOA_ARRAY; 2103 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 2104 "Radio_A:RTL8821AE_RADIOA_ARRAY %d\n", radioa_arraylen); 2105 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath); 2106 rtstatus = true; 2107 switch (rfpath) { 2108 case RF90_PATH_A: 2109 for (i = 0; i < radioa_arraylen; i = i + 2) { 2110 v1 = radioa_array_table[i]; 2111 v2 = radioa_array_table[i+1]; 2112 if (v1 < 0xcdcdcdcd) 2113 _rtl8821ae_config_rf_radio_a(hw, v1, v2); 2114 else{/*This line is the start line of branch.*/ 2115 if (!_rtl8821ae_check_condition(hw, v1)) { 2116 /*Discard the following (offset, data) pairs*/ 2117 READ_NEXT_RF_PAIR(v1, v2, i); 2118 while (v2 != 0xDEAD && 2119 v2 != 0xCDEF && 2120 v2 != 0xCDCD && i < radioa_arraylen - 2) 2121 READ_NEXT_RF_PAIR(v1, v2, i); 2122 2123 i -= 2; /* prevent from for-loop += 2*/ 2124 } else {/*Configure matched pairs and skip to end of if-else.*/ 2125 READ_NEXT_RF_PAIR(v1, v2, i); 2126 while (v2 != 0xDEAD && 2127 v2 != 0xCDEF && 2128 v2 != 0xCDCD && i < radioa_arraylen - 2) { 2129 _rtl8821ae_config_rf_radio_a(hw, v1, v2); 2130 READ_NEXT_RF_PAIR(v1, v2, i); 2131 } 2132 2133 while (v2 != 0xDEAD && i < radioa_arraylen - 2) 2134 READ_NEXT_RF_PAIR(v1, v2, i); 2135 } 2136 } 2137 } 2138 break; 2139 2140 case RF90_PATH_B: 2141 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 2142 "switch case not process\n"); 2143 break; 2144 case RF90_PATH_C: 2145 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 2146 "switch case not process\n"); 2147 break; 2148 case RF90_PATH_D: 2149 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 2150 "switch case not process\n"); 2151 break; 2152 } 2153 return true; 2154} 2155 2156void rtl8821ae_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) 2157{ 2158 struct rtl_priv *rtlpriv = rtl_priv(hw); 2159 struct rtl_phy *rtlphy = &rtlpriv->phy; 2160 2161 rtlphy->default_initialgain[0] = 2162 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); 2163 rtlphy->default_initialgain[1] = 2164 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); 2165 rtlphy->default_initialgain[2] = 2166 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); 2167 rtlphy->default_initialgain[3] = 2168 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); 2169 2170 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 2171 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", 2172 rtlphy->default_initialgain[0], 2173 rtlphy->default_initialgain[1], 2174 rtlphy->default_initialgain[2], 2175 rtlphy->default_initialgain[3]); 2176 2177 rtlphy->framesync = (u8)rtl_get_bbreg(hw, 2178 ROFDM0_RXDETECTOR3, MASKBYTE0); 2179 rtlphy->framesync_c34 = rtl_get_bbreg(hw, 2180 ROFDM0_RXDETECTOR2, MASKDWORD); 2181 2182 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 2183 "Default framesync (0x%x) = 0x%x\n", 2184 ROFDM0_RXDETECTOR3, rtlphy->framesync); 2185} 2186 2187static void phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) 2188{ 2189 struct rtl_priv *rtlpriv = rtl_priv(hw); 2190 struct rtl_phy *rtlphy = &rtlpriv->phy; 2191 2192 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; 2193 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; 2194 2195 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; 2196 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; 2197 2198 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; 2199 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; 2200 2201 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = RA_LSSIWRITE_8821A; 2202 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = RB_LSSIWRITE_8821A; 2203 2204 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RHSSIREAD_8821AE; 2205 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RHSSIREAD_8821AE; 2206 2207 rtlphy->phyreg_def[RF90_PATH_A].rf_rb = RA_SIREAD_8821A; 2208 rtlphy->phyreg_def[RF90_PATH_B].rf_rb = RB_SIREAD_8821A; 2209 2210 rtlphy->phyreg_def[RF90_PATH_A].rf_rbpi = RA_PIREAD_8821A; 2211 rtlphy->phyreg_def[RF90_PATH_B].rf_rbpi = RB_PIREAD_8821A; 2212} 2213 2214void rtl8821ae_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) 2215{ 2216 struct rtl_priv *rtlpriv = rtl_priv(hw); 2217 struct rtl_phy *rtlphy = &rtlpriv->phy; 2218 u8 txpwr_level; 2219 long txpwr_dbm; 2220 2221 txpwr_level = rtlphy->cur_cck_txpwridx; 2222 txpwr_dbm = _rtl8821ae_phy_txpwr_idx_to_dbm(hw, 2223 WIRELESS_MODE_B, txpwr_level); 2224 txpwr_level = rtlphy->cur_ofdm24g_txpwridx; 2225 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw, 2226 WIRELESS_MODE_G, 2227 txpwr_level) > txpwr_dbm) 2228 txpwr_dbm = 2229 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, 2230 txpwr_level); 2231 txpwr_level = rtlphy->cur_ofdm24g_txpwridx; 2232 if (_rtl8821ae_phy_txpwr_idx_to_dbm(hw, 2233 WIRELESS_MODE_N_24G, 2234 txpwr_level) > txpwr_dbm) 2235 txpwr_dbm = 2236 _rtl8821ae_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, 2237 txpwr_level); 2238 *powerlevel = txpwr_dbm; 2239} 2240 2241static bool _rtl8821ae_phy_get_chnl_index(u8 channel, u8 *chnl_index) 2242{ 2243 u8 channel_5g[CHANNEL_MAX_NUMBER_5G] = { 2244 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 56, 58, 60, 62, 2245 64, 100, 102, 104, 106, 108, 110, 112, 114, 116, 118, 2246 120, 122, 124, 126, 128, 130, 132, 134, 136, 138, 140, 2247 142, 144, 149, 151, 153, 155, 157, 159, 161, 163, 165, 2248 167, 168, 169, 171, 173, 175, 177 2249 }; 2250 u8 i = 0; 2251 bool in_24g = true; 2252 2253 if (channel <= 14) { 2254 in_24g = true; 2255 *chnl_index = channel - 1; 2256 } else { 2257 in_24g = false; 2258 2259 for (i = 0; i < CHANNEL_MAX_NUMBER_5G; ++i) { 2260 if (channel_5g[i] == channel) { 2261 *chnl_index = i; 2262 return in_24g; 2263 } 2264 } 2265 } 2266 return in_24g; 2267} 2268 2269static char _rtl8821ae_phy_get_ratesection_intxpower_byrate(u8 path, u8 rate) 2270{ 2271 char rate_section = 0; 2272 switch (rate) { 2273 case DESC_RATE1M: 2274 case DESC_RATE2M: 2275 case DESC_RATE5_5M: 2276 case DESC_RATE11M: 2277 rate_section = 0; 2278 break; 2279 case DESC_RATE6M: 2280 case DESC_RATE9M: 2281 case DESC_RATE12M: 2282 case DESC_RATE18M: 2283 rate_section = 1; 2284 break; 2285 case DESC_RATE24M: 2286 case DESC_RATE36M: 2287 case DESC_RATE48M: 2288 case DESC_RATE54M: 2289 rate_section = 2; 2290 break; 2291 case DESC_RATEMCS0: 2292 case DESC_RATEMCS1: 2293 case DESC_RATEMCS2: 2294 case DESC_RATEMCS3: 2295 rate_section = 3; 2296 break; 2297 case DESC_RATEMCS4: 2298 case DESC_RATEMCS5: 2299 case DESC_RATEMCS6: 2300 case DESC_RATEMCS7: 2301 rate_section = 4; 2302 break; 2303 case DESC_RATEMCS8: 2304 case DESC_RATEMCS9: 2305 case DESC_RATEMCS10: 2306 case DESC_RATEMCS11: 2307 rate_section = 5; 2308 break; 2309 case DESC_RATEMCS12: 2310 case DESC_RATEMCS13: 2311 case DESC_RATEMCS14: 2312 case DESC_RATEMCS15: 2313 rate_section = 6; 2314 break; 2315 case DESC_RATEVHT1SS_MCS0: 2316 case DESC_RATEVHT1SS_MCS1: 2317 case DESC_RATEVHT1SS_MCS2: 2318 case DESC_RATEVHT1SS_MCS3: 2319 rate_section = 7; 2320 break; 2321 case DESC_RATEVHT1SS_MCS4: 2322 case DESC_RATEVHT1SS_MCS5: 2323 case DESC_RATEVHT1SS_MCS6: 2324 case DESC_RATEVHT1SS_MCS7: 2325 rate_section = 8; 2326 break; 2327 case DESC_RATEVHT1SS_MCS8: 2328 case DESC_RATEVHT1SS_MCS9: 2329 case DESC_RATEVHT2SS_MCS0: 2330 case DESC_RATEVHT2SS_MCS1: 2331 rate_section = 9; 2332 break; 2333 case DESC_RATEVHT2SS_MCS2: 2334 case DESC_RATEVHT2SS_MCS3: 2335 case DESC_RATEVHT2SS_MCS4: 2336 case DESC_RATEVHT2SS_MCS5: 2337 rate_section = 10; 2338 break; 2339 case DESC_RATEVHT2SS_MCS6: 2340 case DESC_RATEVHT2SS_MCS7: 2341 case DESC_RATEVHT2SS_MCS8: 2342 case DESC_RATEVHT2SS_MCS9: 2343 rate_section = 11; 2344 break; 2345 default: 2346 RT_ASSERT(true, "Rate_Section is Illegal\n"); 2347 break; 2348 } 2349 2350 return rate_section; 2351} 2352 2353static char _rtl8812ae_phy_get_world_wide_limit(char *limit_table) 2354{ 2355 char min = limit_table[0]; 2356 u8 i = 0; 2357 2358 for (i = 0; i < MAX_REGULATION_NUM; ++i) { 2359 if (limit_table[i] < min) 2360 min = limit_table[i]; 2361 } 2362 return min; 2363} 2364 2365static char _rtl8812ae_phy_get_txpower_limit(struct ieee80211_hw *hw, 2366 u8 band, 2367 enum ht_channel_width bandwidth, 2368 enum radio_path rf_path, 2369 u8 rate, u8 channel) 2370{ 2371 struct rtl_priv *rtlpriv = rtl_priv(hw); 2372 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); 2373 struct rtl_phy *rtlphy = &rtlpriv->phy; 2374 short band_temp = -1, regulation = -1, bandwidth_temp = -1, 2375 rate_section = -1, channel_temp = -1; 2376 u16 bd, regu, bdwidth, sec, chnl; 2377 char power_limit = MAX_POWER_INDEX; 2378 2379 if (rtlefuse->eeprom_regulatory == 2) 2380 return MAX_POWER_INDEX; 2381 2382 regulation = TXPWR_LMT_WW; 2383 2384 if (band == BAND_ON_2_4G) 2385 band_temp = 0; 2386 else if (band == BAND_ON_5G) 2387 band_temp = 1; 2388 2389 if (bandwidth == HT_CHANNEL_WIDTH_20) 2390 bandwidth_temp = 0; 2391 else if (bandwidth == HT_CHANNEL_WIDTH_20_40) 2392 bandwidth_temp = 1; 2393 else if (bandwidth == HT_CHANNEL_WIDTH_80) 2394 bandwidth_temp = 2; 2395 2396 switch (rate) { 2397 case DESC_RATE1M: 2398 case DESC_RATE2M: 2399 case DESC_RATE5_5M: 2400 case DESC_RATE11M: 2401 rate_section = 0; 2402 break; 2403 case DESC_RATE6M: 2404 case DESC_RATE9M: 2405 case DESC_RATE12M: 2406 case DESC_RATE18M: 2407 case DESC_RATE24M: 2408 case DESC_RATE36M: 2409 case DESC_RATE48M: 2410 case DESC_RATE54M: 2411 rate_section = 1; 2412 break; 2413 case DESC_RATEMCS0: 2414 case DESC_RATEMCS1: 2415 case DESC_RATEMCS2: 2416 case DESC_RATEMCS3: 2417 case DESC_RATEMCS4: 2418 case DESC_RATEMCS5: 2419 case DESC_RATEMCS6: 2420 case DESC_RATEMCS7: 2421 rate_section = 2; 2422 break; 2423 case DESC_RATEMCS8: 2424 case DESC_RATEMCS9: 2425 case DESC_RATEMCS10: 2426 case DESC_RATEMCS11: 2427 case DESC_RATEMCS12: 2428 case DESC_RATEMCS13: 2429 case DESC_RATEMCS14: 2430 case DESC_RATEMCS15: 2431 rate_section = 3; 2432 break; 2433 case DESC_RATEVHT1SS_MCS0: 2434 case DESC_RATEVHT1SS_MCS1: 2435 case DESC_RATEVHT1SS_MCS2: 2436 case DESC_RATEVHT1SS_MCS3: 2437 case DESC_RATEVHT1SS_MCS4: 2438 case DESC_RATEVHT1SS_MCS5: 2439 case DESC_RATEVHT1SS_MCS6: 2440 case DESC_RATEVHT1SS_MCS7: 2441 case DESC_RATEVHT1SS_MCS8: 2442 case DESC_RATEVHT1SS_MCS9: 2443 rate_section = 4; 2444 break; 2445 case DESC_RATEVHT2SS_MCS0: 2446 case DESC_RATEVHT2SS_MCS1: 2447 case DESC_RATEVHT2SS_MCS2: 2448 case DESC_RATEVHT2SS_MCS3: 2449 case DESC_RATEVHT2SS_MCS4: 2450 case DESC_RATEVHT2SS_MCS5: 2451 case DESC_RATEVHT2SS_MCS6: 2452 case DESC_RATEVHT2SS_MCS7: 2453 case DESC_RATEVHT2SS_MCS8: 2454 case DESC_RATEVHT2SS_MCS9: 2455 rate_section = 5; 2456 break; 2457 default: 2458 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 2459 "Wrong rate 0x%x\n", rate); 2460 break; 2461 } 2462 2463 if (band_temp == BAND_ON_5G && rate_section == 0) 2464 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 2465 "Wrong rate 0x%x: No CCK in 5G Band\n", rate); 2466 2467 /*workaround for wrong index combination to obtain tx power limit, 2468 OFDM only exists in BW 20M*/ 2469 if (rate_section == 1) 2470 bandwidth_temp = 0; 2471 2472 /*workaround for wrong index combination to obtain tx power limit, 2473 *HT on 80M will reference to HT on 40M 2474 */ 2475 if ((rate_section == 2 || rate_section == 3) && band == BAND_ON_5G && 2476 bandwidth_temp == 2) 2477 bandwidth_temp = 1; 2478 2479 if (band == BAND_ON_2_4G) 2480 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, 2481 BAND_ON_2_4G, channel); 2482 else if (band == BAND_ON_5G) 2483 channel_temp = _rtl8812ae_phy_get_chnl_idx_of_txpwr_lmt(hw, 2484 BAND_ON_5G, channel); 2485 else if (band == BAND_ON_BOTH) 2486 ;/* BAND_ON_BOTH don't care temporarily */ 2487 2488 if (band_temp == -1 || regulation == -1 || bandwidth_temp == -1 || 2489 rate_section == -1 || channel_temp == -1) { 2490 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 2491 "Wrong index value to access power limit table [band %d][regulation %d][bandwidth %d][rf_path %d][rate_section %d][chnl %d]\n", 2492 band_temp, regulation, bandwidth_temp, rf_path, 2493 rate_section, channel_temp); 2494 return MAX_POWER_INDEX; 2495 } 2496 2497 bd = band_temp; 2498 regu = regulation; 2499 bdwidth = bandwidth_temp; 2500 sec = rate_section; 2501 chnl = channel_temp; 2502 2503 if (band == BAND_ON_2_4G) { 2504 char limits[10] = {0}; 2505 u8 i; 2506 2507 for (i = 0; i < 4; ++i) 2508 limits[i] = rtlphy->txpwr_limit_2_4g[i][bdwidth] 2509 [sec][chnl][rf_path]; 2510 2511 power_limit = (regulation == TXPWR_LMT_WW) ? 2512 _rtl8812ae_phy_get_world_wide_limit(limits) : 2513 rtlphy->txpwr_limit_2_4g[regu][bdwidth] 2514 [sec][chnl][rf_path]; 2515 } else if (band == BAND_ON_5G) { 2516 char limits[10] = {0}; 2517 u8 i; 2518 2519 for (i = 0; i < MAX_REGULATION_NUM; ++i) 2520 limits[i] = rtlphy->txpwr_limit_5g[i][bdwidth] 2521 [sec][chnl][rf_path]; 2522 2523 power_limit = (regulation == TXPWR_LMT_WW) ? 2524 _rtl8812ae_phy_get_world_wide_limit(limits) : 2525 rtlphy->txpwr_limit_5g[regu][chnl] 2526 [sec][chnl][rf_path]; 2527 } else { 2528 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, 2529 "No power limit table of the specified band\n"); 2530 } 2531 return power_limit; 2532} 2533 2534static char _rtl8821ae_phy_get_txpower_by_rate(struct ieee80211_hw *hw, 2535 u8 band, u8 path, u8 rate) 2536{ 2537 struct rtl_priv *rtlpriv = rtl_priv(hw); 2538 struct rtl_phy *rtlphy = &rtlpriv->phy; 2539 u8 shift = 0, rate_section, tx_num; 2540 char tx_pwr_diff = 0; 2541 char limit = 0; 2542 2543 rate_section = _rtl8821ae_phy_get_ratesection_intxpower_byrate(path, rate); 2544 tx_num = RF_TX_NUM_NONIMPLEMENT; 2545 2546 if (tx_num == RF_TX_NUM_NONIMPLEMENT) { 2547 if ((rate >= DESC_RATEMCS8 && rate <= DESC_RATEMCS15) || 2548 (rate >= DESC_RATEVHT2SS_MCS2 && rate <= DESC_RATEVHT2SS_MCS9)) 2549 tx_num = RF_2TX; 2550 else 2551 tx_num = RF_1TX; 2552 } 2553 2554 switch (rate) { 2555 case DESC_RATE1M: 2556 case DESC_RATE6M: 2557 case DESC_RATE24M: 2558 case DESC_RATEMCS0: 2559 case DESC_RATEMCS4: 2560 case DESC_RATEMCS8: 2561 case DESC_RATEMCS12: 2562 case DESC_RATEVHT1SS_MCS0: 2563 case DESC_RATEVHT1SS_MCS4: 2564 case DESC_RATEVHT1SS_MCS8: 2565 case DESC_RATEVHT2SS_MCS2: 2566 case DESC_RATEVHT2SS_MCS6: 2567 shift = 0; 2568 break; 2569 case DESC_RATE2M: 2570 case DESC_RATE9M: 2571 case DESC_RATE36M: 2572 case DESC_RATEMCS1: 2573 case DESC_RATEMCS5: 2574 case DESC_RATEMCS9: 2575 case DESC_RATEMCS13: 2576 case DESC_RATEVHT1SS_MCS1: 2577 case DESC_RATEVHT1SS_MCS5: 2578 case DESC_RATEVHT1SS_MCS9: 2579 case DESC_RATEVHT2SS_MCS3: 2580 case DESC_RATEVHT2SS_MCS7: 2581 shift = 8; 2582 break; 2583 case DESC_RATE5_5M: 2584 case DESC_RATE12M: 2585 case DESC_RATE48M: 2586 case DESC_RATEMCS2: 2587 case DESC_RATEMCS6: 2588 case DESC_RATEMCS10: 2589 case DESC_RATEMCS14: 2590 case DESC_RATEVHT1SS_MCS2: 2591 case DESC_RATEVHT1SS_MCS6: 2592 case DESC_RATEVHT2SS_MCS0: 2593 case DESC_RATEVHT2SS_MCS4: 2594 case DESC_RATEVHT2SS_MCS8: 2595 shift = 16; 2596 break; 2597 case DESC_RATE11M: 2598 case DESC_RATE18M: 2599 case DESC_RATE54M: 2600 case DESC_RATEMCS3: 2601 case DESC_RATEMCS7: 2602 case DESC_RATEMCS11: 2603 case DESC_RATEMCS15: 2604 case DESC_RATEVHT1SS_MCS3: 2605 case DESC_RATEVHT1SS_MCS7: 2606 case DESC_RATEVHT2SS_MCS1: 2607 case DESC_RATEVHT2SS_MCS5: 2608 case DESC_RATEVHT2SS_MCS9: 2609 shift = 24; 2610 break; 2611 default: 2612 RT_ASSERT(true, "Rate_Section is Illegal\n"); 2613 break; 2614 } 2615 2616 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][path] 2617 [tx_num][rate_section] >> shift) & 0xff; 2618 2619 /* RegEnableTxPowerLimit == 1 for 8812a & 8821a */ 2620 if (rtlpriv->efuse.eeprom_regulatory != 2) { 2621 limit = _rtl8812ae_phy_get_txpower_limit(hw, band, 2622 rtlphy->current_chan_bw, path, rate, 2623 rtlphy->current_channel); 2624 2625 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 || 2626 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) { 2627 if (limit < 0) { 2628 if (tx_pwr_diff < (-limit)) 2629 tx_pwr_diff = -limit; 2630 } 2631 } else { 2632 if (limit < 0) 2633 tx_pwr_diff = limit; 2634 else 2635 tx_pwr_diff = tx_pwr_diff > limit ? limit : tx_pwr_diff; 2636 } 2637 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2638 "Maximum power by rate %d, final power by rate %d\n", 2639 limit, tx_pwr_diff); 2640 } 2641 2642 return tx_pwr_diff; 2643} 2644 2645static u8 _rtl8821ae_get_txpower_index(struct ieee80211_hw *hw, u8 path, 2646 u8 rate, u8 bandwidth, u8 channel) 2647{ 2648 struct rtl_priv *rtlpriv = rtl_priv(hw); 2649 struct rtl_hal *rtlhal = rtl_hal(rtlpriv); 2650 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 2651 u8 index = (channel - 1); 2652 u8 txpower = 0; 2653 bool in_24g = false; 2654 char powerdiff_byrate = 0; 2655 2656 if (((rtlhal->current_bandtype == BAND_ON_2_4G) && 2657 (channel > 14 || channel < 1)) || 2658 ((rtlhal->current_bandtype == BAND_ON_5G) && (channel <= 14))) { 2659 index = 0; 2660 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, 2661 "Illegal channel!!\n"); 2662 } 2663 2664 in_24g = _rtl8821ae_phy_get_chnl_index(channel, &index); 2665 if (in_24g) { 2666 if (RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) 2667 txpower = rtlefuse->txpwrlevel_cck[path][index]; 2668 else if (DESC_RATE6M <= rate) 2669 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index]; 2670 else 2671 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "invalid rate\n"); 2672 2673 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M && 2674 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) 2675 txpower += rtlefuse->txpwr_legacyhtdiff[path][TX_1S]; 2676 2677 if (bandwidth == HT_CHANNEL_WIDTH_20) { 2678 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || 2679 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9)) 2680 txpower += rtlefuse->txpwr_ht20diff[path][TX_1S]; 2681 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || 2682 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9)) 2683 txpower += rtlefuse->txpwr_ht20diff[path][TX_2S]; 2684 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { 2685 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || 2686 (DESC_RATEVHT1SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9)) 2687 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S]; 2688 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || 2689 (DESC_RATEVHT2SS_MCS0 <= rate && rate <= DESC_RATEVHT2SS_MCS9)) 2690 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S]; 2691 } else if (bandwidth == HT_CHANNEL_WIDTH_80) { 2692 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || 2693 (DESC_RATEVHT1SS_MCS0 <= rate && 2694 rate <= DESC_RATEVHT2SS_MCS9)) 2695 txpower += rtlefuse->txpwr_ht40diff[path][TX_1S]; 2696 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || 2697 (DESC_RATEVHT2SS_MCS0 <= rate && 2698 rate <= DESC_RATEVHT2SS_MCS9)) 2699 txpower += rtlefuse->txpwr_ht40diff[path][TX_2S]; 2700 } 2701 } else { 2702 if (DESC_RATE6M <= rate) 2703 txpower = rtlefuse->txpwr_5g_bw40base[path][index]; 2704 else 2705 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_WARNING, 2706 "INVALID Rate.\n"); 2707 2708 if (DESC_RATE6M <= rate && rate <= DESC_RATE54M && 2709 !RTL8821AE_RX_HAL_IS_CCK_RATE(rate)) 2710 txpower += rtlefuse->txpwr_5g_ofdmdiff[path][TX_1S]; 2711 2712 if (bandwidth == HT_CHANNEL_WIDTH_20) { 2713 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || 2714 (DESC_RATEVHT1SS_MCS0 <= rate && 2715 rate <= DESC_RATEVHT2SS_MCS9)) 2716 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_1S]; 2717 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || 2718 (DESC_RATEVHT2SS_MCS0 <= rate && 2719 rate <= DESC_RATEVHT2SS_MCS9)) 2720 txpower += rtlefuse->txpwr_5g_bw20diff[path][TX_2S]; 2721 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) { 2722 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || 2723 (DESC_RATEVHT1SS_MCS0 <= rate && 2724 rate <= DESC_RATEVHT2SS_MCS9)) 2725 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_1S]; 2726 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || 2727 (DESC_RATEVHT2SS_MCS0 <= rate && 2728 rate <= DESC_RATEVHT2SS_MCS9)) 2729 txpower += rtlefuse->txpwr_5g_bw40diff[path][TX_2S]; 2730 } else if (bandwidth == HT_CHANNEL_WIDTH_80) { 2731 u8 channel_5g_80m[CHANNEL_MAX_NUMBER_5G_80M] = { 2732 42, 58, 106, 122, 138, 155, 171 2733 }; 2734 u8 i; 2735 2736 for (i = 0; i < sizeof(channel_5g_80m) / sizeof(u8); ++i) 2737 if (channel_5g_80m[i] == channel) 2738 index = i; 2739 2740 if ((DESC_RATEMCS0 <= rate && rate <= DESC_RATEMCS15) || 2741 (DESC_RATEVHT1SS_MCS0 <= rate && 2742 rate <= DESC_RATEVHT2SS_MCS9)) 2743 txpower = rtlefuse->txpwr_5g_bw80base[path][index] 2744 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S]; 2745 if ((DESC_RATEMCS8 <= rate && rate <= DESC_RATEMCS15) || 2746 (DESC_RATEVHT2SS_MCS0 <= rate && 2747 rate <= DESC_RATEVHT2SS_MCS9)) 2748 txpower = rtlefuse->txpwr_5g_bw80base[path][index] 2749 + rtlefuse->txpwr_5g_bw80diff[path][TX_1S] 2750 + rtlefuse->txpwr_5g_bw80diff[path][TX_2S]; 2751 } 2752 } 2753 if (rtlefuse->eeprom_regulatory != 2) 2754 powerdiff_byrate = 2755 _rtl8821ae_phy_get_txpower_by_rate(hw, (u8)(!in_24g), 2756 path, rate); 2757 2758 if (rate == DESC_RATEVHT1SS_MCS8 || rate == DESC_RATEVHT1SS_MCS9 || 2759 rate == DESC_RATEVHT2SS_MCS8 || rate == DESC_RATEVHT2SS_MCS9) 2760 txpower -= powerdiff_byrate; 2761 else 2762 txpower += powerdiff_byrate; 2763 2764 if (rate > DESC_RATE11M) 2765 txpower += rtlpriv->dm.remnant_ofdm_swing_idx[path]; 2766 else 2767 txpower += rtlpriv->dm.remnant_cck_idx; 2768 2769 if (txpower > MAX_POWER_INDEX) 2770 txpower = MAX_POWER_INDEX; 2771 2772 return txpower; 2773} 2774 2775static void _rtl8821ae_phy_set_txpower_index(struct ieee80211_hw *hw, 2776 u8 power_index, u8 path, u8 rate) 2777{ 2778 struct rtl_priv *rtlpriv = rtl_priv(hw); 2779 2780 if (path == RF90_PATH_A) { 2781 switch (rate) { 2782 case DESC_RATE1M: 2783 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, 2784 MASKBYTE0, power_index); 2785 break; 2786 case DESC_RATE2M: 2787 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, 2788 MASKBYTE1, power_index); 2789 break; 2790 case DESC_RATE5_5M: 2791 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, 2792 MASKBYTE2, power_index); 2793 break; 2794 case DESC_RATE11M: 2795 rtl_set_bbreg(hw, RTXAGC_A_CCK11_CCK1, 2796 MASKBYTE3, power_index); 2797 break; 2798 case DESC_RATE6M: 2799 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, 2800 MASKBYTE0, power_index); 2801 break; 2802 case DESC_RATE9M: 2803 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, 2804 MASKBYTE1, power_index); 2805 break; 2806 case DESC_RATE12M: 2807 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, 2808 MASKBYTE2, power_index); 2809 break; 2810 case DESC_RATE18M: 2811 rtl_set_bbreg(hw, RTXAGC_A_OFDM18_OFDM6, 2812 MASKBYTE3, power_index); 2813 break; 2814 case DESC_RATE24M: 2815 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, 2816 MASKBYTE0, power_index); 2817 break; 2818 case DESC_RATE36M: 2819 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, 2820 MASKBYTE1, power_index); 2821 break; 2822 case DESC_RATE48M: 2823 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, 2824 MASKBYTE2, power_index); 2825 break; 2826 case DESC_RATE54M: 2827 rtl_set_bbreg(hw, RTXAGC_A_OFDM54_OFDM24, 2828 MASKBYTE3, power_index); 2829 break; 2830 case DESC_RATEMCS0: 2831 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, 2832 MASKBYTE0, power_index); 2833 break; 2834 case DESC_RATEMCS1: 2835 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, 2836 MASKBYTE1, power_index); 2837 break; 2838 case DESC_RATEMCS2: 2839 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, 2840 MASKBYTE2, power_index); 2841 break; 2842 case DESC_RATEMCS3: 2843 rtl_set_bbreg(hw, RTXAGC_A_MCS03_MCS00, 2844 MASKBYTE3, power_index); 2845 break; 2846 case DESC_RATEMCS4: 2847 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, 2848 MASKBYTE0, power_index); 2849 break; 2850 case DESC_RATEMCS5: 2851 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, 2852 MASKBYTE1, power_index); 2853 break; 2854 case DESC_RATEMCS6: 2855 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, 2856 MASKBYTE2, power_index); 2857 break; 2858 case DESC_RATEMCS7: 2859 rtl_set_bbreg(hw, RTXAGC_A_MCS07_MCS04, 2860 MASKBYTE3, power_index); 2861 break; 2862 case DESC_RATEMCS8: 2863 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, 2864 MASKBYTE0, power_index); 2865 break; 2866 case DESC_RATEMCS9: 2867 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, 2868 MASKBYTE1, power_index); 2869 break; 2870 case DESC_RATEMCS10: 2871 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, 2872 MASKBYTE2, power_index); 2873 break; 2874 case DESC_RATEMCS11: 2875 rtl_set_bbreg(hw, RTXAGC_A_MCS11_MCS08, 2876 MASKBYTE3, power_index); 2877 break; 2878 case DESC_RATEMCS12: 2879 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, 2880 MASKBYTE0, power_index); 2881 break; 2882 case DESC_RATEMCS13: 2883 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, 2884 MASKBYTE1, power_index); 2885 break; 2886 case DESC_RATEMCS14: 2887 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, 2888 MASKBYTE2, power_index); 2889 break; 2890 case DESC_RATEMCS15: 2891 rtl_set_bbreg(hw, RTXAGC_A_MCS15_MCS12, 2892 MASKBYTE3, power_index); 2893 break; 2894 case DESC_RATEVHT1SS_MCS0: 2895 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, 2896 MASKBYTE0, power_index); 2897 break; 2898 case DESC_RATEVHT1SS_MCS1: 2899 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, 2900 MASKBYTE1, power_index); 2901 break; 2902 case DESC_RATEVHT1SS_MCS2: 2903 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, 2904 MASKBYTE2, power_index); 2905 break; 2906 case DESC_RATEVHT1SS_MCS3: 2907 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX3_NSS1INDEX0, 2908 MASKBYTE3, power_index); 2909 break; 2910 case DESC_RATEVHT1SS_MCS4: 2911 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, 2912 MASKBYTE0, power_index); 2913 break; 2914 case DESC_RATEVHT1SS_MCS5: 2915 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, 2916 MASKBYTE1, power_index); 2917 break; 2918 case DESC_RATEVHT1SS_MCS6: 2919 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, 2920 MASKBYTE2, power_index); 2921 break; 2922 case DESC_RATEVHT1SS_MCS7: 2923 rtl_set_bbreg(hw, RTXAGC_A_NSS1INDEX7_NSS1INDEX4, 2924 MASKBYTE3, power_index); 2925 break; 2926 case DESC_RATEVHT1SS_MCS8: 2927 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, 2928 MASKBYTE0, power_index); 2929 break; 2930 case DESC_RATEVHT1SS_MCS9: 2931 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, 2932 MASKBYTE1, power_index); 2933 break; 2934 case DESC_RATEVHT2SS_MCS0: 2935 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, 2936 MASKBYTE2, power_index); 2937 break; 2938 case DESC_RATEVHT2SS_MCS1: 2939 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX1_NSS1INDEX8, 2940 MASKBYTE3, power_index); 2941 break; 2942 case DESC_RATEVHT2SS_MCS2: 2943 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, 2944 MASKBYTE0, power_index); 2945 break; 2946 case DESC_RATEVHT2SS_MCS3: 2947 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, 2948 MASKBYTE1, power_index); 2949 break; 2950 case DESC_RATEVHT2SS_MCS4: 2951 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, 2952 MASKBYTE2, power_index); 2953 break; 2954 case DESC_RATEVHT2SS_MCS5: 2955 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX5_NSS2INDEX2, 2956 MASKBYTE3, power_index); 2957 break; 2958 case DESC_RATEVHT2SS_MCS6: 2959 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, 2960 MASKBYTE0, power_index); 2961 break; 2962 case DESC_RATEVHT2SS_MCS7: 2963 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, 2964 MASKBYTE1, power_index); 2965 break; 2966 case DESC_RATEVHT2SS_MCS8: 2967 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, 2968 MASKBYTE2, power_index); 2969 break; 2970 case DESC_RATEVHT2SS_MCS9: 2971 rtl_set_bbreg(hw, RTXAGC_A_NSS2INDEX9_NSS2INDEX6, 2972 MASKBYTE3, power_index); 2973 break; 2974 default: 2975 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 2976 "Invalid Rate!!\n"); 2977 break; 2978 } 2979 } else if (path == RF90_PATH_B) { 2980 switch (rate) { 2981 case DESC_RATE1M: 2982 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, 2983 MASKBYTE0, power_index); 2984 break; 2985 case DESC_RATE2M: 2986 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, 2987 MASKBYTE1, power_index); 2988 break; 2989 case DESC_RATE5_5M: 2990 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, 2991 MASKBYTE2, power_index); 2992 break; 2993 case DESC_RATE11M: 2994 rtl_set_bbreg(hw, RTXAGC_B_CCK11_CCK1, 2995 MASKBYTE3, power_index); 2996 break; 2997 case DESC_RATE6M: 2998 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, 2999 MASKBYTE0, power_index); 3000 break; 3001 case DESC_RATE9M: 3002 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, 3003 MASKBYTE1, power_index); 3004 break; 3005 case DESC_RATE12M: 3006 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, 3007 MASKBYTE2, power_index); 3008 break; 3009 case DESC_RATE18M: 3010 rtl_set_bbreg(hw, RTXAGC_B_OFDM18_OFDM6, 3011 MASKBYTE3, power_index); 3012 break; 3013 case DESC_RATE24M: 3014 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, 3015 MASKBYTE0, power_index); 3016 break; 3017 case DESC_RATE36M: 3018 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, 3019 MASKBYTE1, power_index); 3020 break; 3021 case DESC_RATE48M: 3022 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, 3023 MASKBYTE2, power_index); 3024 break; 3025 case DESC_RATE54M: 3026 rtl_set_bbreg(hw, RTXAGC_B_OFDM54_OFDM24, 3027 MASKBYTE3, power_index); 3028 break; 3029 case DESC_RATEMCS0: 3030 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, 3031 MASKBYTE0, power_index); 3032 break; 3033 case DESC_RATEMCS1: 3034 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, 3035 MASKBYTE1, power_index); 3036 break; 3037 case DESC_RATEMCS2: 3038 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, 3039 MASKBYTE2, power_index); 3040 break; 3041 case DESC_RATEMCS3: 3042 rtl_set_bbreg(hw, RTXAGC_B_MCS03_MCS00, 3043 MASKBYTE3, power_index); 3044 break; 3045 case DESC_RATEMCS4: 3046 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, 3047 MASKBYTE0, power_index); 3048 break; 3049 case DESC_RATEMCS5: 3050 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, 3051 MASKBYTE1, power_index); 3052 break; 3053 case DESC_RATEMCS6: 3054 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, 3055 MASKBYTE2, power_index); 3056 break; 3057 case DESC_RATEMCS7: 3058 rtl_set_bbreg(hw, RTXAGC_B_MCS07_MCS04, 3059 MASKBYTE3, power_index); 3060 break; 3061 case DESC_RATEMCS8: 3062 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, 3063 MASKBYTE0, power_index); 3064 break; 3065 case DESC_RATEMCS9: 3066 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, 3067 MASKBYTE1, power_index); 3068 break; 3069 case DESC_RATEMCS10: 3070 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, 3071 MASKBYTE2, power_index); 3072 break; 3073 case DESC_RATEMCS11: 3074 rtl_set_bbreg(hw, RTXAGC_B_MCS11_MCS08, 3075 MASKBYTE3, power_index); 3076 break; 3077 case DESC_RATEMCS12: 3078 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, 3079 MASKBYTE0, power_index); 3080 break; 3081 case DESC_RATEMCS13: 3082 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, 3083 MASKBYTE1, power_index); 3084 break; 3085 case DESC_RATEMCS14: 3086 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, 3087 MASKBYTE2, power_index); 3088 break; 3089 case DESC_RATEMCS15: 3090 rtl_set_bbreg(hw, RTXAGC_B_MCS15_MCS12, 3091 MASKBYTE3, power_index); 3092 break; 3093 case DESC_RATEVHT1SS_MCS0: 3094 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, 3095 MASKBYTE0, power_index); 3096 break; 3097 case DESC_RATEVHT1SS_MCS1: 3098 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, 3099 MASKBYTE1, power_index); 3100 break; 3101 case DESC_RATEVHT1SS_MCS2: 3102 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, 3103 MASKBYTE2, power_index); 3104 break; 3105 case DESC_RATEVHT1SS_MCS3: 3106 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX3_NSS1INDEX0, 3107 MASKBYTE3, power_index); 3108 break; 3109 case DESC_RATEVHT1SS_MCS4: 3110 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, 3111 MASKBYTE0, power_index); 3112 break; 3113 case DESC_RATEVHT1SS_MCS5: 3114 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, 3115 MASKBYTE1, power_index); 3116 break; 3117 case DESC_RATEVHT1SS_MCS6: 3118 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, 3119 MASKBYTE2, power_index); 3120 break; 3121 case DESC_RATEVHT1SS_MCS7: 3122 rtl_set_bbreg(hw, RTXAGC_B_NSS1INDEX7_NSS1INDEX4, 3123 MASKBYTE3, power_index); 3124 break; 3125 case DESC_RATEVHT1SS_MCS8: 3126 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, 3127 MASKBYTE0, power_index); 3128 break; 3129 case DESC_RATEVHT1SS_MCS9: 3130 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, 3131 MASKBYTE1, power_index); 3132 break; 3133 case DESC_RATEVHT2SS_MCS0: 3134 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, 3135 MASKBYTE2, power_index); 3136 break; 3137 case DESC_RATEVHT2SS_MCS1: 3138 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX1_NSS1INDEX8, 3139 MASKBYTE3, power_index); 3140 break; 3141 case DESC_RATEVHT2SS_MCS2: 3142 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, 3143 MASKBYTE0, power_index); 3144 break; 3145 case DESC_RATEVHT2SS_MCS3: 3146 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, 3147 MASKBYTE1, power_index); 3148 break; 3149 case DESC_RATEVHT2SS_MCS4: 3150 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, 3151 MASKBYTE2, power_index); 3152 break; 3153 case DESC_RATEVHT2SS_MCS5: 3154 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX5_NSS2INDEX2, 3155 MASKBYTE3, power_index); 3156 break; 3157 case DESC_RATEVHT2SS_MCS6: 3158 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, 3159 MASKBYTE0, power_index); 3160 break; 3161 case DESC_RATEVHT2SS_MCS7: 3162 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, 3163 MASKBYTE1, power_index); 3164 break; 3165 case DESC_RATEVHT2SS_MCS8: 3166 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, 3167 MASKBYTE2, power_index); 3168 break; 3169 case DESC_RATEVHT2SS_MCS9: 3170 rtl_set_bbreg(hw, RTXAGC_B_NSS2INDEX9_NSS2INDEX6, 3171 MASKBYTE3, power_index); 3172 break; 3173 default: 3174 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 3175 "Invalid Rate!!\n"); 3176 break; 3177 } 3178 } else { 3179 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, 3180 "Invalid RFPath!!\n"); 3181 } 3182} 3183 3184static void _rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, 3185 u8 *array, u8 path, 3186 u8 channel, u8 size) 3187{ 3188 struct rtl_priv *rtlpriv = rtl_priv(hw); 3189 struct rtl_phy *rtlphy = &rtlpriv->phy; 3190 u8 i; 3191 u8 power_index; 3192 3193 for (i = 0; i < size; i++) { 3194 power_index = 3195 _rtl8821ae_get_txpower_index(hw, path, array[i], 3196 rtlphy->current_chan_bw, 3197 channel); 3198 _rtl8821ae_phy_set_txpower_index(hw, power_index, path, 3199 array[i]); 3200 } 3201} 3202 3203static void _rtl8821ae_phy_txpower_training_by_path(struct ieee80211_hw *hw, 3204 u8 bw, u8 channel, u8 path) 3205{ 3206 struct rtl_priv *rtlpriv = rtl_priv(hw); 3207 struct rtl_phy *rtlphy = &rtlpriv->phy; 3208 3209 u8 i; 3210 u32 power_level, data, offset; 3211 3212 if (path >= rtlphy->num_total_rfpath) 3213 return; 3214 3215 data = 0; 3216 if (path == RF90_PATH_A) { 3217 power_level = 3218 _rtl8821ae_get_txpower_index(hw, RF90_PATH_A, 3219 DESC_RATEMCS7, bw, channel); 3220 offset = RA_TXPWRTRAING; 3221 } else { 3222 power_level = 3223 _rtl8821ae_get_txpower_index(hw, RF90_PATH_B, 3224 DESC_RATEMCS7, bw, channel); 3225 offset = RB_TXPWRTRAING; 3226 } 3227 3228 for (i = 0; i < 3; i++) { 3229 if (i == 0) 3230 power_level = power_level - 10; 3231 else if (i == 1) 3232 power_level = power_level - 8; 3233 else 3234 power_level = power_level - 6; 3235 3236 data |= (((power_level > 2) ? (power_level) : 2) << (i * 8)); 3237 } 3238 rtl_set_bbreg(hw, offset, 0xffffff, data); 3239} 3240 3241void rtl8821ae_phy_set_txpower_level_by_path(struct ieee80211_hw *hw, 3242 u8 channel, u8 path) 3243{ 3244 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */ 3245 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3246 struct rtl_priv *rtlpriv = rtl_priv(hw); 3247 struct rtl_phy *rtlphy = &rtlpriv->phy; 3248 u8 cck_rates[] = {DESC_RATE1M, DESC_RATE2M, DESC_RATE5_5M, 3249 DESC_RATE11M}; 3250 u8 sizes_of_cck_retes = 4; 3251 u8 ofdm_rates[] = {DESC_RATE6M, DESC_RATE9M, DESC_RATE12M, 3252 DESC_RATE18M, DESC_RATE24M, DESC_RATE36M, 3253 DESC_RATE48M, DESC_RATE54M}; 3254 u8 sizes_of_ofdm_retes = 8; 3255 u8 ht_rates_1t[] = {DESC_RATEMCS0, DESC_RATEMCS1, DESC_RATEMCS2, 3256 DESC_RATEMCS3, DESC_RATEMCS4, DESC_RATEMCS5, 3257 DESC_RATEMCS6, DESC_RATEMCS7}; 3258 u8 sizes_of_ht_retes_1t = 8; 3259 u8 ht_rates_2t[] = {DESC_RATEMCS8, DESC_RATEMCS9, 3260 DESC_RATEMCS10, DESC_RATEMCS11, 3261 DESC_RATEMCS12, DESC_RATEMCS13, 3262 DESC_RATEMCS14, DESC_RATEMCS15}; 3263 u8 sizes_of_ht_retes_2t = 8; 3264 u8 vht_rates_1t[] = {DESC_RATEVHT1SS_MCS0, DESC_RATEVHT1SS_MCS1, 3265 DESC_RATEVHT1SS_MCS2, DESC_RATEVHT1SS_MCS3, 3266 DESC_RATEVHT1SS_MCS4, DESC_RATEVHT1SS_MCS5, 3267 DESC_RATEVHT1SS_MCS6, DESC_RATEVHT1SS_MCS7, 3268 DESC_RATEVHT1SS_MCS8, DESC_RATEVHT1SS_MCS9}; 3269 u8 vht_rates_2t[] = {DESC_RATEVHT2SS_MCS0, DESC_RATEVHT2SS_MCS1, 3270 DESC_RATEVHT2SS_MCS2, DESC_RATEVHT2SS_MCS3, 3271 DESC_RATEVHT2SS_MCS4, DESC_RATEVHT2SS_MCS5, 3272 DESC_RATEVHT2SS_MCS6, DESC_RATEVHT2SS_MCS7, 3273 DESC_RATEVHT2SS_MCS8, DESC_RATEVHT2SS_MCS9}; 3274 u8 sizes_of_vht_retes = 10; 3275 3276 if (rtlhal->current_bandtype == BAND_ON_2_4G) 3277 _rtl8821ae_phy_set_txpower_level_by_path(hw, cck_rates, path, channel, 3278 sizes_of_cck_retes); 3279 3280 _rtl8821ae_phy_set_txpower_level_by_path(hw, ofdm_rates, path, channel, 3281 sizes_of_ofdm_retes); 3282 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_1t, path, channel, 3283 sizes_of_ht_retes_1t); 3284 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_1t, path, channel, 3285 sizes_of_vht_retes); 3286 3287 if (rtlphy->num_total_rfpath >= 2) { 3288 _rtl8821ae_phy_set_txpower_level_by_path(hw, ht_rates_2t, path, 3289 channel, 3290 sizes_of_ht_retes_2t); 3291 _rtl8821ae_phy_set_txpower_level_by_path(hw, vht_rates_2t, path, 3292 channel, 3293 sizes_of_vht_retes); 3294 } 3295 3296 _rtl8821ae_phy_txpower_training_by_path(hw, rtlphy->current_chan_bw, 3297 channel, path); 3298} 3299 3300/*just in case, write txpower in DW, to reduce time*/ 3301void rtl8821ae_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) 3302{ 3303 struct rtl_priv *rtlpriv = rtl_priv(hw); 3304 struct rtl_phy *rtlphy = &rtlpriv->phy; 3305 u8 path = 0; 3306 3307 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; ++path) 3308 rtl8821ae_phy_set_txpower_level_by_path(hw, channel, path); 3309} 3310 3311static long _rtl8821ae_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, 3312 enum wireless_mode wirelessmode, 3313 u8 txpwridx) 3314{ 3315 long offset; 3316 long pwrout_dbm; 3317 3318 switch (wirelessmode) { 3319 case WIRELESS_MODE_B: 3320 offset = -7; 3321 break; 3322 case WIRELESS_MODE_G: 3323 case WIRELESS_MODE_N_24G: 3324 offset = -8; 3325 break; 3326 default: 3327 offset = -8; 3328 break; 3329 } 3330 pwrout_dbm = txpwridx / 2 + offset; 3331 return pwrout_dbm; 3332} 3333 3334void rtl8821ae_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) 3335{ 3336 struct rtl_priv *rtlpriv = rtl_priv(hw); 3337 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3338 enum io_type iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; 3339 3340 if (!is_hal_stop(rtlhal)) { 3341 switch (operation) { 3342 case SCAN_OPT_BACKUP_BAND0: 3343 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; 3344 rtlpriv->cfg->ops->set_hw_reg(hw, 3345 HW_VAR_IO_CMD, 3346 (u8 *)&iotype); 3347 3348 break; 3349 case SCAN_OPT_BACKUP_BAND1: 3350 iotype = IO_CMD_PAUSE_BAND1_DM_BY_SCAN; 3351 rtlpriv->cfg->ops->set_hw_reg(hw, 3352 HW_VAR_IO_CMD, 3353 (u8 *)&iotype); 3354 3355 break; 3356 case SCAN_OPT_RESTORE: 3357 iotype = IO_CMD_RESUME_DM_BY_SCAN; 3358 rtlpriv->cfg->ops->set_hw_reg(hw, 3359 HW_VAR_IO_CMD, 3360 (u8 *)&iotype); 3361 break; 3362 default: 3363 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 3364 "Unknown Scan Backup operation.\n"); 3365 break; 3366 } 3367 } 3368} 3369 3370static void _rtl8821ae_phy_set_reg_bw(struct rtl_priv *rtlpriv, u8 bw) 3371{ 3372 u16 reg_rf_mode_bw, tmp = 0; 3373 3374 reg_rf_mode_bw = rtl_read_word(rtlpriv, REG_TRXPTCL_CTL); 3375 switch (bw) { 3376 case HT_CHANNEL_WIDTH_20: 3377 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, reg_rf_mode_bw & 0xFE7F); 3378 break; 3379 case HT_CHANNEL_WIDTH_20_40: 3380 tmp = reg_rf_mode_bw | BIT(7); 3381 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFEFF); 3382 break; 3383 case HT_CHANNEL_WIDTH_80: 3384 tmp = reg_rf_mode_bw | BIT(8); 3385 rtl_write_word(rtlpriv, REG_TRXPTCL_CTL, tmp & 0xFF7F); 3386 break; 3387 default: 3388 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, "unknown Bandwidth: 0x%x\n", bw); 3389 break; 3390 } 3391} 3392 3393static u8 _rtl8821ae_phy_get_secondary_chnl(struct rtl_priv *rtlpriv) 3394{ 3395 struct rtl_phy *rtlphy = &rtlpriv->phy; 3396 struct rtl_mac *mac = rtl_mac(rtlpriv); 3397 u8 sc_set_40 = 0, sc_set_20 = 0; 3398 3399 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) { 3400 if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_LOWER) 3401 sc_set_40 = VHT_DATA_SC_40_LOWER_OF_80MHZ; 3402 else if (mac->cur_80_prime_sc == PRIME_CHNL_OFFSET_UPPER) 3403 sc_set_40 = VHT_DATA_SC_40_UPPER_OF_80MHZ; 3404 else 3405 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 3406 "SCMapping: Not Correct Primary40MHz Setting\n"); 3407 3408 if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) && 3409 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)) 3410 sc_set_20 = VHT_DATA_SC_20_LOWEST_OF_80MHZ; 3411 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) && 3412 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER)) 3413 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ; 3414 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) && 3415 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER)) 3416 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ; 3417 else if ((mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) && 3418 (mac->cur_80_prime_sc == HAL_PRIME_CHNL_OFFSET_UPPER)) 3419 sc_set_20 = VHT_DATA_SC_20_UPPERST_OF_80MHZ; 3420 else 3421 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 3422 "SCMapping: Not Correct Primary40MHz Setting\n"); 3423 } else if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) { 3424 if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_UPPER) 3425 sc_set_20 = VHT_DATA_SC_20_UPPER_OF_80MHZ; 3426 else if (mac->cur_40_prime_sc == PRIME_CHNL_OFFSET_LOWER) 3427 sc_set_20 = VHT_DATA_SC_20_LOWER_OF_80MHZ; 3428 else 3429 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 3430 "SCMapping: Not Correct Primary40MHz Setting\n"); 3431 } 3432 return (sc_set_40 << 4) | sc_set_20; 3433} 3434 3435void rtl8821ae_phy_set_bw_mode_callback(struct ieee80211_hw *hw) 3436{ 3437 struct rtl_priv *rtlpriv = rtl_priv(hw); 3438 struct rtl_phy *rtlphy = &rtlpriv->phy; 3439 u8 sub_chnl = 0; 3440 u8 l1pk_val = 0; 3441 3442 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, 3443 "Switch to %s bandwidth\n", 3444 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? 3445 "20MHz" : 3446 (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40 ? 3447 "40MHz" : "80MHz"))); 3448 3449 _rtl8821ae_phy_set_reg_bw(rtlpriv, rtlphy->current_chan_bw); 3450 sub_chnl = _rtl8821ae_phy_get_secondary_chnl(rtlpriv); 3451 rtl_write_byte(rtlpriv, 0x0483, sub_chnl); 3452 3453 switch (rtlphy->current_chan_bw) { 3454 case HT_CHANNEL_WIDTH_20: 3455 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300200); 3456 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0); 3457 3458 if (rtlphy->rf_type == RF_2T2R) 3459 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 7); 3460 else 3461 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, 8); 3462 break; 3463 case HT_CHANNEL_WIDTH_20_40: 3464 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300201); 3465 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 0); 3466 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl); 3467 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl); 3468 3469 if (rtlphy->reg_837 & BIT(2)) 3470 l1pk_val = 6; 3471 else { 3472 if (rtlphy->rf_type == RF_2T2R) 3473 l1pk_val = 7; 3474 else 3475 l1pk_val = 8; 3476 } 3477 /* 0x848[25:22] = 0x6 */ 3478 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val); 3479 3480 if (sub_chnl == VHT_DATA_SC_20_UPPER_OF_80MHZ) 3481 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 1); 3482 else 3483 rtl_set_bbreg(hw, RCCK_SYSTEM, BCCK_SYSTEM, 0); 3484 break; 3485 3486 case HT_CHANNEL_WIDTH_80: 3487 /* 0x8ac[21,20,9:6,1,0]=8'b11100010 */ 3488 rtl_set_bbreg(hw, RRFMOD, 0x003003C3, 0x00300202); 3489 /* 0x8c4[30] = 1 */ 3490 rtl_set_bbreg(hw, RADC_BUF_CLK, BIT(30), 1); 3491 rtl_set_bbreg(hw, RRFMOD, 0x3C, sub_chnl); 3492 rtl_set_bbreg(hw, RCCAONSEC, 0xf0000000, sub_chnl); 3493 3494 if (rtlphy->reg_837 & BIT(2)) 3495 l1pk_val = 5; 3496 else { 3497 if (rtlphy->rf_type == RF_2T2R) 3498 l1pk_val = 6; 3499 else 3500 l1pk_val = 7; 3501 } 3502 rtl_set_bbreg(hw, RL1PEAKTH, 0x03C00000, l1pk_val); 3503 3504 break; 3505 default: 3506 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 3507 "unknown bandwidth: %#X\n", rtlphy->current_chan_bw); 3508 break; 3509 } 3510 3511 rtl8812ae_fixspur(hw, rtlphy->current_chan_bw, rtlphy->current_channel); 3512 3513 rtl8821ae_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw); 3514 rtlphy->set_bwmode_inprogress = false; 3515 3516 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n"); 3517} 3518 3519void rtl8821ae_phy_set_bw_mode(struct ieee80211_hw *hw, 3520 enum nl80211_channel_type ch_type) 3521{ 3522 struct rtl_priv *rtlpriv = rtl_priv(hw); 3523 struct rtl_phy *rtlphy = &rtlpriv->phy; 3524 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3525 u8 tmp_bw = rtlphy->current_chan_bw; 3526 3527 if (rtlphy->set_bwmode_inprogress) 3528 return; 3529 rtlphy->set_bwmode_inprogress = true; 3530 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) 3531 rtl8821ae_phy_set_bw_mode_callback(hw); 3532 else { 3533 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 3534 "FALSE driver sleep or unload\n"); 3535 rtlphy->set_bwmode_inprogress = false; 3536 rtlphy->current_chan_bw = tmp_bw; 3537 } 3538} 3539 3540void rtl8821ae_phy_sw_chnl_callback(struct ieee80211_hw *hw) 3541{ 3542 struct rtl_priv *rtlpriv = rtl_priv(hw); 3543 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3544 struct rtl_phy *rtlphy = &rtlpriv->phy; 3545 u8 channel = rtlphy->current_channel; 3546 u8 path; 3547 u32 data; 3548 3549 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, 3550 "switch to channel%d\n", rtlphy->current_channel); 3551 if (is_hal_stop(rtlhal)) 3552 return; 3553 3554 if (36 <= channel && channel <= 48) 3555 data = 0x494; 3556 else if (50 <= channel && channel <= 64) 3557 data = 0x453; 3558 else if (100 <= channel && channel <= 116) 3559 data = 0x452; 3560 else if (118 <= channel) 3561 data = 0x412; 3562 else 3563 data = 0x96a; 3564 rtl_set_bbreg(hw, RFC_AREA, 0x1ffe0000, data); 3565 3566 for (path = RF90_PATH_A; path < rtlphy->num_total_rfpath; path++) { 3567 if (36 <= channel && channel <= 64) 3568 data = 0x101; 3569 else if (100 <= channel && channel <= 140) 3570 data = 0x301; 3571 else if (140 < channel) 3572 data = 0x501; 3573 else 3574 data = 0x000; 3575 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW, 3576 BIT(18)|BIT(17)|BIT(16)|BIT(9)|BIT(8), data); 3577 3578 rtl8821ae_phy_set_rf_reg(hw, path, RF_CHNLBW, 3579 BMASKBYTE0, channel); 3580 3581 if (channel > 14) { 3582 if (rtlhal->hw_type == HARDWARE_TYPE_RTL8821AE) { 3583 if (36 <= channel && channel <= 64) 3584 data = 0x114E9; 3585 else if (100 <= channel && channel <= 140) 3586 data = 0x110E9; 3587 else 3588 data = 0x110E9; 3589 rtl8821ae_phy_set_rf_reg(hw, path, RF_APK, 3590 BRFREGOFFSETMASK, data); 3591 } 3592 } 3593 } 3594 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); 3595} 3596 3597u8 rtl8821ae_phy_sw_chnl(struct ieee80211_hw *hw) 3598{ 3599 struct rtl_priv *rtlpriv = rtl_priv(hw); 3600 struct rtl_phy *rtlphy = &rtlpriv->phy; 3601 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3602 u32 timeout = 1000, timecount = 0; 3603 u8 channel = rtlphy->current_channel; 3604 3605 if (rtlphy->sw_chnl_inprogress) 3606 return 0; 3607 if (rtlphy->set_bwmode_inprogress) 3608 return 0; 3609 3610 if ((is_hal_stop(rtlhal)) || (RT_CANNOT_IO(hw))) { 3611 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, 3612 "sw_chnl_inprogress false driver sleep or unload\n"); 3613 return 0; 3614 } 3615 while (rtlphy->lck_inprogress && timecount < timeout) { 3616 mdelay(50); 3617 timecount += 50; 3618 } 3619 3620 if (rtlphy->current_channel > 14 && rtlhal->current_bandtype != BAND_ON_5G) 3621 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_5G); 3622 else if (rtlphy->current_channel <= 14 && rtlhal->current_bandtype != BAND_ON_2_4G) 3623 rtl8821ae_phy_switch_wirelessband(hw, BAND_ON_2_4G); 3624 3625 rtlphy->sw_chnl_inprogress = true; 3626 if (channel == 0) 3627 channel = 1; 3628 3629 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, 3630 "switch to channel%d, band type is %d\n", 3631 rtlphy->current_channel, rtlhal->current_bandtype); 3632 3633 rtl8821ae_phy_sw_chnl_callback(hw); 3634 3635 rtl8821ae_dm_clear_txpower_tracking_state(hw); 3636 rtl8821ae_phy_set_txpower_level(hw, rtlphy->current_channel); 3637 3638 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n"); 3639 rtlphy->sw_chnl_inprogress = false; 3640 return 1; 3641} 3642 3643u8 _rtl8812ae_get_right_chnl_place_for_iqk(u8 chnl) 3644{ 3645 u8 channel_all[TARGET_CHNL_NUM_2G_5G_8812] = { 3646 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 3647 14, 36, 38, 40, 42, 44, 46, 48, 50, 52, 54, 3648 56, 58, 60, 62, 64, 100, 102, 104, 106, 108, 3649 110, 112, 114, 116, 118, 120, 122, 124, 126, 3650 128, 130, 132, 134, 136, 138, 140, 149, 151, 3651 153, 155, 157, 159, 161, 163, 165}; 3652 u8 place = chnl; 3653 3654 if (chnl > 14) { 3655 for (place = 14; place < sizeof(channel_all); place++) 3656 if (channel_all[place] == chnl) 3657 return place-13; 3658 } 3659 3660 return 0; 3661} 3662 3663#define MACBB_REG_NUM 10 3664#define AFE_REG_NUM 14 3665#define RF_REG_NUM 3 3666 3667static void _rtl8821ae_iqk_backup_macbb(struct ieee80211_hw *hw, 3668 u32 *macbb_backup, 3669 u32 *backup_macbb_reg, u32 mac_bb_num) 3670{ 3671 struct rtl_priv *rtlpriv = rtl_priv(hw); 3672 u32 i; 3673 3674 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ 3675 /*save MACBB default value*/ 3676 for (i = 0; i < mac_bb_num; i++) 3677 macbb_backup[i] = rtl_read_dword(rtlpriv, backup_macbb_reg[i]); 3678 3679 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupMacBB Success!!!!\n"); 3680} 3681 3682static void _rtl8821ae_iqk_backup_afe(struct ieee80211_hw *hw, u32 *afe_backup, 3683 u32 *backup_afe_REG, u32 afe_num) 3684{ 3685 struct rtl_priv *rtlpriv = rtl_priv(hw); 3686 u32 i; 3687 3688 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ 3689 /*Save AFE Parameters */ 3690 for (i = 0; i < afe_num; i++) 3691 afe_backup[i] = rtl_read_dword(rtlpriv, backup_afe_REG[i]); 3692 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupAFE Success!!!!\n"); 3693} 3694 3695static void _rtl8821ae_iqk_backup_rf(struct ieee80211_hw *hw, u32 *rfa_backup, 3696 u32 *rfb_backup, u32 *backup_rf_reg, 3697 u32 rf_num) 3698{ 3699 struct rtl_priv *rtlpriv = rtl_priv(hw); 3700 u32 i; 3701 3702 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ 3703 /*Save RF Parameters*/ 3704 for (i = 0; i < rf_num; i++) { 3705 rfa_backup[i] = rtl_get_rfreg(hw, RF90_PATH_A, backup_rf_reg[i], 3706 BMASKDWORD); 3707 rfb_backup[i] = rtl_get_rfreg(hw, RF90_PATH_B, backup_rf_reg[i], 3708 BMASKDWORD); 3709 } 3710 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "BackupRF Success!!!!\n"); 3711} 3712 3713static void _rtl8821ae_iqk_configure_mac( 3714 struct ieee80211_hw *hw 3715 ) 3716{ 3717 struct rtl_priv *rtlpriv = rtl_priv(hw); 3718 /* ========MAC register setting========*/ 3719 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ 3720 rtl_write_byte(rtlpriv, 0x522, 0x3f); 3721 rtl_set_bbreg(hw, 0x550, BIT(11) | BIT(3), 0x0); 3722 rtl_write_byte(rtlpriv, 0x808, 0x00); /*RX ante off*/ 3723 rtl_set_bbreg(hw, 0x838, 0xf, 0xc); /*CCA off*/ 3724} 3725 3726static void _rtl8821ae_iqk_tx_fill_iqc(struct ieee80211_hw *hw, 3727 enum radio_path path, u32 tx_x, u32 tx_y) 3728{ 3729 struct rtl_priv *rtlpriv = rtl_priv(hw); 3730 switch (path) { 3731 case RF90_PATH_A: 3732 /* [31] = 1 --> Page C1 */ 3733 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); 3734 rtl_write_dword(rtlpriv, 0xc90, 0x00000080); 3735 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000); 3736 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000); 3737 rtl_set_bbreg(hw, 0xccc, 0x000007ff, tx_y); 3738 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, tx_x); 3739 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 3740 "TX_X = %x;;TX_Y = %x =====> fill to IQC\n", 3741 tx_x, tx_y); 3742 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 3743 "0xcd4 = %x;;0xccc = %x ====>fill to IQC\n", 3744 rtl_get_bbreg(hw, 0xcd4, 0x000007ff), 3745 rtl_get_bbreg(hw, 0xccc, 0x000007ff)); 3746 break; 3747 default: 3748 break; 3749 } 3750} 3751 3752static void _rtl8821ae_iqk_rx_fill_iqc(struct ieee80211_hw *hw, 3753 enum radio_path path, u32 rx_x, u32 rx_y) 3754{ 3755 struct rtl_priv *rtlpriv = rtl_priv(hw); 3756 switch (path) { 3757 case RF90_PATH_A: 3758 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 3759 rtl_set_bbreg(hw, 0xc10, 0x000003ff, rx_x>>1); 3760 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, rx_y>>1); 3761 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 3762 "rx_x = %x;;rx_y = %x ====>fill to IQC\n", 3763 rx_x>>1, rx_y>>1); 3764 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 3765 "0xc10 = %x ====>fill to IQC\n", 3766 rtl_read_dword(rtlpriv, 0xc10)); 3767 break; 3768 default: 3769 break; 3770 } 3771} 3772 3773#define cal_num 10 3774 3775static void _rtl8821ae_iqk_tx(struct ieee80211_hw *hw, enum radio_path path) 3776{ 3777 struct rtl_priv *rtlpriv = rtl_priv(hw); 3778 struct rtl_phy *rtlphy = &rtlpriv->phy; 3779 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 3780 3781 u32 tx_fail, rx_fail, delay_count, iqk_ready, cal_retry, cal = 0, temp_reg65; 3782 int tx_x = 0, tx_y = 0, rx_x = 0, rx_y = 0, tx_average = 0, rx_average = 0; 3783 int tx_x0[cal_num], tx_y0[cal_num], tx_x0_rxk[cal_num], 3784 tx_y0_rxk[cal_num], rx_x0[cal_num], rx_y0[cal_num]; 3785 bool tx0iqkok = false, rx0iqkok = false; 3786 bool vdf_enable = false; 3787 int i, k, vdf_y[3], vdf_x[3], tx_dt[3], rx_dt[3], 3788 ii, dx = 0, dy = 0, tx_finish = 0, rx_finish = 0; 3789 3790 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 3791 "BandWidth = %d.\n", 3792 rtlphy->current_chan_bw); 3793 if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_80) 3794 vdf_enable = true; 3795 3796 while (cal < cal_num) { 3797 switch (path) { 3798 case RF90_PATH_A: 3799 temp_reg65 = rtl_get_rfreg(hw, path, 0x65, 0xffffffff); 3800 /* Path-A LOK */ 3801 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /*[31] = 0 --> Page C*/ 3802 /*========Path-A AFE all on========*/ 3803 /*Port 0 DAC/ADC on*/ 3804 rtl_write_dword(rtlpriv, 0xc60, 0x77777777); 3805 rtl_write_dword(rtlpriv, 0xc64, 0x77777777); 3806 rtl_write_dword(rtlpriv, 0xc68, 0x19791979); 3807 rtl_write_dword(rtlpriv, 0xc6c, 0x19791979); 3808 rtl_write_dword(rtlpriv, 0xc70, 0x19791979); 3809 rtl_write_dword(rtlpriv, 0xc74, 0x19791979); 3810 rtl_write_dword(rtlpriv, 0xc78, 0x19791979); 3811 rtl_write_dword(rtlpriv, 0xc7c, 0x19791979); 3812 rtl_write_dword(rtlpriv, 0xc80, 0x19791979); 3813 rtl_write_dword(rtlpriv, 0xc84, 0x19791979); 3814 3815 rtl_set_bbreg(hw, 0xc00, 0xf, 0x4); /*hardware 3-wire off*/ 3816 3817 /* LOK Setting */ 3818 /* ====== LOK ====== */ 3819 /*DAC/ADC sampling rate (160 MHz)*/ 3820 rtl_set_bbreg(hw, 0xc5c, BIT(26) | BIT(25) | BIT(24), 0x7); 3821 3822 /* 2. LoK RF Setting (at BW = 20M) */ 3823 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80002); 3824 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x3); /* BW 20M */ 3825 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000); 3826 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f); 3827 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3); 3828 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5); 3829 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001); 3830 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd); 3831 rtl_write_dword(rtlpriv, 0x90c, 0x00008000); 3832 rtl_write_dword(rtlpriv, 0xb00, 0x03000100); 3833 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1); 3834 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */ 3835 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */ 3836 rtl_write_dword(rtlpriv, 0x984, 0x00462910);/* [0]:AGC_en, [15]:idac_K_Mask */ 3837 3838 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ 3839 rtl_write_dword(rtlpriv, 0xc88, 0x821403f4); 3840 3841 if (rtlhal->current_bandtype) 3842 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96); 3843 else 3844 rtl_write_dword(rtlpriv, 0xc8c, 0x28163e96); 3845 3846 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 3847 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */ 3848 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ 3849 rtl_write_dword(rtlpriv, 0x980, 0xfa000000); 3850 rtl_write_dword(rtlpriv, 0x980, 0xf8000000); 3851 3852 mdelay(10); /* Delay 10ms */ 3853 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); 3854 3855 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 3856 rtl_set_rfreg(hw, path, 0x58, 0x7fe00, rtl_get_rfreg(hw, path, 0x8, 0xffc00)); /* Load LOK */ 3857 3858 switch (rtlphy->current_chan_bw) { 3859 case 1: 3860 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x1); 3861 break; 3862 case 2: 3863 rtl_set_rfreg(hw, path, 0x18, 0x00c00, 0x0); 3864 break; 3865 default: 3866 break; 3867 } 3868 3869 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ 3870 3871 /* 3. TX RF Setting */ 3872 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 3873 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); 3874 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x20000); 3875 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0003f); 3876 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xf3fc3); 3877 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d5); 3878 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001); 3879 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); 3880 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xf, 0xd); */ 3881 rtl_write_dword(rtlpriv, 0x90c, 0x00008000); 3882 rtl_write_dword(rtlpriv, 0xb00, 0x03000100); 3883 rtl_set_bbreg(hw, 0xc94, BIT(0), 0x1); 3884 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */ 3885 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */ 3886 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */ 3887 3888 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ 3889 rtl_write_dword(rtlpriv, 0xc88, 0x821403f1); 3890 if (rtlhal->current_bandtype) 3891 rtl_write_dword(rtlpriv, 0xc8c, 0x40163e96); 3892 else 3893 rtl_write_dword(rtlpriv, 0xc8c, 0x00163e96); 3894 3895 if (vdf_enable == 1) { 3896 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "VDF_enable\n"); 3897 for (k = 0; k <= 2; k++) { 3898 switch (k) { 3899 case 0: 3900 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 3901 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */ 3902 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); 3903 break; 3904 case 1: 3905 rtl_set_bbreg(hw, 0xc80, BIT(28), 0x0); 3906 rtl_set_bbreg(hw, 0xc84, BIT(28), 0x0); 3907 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); 3908 break; 3909 case 2: 3910 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 3911 "vdf_y[1] = %x;;;vdf_y[0] = %x\n", vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff); 3912 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 3913 "vdf_x[1] = %x;;;vdf_x[0] = %x\n", vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff); 3914 tx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20); 3915 tx_dt[cal] = ((16*tx_dt[cal])*10000/15708); 3916 tx_dt[cal] = (tx_dt[cal] >> 1)+(tx_dt[cal] & BIT(0)); 3917 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 3918 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */ 3919 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); 3920 rtl_set_bbreg(hw, 0xce8, 0x3fff0000, tx_dt[cal] & 0x00003fff); 3921 break; 3922 default: 3923 break; 3924 } 3925 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ 3926 cal_retry = 0; 3927 while (1) { 3928 /* one shot */ 3929 rtl_write_dword(rtlpriv, 0x980, 0xfa000000); 3930 rtl_write_dword(rtlpriv, 0x980, 0xf8000000); 3931 3932 mdelay(10); /* Delay 10ms */ 3933 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); 3934 delay_count = 0; 3935 while (1) { 3936 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); 3937 if ((~iqk_ready) || (delay_count > 20)) 3938 break; 3939 else{ 3940 mdelay(1); 3941 delay_count++; 3942 } 3943 } 3944 3945 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ 3946 /* ============TXIQK Check============== */ 3947 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12)); 3948 3949 if (~tx_fail) { 3950 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000); 3951 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 3952 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000); 3953 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 3954 tx0iqkok = true; 3955 break; 3956 } else { 3957 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0); 3958 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200); 3959 tx0iqkok = false; 3960 cal_retry++; 3961 if (cal_retry == 10) 3962 break; 3963 } 3964 } else { 3965 tx0iqkok = false; 3966 cal_retry++; 3967 if (cal_retry == 10) 3968 break; 3969 } 3970 } 3971 } 3972 if (k == 3) { 3973 tx_x0[cal] = vdf_x[k-1]; 3974 tx_y0[cal] = vdf_y[k-1]; 3975 } 3976 } else { 3977 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 3978 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */ 3979 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ 3980 cal_retry = 0; 3981 while (1) { 3982 /* one shot */ 3983 rtl_write_dword(rtlpriv, 0x980, 0xfa000000); 3984 rtl_write_dword(rtlpriv, 0x980, 0xf8000000); 3985 3986 mdelay(10); /* Delay 10ms */ 3987 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); 3988 delay_count = 0; 3989 while (1) { 3990 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); 3991 if ((~iqk_ready) || (delay_count > 20)) 3992 break; 3993 else{ 3994 mdelay(1); 3995 delay_count++; 3996 } 3997 } 3998 3999 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ 4000 /* ============TXIQK Check============== */ 4001 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12)); 4002 4003 if (~tx_fail) { 4004 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000); 4005 tx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4006 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000); 4007 tx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4008 tx0iqkok = true; 4009 break; 4010 } else { 4011 rtl_set_bbreg(hw, 0xccc, 0x000007ff, 0x0); 4012 rtl_set_bbreg(hw, 0xcd4, 0x000007ff, 0x200); 4013 tx0iqkok = false; 4014 cal_retry++; 4015 if (cal_retry == 10) 4016 break; 4017 } 4018 } else { 4019 tx0iqkok = false; 4020 cal_retry++; 4021 if (cal_retry == 10) 4022 break; 4023 } 4024 } 4025 } 4026 4027 if (tx0iqkok == false) 4028 break; /* TXK fail, Don't do RXK */ 4029 4030 if (vdf_enable == 1) { 4031 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x0); /* TX VDF Disable */ 4032 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RXVDF Start\n"); 4033 for (k = 0; k <= 2; k++) { 4034 /* ====== RX mode TXK (RXK Step 1) ====== */ 4035 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 4036 /* 1. TX RF Setting */ 4037 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); 4038 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000); 4039 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029); 4040 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb); 4041 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65); 4042 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001); 4043 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); 4044 4045 rtl_set_bbreg(hw, 0xcb8, 0xf, 0xd); 4046 rtl_write_dword(rtlpriv, 0x978, 0x29002000);/* TX (X,Y) */ 4047 rtl_write_dword(rtlpriv, 0x97c, 0xa9002000);/* RX (X,Y) */ 4048 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */ 4049 rtl_write_dword(rtlpriv, 0x90c, 0x00008000); 4050 rtl_write_dword(rtlpriv, 0xb00, 0x03000100); 4051 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ 4052 switch (k) { 4053 case 0: 4054 { 4055 rtl_write_dword(rtlpriv, 0xc80, 0x18008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 4056 rtl_write_dword(rtlpriv, 0xc84, 0x38008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */ 4057 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0); 4058 } 4059 break; 4060 case 1: 4061 { 4062 rtl_write_dword(rtlpriv, 0xc80, 0x08008c38);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 4063 rtl_write_dword(rtlpriv, 0xc84, 0x28008c38);/* RX_TONE_idx[9:0], RxK_Mask[29] */ 4064 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x0); 4065 } 4066 break; 4067 case 2: 4068 { 4069 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 4070 "VDF_Y[1] = %x;;;VDF_Y[0] = %x\n", 4071 vdf_y[1]>>21 & 0x00007ff, vdf_y[0]>>21 & 0x00007ff); 4072 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 4073 "VDF_X[1] = %x;;;VDF_X[0] = %x\n", 4074 vdf_x[1]>>21 & 0x00007ff, vdf_x[0]>>21 & 0x00007ff); 4075 rx_dt[cal] = (vdf_y[1]>>20)-(vdf_y[0]>>20); 4076 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "Rx_dt = %d\n", rx_dt[cal]); 4077 rx_dt[cal] = ((16*rx_dt[cal])*10000/13823); 4078 rx_dt[cal] = (rx_dt[cal] >> 1)+(rx_dt[cal] & BIT(0)); 4079 rtl_write_dword(rtlpriv, 0xc80, 0x18008c20);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 4080 rtl_write_dword(rtlpriv, 0xc84, 0x38008c20);/* RX_TONE_idx[9:0], RxK_Mask[29] */ 4081 rtl_set_bbreg(hw, 0xce8, 0x00003fff, rx_dt[cal] & 0x00003fff); 4082 } 4083 break; 4084 default: 4085 break; 4086 } 4087 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0); 4088 rtl_write_dword(rtlpriv, 0xc8c, 0x68163e96); 4089 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ 4090 cal_retry = 0; 4091 while (1) { 4092 /* one shot */ 4093 rtl_write_dword(rtlpriv, 0x980, 0xfa000000); 4094 rtl_write_dword(rtlpriv, 0x980, 0xf8000000); 4095 4096 mdelay(10); /* Delay 10ms */ 4097 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); 4098 delay_count = 0; 4099 while (1) { 4100 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); 4101 if ((~iqk_ready) || (delay_count > 20)) 4102 break; 4103 else{ 4104 mdelay(1); 4105 delay_count++; 4106 } 4107 } 4108 4109 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ 4110 /* ============TXIQK Check============== */ 4111 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12)); 4112 4113 if (~tx_fail) { 4114 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000); 4115 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4116 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000); 4117 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4118 tx0iqkok = true; 4119 break; 4120 } else{ 4121 tx0iqkok = false; 4122 cal_retry++; 4123 if (cal_retry == 10) 4124 break; 4125 } 4126 } else { 4127 tx0iqkok = false; 4128 cal_retry++; 4129 if (cal_retry == 10) 4130 break; 4131 } 4132 } 4133 4134 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */ 4135 tx_x0_rxk[cal] = tx_x0[cal]; 4136 tx_y0_rxk[cal] = tx_y0[cal]; 4137 tx0iqkok = true; 4138 RT_TRACE(rtlpriv, 4139 COMP_IQK, 4140 DBG_LOUD, 4141 "RXK Step 1 fail\n"); 4142 } 4143 4144 /* ====== RX IQK ====== */ 4145 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 4146 /* 1. RX RF Setting */ 4147 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); 4148 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000); 4149 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f); 4150 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb); 4151 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001); 4152 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8); 4153 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); 4154 4155 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff); 4156 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff); 4157 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1); 4158 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0); 4159 rtl_set_bbreg(hw, 0xcb8, 0xF, 0xe); 4160 rtl_write_dword(rtlpriv, 0x90c, 0x00008000); 4161 rtl_write_dword(rtlpriv, 0x984, 0x0046a911); 4162 4163 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ 4164 rtl_set_bbreg(hw, 0xc80, BIT(29), 0x1); 4165 rtl_set_bbreg(hw, 0xc84, BIT(29), 0x0); 4166 rtl_write_dword(rtlpriv, 0xc88, 0x02140119); 4167 4168 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /* pDM_Odm->SupportInterface == 1 */ 4169 4170 if (k == 2) 4171 rtl_set_bbreg(hw, 0xce8, BIT(30), 0x1); /* RX VDF Enable */ 4172 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ 4173 4174 cal_retry = 0; 4175 while (1) { 4176 /* one shot */ 4177 rtl_write_dword(rtlpriv, 0x980, 0xfa000000); 4178 rtl_write_dword(rtlpriv, 0x980, 0xf8000000); 4179 4180 mdelay(10); /* Delay 10ms */ 4181 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); 4182 delay_count = 0; 4183 while (1) { 4184 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); 4185 if ((~iqk_ready) || (delay_count > 20)) 4186 break; 4187 else{ 4188 mdelay(1); 4189 delay_count++; 4190 } 4191 } 4192 4193 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ 4194 /* ============RXIQK Check============== */ 4195 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11)); 4196 if (rx_fail == 0) { 4197 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000); 4198 vdf_x[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4199 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000); 4200 vdf_y[k] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4201 rx0iqkok = true; 4202 break; 4203 } else { 4204 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1); 4205 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1); 4206 rx0iqkok = false; 4207 cal_retry++; 4208 if (cal_retry == 10) 4209 break; 4210 4211 } 4212 } else{ 4213 rx0iqkok = false; 4214 cal_retry++; 4215 if (cal_retry == 10) 4216 break; 4217 } 4218 } 4219 4220 } 4221 if (k == 3) { 4222 rx_x0[cal] = vdf_x[k-1]; 4223 rx_y0[cal] = vdf_y[k-1]; 4224 } 4225 rtl_set_bbreg(hw, 0xce8, BIT(31), 0x1); /* TX VDF Enable */ 4226 } 4227 4228 else{ 4229 /* ====== RX mode TXK (RXK Step 1) ====== */ 4230 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 4231 /* 1. TX RF Setting */ 4232 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); 4233 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000); 4234 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x00029); 4235 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xd7ffb); 4236 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65); 4237 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x8a001); 4238 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); 4239 rtl_write_dword(rtlpriv, 0x90c, 0x00008000); 4240 rtl_write_dword(rtlpriv, 0xb00, 0x03000100); 4241 rtl_write_dword(rtlpriv, 0x984, 0x0046a910);/* [0]:AGC_en, [15]:idac_K_Mask */ 4242 4243 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ 4244 rtl_write_dword(rtlpriv, 0xc80, 0x18008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 4245 rtl_write_dword(rtlpriv, 0xc84, 0x38008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */ 4246 rtl_write_dword(rtlpriv, 0xc88, 0x821603e0); 4247 /* ODM_Write4Byte(pDM_Odm, 0xc8c, 0x68163e96); */ 4248 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ 4249 cal_retry = 0; 4250 while (1) { 4251 /* one shot */ 4252 rtl_write_dword(rtlpriv, 0x980, 0xfa000000); 4253 rtl_write_dword(rtlpriv, 0x980, 0xf8000000); 4254 4255 mdelay(10); /* Delay 10ms */ 4256 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); 4257 delay_count = 0; 4258 while (1) { 4259 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); 4260 if ((~iqk_ready) || (delay_count > 20)) 4261 break; 4262 else{ 4263 mdelay(1); 4264 delay_count++; 4265 } 4266 } 4267 4268 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ 4269 /* ============TXIQK Check============== */ 4270 tx_fail = rtl_get_bbreg(hw, 0xd00, BIT(12)); 4271 4272 if (~tx_fail) { 4273 rtl_write_dword(rtlpriv, 0xcb8, 0x02000000); 4274 tx_x0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4275 rtl_write_dword(rtlpriv, 0xcb8, 0x04000000); 4276 tx_y0_rxk[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4277 tx0iqkok = true; 4278 break; 4279 } else { 4280 tx0iqkok = false; 4281 cal_retry++; 4282 if (cal_retry == 10) 4283 break; 4284 } 4285 } else{ 4286 tx0iqkok = false; 4287 cal_retry++; 4288 if (cal_retry == 10) 4289 break; 4290 } 4291 } 4292 4293 if (tx0iqkok == false) { /* If RX mode TXK fail, then take TXK Result */ 4294 tx_x0_rxk[cal] = tx_x0[cal]; 4295 tx_y0_rxk[cal] = tx_y0[cal]; 4296 tx0iqkok = true; 4297 RT_TRACE(rtlpriv, COMP_IQK, 4298 DBG_LOUD, "1"); 4299 } 4300 4301 /* ====== RX IQK ====== */ 4302 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 4303 /* 1. RX RF Setting */ 4304 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x80000); 4305 rtl_set_rfreg(hw, path, 0x30, RFREG_OFFSET_MASK, 0x30000); 4306 rtl_set_rfreg(hw, path, 0x31, RFREG_OFFSET_MASK, 0x0002f); 4307 rtl_set_rfreg(hw, path, 0x32, RFREG_OFFSET_MASK, 0xfffbb); 4308 rtl_set_rfreg(hw, path, 0x8f, RFREG_OFFSET_MASK, 0x88001); 4309 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, 0x931d8); 4310 rtl_set_rfreg(hw, path, 0xef, RFREG_OFFSET_MASK, 0x00000); 4311 4312 rtl_set_bbreg(hw, 0x978, 0x03FF8000, (tx_x0_rxk[cal])>>21&0x000007ff); 4313 rtl_set_bbreg(hw, 0x978, 0x000007FF, (tx_y0_rxk[cal])>>21&0x000007ff); 4314 rtl_set_bbreg(hw, 0x978, BIT(31), 0x1); 4315 rtl_set_bbreg(hw, 0x97c, BIT(31), 0x0); 4316 /* ODM_SetBBReg(pDM_Odm, 0xcb8, 0xF, 0xe); */ 4317 rtl_write_dword(rtlpriv, 0x90c, 0x00008000); 4318 rtl_write_dword(rtlpriv, 0x984, 0x0046a911); 4319 4320 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ 4321 rtl_write_dword(rtlpriv, 0xc80, 0x38008c10);/* TX_TONE_idx[9:0], TxK_Mask[29] TX_Tone = 16 */ 4322 rtl_write_dword(rtlpriv, 0xc84, 0x18008c10);/* RX_TONE_idx[9:0], RxK_Mask[29] */ 4323 rtl_write_dword(rtlpriv, 0xc88, 0x02140119); 4324 4325 rtl_write_dword(rtlpriv, 0xc8c, 0x28160d00); /*pDM_Odm->SupportInterface == 1*/ 4326 4327 rtl_write_dword(rtlpriv, 0xcb8, 0x00100000);/* cb8[20] \B1N SI/PI \A8ϥ\CE\C5v\A4\C1\B5\B9 iqk_dpk module */ 4328 4329 cal_retry = 0; 4330 while (1) { 4331 /* one shot */ 4332 rtl_write_dword(rtlpriv, 0x980, 0xfa000000); 4333 rtl_write_dword(rtlpriv, 0x980, 0xf8000000); 4334 4335 mdelay(10); /* Delay 10ms */ 4336 rtl_write_dword(rtlpriv, 0xcb8, 0x00000000); 4337 delay_count = 0; 4338 while (1) { 4339 iqk_ready = rtl_get_bbreg(hw, 0xd00, BIT(10)); 4340 if ((~iqk_ready) || (delay_count > 20)) 4341 break; 4342 else{ 4343 mdelay(1); 4344 delay_count++; 4345 } 4346 } 4347 4348 if (delay_count < 20) { /* If 20ms No Result, then cal_retry++ */ 4349 /* ============RXIQK Check============== */ 4350 rx_fail = rtl_get_bbreg(hw, 0xd00, BIT(11)); 4351 if (rx_fail == 0) { 4352 rtl_write_dword(rtlpriv, 0xcb8, 0x06000000); 4353 rx_x0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4354 rtl_write_dword(rtlpriv, 0xcb8, 0x08000000); 4355 rx_y0[cal] = rtl_get_bbreg(hw, 0xd00, 0x07ff0000)<<21; 4356 rx0iqkok = true; 4357 break; 4358 } else{ 4359 rtl_set_bbreg(hw, 0xc10, 0x000003ff, 0x200>>1); 4360 rtl_set_bbreg(hw, 0xc10, 0x03ff0000, 0x0>>1); 4361 rx0iqkok = false; 4362 cal_retry++; 4363 if (cal_retry == 10) 4364 break; 4365 4366 } 4367 } else{ 4368 rx0iqkok = false; 4369 cal_retry++; 4370 if (cal_retry == 10) 4371 break; 4372 } 4373 } 4374 } 4375 4376 if (tx0iqkok) 4377 tx_average++; 4378 if (rx0iqkok) 4379 rx_average++; 4380 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 4381 rtl_set_rfreg(hw, path, 0x65, RFREG_OFFSET_MASK, temp_reg65); 4382 break; 4383 default: 4384 break; 4385 } 4386 cal++; 4387 } 4388 4389 /* FillIQK Result */ 4390 switch (path) { 4391 case RF90_PATH_A: 4392 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 4393 "========Path_A =======\n"); 4394 if (tx_average == 0) 4395 break; 4396 4397 for (i = 0; i < tx_average; i++) { 4398 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 4399 "TX_X0_RXK[%d] = %x ;; TX_Y0_RXK[%d] = %x\n", i, 4400 (tx_x0_rxk[i])>>21&0x000007ff, i, 4401 (tx_y0_rxk[i])>>21&0x000007ff); 4402 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 4403 "TX_X0[%d] = %x ;; TX_Y0[%d] = %x\n", i, 4404 (tx_x0[i])>>21&0x000007ff, i, 4405 (tx_y0[i])>>21&0x000007ff); 4406 } 4407 for (i = 0; i < tx_average; i++) { 4408 for (ii = i+1; ii < tx_average; ii++) { 4409 dx = (tx_x0[i]>>21) - (tx_x0[ii]>>21); 4410 if (dx < 3 && dx > -3) { 4411 dy = (tx_y0[i]>>21) - (tx_y0[ii]>>21); 4412 if (dy < 3 && dy > -3) { 4413 tx_x = ((tx_x0[i]>>21) + (tx_x0[ii]>>21))/2; 4414 tx_y = ((tx_y0[i]>>21) + (tx_y0[ii]>>21))/2; 4415 tx_finish = 1; 4416 break; 4417 } 4418 } 4419 } 4420 if (tx_finish == 1) 4421 break; 4422 } 4423 4424 if (tx_finish == 1) 4425 _rtl8821ae_iqk_tx_fill_iqc(hw, path, tx_x, tx_y); /* ? */ 4426 else 4427 _rtl8821ae_iqk_tx_fill_iqc(hw, path, 0x200, 0x0); 4428 4429 if (rx_average == 0) 4430 break; 4431 4432 for (i = 0; i < rx_average; i++) 4433 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 4434 "RX_X0[%d] = %x ;; RX_Y0[%d] = %x\n", i, 4435 (rx_x0[i])>>21&0x000007ff, i, 4436 (rx_y0[i])>>21&0x000007ff); 4437 for (i = 0; i < rx_average; i++) { 4438 for (ii = i+1; ii < rx_average; ii++) { 4439 dx = (rx_x0[i]>>21) - (rx_x0[ii]>>21); 4440 if (dx < 4 && dx > -4) { 4441 dy = (rx_y0[i]>>21) - (rx_y0[ii]>>21); 4442 if (dy < 4 && dy > -4) { 4443 rx_x = ((rx_x0[i]>>21) + (rx_x0[ii]>>21))/2; 4444 rx_y = ((rx_y0[i]>>21) + (rx_y0[ii]>>21))/2; 4445 rx_finish = 1; 4446 break; 4447 } 4448 } 4449 } 4450 if (rx_finish == 1) 4451 break; 4452 } 4453 4454 if (rx_finish == 1) 4455 _rtl8821ae_iqk_rx_fill_iqc(hw, path, rx_x, rx_y); 4456 else 4457 _rtl8821ae_iqk_rx_fill_iqc(hw, path, 0x200, 0x0); 4458 break; 4459 default: 4460 break; 4461 } 4462} 4463 4464static void _rtl8821ae_iqk_restore_rf(struct ieee80211_hw *hw, 4465 enum radio_path path, 4466 u32 *backup_rf_reg, 4467 u32 *rf_backup, u32 rf_reg_num) 4468{ 4469 struct rtl_priv *rtlpriv = rtl_priv(hw); 4470 u32 i; 4471 4472 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 4473 for (i = 0; i < RF_REG_NUM; i++) 4474 rtl_set_rfreg(hw, path, backup_rf_reg[i], RFREG_OFFSET_MASK, 4475 rf_backup[i]); 4476 4477 switch (path) { 4478 case RF90_PATH_A: 4479 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 4480 "RestoreRF Path A Success!!!!\n"); 4481 break; 4482 default: 4483 break; 4484 } 4485} 4486 4487static void _rtl8821ae_iqk_restore_afe(struct ieee80211_hw *hw, 4488 u32 *afe_backup, u32 *backup_afe_reg, 4489 u32 afe_num) 4490{ 4491 u32 i; 4492 struct rtl_priv *rtlpriv = rtl_priv(hw); 4493 4494 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 4495 /* Reload AFE Parameters */ 4496 for (i = 0; i < afe_num; i++) 4497 rtl_write_dword(rtlpriv, backup_afe_reg[i], afe_backup[i]); 4498 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x1); /* [31] = 1 --> Page C1 */ 4499 rtl_write_dword(rtlpriv, 0xc80, 0x0); 4500 rtl_write_dword(rtlpriv, 0xc84, 0x0); 4501 rtl_write_dword(rtlpriv, 0xc88, 0x0); 4502 rtl_write_dword(rtlpriv, 0xc8c, 0x3c000000); 4503 rtl_write_dword(rtlpriv, 0xc90, 0x00000080); 4504 rtl_write_dword(rtlpriv, 0xc94, 0x00000000); 4505 rtl_write_dword(rtlpriv, 0xcc4, 0x20040000); 4506 rtl_write_dword(rtlpriv, 0xcc8, 0x20000000); 4507 rtl_write_dword(rtlpriv, 0xcb8, 0x0); 4508 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreAFE Success!!!!\n"); 4509} 4510 4511static void _rtl8821ae_iqk_restore_macbb(struct ieee80211_hw *hw, 4512 u32 *macbb_backup, 4513 u32 *backup_macbb_reg, 4514 u32 macbb_num) 4515{ 4516 u32 i; 4517 struct rtl_priv *rtlpriv = rtl_priv(hw); 4518 4519 rtl_set_bbreg(hw, 0x82c, BIT(31), 0x0); /* [31] = 0 --> Page C */ 4520 /* Reload MacBB Parameters */ 4521 for (i = 0; i < macbb_num; i++) 4522 rtl_write_dword(rtlpriv, backup_macbb_reg[i], macbb_backup[i]); 4523 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, "RestoreMacBB Success!!!!\n"); 4524} 4525 4526#undef MACBB_REG_NUM 4527#undef AFE_REG_NUM 4528#undef RF_REG_NUM 4529 4530#define MACBB_REG_NUM 11 4531#define AFE_REG_NUM 12 4532#define RF_REG_NUM 3 4533 4534static void _rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw) 4535{ 4536 u32 macbb_backup[MACBB_REG_NUM]; 4537 u32 afe_backup[AFE_REG_NUM]; 4538 u32 rfa_backup[RF_REG_NUM]; 4539 u32 rfb_backup[RF_REG_NUM]; 4540 u32 backup_macbb_reg[MACBB_REG_NUM] = { 4541 0xb00, 0x520, 0x550, 0x808, 0x90c, 0xc00, 0xc50, 4542 0xe00, 0xe50, 0x838, 0x82c 4543 }; 4544 u32 backup_afe_reg[AFE_REG_NUM] = { 4545 0xc5c, 0xc60, 0xc64, 0xc68, 0xc6c, 0xc70, 0xc74, 4546 0xc78, 0xc7c, 0xc80, 0xc84, 0xcb8 4547 }; 4548 u32 backup_rf_reg[RF_REG_NUM] = {0x65, 0x8f, 0x0}; 4549 4550 _rtl8821ae_iqk_backup_macbb(hw, macbb_backup, backup_macbb_reg, 4551 MACBB_REG_NUM); 4552 _rtl8821ae_iqk_backup_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM); 4553 _rtl8821ae_iqk_backup_rf(hw, rfa_backup, rfb_backup, backup_rf_reg, 4554 RF_REG_NUM); 4555 4556 _rtl8821ae_iqk_configure_mac(hw); 4557 _rtl8821ae_iqk_tx(hw, RF90_PATH_A); 4558 _rtl8821ae_iqk_restore_rf(hw, RF90_PATH_A, backup_rf_reg, rfa_backup, 4559 RF_REG_NUM); 4560 4561 _rtl8821ae_iqk_restore_afe(hw, afe_backup, backup_afe_reg, AFE_REG_NUM); 4562 _rtl8821ae_iqk_restore_macbb(hw, macbb_backup, backup_macbb_reg, 4563 MACBB_REG_NUM); 4564} 4565 4566static void _rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool main) 4567{ 4568 struct rtl_priv *rtlpriv = rtl_priv(hw); 4569 /* struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); */ 4570 /* struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); */ 4571 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); 4572 4573 if (main) 4574 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x1); 4575 else 4576 rtl_set_bbreg(hw, RA_RFE_PINMUX + 4, BIT(29) | BIT(28), 0x2); 4577} 4578 4579#undef IQK_ADDA_REG_NUM 4580#undef IQK_DELAY_TIME 4581 4582void rtl8812ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) 4583{ 4584} 4585 4586void rtl8812ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, 4587 u8 thermal_value, u8 threshold) 4588{ 4589 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 4590 4591 rtldm->thermalvalue_iqk = thermal_value; 4592 rtl8812ae_phy_iq_calibrate(hw, false); 4593} 4594 4595void rtl8821ae_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) 4596{ 4597 struct rtl_priv *rtlpriv = rtl_priv(hw); 4598 struct rtl_phy *rtlphy = &rtlpriv->phy; 4599 4600 if (!rtlphy->lck_inprogress) { 4601 spin_lock(&rtlpriv->locks.iqk_lock); 4602 rtlphy->lck_inprogress = true; 4603 spin_unlock(&rtlpriv->locks.iqk_lock); 4604 4605 _rtl8821ae_phy_iq_calibrate(hw); 4606 4607 spin_lock(&rtlpriv->locks.iqk_lock); 4608 rtlphy->lck_inprogress = false; 4609 spin_unlock(&rtlpriv->locks.iqk_lock); 4610 } 4611} 4612 4613void rtl8821ae_reset_iqk_result(struct ieee80211_hw *hw) 4614{ 4615 struct rtl_priv *rtlpriv = rtl_priv(hw); 4616 struct rtl_phy *rtlphy = &rtlpriv->phy; 4617 u8 i; 4618 4619 RT_TRACE(rtlpriv, COMP_IQK, DBG_LOUD, 4620 "rtl8812ae_dm_reset_iqk_result:: settings regs %d default regs %d\n", 4621 (int)(sizeof(rtlphy->iqk_matrix) / 4622 sizeof(struct iqk_matrix_regs)), 4623 IQK_MATRIX_SETTINGS_NUM); 4624 4625 for (i = 0; i < IQK_MATRIX_SETTINGS_NUM; i++) { 4626 rtlphy->iqk_matrix[i].value[0][0] = 0x100; 4627 rtlphy->iqk_matrix[i].value[0][2] = 0x100; 4628 rtlphy->iqk_matrix[i].value[0][4] = 0x100; 4629 rtlphy->iqk_matrix[i].value[0][6] = 0x100; 4630 4631 rtlphy->iqk_matrix[i].value[0][1] = 0x0; 4632 rtlphy->iqk_matrix[i].value[0][3] = 0x0; 4633 rtlphy->iqk_matrix[i].value[0][5] = 0x0; 4634 rtlphy->iqk_matrix[i].value[0][7] = 0x0; 4635 4636 rtlphy->iqk_matrix[i].iqk_done = false; 4637 } 4638} 4639 4640void rtl8821ae_do_iqk(struct ieee80211_hw *hw, u8 delta_thermal_index, 4641 u8 thermal_value, u8 threshold) 4642{ 4643 struct rtl_dm *rtldm = rtl_dm(rtl_priv(hw)); 4644 4645 rtl8821ae_reset_iqk_result(hw); 4646 4647 rtldm->thermalvalue_iqk = thermal_value; 4648 rtl8821ae_phy_iq_calibrate(hw, false); 4649} 4650 4651void rtl8821ae_phy_lc_calibrate(struct ieee80211_hw *hw) 4652{ 4653} 4654 4655void rtl8821ae_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) 4656{ 4657} 4658 4659void rtl8821ae_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) 4660{ 4661 _rtl8821ae_phy_set_rfpath_switch(hw, bmain); 4662} 4663 4664bool rtl8821ae_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) 4665{ 4666 struct rtl_priv *rtlpriv = rtl_priv(hw); 4667 struct rtl_phy *rtlphy = &rtlpriv->phy; 4668 bool postprocessing = false; 4669 4670 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, 4671 "-->IO Cmd(%#x), set_io_inprogress(%d)\n", 4672 iotype, rtlphy->set_io_inprogress); 4673 do { 4674 switch (iotype) { 4675 case IO_CMD_RESUME_DM_BY_SCAN: 4676 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, 4677 "[IO CMD] Resume DM after scan.\n"); 4678 postprocessing = true; 4679 break; 4680 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 4681 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN: 4682 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, 4683 "[IO CMD] Pause DM before scan.\n"); 4684 postprocessing = true; 4685 break; 4686 default: 4687 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 4688 "switch case not process\n"); 4689 break; 4690 } 4691 } while (false); 4692 if (postprocessing && !rtlphy->set_io_inprogress) { 4693 rtlphy->set_io_inprogress = true; 4694 rtlphy->current_io_type = iotype; 4695 } else { 4696 return false; 4697 } 4698 rtl8821ae_phy_set_io(hw); 4699 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype); 4700 return true; 4701} 4702 4703static void rtl8821ae_phy_set_io(struct ieee80211_hw *hw) 4704{ 4705 struct rtl_priv *rtlpriv = rtl_priv(hw); 4706 struct dig_t *dm_digtable = &rtlpriv->dm_digtable; 4707 struct rtl_phy *rtlphy = &rtlpriv->phy; 4708 4709 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, 4710 "--->Cmd(%#x), set_io_inprogress(%d)\n", 4711 rtlphy->current_io_type, rtlphy->set_io_inprogress); 4712 switch (rtlphy->current_io_type) { 4713 case IO_CMD_RESUME_DM_BY_SCAN: 4714 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) 4715 _rtl8821ae_resume_tx_beacon(hw); 4716 rtl8821ae_dm_write_dig(hw, rtlphy->initgain_backup.xaagccore1); 4717 rtl8821ae_dm_write_cck_cca_thres(hw, 4718 rtlphy->initgain_backup.cca); 4719 break; 4720 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: 4721 if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_ADHOC) 4722 _rtl8821ae_stop_tx_beacon(hw); 4723 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; 4724 rtl8821ae_dm_write_dig(hw, 0x17); 4725 rtlphy->initgain_backup.cca = dm_digtable->cur_cck_cca_thres; 4726 rtl8821ae_dm_write_cck_cca_thres(hw, 0x40); 4727 break; 4728 case IO_CMD_PAUSE_BAND1_DM_BY_SCAN: 4729 break; 4730 default: 4731 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 4732 "switch case not process\n"); 4733 break; 4734 } 4735 rtlphy->set_io_inprogress = false; 4736 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, 4737 "(%#x)\n", rtlphy->current_io_type); 4738} 4739 4740static void rtl8821ae_phy_set_rf_on(struct ieee80211_hw *hw) 4741{ 4742 struct rtl_priv *rtlpriv = rtl_priv(hw); 4743 4744 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); 4745 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 4746 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 4747 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 4748 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 4749} 4750 4751static bool _rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw, 4752 enum rf_pwrstate rfpwr_state) 4753{ 4754 struct rtl_priv *rtlpriv = rtl_priv(hw); 4755 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw); 4756 struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); 4757 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 4758 bool bresult = true; 4759 u8 i, queue_id; 4760 struct rtl8192_tx_ring *ring = NULL; 4761 4762 switch (rfpwr_state) { 4763 case ERFON: 4764 if ((ppsc->rfpwr_state == ERFOFF) && 4765 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { 4766 bool rtstatus = false; 4767 u32 initializecount = 0; 4768 4769 do { 4770 initializecount++; 4771 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, 4772 "IPS Set eRf nic enable\n"); 4773 rtstatus = rtl_ps_enable_nic(hw); 4774 } while (!rtstatus && (initializecount < 10)); 4775 RT_CLEAR_PS_LEVEL(ppsc, 4776 RT_RF_OFF_LEVL_HALT_NIC); 4777 } else { 4778 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, 4779 "Set ERFON sleeped:%d ms\n", 4780 jiffies_to_msecs(jiffies - 4781 ppsc-> 4782 last_sleep_jiffies)); 4783 ppsc->last_awake_jiffies = jiffies; 4784 rtl8821ae_phy_set_rf_on(hw); 4785 } 4786 if (mac->link_state == MAC80211_LINKED) { 4787 rtlpriv->cfg->ops->led_control(hw, 4788 LED_CTL_LINK); 4789 } else { 4790 rtlpriv->cfg->ops->led_control(hw, 4791 LED_CTL_NO_LINK); 4792 } 4793 break; 4794 case ERFOFF: 4795 for (queue_id = 0, i = 0; 4796 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { 4797 ring = &pcipriv->dev.tx_ring[queue_id]; 4798 if (queue_id == BEACON_QUEUE || 4799 skb_queue_len(&ring->queue) == 0) { 4800 queue_id++; 4801 continue; 4802 } else { 4803 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 4804 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", 4805 (i + 1), queue_id, 4806 skb_queue_len(&ring->queue)); 4807 4808 udelay(10); 4809 i++; 4810 } 4811 if (i >= MAX_DOZE_WAITING_TIMES_9x) { 4812 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 4813 "\n ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", 4814 MAX_DOZE_WAITING_TIMES_9x, 4815 queue_id, 4816 skb_queue_len(&ring->queue)); 4817 break; 4818 } 4819 } 4820 4821 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) { 4822 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, 4823 "IPS Set eRf nic disable\n"); 4824 rtl_ps_disable_nic(hw); 4825 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); 4826 } else { 4827 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) { 4828 rtlpriv->cfg->ops->led_control(hw, 4829 LED_CTL_NO_LINK); 4830 } else { 4831 rtlpriv->cfg->ops->led_control(hw, 4832 LED_CTL_POWER_OFF); 4833 } 4834 } 4835 break; 4836 default: 4837 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 4838 "switch case not process\n"); 4839 bresult = false; 4840 break; 4841 } 4842 if (bresult) 4843 ppsc->rfpwr_state = rfpwr_state; 4844 return bresult; 4845} 4846 4847bool rtl8821ae_phy_set_rf_power_state(struct ieee80211_hw *hw, 4848 enum rf_pwrstate rfpwr_state) 4849{ 4850 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw)); 4851 4852 bool bresult = false; 4853 4854 if (rfpwr_state == ppsc->rfpwr_state) 4855 return bresult; 4856 bresult = _rtl8821ae_phy_set_rf_power_state(hw, rfpwr_state); 4857 return bresult; 4858} 4859