1/****************************************************************************** 2 * 3 * Copyright(c) 2009-2012 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 * You should have received a copy of the GNU General Public License along with 15 * this program; if not, write to the Free Software Foundation, Inc., 16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA 17 * 18 * The full GNU General Public License is included in this distribution in the 19 * file called LICENSE. 20 * 21 * Contact Information: 22 * wlanfae <wlanfae@realtek.com> 23 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park, 24 * Hsinchu 300, Taiwan. 25 * 26 * Larry Finger <Larry.Finger@lwfinger.net> 27 * 28 *****************************************************************************/ 29 30#include <linux/export.h> 31#include "../wifi.h" 32#include "../rtl8192ce/reg.h" 33#include "../rtl8192ce/def.h" 34#include "dm_common.h" 35#include "phy_common.h" 36 37/* Define macro to shorten lines */ 38#define MCS_TXPWR mcs_txpwrlevel_origoffset 39 40u32 rtl92c_phy_query_bb_reg(struct ieee80211_hw *hw, u32 regaddr, u32 bitmask) 41{ 42 struct rtl_priv *rtlpriv = rtl_priv(hw); 43 u32 returnvalue, originalvalue, bitshift; 44 45 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x)\n", 46 regaddr, bitmask); 47 originalvalue = rtl_read_dword(rtlpriv, regaddr); 48 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); 49 returnvalue = (originalvalue & bitmask) >> bitshift; 50 51 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 52 "BBR MASK=0x%x Addr[0x%x]=0x%x\n", 53 bitmask, regaddr, originalvalue); 54 55 return returnvalue; 56 57} 58EXPORT_SYMBOL(rtl92c_phy_query_bb_reg); 59 60void rtl92c_phy_set_bb_reg(struct ieee80211_hw *hw, 61 u32 regaddr, u32 bitmask, u32 data) 62{ 63 struct rtl_priv *rtlpriv = rtl_priv(hw); 64 u32 originalvalue, bitshift; 65 66 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 67 "regaddr(%#x), bitmask(%#x), data(%#x)\n", 68 regaddr, bitmask, data); 69 70 if (bitmask != MASKDWORD) { 71 originalvalue = rtl_read_dword(rtlpriv, regaddr); 72 bitshift = _rtl92c_phy_calculate_bit_shift(bitmask); 73 data = ((originalvalue & (~bitmask)) | (data << bitshift)); 74 } 75 76 rtl_write_dword(rtlpriv, regaddr, data); 77 78 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, 79 "regaddr(%#x), bitmask(%#x), data(%#x)\n", 80 regaddr, bitmask, data); 81 82} 83EXPORT_SYMBOL(rtl92c_phy_set_bb_reg); 84 85u32 _rtl92c_phy_fw_rf_serial_read(struct ieee80211_hw *hw, 86 enum radio_path rfpath, u32 offset) 87{ 88 RT_ASSERT(false, "deprecated!\n"); 89 return 0; 90 91} 92EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_read); 93 94void _rtl92c_phy_fw_rf_serial_write(struct ieee80211_hw *hw, 95 enum radio_path rfpath, u32 offset, 96 u32 data) 97{ 98 RT_ASSERT(false, "deprecated!\n"); 99} 100EXPORT_SYMBOL(_rtl92c_phy_fw_rf_serial_write); 101 102u32 _rtl92c_phy_rf_serial_read(struct ieee80211_hw *hw, 103 enum radio_path rfpath, u32 offset) 104{ 105 struct rtl_priv *rtlpriv = rtl_priv(hw); 106 struct rtl_phy *rtlphy = &(rtlpriv->phy); 107 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 108 u32 newoffset; 109 u32 tmplong, tmplong2; 110 u8 rfpi_enable = 0; 111 u32 retvalue; 112 113 offset &= 0x3f; 114 newoffset = offset; 115 if (RT_CANNOT_IO(hw)) { 116 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "return all one\n"); 117 return 0xFFFFFFFF; 118 } 119 tmplong = rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD); 120 if (rfpath == RF90_PATH_A) 121 tmplong2 = tmplong; 122 else 123 tmplong2 = rtl_get_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD); 124 tmplong2 = (tmplong2 & (~BLSSIREADADDRESS)) | 125 (newoffset << 23) | BLSSIREADEDGE; 126 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, 127 tmplong & (~BLSSIREADEDGE)); 128 mdelay(1); 129 rtl_set_bbreg(hw, pphyreg->rfhssi_para2, MASKDWORD, tmplong2); 130 mdelay(1); 131 rtl_set_bbreg(hw, RFPGA0_XA_HSSIPARAMETER2, MASKDWORD, 132 tmplong | BLSSIREADEDGE); 133 mdelay(1); 134 if (rfpath == RF90_PATH_A) 135 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, 136 BIT(8)); 137 else if (rfpath == RF90_PATH_B) 138 rfpi_enable = (u8) rtl_get_bbreg(hw, RFPGA0_XB_HSSIPARAMETER1, 139 BIT(8)); 140 if (rfpi_enable) 141 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readbackpi, 142 BLSSIREADBACKDATA); 143 else 144 retvalue = rtl_get_bbreg(hw, pphyreg->rflssi_readback, 145 BLSSIREADBACKDATA); 146 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFR-%d Addr[0x%x]=0x%x\n", 147 rfpath, pphyreg->rflssi_readback, retvalue); 148 return retvalue; 149} 150EXPORT_SYMBOL(_rtl92c_phy_rf_serial_read); 151 152void _rtl92c_phy_rf_serial_write(struct ieee80211_hw *hw, 153 enum radio_path rfpath, u32 offset, 154 u32 data) 155{ 156 u32 data_and_addr; 157 u32 newoffset; 158 struct rtl_priv *rtlpriv = rtl_priv(hw); 159 struct rtl_phy *rtlphy = &(rtlpriv->phy); 160 struct bb_reg_def *pphyreg = &rtlphy->phyreg_def[rfpath]; 161 162 if (RT_CANNOT_IO(hw)) { 163 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "stop\n"); 164 return; 165 } 166 offset &= 0x3f; 167 newoffset = offset; 168 data_and_addr = ((newoffset << 20) | (data & 0x000fffff)) & 0x0fffffff; 169 rtl_set_bbreg(hw, pphyreg->rf3wire_offset, MASKDWORD, data_and_addr); 170 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "RFW-%d Addr[0x%x]=0x%x\n", 171 rfpath, pphyreg->rf3wire_offset, data_and_addr); 172} 173EXPORT_SYMBOL(_rtl92c_phy_rf_serial_write); 174 175u32 _rtl92c_phy_calculate_bit_shift(u32 bitmask) 176{ 177 u32 i; 178 179 for (i = 0; i <= 31; i++) { 180 if ((bitmask >> i) & 0x1) 181 break; 182 } 183 return i; 184} 185EXPORT_SYMBOL(_rtl92c_phy_calculate_bit_shift); 186 187static void _rtl92c_phy_bb_config_1t(struct ieee80211_hw *hw) 188{ 189 rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2); 190 rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022); 191 rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45); 192 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23); 193 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1); 194 rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2); 195 rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2); 196 rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2); 197 rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2); 198 rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2); 199} 200 201bool rtl92c_phy_rf_config(struct ieee80211_hw *hw) 202{ 203 struct rtl_priv *rtlpriv = rtl_priv(hw); 204 205 return rtlpriv->cfg->ops->phy_rf6052_config(hw); 206} 207EXPORT_SYMBOL(rtl92c_phy_rf_config); 208 209bool _rtl92c_phy_bb8192c_config_parafile(struct ieee80211_hw *hw) 210{ 211 struct rtl_priv *rtlpriv = rtl_priv(hw); 212 struct rtl_phy *rtlphy = &(rtlpriv->phy); 213 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 214 bool rtstatus; 215 216 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "==>\n"); 217 rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, 218 BASEBAND_CONFIG_PHY_REG); 219 if (!rtstatus) { 220 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "Write BB Reg Fail!!\n"); 221 return false; 222 } 223 if (rtlphy->rf_type == RF_1T2R) { 224 _rtl92c_phy_bb_config_1t(hw); 225 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n"); 226 } 227 if (rtlefuse->autoload_failflag == false) { 228 rtlphy->pwrgroup_cnt = 0; 229 rtstatus = rtlpriv->cfg->ops->config_bb_with_pgheaderfile(hw, 230 BASEBAND_CONFIG_PHY_REG); 231 } 232 if (!rtstatus) { 233 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!\n"); 234 return false; 235 } 236 rtstatus = rtlpriv->cfg->ops->config_bb_with_headerfile(hw, 237 BASEBAND_CONFIG_AGC_TAB); 238 if (!rtstatus) { 239 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); 240 return false; 241 } 242 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, 243 RFPGA0_XA_HSSIPARAMETER2, 244 0x200)); 245 246 return true; 247} 248EXPORT_SYMBOL(_rtl92c_phy_bb8192c_config_parafile); 249 250void _rtl92c_store_pwrIndex_diffrate_offset(struct ieee80211_hw *hw, 251 u32 regaddr, u32 bitmask, 252 u32 data) 253{ 254 struct rtl_priv *rtlpriv = rtl_priv(hw); 255 struct rtl_phy *rtlphy = &(rtlpriv->phy); 256 int index; 257 258 if (regaddr == RTXAGC_A_RATE18_06) 259 index = 0; 260 else if (regaddr == RTXAGC_A_RATE54_24) 261 index = 1; 262 else if (regaddr == RTXAGC_A_CCK1_MCS32) 263 index = 6; 264 else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) 265 index = 7; 266 else if (regaddr == RTXAGC_A_MCS03_MCS00) 267 index = 2; 268 else if (regaddr == RTXAGC_A_MCS07_MCS04) 269 index = 3; 270 else if (regaddr == RTXAGC_A_MCS11_MCS08) 271 index = 4; 272 else if (regaddr == RTXAGC_A_MCS15_MCS12) 273 index = 5; 274 else if (regaddr == RTXAGC_B_RATE18_06) 275 index = 8; 276 else if (regaddr == RTXAGC_B_RATE54_24) 277 index = 9; 278 else if (regaddr == RTXAGC_B_CCK1_55_MCS32) 279 index = 14; 280 else if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) 281 index = 15; 282 else if (regaddr == RTXAGC_B_MCS03_MCS00) 283 index = 10; 284 else if (regaddr == RTXAGC_B_MCS07_MCS04) 285 index = 11; 286 else if (regaddr == RTXAGC_B_MCS11_MCS08) 287 index = 12; 288 else if (regaddr == RTXAGC_B_MCS15_MCS12) 289 index = 13; 290 else 291 return; 292 293 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index] = data; 294 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 295 "MCSTxPowerLevelOriginalOffset[%d][%d] = 0x%x\n", 296 rtlphy->pwrgroup_cnt, index, 297 rtlphy->MCS_TXPWR[rtlphy->pwrgroup_cnt][index]); 298 299 if (index == 13) 300 rtlphy->pwrgroup_cnt++; 301} 302EXPORT_SYMBOL(_rtl92c_store_pwrIndex_diffrate_offset); 303 304void rtl92c_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) 305{ 306 struct rtl_priv *rtlpriv = rtl_priv(hw); 307 struct rtl_phy *rtlphy = &(rtlpriv->phy); 308 309 rtlphy->default_initialgain[0] = 310 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); 311 rtlphy->default_initialgain[1] = 312 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); 313 rtlphy->default_initialgain[2] = 314 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); 315 rtlphy->default_initialgain[3] = 316 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); 317 318 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 319 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", 320 rtlphy->default_initialgain[0], 321 rtlphy->default_initialgain[1], 322 rtlphy->default_initialgain[2], 323 rtlphy->default_initialgain[3]); 324 325 rtlphy->framesync = (u8) rtl_get_bbreg(hw, 326 ROFDM0_RXDETECTOR3, MASKBYTE0); 327 rtlphy->framesync_c34 = rtl_get_bbreg(hw, 328 ROFDM0_RXDETECTOR2, MASKDWORD); 329 330 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, 331 "Default framesync (0x%x) = 0x%x\n", 332 ROFDM0_RXDETECTOR3, rtlphy->framesync); 333} 334 335void _rtl92c_phy_init_bb_rf_register_definition(struct ieee80211_hw *hw) 336{ 337 struct rtl_priv *rtlpriv = rtl_priv(hw); 338 struct rtl_phy *rtlphy = &(rtlpriv->phy); 339 340 rtlphy->phyreg_def[RF90_PATH_A].rfintfs = RFPGA0_XAB_RFINTERFACESW; 341 rtlphy->phyreg_def[RF90_PATH_B].rfintfs = RFPGA0_XAB_RFINTERFACESW; 342 rtlphy->phyreg_def[RF90_PATH_C].rfintfs = RFPGA0_XCD_RFINTERFACESW; 343 rtlphy->phyreg_def[RF90_PATH_D].rfintfs = RFPGA0_XCD_RFINTERFACESW; 344 345 rtlphy->phyreg_def[RF90_PATH_A].rfintfi = RFPGA0_XAB_RFINTERFACERB; 346 rtlphy->phyreg_def[RF90_PATH_B].rfintfi = RFPGA0_XAB_RFINTERFACERB; 347 rtlphy->phyreg_def[RF90_PATH_C].rfintfi = RFPGA0_XCD_RFINTERFACERB; 348 rtlphy->phyreg_def[RF90_PATH_D].rfintfi = RFPGA0_XCD_RFINTERFACERB; 349 350 rtlphy->phyreg_def[RF90_PATH_A].rfintfo = RFPGA0_XA_RFINTERFACEOE; 351 rtlphy->phyreg_def[RF90_PATH_B].rfintfo = RFPGA0_XB_RFINTERFACEOE; 352 353 rtlphy->phyreg_def[RF90_PATH_A].rfintfe = RFPGA0_XA_RFINTERFACEOE; 354 rtlphy->phyreg_def[RF90_PATH_B].rfintfe = RFPGA0_XB_RFINTERFACEOE; 355 356 rtlphy->phyreg_def[RF90_PATH_A].rf3wire_offset = 357 RFPGA0_XA_LSSIPARAMETER; 358 rtlphy->phyreg_def[RF90_PATH_B].rf3wire_offset = 359 RFPGA0_XB_LSSIPARAMETER; 360 361 rtlphy->phyreg_def[RF90_PATH_A].rflssi_select = rFPGA0_XAB_RFPARAMETER; 362 rtlphy->phyreg_def[RF90_PATH_B].rflssi_select = rFPGA0_XAB_RFPARAMETER; 363 rtlphy->phyreg_def[RF90_PATH_C].rflssi_select = rFPGA0_XCD_RFPARAMETER; 364 rtlphy->phyreg_def[RF90_PATH_D].rflssi_select = rFPGA0_XCD_RFPARAMETER; 365 366 rtlphy->phyreg_def[RF90_PATH_A].rftxgain_stage = RFPGA0_TXGAINSTAGE; 367 rtlphy->phyreg_def[RF90_PATH_B].rftxgain_stage = RFPGA0_TXGAINSTAGE; 368 rtlphy->phyreg_def[RF90_PATH_C].rftxgain_stage = RFPGA0_TXGAINSTAGE; 369 rtlphy->phyreg_def[RF90_PATH_D].rftxgain_stage = RFPGA0_TXGAINSTAGE; 370 371 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para1 = RFPGA0_XA_HSSIPARAMETER1; 372 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para1 = RFPGA0_XB_HSSIPARAMETER1; 373 374 rtlphy->phyreg_def[RF90_PATH_A].rfhssi_para2 = RFPGA0_XA_HSSIPARAMETER2; 375 rtlphy->phyreg_def[RF90_PATH_B].rfhssi_para2 = RFPGA0_XB_HSSIPARAMETER2; 376 377 rtlphy->phyreg_def[RF90_PATH_A].rfswitch_control = 378 RFPGA0_XAB_SWITCHCONTROL; 379 rtlphy->phyreg_def[RF90_PATH_B].rfswitch_control = 380 RFPGA0_XAB_SWITCHCONTROL; 381 rtlphy->phyreg_def[RF90_PATH_C].rfswitch_control = 382 RFPGA0_XCD_SWITCHCONTROL; 383 rtlphy->phyreg_def[RF90_PATH_D].rfswitch_control = 384 RFPGA0_XCD_SWITCHCONTROL; 385 386 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control1 = ROFDM0_XAAGCCORE1; 387 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control1 = ROFDM0_XBAGCCORE1; 388 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control1 = ROFDM0_XCAGCCORE1; 389 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control1 = ROFDM0_XDAGCCORE1; 390 391 rtlphy->phyreg_def[RF90_PATH_A].rfagc_control2 = ROFDM0_XAAGCCORE2; 392 rtlphy->phyreg_def[RF90_PATH_B].rfagc_control2 = ROFDM0_XBAGCCORE2; 393 rtlphy->phyreg_def[RF90_PATH_C].rfagc_control2 = ROFDM0_XCAGCCORE2; 394 rtlphy->phyreg_def[RF90_PATH_D].rfagc_control2 = ROFDM0_XDAGCCORE2; 395 396 rtlphy->phyreg_def[RF90_PATH_A].rfrxiq_imbalance = 397 ROFDM0_XARXIQIMBALANCE; 398 rtlphy->phyreg_def[RF90_PATH_B].rfrxiq_imbalance = 399 ROFDM0_XBRXIQIMBALANCE; 400 rtlphy->phyreg_def[RF90_PATH_C].rfrxiq_imbalance = 401 ROFDM0_XCRXIQIMBANLANCE; 402 rtlphy->phyreg_def[RF90_PATH_D].rfrxiq_imbalance = 403 ROFDM0_XDRXIQIMBALANCE; 404 405 rtlphy->phyreg_def[RF90_PATH_A].rfrx_afe = ROFDM0_XARXAFE; 406 rtlphy->phyreg_def[RF90_PATH_B].rfrx_afe = ROFDM0_XBRXAFE; 407 rtlphy->phyreg_def[RF90_PATH_C].rfrx_afe = ROFDM0_XCRXAFE; 408 rtlphy->phyreg_def[RF90_PATH_D].rfrx_afe = ROFDM0_XDRXAFE; 409 410 rtlphy->phyreg_def[RF90_PATH_A].rftxiq_imbalance = 411 ROFDM0_XATXIQIMBALANCE; 412 rtlphy->phyreg_def[RF90_PATH_B].rftxiq_imbalance = 413 ROFDM0_XBTXIQIMBALANCE; 414 rtlphy->phyreg_def[RF90_PATH_C].rftxiq_imbalance = 415 ROFDM0_XCTXIQIMBALANCE; 416 rtlphy->phyreg_def[RF90_PATH_D].rftxiq_imbalance = 417 ROFDM0_XDTXIQIMBALANCE; 418 419 rtlphy->phyreg_def[RF90_PATH_A].rftx_afe = ROFDM0_XATXAFE; 420 rtlphy->phyreg_def[RF90_PATH_B].rftx_afe = ROFDM0_XBTXAFE; 421 rtlphy->phyreg_def[RF90_PATH_C].rftx_afe = ROFDM0_XCTXAFE; 422 rtlphy->phyreg_def[RF90_PATH_D].rftx_afe = ROFDM0_XDTXAFE; 423 424 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readback = 425 RFPGA0_XA_LSSIREADBACK; 426 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readback = 427 RFPGA0_XB_LSSIREADBACK; 428 rtlphy->phyreg_def[RF90_PATH_C].rflssi_readback = 429 RFPGA0_XC_LSSIREADBACK; 430 rtlphy->phyreg_def[RF90_PATH_D].rflssi_readback = 431 RFPGA0_XD_LSSIREADBACK; 432 433 rtlphy->phyreg_def[RF90_PATH_A].rflssi_readbackpi = 434 TRANSCEIVEA_HSPI_READBACK; 435 rtlphy->phyreg_def[RF90_PATH_B].rflssi_readbackpi = 436 TRANSCEIVEB_HSPI_READBACK; 437 438} 439EXPORT_SYMBOL(_rtl92c_phy_init_bb_rf_register_definition); 440 441void rtl92c_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) 442{ 443 struct rtl_priv *rtlpriv = rtl_priv(hw); 444 struct rtl_phy *rtlphy = &(rtlpriv->phy); 445 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 446 u8 txpwr_level; 447 long txpwr_dbm; 448 449 txpwr_level = rtlphy->cur_cck_txpwridx; 450 txpwr_dbm = _rtl92c_phy_txpwr_idx_to_dbm(hw, 451 WIRELESS_MODE_B, txpwr_level); 452 txpwr_level = rtlphy->cur_ofdm24g_txpwridx + 453 rtlefuse->legacy_ht_txpowerdiff; 454 if (_rtl92c_phy_txpwr_idx_to_dbm(hw, 455 WIRELESS_MODE_G, 456 txpwr_level) > txpwr_dbm) 457 txpwr_dbm = 458 _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G, 459 txpwr_level); 460 txpwr_level = rtlphy->cur_ofdm24g_txpwridx; 461 if (_rtl92c_phy_txpwr_idx_to_dbm(hw, 462 WIRELESS_MODE_N_24G, 463 txpwr_level) > txpwr_dbm) 464 txpwr_dbm = 465 _rtl92c_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G, 466 txpwr_level); 467 *powerlevel = txpwr_dbm; 468} 469 470static void _rtl92c_get_txpower_index(struct ieee80211_hw *hw, u8 channel, 471 u8 *cckpowerlevel, u8 *ofdmpowerlevel) 472{ 473 struct rtl_priv *rtlpriv = rtl_priv(hw); 474 struct rtl_phy *rtlphy = &(rtlpriv->phy); 475 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 476 u8 index = (channel - 1); 477 478 cckpowerlevel[RF90_PATH_A] = 479 rtlefuse->txpwrlevel_cck[RF90_PATH_A][index]; 480 cckpowerlevel[RF90_PATH_B] = 481 rtlefuse->txpwrlevel_cck[RF90_PATH_B][index]; 482 if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) { 483 ofdmpowerlevel[RF90_PATH_A] = 484 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index]; 485 ofdmpowerlevel[RF90_PATH_B] = 486 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index]; 487 } else if (get_rf_type(rtlphy) == RF_2T2R) { 488 ofdmpowerlevel[RF90_PATH_A] = 489 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index]; 490 ofdmpowerlevel[RF90_PATH_B] = 491 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index]; 492 } 493} 494 495static void _rtl92c_ccxpower_index_check(struct ieee80211_hw *hw, 496 u8 channel, u8 *cckpowerlevel, 497 u8 *ofdmpowerlevel) 498{ 499 struct rtl_priv *rtlpriv = rtl_priv(hw); 500 struct rtl_phy *rtlphy = &(rtlpriv->phy); 501 502 rtlphy->cur_cck_txpwridx = cckpowerlevel[0]; 503 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0]; 504 505} 506 507void rtl92c_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel) 508{ 509 struct rtl_priv *rtlpriv = rtl_priv(hw); 510 struct rtl_efuse *rtlefuse = rtl_efuse(rtlpriv); 511 u8 cckpowerlevel[2], ofdmpowerlevel[2]; 512 513 if (!rtlefuse->txpwr_fromeprom) 514 return; 515 _rtl92c_get_txpower_index(hw, channel, 516 &cckpowerlevel[0], &ofdmpowerlevel[0]); 517 _rtl92c_ccxpower_index_check(hw, 518 channel, &cckpowerlevel[0], 519 &ofdmpowerlevel[0]); 520 rtlpriv->cfg->ops->phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]); 521 rtlpriv->cfg->ops->phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], 522 channel); 523} 524EXPORT_SYMBOL(rtl92c_phy_set_txpower_level); 525 526bool rtl92c_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm) 527{ 528 struct rtl_priv *rtlpriv = rtl_priv(hw); 529 struct rtl_phy *rtlphy = &(rtlpriv->phy); 530 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 531 u8 idx; 532 u8 rf_path; 533 u8 ccktxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, 534 WIRELESS_MODE_B, 535 power_indbm); 536 u8 ofdmtxpwridx = _rtl92c_phy_dbm_to_txpwr_Idx(hw, 537 WIRELESS_MODE_N_24G, 538 power_indbm); 539 if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0) 540 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff; 541 else 542 ofdmtxpwridx = 0; 543 RT_TRACE(rtlpriv, COMP_TXAGC, DBG_TRACE, 544 "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n", 545 power_indbm, ccktxpwridx, ofdmtxpwridx); 546 for (idx = 0; idx < 14; idx++) { 547 for (rf_path = 0; rf_path < 2; rf_path++) { 548 rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx; 549 rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] = 550 ofdmtxpwridx; 551 rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] = 552 ofdmtxpwridx; 553 } 554 } 555 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); 556 return true; 557} 558EXPORT_SYMBOL(rtl92c_phy_update_txpower_dbm); 559 560u8 _rtl92c_phy_dbm_to_txpwr_Idx(struct ieee80211_hw *hw, 561 enum wireless_mode wirelessmode, 562 long power_indbm) 563{ 564 u8 txpwridx; 565 long offset; 566 567 switch (wirelessmode) { 568 case WIRELESS_MODE_B: 569 offset = -7; 570 break; 571 case WIRELESS_MODE_G: 572 case WIRELESS_MODE_N_24G: 573 offset = -8; 574 break; 575 default: 576 offset = -8; 577 break; 578 } 579 580 if ((power_indbm - offset) > 0) 581 txpwridx = (u8) ((power_indbm - offset) * 2); 582 else 583 txpwridx = 0; 584 585 if (txpwridx > MAX_TXPWR_IDX_NMODE_92S) 586 txpwridx = MAX_TXPWR_IDX_NMODE_92S; 587 588 return txpwridx; 589} 590EXPORT_SYMBOL(_rtl92c_phy_dbm_to_txpwr_Idx); 591 592long _rtl92c_phy_txpwr_idx_to_dbm(struct ieee80211_hw *hw, 593 enum wireless_mode wirelessmode, 594 u8 txpwridx) 595{ 596 long offset; 597 long pwrout_dbm; 598 599 switch (wirelessmode) { 600 case WIRELESS_MODE_B: 601 offset = -7; 602 break; 603 case WIRELESS_MODE_G: 604 case WIRELESS_MODE_N_24G: 605 offset = -8; 606 break; 607 default: 608 offset = -8; 609 break; 610 } 611 pwrout_dbm = txpwridx / 2 + offset; 612 return pwrout_dbm; 613} 614EXPORT_SYMBOL(_rtl92c_phy_txpwr_idx_to_dbm); 615 616void rtl92c_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) 617{ 618 struct rtl_priv *rtlpriv = rtl_priv(hw); 619 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 620 enum io_type iotype; 621 622 if (!is_hal_stop(rtlhal)) { 623 switch (operation) { 624 case SCAN_OPT_BACKUP: 625 iotype = IO_CMD_PAUSE_DM_BY_SCAN; 626 rtlpriv->cfg->ops->set_hw_reg(hw, 627 HW_VAR_IO_CMD, 628 (u8 *)&iotype); 629 630 break; 631 case SCAN_OPT_RESTORE: 632 iotype = IO_CMD_RESUME_DM_BY_SCAN; 633 rtlpriv->cfg->ops->set_hw_reg(hw, 634 HW_VAR_IO_CMD, 635 (u8 *)&iotype); 636 break; 637 default: 638 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 639 "Unknown Scan Backup operation\n"); 640 break; 641 } 642 } 643} 644EXPORT_SYMBOL(rtl92c_phy_scan_operation_backup); 645 646void rtl92c_phy_set_bw_mode(struct ieee80211_hw *hw, 647 enum nl80211_channel_type ch_type) 648{ 649 struct rtl_priv *rtlpriv = rtl_priv(hw); 650 struct rtl_phy *rtlphy = &(rtlpriv->phy); 651 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 652 u8 tmp_bw = rtlphy->current_chan_bw; 653 654 if (rtlphy->set_bwmode_inprogress) 655 return; 656 rtlphy->set_bwmode_inprogress = true; 657 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 658 rtlpriv->cfg->ops->phy_set_bw_mode_callback(hw); 659 } else { 660 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, 661 "FALSE driver sleep or unload\n"); 662 rtlphy->set_bwmode_inprogress = false; 663 rtlphy->current_chan_bw = tmp_bw; 664 } 665} 666EXPORT_SYMBOL(rtl92c_phy_set_bw_mode); 667 668void rtl92c_phy_sw_chnl_callback(struct ieee80211_hw *hw) 669{ 670 struct rtl_priv *rtlpriv = rtl_priv(hw); 671 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 672 struct rtl_phy *rtlphy = &(rtlpriv->phy); 673 u32 delay; 674 675 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, 676 "switch to channel%d\n", rtlphy->current_channel); 677 if (is_hal_stop(rtlhal)) 678 return; 679 do { 680 if (!rtlphy->sw_chnl_inprogress) 681 break; 682 if (!_rtl92c_phy_sw_chnl_step_by_step 683 (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage, 684 &rtlphy->sw_chnl_step, &delay)) { 685 if (delay > 0) 686 mdelay(delay); 687 else 688 continue; 689 } else { 690 rtlphy->sw_chnl_inprogress = false; 691 } 692 break; 693 } while (true); 694 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "<==\n"); 695} 696EXPORT_SYMBOL(rtl92c_phy_sw_chnl_callback); 697 698u8 rtl92c_phy_sw_chnl(struct ieee80211_hw *hw) 699{ 700 struct rtl_priv *rtlpriv = rtl_priv(hw); 701 struct rtl_phy *rtlphy = &(rtlpriv->phy); 702 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 703 704 if (rtlphy->sw_chnl_inprogress) 705 return 0; 706 if (rtlphy->set_bwmode_inprogress) 707 return 0; 708 RT_ASSERT((rtlphy->current_channel <= 14), 709 "WIRELESS_MODE_G but channel>14\n"); 710 rtlphy->sw_chnl_inprogress = true; 711 rtlphy->sw_chnl_stage = 0; 712 rtlphy->sw_chnl_step = 0; 713 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { 714 rtl92c_phy_sw_chnl_callback(hw); 715 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, 716 "sw_chnl_inprogress false schdule workitem\n"); 717 rtlphy->sw_chnl_inprogress = false; 718 } else { 719 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, 720 "sw_chnl_inprogress false driver sleep or unload\n"); 721 rtlphy->sw_chnl_inprogress = false; 722 } 723 return 1; 724} 725EXPORT_SYMBOL(rtl92c_phy_sw_chnl); 726 727static bool _rtl92c_phy_set_sw_chnl_cmdarray(struct swchnlcmd *cmdtable, 728 u32 cmdtableidx, u32 cmdtablesz, 729 enum swchnlcmd_id cmdid, 730 u32 para1, u32 para2, u32 msdelay) 731{ 732 struct swchnlcmd *pcmd; 733 734 if (cmdtable == NULL) { 735 RT_ASSERT(false, "cmdtable cannot be NULL\n"); 736 return false; 737 } 738 739 if (cmdtableidx >= cmdtablesz) 740 return false; 741 742 pcmd = cmdtable + cmdtableidx; 743 pcmd->cmdid = cmdid; 744 pcmd->para1 = para1; 745 pcmd->para2 = para2; 746 pcmd->msdelay = msdelay; 747 return true; 748} 749 750bool _rtl92c_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, 751 u8 channel, u8 *stage, u8 *step, 752 u32 *delay) 753{ 754 struct rtl_priv *rtlpriv = rtl_priv(hw); 755 struct rtl_phy *rtlphy = &(rtlpriv->phy); 756 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; 757 u32 precommoncmdcnt; 758 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; 759 u32 postcommoncmdcnt; 760 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT]; 761 u32 rfdependcmdcnt; 762 struct swchnlcmd *currentcmd = NULL; 763 u8 rfpath; 764 u8 num_total_rfpath = rtlphy->num_total_rfpath; 765 766 precommoncmdcnt = 0; 767 _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 768 MAX_PRECMD_CNT, 769 CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0); 770 _rtl92c_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, 771 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); 772 773 postcommoncmdcnt = 0; 774 775 _rtl92c_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, 776 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0); 777 778 rfdependcmdcnt = 0; 779 780 RT_ASSERT((channel >= 1 && channel <= 14), 781 "invalid channel for Zebra: %d\n", channel); 782 783 _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 784 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG, 785 RF_CHNLBW, channel, 10); 786 787 _rtl92c_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, 788 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0, 789 0); 790 791 do { 792 switch (*stage) { 793 case 0: 794 currentcmd = &precommoncmd[*step]; 795 break; 796 case 1: 797 currentcmd = &rfdependcmd[*step]; 798 break; 799 case 2: 800 currentcmd = &postcommoncmd[*step]; 801 break; 802 } 803 804 if (currentcmd->cmdid == CMDID_END) { 805 if ((*stage) == 2) { 806 return true; 807 } else { 808 (*stage)++; 809 (*step) = 0; 810 continue; 811 } 812 } 813 814 switch (currentcmd->cmdid) { 815 case CMDID_SET_TXPOWEROWER_LEVEL: 816 rtl92c_phy_set_txpower_level(hw, channel); 817 break; 818 case CMDID_WRITEPORT_ULONG: 819 rtl_write_dword(rtlpriv, currentcmd->para1, 820 currentcmd->para2); 821 break; 822 case CMDID_WRITEPORT_USHORT: 823 rtl_write_word(rtlpriv, currentcmd->para1, 824 (u16) currentcmd->para2); 825 break; 826 case CMDID_WRITEPORT_UCHAR: 827 rtl_write_byte(rtlpriv, currentcmd->para1, 828 (u8) currentcmd->para2); 829 break; 830 case CMDID_RF_WRITEREG: 831 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { 832 rtlphy->rfreg_chnlval[rfpath] = 833 ((rtlphy->rfreg_chnlval[rfpath] & 834 0xfffffc00) | currentcmd->para2); 835 836 rtl_set_rfreg(hw, (enum radio_path)rfpath, 837 currentcmd->para1, 838 RFREG_OFFSET_MASK, 839 rtlphy->rfreg_chnlval[rfpath]); 840 } 841 break; 842 default: 843 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 844 "switch case not processed\n"); 845 break; 846 } 847 848 break; 849 } while (true); 850 851 (*delay) = currentcmd->msdelay; 852 (*step)++; 853 return false; 854} 855 856bool rtl8192_phy_check_is_legal_rfpath(struct ieee80211_hw *hw, u32 rfpath) 857{ 858 return true; 859} 860EXPORT_SYMBOL(rtl8192_phy_check_is_legal_rfpath); 861 862static u8 _rtl92c_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) 863{ 864 u32 reg_eac, reg_e94, reg_e9c, reg_ea4; 865 u8 result = 0x00; 866 867 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f); 868 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f); 869 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102); 870 rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 871 config_pathb ? 0x28160202 : 0x28160502); 872 873 if (config_pathb) { 874 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22); 875 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22); 876 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102); 877 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202); 878 } 879 880 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1); 881 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); 882 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); 883 884 mdelay(IQK_DELAY_TIME); 885 886 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); 887 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); 888 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); 889 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); 890 891 if (!(reg_eac & BIT(28)) && 892 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && 893 (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) 894 result |= 0x01; 895 else 896 return result; 897 898 if (!(reg_eac & BIT(27)) && 899 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && 900 (((reg_eac & 0x03FF0000) >> 16) != 0x36)) 901 result |= 0x02; 902 return result; 903} 904 905static u8 _rtl92c_phy_path_b_iqk(struct ieee80211_hw *hw) 906{ 907 u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc; 908 u8 result = 0x00; 909 910 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002); 911 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000); 912 mdelay(IQK_DELAY_TIME); 913 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); 914 reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD); 915 reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD); 916 reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD); 917 reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD); 918 919 if (!(reg_eac & BIT(31)) && 920 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) && 921 (((reg_ebc & 0x03FF0000) >> 16) != 0x42)) 922 result |= 0x01; 923 else 924 return result; 925 if (!(reg_eac & BIT(30)) && 926 (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) && 927 (((reg_ecc & 0x03FF0000) >> 16) != 0x36)) 928 result |= 0x02; 929 return result; 930} 931 932static void _rtl92c_phy_path_a_fill_iqk_matrix(struct ieee80211_hw *hw, 933 bool iqk_ok, long result[][8], 934 u8 final_candidate, bool btxonly) 935{ 936 u32 oldval_0, x, tx0_a, reg; 937 long y, tx0_c; 938 939 if (final_candidate == 0xFF) { 940 return; 941 } else if (iqk_ok) { 942 oldval_0 = (rtl_get_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 943 MASKDWORD) >> 22) & 0x3FF; 944 x = result[final_candidate][0]; 945 if ((x & 0x00000200) != 0) 946 x = x | 0xFFFFFC00; 947 tx0_a = (x * oldval_0) >> 8; 948 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x3FF, tx0_a); 949 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(31), 950 ((x * oldval_0 >> 7) & 0x1)); 951 y = result[final_candidate][1]; 952 if ((y & 0x00000200) != 0) 953 y = y | 0xFFFFFC00; 954 tx0_c = (y * oldval_0) >> 8; 955 rtl_set_bbreg(hw, ROFDM0_XCTXAFE, 0xF0000000, 956 ((tx0_c & 0x3C0) >> 6)); 957 rtl_set_bbreg(hw, ROFDM0_XATXIQIMBALANCE, 0x003F0000, 958 (tx0_c & 0x3F)); 959 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(29), 960 ((y * oldval_0 >> 7) & 0x1)); 961 if (btxonly) 962 return; 963 reg = result[final_candidate][2]; 964 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0x3FF, reg); 965 reg = result[final_candidate][3] & 0x3F; 966 rtl_set_bbreg(hw, ROFDM0_XARXIQIMBALANCE, 0xFC00, reg); 967 reg = (result[final_candidate][3] >> 6) & 0xF; 968 rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); 969 } 970} 971 972static void _rtl92c_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, 973 bool iqk_ok, long result[][8], 974 u8 final_candidate, bool btxonly) 975{ 976 u32 oldval_1, x, tx1_a, reg; 977 long y, tx1_c; 978 979 if (final_candidate == 0xFF) { 980 return; 981 } else if (iqk_ok) { 982 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 983 MASKDWORD) >> 22) & 0x3FF; 984 x = result[final_candidate][4]; 985 if ((x & 0x00000200) != 0) 986 x = x | 0xFFFFFC00; 987 tx1_a = (x * oldval_1) >> 8; 988 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); 989 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), 990 ((x * oldval_1 >> 7) & 0x1)); 991 y = result[final_candidate][5]; 992 if ((y & 0x00000200) != 0) 993 y = y | 0xFFFFFC00; 994 tx1_c = (y * oldval_1) >> 8; 995 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, 996 ((tx1_c & 0x3C0) >> 6)); 997 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, 998 (tx1_c & 0x3F)); 999 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), 1000 ((y * oldval_1 >> 7) & 0x1)); 1001 if (btxonly) 1002 return; 1003 reg = result[final_candidate][6]; 1004 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); 1005 reg = result[final_candidate][7] & 0x3F; 1006 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); 1007 reg = (result[final_candidate][7] >> 6) & 0xF; 1008 rtl_set_bbreg(hw, ROFDM0_AGCRSSITABLE, 0x0000F000, reg); 1009 } 1010} 1011 1012static void _rtl92c_phy_save_adda_registers(struct ieee80211_hw *hw, 1013 u32 *addareg, u32 *addabackup, 1014 u32 registernum) 1015{ 1016 u32 i; 1017 1018 for (i = 0; i < registernum; i++) 1019 addabackup[i] = rtl_get_bbreg(hw, addareg[i], MASKDWORD); 1020} 1021 1022static void _rtl92c_phy_save_mac_registers(struct ieee80211_hw *hw, 1023 u32 *macreg, u32 *macbackup) 1024{ 1025 struct rtl_priv *rtlpriv = rtl_priv(hw); 1026 u32 i; 1027 1028 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) 1029 macbackup[i] = rtl_read_byte(rtlpriv, macreg[i]); 1030 macbackup[i] = rtl_read_dword(rtlpriv, macreg[i]); 1031} 1032 1033static void _rtl92c_phy_reload_adda_registers(struct ieee80211_hw *hw, 1034 u32 *addareg, u32 *addabackup, 1035 u32 regiesternum) 1036{ 1037 u32 i; 1038 1039 for (i = 0; i < regiesternum; i++) 1040 rtl_set_bbreg(hw, addareg[i], MASKDWORD, addabackup[i]); 1041} 1042 1043static void _rtl92c_phy_reload_mac_registers(struct ieee80211_hw *hw, 1044 u32 *macreg, u32 *macbackup) 1045{ 1046 struct rtl_priv *rtlpriv = rtl_priv(hw); 1047 u32 i; 1048 1049 for (i = 0; i < (IQK_MAC_REG_NUM - 1); i++) 1050 rtl_write_byte(rtlpriv, macreg[i], (u8) macbackup[i]); 1051 rtl_write_dword(rtlpriv, macreg[i], macbackup[i]); 1052} 1053 1054static void _rtl92c_phy_path_adda_on(struct ieee80211_hw *hw, 1055 u32 *addareg, bool is_patha_on, bool is2t) 1056{ 1057 u32 pathOn; 1058 u32 i; 1059 1060 pathOn = is_patha_on ? 0x04db25a4 : 0x0b1b25a4; 1061 if (false == is2t) { 1062 pathOn = 0x0bdb25a0; 1063 rtl_set_bbreg(hw, addareg[0], MASKDWORD, 0x0b1b25a0); 1064 } else { 1065 rtl_set_bbreg(hw, addareg[0], MASKDWORD, pathOn); 1066 } 1067 1068 for (i = 1; i < IQK_ADDA_REG_NUM; i++) 1069 rtl_set_bbreg(hw, addareg[i], MASKDWORD, pathOn); 1070} 1071 1072static void _rtl92c_phy_mac_setting_calibration(struct ieee80211_hw *hw, 1073 u32 *macreg, u32 *macbackup) 1074{ 1075 struct rtl_priv *rtlpriv = rtl_priv(hw); 1076 u32 i; 1077 1078 rtl_write_byte(rtlpriv, macreg[0], 0x3F); 1079 1080 for (i = 1; i < (IQK_MAC_REG_NUM - 1); i++) 1081 rtl_write_byte(rtlpriv, macreg[i], 1082 (u8) (macbackup[i] & (~BIT(3)))); 1083 rtl_write_byte(rtlpriv, macreg[i], (u8) (macbackup[i] & (~BIT(5)))); 1084} 1085 1086static void _rtl92c_phy_path_a_standby(struct ieee80211_hw *hw) 1087{ 1088 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x0); 1089 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); 1090 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); 1091} 1092 1093static void _rtl92c_phy_pi_mode_switch(struct ieee80211_hw *hw, bool pi_mode) 1094{ 1095 u32 mode; 1096 1097 mode = pi_mode ? 0x01000100 : 0x01000000; 1098 rtl_set_bbreg(hw, 0x820, MASKDWORD, mode); 1099 rtl_set_bbreg(hw, 0x828, MASKDWORD, mode); 1100} 1101 1102static bool _rtl92c_phy_simularity_compare(struct ieee80211_hw *hw, 1103 long result[][8], u8 c1, u8 c2) 1104{ 1105 u32 i, j, diff, simularity_bitmap, bound; 1106 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1107 1108 u8 final_candidate[2] = { 0xFF, 0xFF }; 1109 bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); 1110 1111 if (is2t) 1112 bound = 8; 1113 else 1114 bound = 4; 1115 1116 simularity_bitmap = 0; 1117 1118 for (i = 0; i < bound; i++) { 1119 diff = (result[c1][i] > result[c2][i]) ? 1120 (result[c1][i] - result[c2][i]) : 1121 (result[c2][i] - result[c1][i]); 1122 1123 if (diff > MAX_TOLERANCE) { 1124 if ((i == 2 || i == 6) && !simularity_bitmap) { 1125 if (result[c1][i] + result[c1][i + 1] == 0) 1126 final_candidate[(i / 4)] = c2; 1127 else if (result[c2][i] + result[c2][i + 1] == 0) 1128 final_candidate[(i / 4)] = c1; 1129 else 1130 simularity_bitmap = simularity_bitmap | 1131 (1 << i); 1132 } else 1133 simularity_bitmap = 1134 simularity_bitmap | (1 << i); 1135 } 1136 } 1137 1138 if (simularity_bitmap == 0) { 1139 for (i = 0; i < (bound / 4); i++) { 1140 if (final_candidate[i] != 0xFF) { 1141 for (j = i * 4; j < (i + 1) * 4 - 2; j++) 1142 result[3][j] = 1143 result[final_candidate[i]][j]; 1144 bresult = false; 1145 } 1146 } 1147 return bresult; 1148 } else if (!(simularity_bitmap & 0x0F)) { 1149 for (i = 0; i < 4; i++) 1150 result[3][i] = result[c1][i]; 1151 return false; 1152 } else if (!(simularity_bitmap & 0xF0) && is2t) { 1153 for (i = 4; i < 8; i++) 1154 result[3][i] = result[c1][i]; 1155 return false; 1156 } else { 1157 return false; 1158 } 1159 1160} 1161 1162static void _rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, 1163 long result[][8], u8 t, bool is2t) 1164{ 1165 struct rtl_priv *rtlpriv = rtl_priv(hw); 1166 struct rtl_phy *rtlphy = &(rtlpriv->phy); 1167 u32 i; 1168 u8 patha_ok, pathb_ok; 1169 u32 adda_reg[IQK_ADDA_REG_NUM] = { 1170 0x85c, 0xe6c, 0xe70, 0xe74, 1171 0xe78, 0xe7c, 0xe80, 0xe84, 1172 0xe88, 0xe8c, 0xed0, 0xed4, 1173 0xed8, 0xedc, 0xee0, 0xeec 1174 }; 1175 1176 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = { 1177 0x522, 0x550, 0x551, 0x040 1178 }; 1179 1180 const u32 retrycount = 2; 1181 1182 if (t == 0) { 1183 /* dummy read */ 1184 rtl_get_bbreg(hw, 0x800, MASKDWORD); 1185 1186 _rtl92c_phy_save_adda_registers(hw, adda_reg, 1187 rtlphy->adda_backup, 16); 1188 _rtl92c_phy_save_mac_registers(hw, iqk_mac_reg, 1189 rtlphy->iqk_mac_backup); 1190 } 1191 _rtl92c_phy_path_adda_on(hw, adda_reg, true, is2t); 1192 if (t == 0) { 1193 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, 1194 RFPGA0_XA_HSSIPARAMETER1, 1195 BIT(8)); 1196 } 1197 1198 if (!rtlphy->rfpi_enable) 1199 _rtl92c_phy_pi_mode_switch(hw, true); 1200 if (t == 0) { 1201 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD); 1202 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD); 1203 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD); 1204 } 1205 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); 1206 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); 1207 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); 1208 if (is2t) { 1209 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000); 1210 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000); 1211 } 1212 _rtl92c_phy_mac_setting_calibration(hw, iqk_mac_reg, 1213 rtlphy->iqk_mac_backup); 1214 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000); 1215 if (is2t) 1216 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000); 1217 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); 1218 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); 1219 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800); 1220 for (i = 0; i < retrycount; i++) { 1221 patha_ok = _rtl92c_phy_path_a_iqk(hw, is2t); 1222 if (patha_ok == 0x03) { 1223 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & 1224 0x3FF0000) >> 16; 1225 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 1226 0x3FF0000) >> 16; 1227 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & 1228 0x3FF0000) >> 16; 1229 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & 1230 0x3FF0000) >> 16; 1231 break; 1232 } else if (i == (retrycount - 1) && patha_ok == 0x01) 1233 1234 result[t][0] = (rtl_get_bbreg(hw, 0xe94, 1235 MASKDWORD) & 0x3FF0000) >> 1236 16; 1237 result[t][1] = 1238 (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; 1239 1240 } 1241 1242 if (is2t) { 1243 _rtl92c_phy_path_a_standby(hw); 1244 _rtl92c_phy_path_adda_on(hw, adda_reg, false, is2t); 1245 for (i = 0; i < retrycount; i++) { 1246 pathb_ok = _rtl92c_phy_path_b_iqk(hw); 1247 if (pathb_ok == 0x03) { 1248 result[t][4] = (rtl_get_bbreg(hw, 1249 0xeb4, 1250 MASKDWORD) & 1251 0x3FF0000) >> 16; 1252 result[t][5] = 1253 (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & 1254 0x3FF0000) >> 16; 1255 result[t][6] = 1256 (rtl_get_bbreg(hw, 0xec4, MASKDWORD) & 1257 0x3FF0000) >> 16; 1258 result[t][7] = 1259 (rtl_get_bbreg(hw, 0xecc, MASKDWORD) & 1260 0x3FF0000) >> 16; 1261 break; 1262 } else if (i == (retrycount - 1) && pathb_ok == 0x01) { 1263 result[t][4] = (rtl_get_bbreg(hw, 1264 0xeb4, 1265 MASKDWORD) & 1266 0x3FF0000) >> 16; 1267 } 1268 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) & 1269 0x3FF0000) >> 16; 1270 } 1271 } 1272 rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04); 1273 rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874); 1274 rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08); 1275 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); 1276 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3); 1277 if (is2t) 1278 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3); 1279 if (t != 0) { 1280 if (!rtlphy->rfpi_enable) 1281 _rtl92c_phy_pi_mode_switch(hw, false); 1282 _rtl92c_phy_reload_adda_registers(hw, adda_reg, 1283 rtlphy->adda_backup, 16); 1284 _rtl92c_phy_reload_mac_registers(hw, iqk_mac_reg, 1285 rtlphy->iqk_mac_backup); 1286 } 1287} 1288 1289static void _rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, 1290 char delta, bool is2t) 1291{ 1292#if 0 /* This routine is deliberately dummied out for later fixes */ 1293 struct rtl_priv *rtlpriv = rtl_priv(hw); 1294 struct rtl_phy *rtlphy = &(rtlpriv->phy); 1295 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); 1296 1297 u32 reg_d[PATH_NUM]; 1298 u32 tmpreg, index, offset, path, i, pathbound = PATH_NUM, apkbound; 1299 1300 u32 bb_backup[APK_BB_REG_NUM]; 1301 u32 bb_reg[APK_BB_REG_NUM] = { 1302 0x904, 0xc04, 0x800, 0xc08, 0x874 1303 }; 1304 u32 bb_ap_mode[APK_BB_REG_NUM] = { 1305 0x00000020, 0x00a05430, 0x02040000, 1306 0x000800e4, 0x00204000 1307 }; 1308 u32 bb_normal_ap_mode[APK_BB_REG_NUM] = { 1309 0x00000020, 0x00a05430, 0x02040000, 1310 0x000800e4, 0x22204000 1311 }; 1312 1313 u32 afe_backup[APK_AFE_REG_NUM]; 1314 u32 afe_reg[APK_AFE_REG_NUM] = { 1315 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 1316 0xe7c, 0xe80, 0xe84, 0xe88, 0xe8c, 1317 0xed0, 0xed4, 0xed8, 0xedc, 0xee0, 1318 0xeec 1319 }; 1320 1321 u32 mac_backup[IQK_MAC_REG_NUM]; 1322 u32 mac_reg[IQK_MAC_REG_NUM] = { 1323 0x522, 0x550, 0x551, 0x040 1324 }; 1325 1326 u32 apk_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { 1327 {0x0852c, 0x1852c, 0x5852c, 0x1852c, 0x5852c}, 1328 {0x2852e, 0x0852e, 0x3852e, 0x0852e, 0x0852e} 1329 }; 1330 1331 u32 apk_normal_rf_init_value[PATH_NUM][APK_BB_REG_NUM] = { 1332 {0x0852c, 0x0a52c, 0x3a52c, 0x5a52c, 0x5a52c}, 1333 {0x0852c, 0x0a52c, 0x5a52c, 0x5a52c, 0x5a52c} 1334 }; 1335 1336 u32 apk_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { 1337 {0x52019, 0x52014, 0x52013, 0x5200f, 0x5208d}, 1338 {0x5201a, 0x52019, 0x52016, 0x52033, 0x52050} 1339 }; 1340 1341 u32 apk_normal_rf_value_0[PATH_NUM][APK_BB_REG_NUM] = { 1342 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a}, 1343 {0x52019, 0x52017, 0x52010, 0x5200d, 0x5206a} 1344 }; 1345 1346 u32 afe_on_off[PATH_NUM] = { 1347 0x04db25a4, 0x0b1b25a4 1348 }; 1349 1350 const u32 apk_offset[PATH_NUM] = { 0xb68, 0xb6c }; 1351 1352 u32 apk_normal_offset[PATH_NUM] = { 0xb28, 0xb98 }; 1353 1354 u32 apk_value[PATH_NUM] = { 0x92fc0000, 0x12fc0000 }; 1355 1356 u32 apk_normal_value[PATH_NUM] = { 0x92680000, 0x12680000 }; 1357 1358 const char apk_delta_mapping[APK_BB_REG_NUM][13] = { 1359 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, 1360 {-4, -3, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, 1361 {-6, -4, -2, -2, -1, -1, 0, 1, 2, 3, 4, 5, 6}, 1362 {-1, -1, -1, -1, -1, -1, 0, 1, 2, 3, 4, 5, 6}, 1363 {-11, -9, -7, -5, -3, -1, 0, 0, 0, 0, 0, 0, 0} 1364 }; 1365 1366 const u32 apk_normal_setting_value_1[13] = { 1367 0x01017018, 0xf7ed8f84, 0x1b1a1816, 0x2522201e, 0x322e2b28, 1368 0x433f3a36, 0x5b544e49, 0x7b726a62, 0xa69a8f84, 0xdfcfc0b3, 1369 0x12680000, 0x00880000, 0x00880000 1370 }; 1371 1372 const u32 apk_normal_setting_value_2[16] = { 1373 0x01c7021d, 0x01670183, 0x01000123, 0x00bf00e2, 0x008d00a3, 1374 0x0068007b, 0x004d0059, 0x003a0042, 0x002b0031, 0x001f0025, 1375 0x0017001b, 0x00110014, 0x000c000f, 0x0009000b, 0x00070008, 1376 0x00050006 1377 }; 1378 1379 u32 apk_result[PATH_NUM][APK_BB_REG_NUM]; 1380 1381 long bb_offset, delta_v, delta_offset; 1382 1383 if (!is2t) 1384 pathbound = 1; 1385 1386 return; 1387 1388 for (index = 0; index < PATH_NUM; index++) { 1389 apk_offset[index] = apk_normal_offset[index]; 1390 apk_value[index] = apk_normal_value[index]; 1391 afe_on_off[index] = 0x6fdb25a4; 1392 } 1393 1394 for (index = 0; index < APK_BB_REG_NUM; index++) { 1395 for (path = 0; path < pathbound; path++) { 1396 apk_rf_init_value[path][index] = 1397 apk_normal_rf_init_value[path][index]; 1398 apk_rf_value_0[path][index] = 1399 apk_normal_rf_value_0[path][index]; 1400 } 1401 bb_ap_mode[index] = bb_normal_ap_mode[index]; 1402 1403 apkbound = 6; 1404 } 1405 1406 for (index = 0; index < APK_BB_REG_NUM; index++) { 1407 if (index == 0) 1408 continue; 1409 bb_backup[index] = rtl_get_bbreg(hw, bb_reg[index], MASKDWORD); 1410 } 1411 1412 _rtl92c_phy_save_mac_registers(hw, mac_reg, mac_backup); 1413 1414 _rtl92c_phy_save_adda_registers(hw, afe_reg, afe_backup, 16); 1415 1416 for (path = 0; path < pathbound; path++) { 1417 if (path == RF90_PATH_A) { 1418 offset = 0xb00; 1419 for (index = 0; index < 11; index++) { 1420 rtl_set_bbreg(hw, offset, MASKDWORD, 1421 apk_normal_setting_value_1 1422 [index]); 1423 1424 offset += 0x04; 1425 } 1426 1427 rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); 1428 1429 offset = 0xb68; 1430 for (; index < 13; index++) { 1431 rtl_set_bbreg(hw, offset, MASKDWORD, 1432 apk_normal_setting_value_1 1433 [index]); 1434 1435 offset += 0x04; 1436 } 1437 1438 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); 1439 1440 offset = 0xb00; 1441 for (index = 0; index < 16; index++) { 1442 rtl_set_bbreg(hw, offset, MASKDWORD, 1443 apk_normal_setting_value_2 1444 [index]); 1445 1446 offset += 0x04; 1447 } 1448 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); 1449 } else if (path == RF90_PATH_B) { 1450 offset = 0xb70; 1451 for (index = 0; index < 10; index++) { 1452 rtl_set_bbreg(hw, offset, MASKDWORD, 1453 apk_normal_setting_value_1 1454 [index]); 1455 1456 offset += 0x04; 1457 } 1458 rtl_set_bbreg(hw, 0xb28, MASKDWORD, 0x12680000); 1459 rtl_set_bbreg(hw, 0xb98, MASKDWORD, 0x12680000); 1460 1461 offset = 0xb68; 1462 index = 11; 1463 for (; index < 13; index++) { 1464 rtl_set_bbreg(hw, offset, MASKDWORD, 1465 apk_normal_setting_value_1 1466 [index]); 1467 1468 offset += 0x04; 1469 } 1470 1471 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x40000000); 1472 1473 offset = 0xb60; 1474 for (index = 0; index < 16; index++) { 1475 rtl_set_bbreg(hw, offset, MASKDWORD, 1476 apk_normal_setting_value_2 1477 [index]); 1478 1479 offset += 0x04; 1480 } 1481 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); 1482 } 1483 1484 reg_d[path] = rtl_get_rfreg(hw, (enum radio_path)path, 1485 0xd, MASKDWORD); 1486 1487 for (index = 0; index < APK_AFE_REG_NUM; index++) 1488 rtl_set_bbreg(hw, afe_reg[index], MASKDWORD, 1489 afe_on_off[path]); 1490 1491 if (path == RF90_PATH_A) { 1492 for (index = 0; index < APK_BB_REG_NUM; index++) { 1493 if (index == 0) 1494 continue; 1495 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, 1496 bb_ap_mode[index]); 1497 } 1498 } 1499 1500 _rtl92c_phy_mac_setting_calibration(hw, mac_reg, mac_backup); 1501 1502 if (path == 0) { 1503 rtl_set_rfreg(hw, RF90_PATH_B, 0x0, MASKDWORD, 0x10000); 1504 } else { 1505 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASKDWORD, 1506 0x10000); 1507 rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, 1508 0x1000f); 1509 rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, 1510 0x20103); 1511 } 1512 1513 delta_offset = ((delta + 14) / 2); 1514 if (delta_offset < 0) 1515 delta_offset = 0; 1516 else if (delta_offset > 12) 1517 delta_offset = 12; 1518 1519 for (index = 0; index < APK_BB_REG_NUM; index++) { 1520 if (index != 1) 1521 continue; 1522 1523 tmpreg = apk_rf_init_value[path][index]; 1524 1525 if (!rtlefuse->apk_thermalmeterignore) { 1526 bb_offset = (tmpreg & 0xF0000) >> 16; 1527 1528 if (!(tmpreg & BIT(15))) 1529 bb_offset = -bb_offset; 1530 1531 delta_v = 1532 apk_delta_mapping[index][delta_offset]; 1533 1534 bb_offset += delta_v; 1535 1536 if (bb_offset < 0) { 1537 tmpreg = tmpreg & (~BIT(15)); 1538 bb_offset = -bb_offset; 1539 } else { 1540 tmpreg = tmpreg | BIT(15); 1541 } 1542 1543 tmpreg = 1544 (tmpreg & 0xFFF0FFFF) | (bb_offset << 16); 1545 } 1546 1547 rtl_set_rfreg(hw, (enum radio_path)path, 0xc, 1548 MASKDWORD, 0x8992e); 1549 rtl_set_rfreg(hw, (enum radio_path)path, 0x0, 1550 MASKDWORD, apk_rf_value_0[path][index]); 1551 rtl_set_rfreg(hw, (enum radio_path)path, 0xd, 1552 MASKDWORD, tmpreg); 1553 1554 i = 0; 1555 do { 1556 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80000000); 1557 rtl_set_bbreg(hw, apk_offset[path], 1558 MASKDWORD, apk_value[0]); 1559 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1560 ("PHY_APCalibrate() offset 0x%x " 1561 "value 0x%x\n", 1562 apk_offset[path], 1563 rtl_get_bbreg(hw, apk_offset[path], 1564 MASKDWORD))); 1565 1566 mdelay(3); 1567 1568 rtl_set_bbreg(hw, apk_offset[path], 1569 MASKDWORD, apk_value[1]); 1570 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1571 ("PHY_APCalibrate() offset 0x%x " 1572 "value 0x%x\n", 1573 apk_offset[path], 1574 rtl_get_bbreg(hw, apk_offset[path], 1575 MASKDWORD))); 1576 1577 mdelay(20); 1578 1579 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x00000000); 1580 1581 if (path == RF90_PATH_A) 1582 tmpreg = rtl_get_bbreg(hw, 0xbd8, 1583 0x03E00000); 1584 else 1585 tmpreg = rtl_get_bbreg(hw, 0xbd8, 1586 0xF8000000); 1587 1588 RTPRINT(rtlpriv, FINIT, INIT_IQK, 1589 ("PHY_APCalibrate() offset " 1590 "0xbd8[25:21] %x\n", tmpreg)); 1591 1592 i++; 1593 1594 } while (tmpreg > apkbound && i < 4); 1595 1596 apk_result[path][index] = tmpreg; 1597 } 1598 } 1599 1600 _rtl92c_phy_reload_mac_registers(hw, mac_reg, mac_backup); 1601 1602 for (index = 0; index < APK_BB_REG_NUM; index++) { 1603 if (index == 0) 1604 continue; 1605 rtl_set_bbreg(hw, bb_reg[index], MASKDWORD, bb_backup[index]); 1606 } 1607 1608 _rtl92c_phy_reload_adda_registers(hw, afe_reg, afe_backup, 16); 1609 1610 for (path = 0; path < pathbound; path++) { 1611 rtl_set_rfreg(hw, (enum radio_path)path, 0xd, 1612 MASKDWORD, reg_d[path]); 1613 1614 if (path == RF90_PATH_B) { 1615 rtl_set_rfreg(hw, RF90_PATH_A, 0x10, MASKDWORD, 1616 0x1000f); 1617 rtl_set_rfreg(hw, RF90_PATH_A, 0x11, MASKDWORD, 1618 0x20101); 1619 } 1620 1621 if (apk_result[path][1] > 6) 1622 apk_result[path][1] = 6; 1623 } 1624 1625 for (path = 0; path < pathbound; path++) { 1626 rtl_set_rfreg(hw, (enum radio_path)path, 0x3, MASKDWORD, 1627 ((apk_result[path][1] << 15) | 1628 (apk_result[path][1] << 10) | 1629 (apk_result[path][1] << 5) | 1630 apk_result[path][1])); 1631 1632 if (path == RF90_PATH_A) 1633 rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, 1634 ((apk_result[path][1] << 15) | 1635 (apk_result[path][1] << 10) | 1636 (0x00 << 5) | 0x05)); 1637 else 1638 rtl_set_rfreg(hw, (enum radio_path)path, 0x4, MASKDWORD, 1639 ((apk_result[path][1] << 15) | 1640 (apk_result[path][1] << 10) | 1641 (0x02 << 5) | 0x05)); 1642 1643 rtl_set_rfreg(hw, (enum radio_path)path, 0xe, MASKDWORD, 1644 ((0x08 << 15) | (0x08 << 10) | (0x08 << 5) | 1645 0x08)); 1646 1647 } 1648 rtlphy->b_apk_done = true; 1649#endif 1650} 1651 1652static void _rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, 1653 bool bmain, bool is2t) 1654{ 1655 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1656 1657 if (is_hal_stop(rtlhal)) { 1658 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01); 1659 rtl_set_bbreg(hw, rFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); 1660 } 1661 if (is2t) { 1662 if (bmain) 1663 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 1664 BIT(5) | BIT(6), 0x1); 1665 else 1666 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, 1667 BIT(5) | BIT(6), 0x2); 1668 } else { 1669 if (bmain) 1670 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2); 1671 else 1672 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1); 1673 1674 } 1675 1676} 1677 1678#undef IQK_ADDA_REG_NUM 1679#undef IQK_DELAY_TIME 1680 1681void rtl92c_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) 1682{ 1683 struct rtl_priv *rtlpriv = rtl_priv(hw); 1684 struct rtl_phy *rtlphy = &(rtlpriv->phy); 1685 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1686 1687 long result[4][8]; 1688 u8 i, final_candidate; 1689 bool patha_ok, pathb_ok; 1690 long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc, reg_ec4, reg_tmp = 0; 1691 bool is12simular, is13simular, is23simular; 1692 bool start_conttx = false, singletone = false; 1693 u32 iqk_bb_reg[10] = { 1694 ROFDM0_XARXIQIMBALANCE, 1695 ROFDM0_XBRXIQIMBALANCE, 1696 ROFDM0_ECCATHRESHOLD, 1697 ROFDM0_AGCRSSITABLE, 1698 ROFDM0_XATXIQIMBALANCE, 1699 ROFDM0_XBTXIQIMBALANCE, 1700 ROFDM0_XCTXIQIMBALANCE, 1701 ROFDM0_XCTXAFE, 1702 ROFDM0_XDTXAFE, 1703 ROFDM0_RXIQEXTANTA 1704 }; 1705 1706 if (recovery) { 1707 _rtl92c_phy_reload_adda_registers(hw, 1708 iqk_bb_reg, 1709 rtlphy->iqk_bb_backup, 10); 1710 return; 1711 } 1712 if (start_conttx || singletone) 1713 return; 1714 for (i = 0; i < 8; i++) { 1715 result[0][i] = 0; 1716 result[1][i] = 0; 1717 result[2][i] = 0; 1718 result[3][i] = 0; 1719 } 1720 final_candidate = 0xff; 1721 patha_ok = false; 1722 pathb_ok = false; 1723 is12simular = false; 1724 is23simular = false; 1725 is13simular = false; 1726 for (i = 0; i < 3; i++) { 1727 if (IS_92C_SERIAL(rtlhal->version)) 1728 _rtl92c_phy_iq_calibrate(hw, result, i, true); 1729 else 1730 _rtl92c_phy_iq_calibrate(hw, result, i, false); 1731 if (i == 1) { 1732 is12simular = _rtl92c_phy_simularity_compare(hw, 1733 result, 0, 1734 1); 1735 if (is12simular) { 1736 final_candidate = 0; 1737 break; 1738 } 1739 } 1740 if (i == 2) { 1741 is13simular = _rtl92c_phy_simularity_compare(hw, 1742 result, 0, 1743 2); 1744 if (is13simular) { 1745 final_candidate = 0; 1746 break; 1747 } 1748 is23simular = _rtl92c_phy_simularity_compare(hw, 1749 result, 1, 1750 2); 1751 if (is23simular) 1752 final_candidate = 1; 1753 else { 1754 for (i = 0; i < 8; i++) 1755 reg_tmp += result[3][i]; 1756 1757 if (reg_tmp != 0) 1758 final_candidate = 3; 1759 else 1760 final_candidate = 0xFF; 1761 } 1762 } 1763 } 1764 for (i = 0; i < 4; i++) { 1765 reg_e94 = result[i][0]; 1766 reg_e9c = result[i][1]; 1767 reg_ea4 = result[i][2]; 1768 reg_eb4 = result[i][4]; 1769 reg_ebc = result[i][5]; 1770 reg_ec4 = result[i][6]; 1771 } 1772 if (final_candidate != 0xff) { 1773 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0]; 1774 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1]; 1775 reg_ea4 = result[final_candidate][2]; 1776 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4]; 1777 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5]; 1778 reg_ec4 = result[final_candidate][6]; 1779 patha_ok = pathb_ok = true; 1780 } else { 1781 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100; 1782 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0; 1783 } 1784 if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ 1785 _rtl92c_phy_path_a_fill_iqk_matrix(hw, patha_ok, result, 1786 final_candidate, 1787 (reg_ea4 == 0)); 1788 if (IS_92C_SERIAL(rtlhal->version)) { 1789 if (reg_eb4 != 0) /*&&(reg_ec4 != 0) */ 1790 _rtl92c_phy_path_b_fill_iqk_matrix(hw, pathb_ok, 1791 result, 1792 final_candidate, 1793 (reg_ec4 == 0)); 1794 } 1795 _rtl92c_phy_save_adda_registers(hw, iqk_bb_reg, 1796 rtlphy->iqk_bb_backup, 10); 1797} 1798EXPORT_SYMBOL(rtl92c_phy_iq_calibrate); 1799 1800void rtl92c_phy_lc_calibrate(struct ieee80211_hw *hw) 1801{ 1802 struct rtl_priv *rtlpriv = rtl_priv(hw); 1803 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1804 bool start_conttx = false, singletone = false; 1805 1806 if (start_conttx || singletone) 1807 return; 1808 if (IS_92C_SERIAL(rtlhal->version)) 1809 rtlpriv->cfg->ops->phy_lc_calibrate(hw, true); 1810 else 1811 rtlpriv->cfg->ops->phy_lc_calibrate(hw, false); 1812} 1813EXPORT_SYMBOL(rtl92c_phy_lc_calibrate); 1814 1815void rtl92c_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) 1816{ 1817 struct rtl_priv *rtlpriv = rtl_priv(hw); 1818 struct rtl_phy *rtlphy = &(rtlpriv->phy); 1819 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1820 1821 if (rtlphy->apk_done) 1822 return; 1823 if (IS_92C_SERIAL(rtlhal->version)) 1824 _rtl92c_phy_ap_calibrate(hw, delta, true); 1825 else 1826 _rtl92c_phy_ap_calibrate(hw, delta, false); 1827} 1828EXPORT_SYMBOL(rtl92c_phy_ap_calibrate); 1829 1830void rtl92c_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) 1831{ 1832 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); 1833 1834 if (IS_92C_SERIAL(rtlhal->version)) 1835 _rtl92c_phy_set_rfpath_switch(hw, bmain, true); 1836 else 1837 _rtl92c_phy_set_rfpath_switch(hw, bmain, false); 1838} 1839EXPORT_SYMBOL(rtl92c_phy_set_rfpath_switch); 1840 1841bool rtl92c_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) 1842{ 1843 struct rtl_priv *rtlpriv = rtl_priv(hw); 1844 struct rtl_phy *rtlphy = &(rtlpriv->phy); 1845 bool postprocessing = false; 1846 1847 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, 1848 "-->IO Cmd(%#x), set_io_inprogress(%d)\n", 1849 iotype, rtlphy->set_io_inprogress); 1850 do { 1851 switch (iotype) { 1852 case IO_CMD_RESUME_DM_BY_SCAN: 1853 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, 1854 "[IO CMD] Resume DM after scan\n"); 1855 postprocessing = true; 1856 break; 1857 case IO_CMD_PAUSE_DM_BY_SCAN: 1858 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, 1859 "[IO CMD] Pause DM before scan\n"); 1860 postprocessing = true; 1861 break; 1862 default: 1863 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1864 "switch case not processed\n"); 1865 break; 1866 } 1867 } while (false); 1868 if (postprocessing && !rtlphy->set_io_inprogress) { 1869 rtlphy->set_io_inprogress = true; 1870 rtlphy->current_io_type = iotype; 1871 } else { 1872 return false; 1873 } 1874 rtl92c_phy_set_io(hw); 1875 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<--IO Type(%#x)\n", iotype); 1876 return true; 1877} 1878EXPORT_SYMBOL(rtl92c_phy_set_io_cmd); 1879 1880void rtl92c_phy_set_io(struct ieee80211_hw *hw) 1881{ 1882 struct rtl_priv *rtlpriv = rtl_priv(hw); 1883 struct rtl_phy *rtlphy = &(rtlpriv->phy); 1884 1885 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, 1886 "--->Cmd(%#x), set_io_inprogress(%d)\n", 1887 rtlphy->current_io_type, rtlphy->set_io_inprogress); 1888 switch (rtlphy->current_io_type) { 1889 case IO_CMD_RESUME_DM_BY_SCAN: 1890 dm_digtable.cur_igvalue = rtlphy->initgain_backup.xaagccore1; 1891 rtl92c_dm_write_dig(hw); 1892 rtl92c_phy_set_txpower_level(hw, rtlphy->current_channel); 1893 break; 1894 case IO_CMD_PAUSE_DM_BY_SCAN: 1895 rtlphy->initgain_backup.xaagccore1 = dm_digtable.cur_igvalue; 1896 dm_digtable.cur_igvalue = 0x37; 1897 rtl92c_dm_write_dig(hw); 1898 break; 1899 default: 1900 RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, 1901 "switch case not processed\n"); 1902 break; 1903 } 1904 rtlphy->set_io_inprogress = false; 1905 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "<---(%#x)\n", 1906 rtlphy->current_io_type); 1907} 1908EXPORT_SYMBOL(rtl92c_phy_set_io); 1909 1910void rtl92ce_phy_set_rf_on(struct ieee80211_hw *hw) 1911{ 1912 struct rtl_priv *rtlpriv = rtl_priv(hw); 1913 1914 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b); 1915 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 1916 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); 1917 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 1918 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 1919 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 1920} 1921EXPORT_SYMBOL(rtl92ce_phy_set_rf_on); 1922 1923void _rtl92c_phy_set_rf_sleep(struct ieee80211_hw *hw) 1924{ 1925 u32 u4b_tmp; 1926 u8 delay = 5; 1927 struct rtl_priv *rtlpriv = rtl_priv(hw); 1928 1929 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF); 1930 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 1931 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 1932 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); 1933 while (u4b_tmp != 0 && delay > 0) { 1934 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0); 1935 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00); 1936 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40); 1937 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK); 1938 delay--; 1939 } 1940 if (delay == 0) { 1941 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00); 1942 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 1943 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3); 1944 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); 1945 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, 1946 "Switch RF timeout !!!\n"); 1947 return; 1948 } 1949 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2); 1950 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22); 1951} 1952EXPORT_SYMBOL(_rtl92c_phy_set_rf_sleep); 1953