1666 lines · c
1// SPDX-License-Identifier: GPL-2.02/* Copyright(c) 2009-2012 Realtek Corporation.*/3 4#include "../wifi.h"5#include "../pci.h"6#include "../ps.h"7#include "reg.h"8#include "def.h"9#include "phy.h"10#include "rf.h"11#include "dm.h"12#include "table.h"13#include "../rtl8723com/phy_common.h"14 15static void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw,16 enum radio_path rfpath, u32 offset,17 u32 data);18static bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw);19static bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);20static bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,21 u8 configtype);22static bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,23 u8 configtype);24static bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,25 u8 channel, u8 *stage, u8 *step,26 u32 *delay);27static u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw,28 enum wireless_mode wirelessmode,29 long power_indbm);30static void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw);31static void rtl8723e_phy_set_io(struct ieee80211_hw *hw);32 33u32 rtl8723e_phy_query_rf_reg(struct ieee80211_hw *hw,34 enum radio_path rfpath,35 u32 regaddr, u32 bitmask)36{37 struct rtl_priv *rtlpriv = rtl_priv(hw);38 u32 original_value = 0, readback_value, bitshift;39 struct rtl_phy *rtlphy = &rtlpriv->phy;40 41 rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,42 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",43 regaddr, rfpath, bitmask);44 45 spin_lock(&rtlpriv->locks.rf_lock);46 47 if (rtlphy->rf_mode != RF_OP_BY_FW) {48 original_value = rtl8723_phy_rf_serial_read(hw,49 rfpath, regaddr);50 }51 52 bitshift = calculate_bit_shift(bitmask);53 readback_value = (original_value & bitmask) >> bitshift;54 55 spin_unlock(&rtlpriv->locks.rf_lock);56 57 rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,58 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",59 regaddr, rfpath, bitmask, original_value);60 61 return readback_value;62}63 64void rtl8723e_phy_set_rf_reg(struct ieee80211_hw *hw,65 enum radio_path rfpath,66 u32 regaddr, u32 bitmask, u32 data)67{68 struct rtl_priv *rtlpriv = rtl_priv(hw);69 struct rtl_phy *rtlphy = &rtlpriv->phy;70 u32 original_value = 0, bitshift;71 72 rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,73 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",74 regaddr, bitmask, data, rfpath);75 76 spin_lock(&rtlpriv->locks.rf_lock);77 78 if (rtlphy->rf_mode != RF_OP_BY_FW) {79 if (bitmask != RFREG_OFFSET_MASK) {80 original_value = rtl8723_phy_rf_serial_read(hw,81 rfpath,82 regaddr);83 bitshift = calculate_bit_shift(bitmask);84 data =85 ((original_value & (~bitmask)) |86 (data << bitshift));87 }88 89 rtl8723_phy_rf_serial_write(hw, rfpath, regaddr, data);90 } else {91 if (bitmask != RFREG_OFFSET_MASK) {92 bitshift = calculate_bit_shift(bitmask);93 data =94 ((original_value & (~bitmask)) |95 (data << bitshift));96 }97 _rtl8723e_phy_fw_rf_serial_write(hw, rfpath, regaddr, data);98 }99 100 spin_unlock(&rtlpriv->locks.rf_lock);101 102 rtl_dbg(rtlpriv, COMP_RF, DBG_TRACE,103 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",104 regaddr, bitmask, data, rfpath);105 106}107 108static void _rtl8723e_phy_fw_rf_serial_write(struct ieee80211_hw *hw,109 enum radio_path rfpath, u32 offset,110 u32 data)111{112 WARN_ONCE(true, "rtl8723ae: _rtl8723e_phy_fw_rf_serial_write deprecated!\n");113}114 115static void _rtl8723e_phy_bb_config_1t(struct ieee80211_hw *hw)116{117 rtl_set_bbreg(hw, RFPGA0_TXINFO, 0x3, 0x2);118 rtl_set_bbreg(hw, RFPGA1_TXINFO, 0x300033, 0x200022);119 rtl_set_bbreg(hw, RCCK0_AFESETTING, MASKBYTE3, 0x45);120 rtl_set_bbreg(hw, ROFDM0_TRXPATHENABLE, MASKBYTE0, 0x23);121 rtl_set_bbreg(hw, ROFDM0_AGCPARAMETER1, 0x30, 0x1);122 rtl_set_bbreg(hw, 0xe74, 0x0c000000, 0x2);123 rtl_set_bbreg(hw, 0xe78, 0x0c000000, 0x2);124 rtl_set_bbreg(hw, 0xe7c, 0x0c000000, 0x2);125 rtl_set_bbreg(hw, 0xe80, 0x0c000000, 0x2);126 rtl_set_bbreg(hw, 0xe88, 0x0c000000, 0x2);127}128 129bool rtl8723e_phy_mac_config(struct ieee80211_hw *hw)130{131 struct rtl_priv *rtlpriv = rtl_priv(hw);132 bool rtstatus = _rtl8723e_phy_config_mac_with_headerfile(hw);133 rtl_write_byte(rtlpriv, 0x04CA, 0x0A);134 return rtstatus;135}136 137bool rtl8723e_phy_bb_config(struct ieee80211_hw *hw)138{139 bool rtstatus = true;140 struct rtl_priv *rtlpriv = rtl_priv(hw);141 u8 tmpu1b;142 u8 b_reg_hwparafile = 1;143 144 rtl8723_phy_init_bb_rf_reg_def(hw);145 146 /* 1. 0x28[1] = 1 */147 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_PLL_CTRL);148 udelay(2);149 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL, (tmpu1b|BIT(1)));150 udelay(2);151 /* 2. 0x29[7:0] = 0xFF */152 rtl_write_byte(rtlpriv, REG_AFE_PLL_CTRL+1, 0xff);153 udelay(2);154 155 /* 3. 0x02[1:0] = 2b'11 */156 tmpu1b = rtl_read_byte(rtlpriv, REG_SYS_FUNC_EN);157 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,158 (tmpu1b | FEN_BB_GLB_RSTN | FEN_BBRSTB));159 160 /* 4. 0x25[6] = 0 */161 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+1);162 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+1, (tmpu1b & (~BIT(6))));163 164 /* 5. 0x24[20] = 0 //Advised by SD3 Alex Wang. 2011.02.09. */165 tmpu1b = rtl_read_byte(rtlpriv, REG_AFE_XTAL_CTRL+2);166 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL+2, (tmpu1b & (~BIT(4))));167 168 /* 6. 0x1f[7:0] = 0x07 */169 rtl_write_byte(rtlpriv, REG_RF_CTRL, 0x07);170 171 if (b_reg_hwparafile == 1)172 rtstatus = _rtl8723e_phy_bb8192c_config_parafile(hw);173 return rtstatus;174}175 176bool rtl8723e_phy_rf_config(struct ieee80211_hw *hw)177{178 return rtl8723e_phy_rf6052_config(hw);179}180 181static bool _rtl8723e_phy_bb8192c_config_parafile(struct ieee80211_hw *hw)182{183 struct rtl_priv *rtlpriv = rtl_priv(hw);184 struct rtl_phy *rtlphy = &rtlpriv->phy;185 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));186 bool rtstatus;187 188 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "\n");189 rtstatus = _rtl8723e_phy_config_bb_with_headerfile(hw,190 BASEBAND_CONFIG_PHY_REG);191 if (!rtstatus) {192 pr_err("Write BB Reg Fail!!\n");193 return false;194 }195 196 if (rtlphy->rf_type == RF_1T2R) {197 _rtl8723e_phy_bb_config_1t(hw);198 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Config to 1T!!\n");199 }200 if (rtlefuse->autoload_failflag == false) {201 rtlphy->pwrgroup_cnt = 0;202 rtstatus = _rtl8723e_phy_config_bb_with_pgheaderfile(hw,203 BASEBAND_CONFIG_PHY_REG);204 }205 if (!rtstatus) {206 pr_err("BB_PG Reg Fail!!\n");207 return false;208 }209 rtstatus =210 _rtl8723e_phy_config_bb_with_headerfile(hw, BASEBAND_CONFIG_AGC_TAB);211 if (!rtstatus) {212 pr_err("AGC Table Fail\n");213 return false;214 }215 rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw,216 RFPGA0_XA_HSSIPARAMETER2,217 0x200));218 219 return true;220}221 222static bool _rtl8723e_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)223{224 struct rtl_priv *rtlpriv = rtl_priv(hw);225 u32 i;226 u32 arraylength;227 u32 *ptrarray;228 229 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE, "Read Rtl723MACPHY_Array\n");230 arraylength = RTL8723E_MACARRAYLENGTH;231 ptrarray = RTL8723EMAC_ARRAY;232 233 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,234 "Img:RTL8192CEMAC_2T_ARRAY\n");235 for (i = 0; i < arraylength; i = i + 2)236 rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]);237 return true;238}239 240static bool _rtl8723e_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,241 u8 configtype)242{243 int i;244 u32 *phy_regarray_table;245 u32 *agctab_array_table;246 u16 phy_reg_arraylen, agctab_arraylen;247 struct rtl_priv *rtlpriv = rtl_priv(hw);248 249 agctab_arraylen = RTL8723E_AGCTAB_1TARRAYLENGTH;250 agctab_array_table = RTL8723EAGCTAB_1TARRAY;251 phy_reg_arraylen = RTL8723E_PHY_REG_1TARRAY_LENGTH;252 phy_regarray_table = RTL8723EPHY_REG_1TARRAY;253 if (configtype == BASEBAND_CONFIG_PHY_REG) {254 for (i = 0; i < phy_reg_arraylen; i = i + 2) {255 if (phy_regarray_table[i] == 0xfe)256 mdelay(50);257 else if (phy_regarray_table[i] == 0xfd)258 mdelay(5);259 else if (phy_regarray_table[i] == 0xfc)260 mdelay(1);261 else if (phy_regarray_table[i] == 0xfb)262 udelay(50);263 else if (phy_regarray_table[i] == 0xfa)264 udelay(5);265 else if (phy_regarray_table[i] == 0xf9)266 udelay(1);267 rtl_set_bbreg(hw, phy_regarray_table[i], MASKDWORD,268 phy_regarray_table[i + 1]);269 udelay(1);270 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,271 "The phy_regarray_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",272 phy_regarray_table[i],273 phy_regarray_table[i + 1]);274 }275 } else if (configtype == BASEBAND_CONFIG_AGC_TAB) {276 for (i = 0; i < agctab_arraylen; i = i + 2) {277 rtl_set_bbreg(hw, agctab_array_table[i], MASKDWORD,278 agctab_array_table[i + 1]);279 udelay(1);280 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,281 "The agctab_array_table[0] is %x Rtl819XPHY_REGArray[1] is %x\n",282 agctab_array_table[i],283 agctab_array_table[i + 1]);284 }285 }286 return true;287}288 289static void store_pwrindex_diffrate_offset(struct ieee80211_hw *hw,290 u32 regaddr, u32 bitmask,291 u32 data)292{293 struct rtl_priv *rtlpriv = rtl_priv(hw);294 struct rtl_phy *rtlphy = &rtlpriv->phy;295 296 if (regaddr == RTXAGC_A_RATE18_06) {297 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][0] =298 data;299 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,300 "MCSTxPowerLevelOriginalOffset[%d][0] = 0x%x\n",301 rtlphy->pwrgroup_cnt,302 rtlphy->mcs_txpwrlevel_origoffset303 [rtlphy->pwrgroup_cnt][0]);304 }305 if (regaddr == RTXAGC_A_RATE54_24) {306 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][1] =307 data;308 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,309 "MCSTxPowerLevelOriginalOffset[%d][1] = 0x%x\n",310 rtlphy->pwrgroup_cnt,311 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->312 pwrgroup_cnt][1]);313 }314 if (regaddr == RTXAGC_A_CCK1_MCS32) {315 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][6] =316 data;317 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,318 "MCSTxPowerLevelOriginalOffset[%d][6] = 0x%x\n",319 rtlphy->pwrgroup_cnt,320 rtlphy->mcs_txpwrlevel_origoffset321 [rtlphy->pwrgroup_cnt][6]);322 }323 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0xffffff00) {324 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][7] =325 data;326 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,327 "MCSTxPowerLevelOriginalOffset[%d][7] = 0x%x\n",328 rtlphy->pwrgroup_cnt,329 rtlphy->mcs_txpwrlevel_origoffset330 [rtlphy->pwrgroup_cnt][7]);331 }332 if (regaddr == RTXAGC_A_MCS03_MCS00) {333 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][2] =334 data;335 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,336 "MCSTxPowerLevelOriginalOffset[%d][2] = 0x%x\n",337 rtlphy->pwrgroup_cnt,338 rtlphy->mcs_txpwrlevel_origoffset339 [rtlphy->pwrgroup_cnt][2]);340 }341 if (regaddr == RTXAGC_A_MCS07_MCS04) {342 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][3] =343 data;344 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,345 "MCSTxPowerLevelOriginalOffset[%d][3] = 0x%x\n",346 rtlphy->pwrgroup_cnt,347 rtlphy->mcs_txpwrlevel_origoffset348 [rtlphy->pwrgroup_cnt][3]);349 }350 if (regaddr == RTXAGC_A_MCS11_MCS08) {351 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][4] =352 data;353 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,354 "MCSTxPowerLevelOriginalOffset[%d][4] = 0x%x\n",355 rtlphy->pwrgroup_cnt,356 rtlphy->mcs_txpwrlevel_origoffset357 [rtlphy->pwrgroup_cnt][4]);358 }359 if (regaddr == RTXAGC_A_MCS15_MCS12) {360 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][5] =361 data;362 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,363 "MCSTxPowerLevelOriginalOffset[%d][5] = 0x%x\n",364 rtlphy->pwrgroup_cnt,365 rtlphy->mcs_txpwrlevel_origoffset366 [rtlphy->pwrgroup_cnt][5]);367 }368 if (regaddr == RTXAGC_B_RATE18_06) {369 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][8] =370 data;371 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,372 "MCSTxPowerLevelOriginalOffset[%d][8] = 0x%x\n",373 rtlphy->pwrgroup_cnt,374 rtlphy->mcs_txpwrlevel_origoffset375 [rtlphy->pwrgroup_cnt][8]);376 }377 if (regaddr == RTXAGC_B_RATE54_24) {378 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][9] =379 data;380 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,381 "MCSTxPowerLevelOriginalOffset[%d][9] = 0x%x\n",382 rtlphy->pwrgroup_cnt,383 rtlphy->mcs_txpwrlevel_origoffset384 [rtlphy->pwrgroup_cnt][9]);385 }386 if (regaddr == RTXAGC_B_CCK1_55_MCS32) {387 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][14] =388 data;389 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,390 "MCSTxPowerLevelOriginalOffset[%d][14] = 0x%x\n",391 rtlphy->pwrgroup_cnt,392 rtlphy->mcs_txpwrlevel_origoffset393 [rtlphy->pwrgroup_cnt][14]);394 }395 if (regaddr == RTXAGC_B_CCK11_A_CCK2_11 && bitmask == 0x000000ff) {396 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][15] =397 data;398 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,399 "MCSTxPowerLevelOriginalOffset[%d][15] = 0x%x\n",400 rtlphy->pwrgroup_cnt,401 rtlphy->mcs_txpwrlevel_origoffset402 [rtlphy->pwrgroup_cnt][15]);403 }404 if (regaddr == RTXAGC_B_MCS03_MCS00) {405 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][10] =406 data;407 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,408 "MCSTxPowerLevelOriginalOffset[%d][10] = 0x%x\n",409 rtlphy->pwrgroup_cnt,410 rtlphy->mcs_txpwrlevel_origoffset411 [rtlphy->pwrgroup_cnt][10]);412 }413 if (regaddr == RTXAGC_B_MCS07_MCS04) {414 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][11] =415 data;416 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,417 "MCSTxPowerLevelOriginalOffset[%d][11] = 0x%x\n",418 rtlphy->pwrgroup_cnt,419 rtlphy->mcs_txpwrlevel_origoffset420 [rtlphy->pwrgroup_cnt][11]);421 }422 if (regaddr == RTXAGC_B_MCS11_MCS08) {423 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][12] =424 data;425 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,426 "MCSTxPowerLevelOriginalOffset[%d][12] = 0x%x\n",427 rtlphy->pwrgroup_cnt,428 rtlphy->mcs_txpwrlevel_origoffset429 [rtlphy->pwrgroup_cnt][12]);430 }431 if (regaddr == RTXAGC_B_MCS15_MCS12) {432 rtlphy->mcs_txpwrlevel_origoffset[rtlphy->pwrgroup_cnt][13] =433 data;434 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,435 "MCSTxPowerLevelOriginalOffset[%d][13] = 0x%x\n",436 rtlphy->pwrgroup_cnt,437 rtlphy->mcs_txpwrlevel_origoffset438 [rtlphy->pwrgroup_cnt][13]);439 440 rtlphy->pwrgroup_cnt++;441 }442}443 444static bool _rtl8723e_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,445 u8 configtype)446{447 struct rtl_priv *rtlpriv = rtl_priv(hw);448 int i;449 u32 *phy_regarray_table_pg;450 u16 phy_regarray_pg_len;451 452 phy_regarray_pg_len = RTL8723E_PHY_REG_ARRAY_PGLENGTH;453 phy_regarray_table_pg = RTL8723EPHY_REG_ARRAY_PG;454 455 if (configtype == BASEBAND_CONFIG_PHY_REG) {456 for (i = 0; i < phy_regarray_pg_len; i = i + 3) {457 if (phy_regarray_table_pg[i] == 0xfe)458 mdelay(50);459 else if (phy_regarray_table_pg[i] == 0xfd)460 mdelay(5);461 else if (phy_regarray_table_pg[i] == 0xfc)462 mdelay(1);463 else if (phy_regarray_table_pg[i] == 0xfb)464 udelay(50);465 else if (phy_regarray_table_pg[i] == 0xfa)466 udelay(5);467 else if (phy_regarray_table_pg[i] == 0xf9)468 udelay(1);469 470 store_pwrindex_diffrate_offset(hw,471 phy_regarray_table_pg[i],472 phy_regarray_table_pg[i + 1],473 phy_regarray_table_pg[i + 2]);474 }475 } else {476 rtl_dbg(rtlpriv, COMP_SEND, DBG_TRACE,477 "configtype != BaseBand_Config_PHY_REG\n");478 }479 return true;480}481 482bool rtl8723e_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,483 enum radio_path rfpath)484{485 int i;486 u32 *radioa_array_table;487 u16 radioa_arraylen;488 489 radioa_arraylen = RTL8723ERADIOA_1TARRAYLENGTH;490 radioa_array_table = RTL8723E_RADIOA_1TARRAY;491 492 switch (rfpath) {493 case RF90_PATH_A:494 for (i = 0; i < radioa_arraylen; i = i + 2) {495 if (radioa_array_table[i] == 0xfe) {496 mdelay(50);497 } else if (radioa_array_table[i] == 0xfd) {498 mdelay(5);499 } else if (radioa_array_table[i] == 0xfc) {500 mdelay(1);501 } else if (radioa_array_table[i] == 0xfb) {502 udelay(50);503 } else if (radioa_array_table[i] == 0xfa) {504 udelay(5);505 } else if (radioa_array_table[i] == 0xf9) {506 udelay(1);507 } else {508 rtl_set_rfreg(hw, rfpath, radioa_array_table[i],509 RFREG_OFFSET_MASK,510 radioa_array_table[i + 1]);511 udelay(1);512 }513 }514 break;515 case RF90_PATH_B:516 case RF90_PATH_C:517 case RF90_PATH_D:518 break;519 }520 return true;521}522 523void rtl8723e_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)524{525 struct rtl_priv *rtlpriv = rtl_priv(hw);526 struct rtl_phy *rtlphy = &rtlpriv->phy;527 528 rtlphy->default_initialgain[0] =529 (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);530 rtlphy->default_initialgain[1] =531 (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);532 rtlphy->default_initialgain[2] =533 (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);534 rtlphy->default_initialgain[3] =535 (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);536 537 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,538 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",539 rtlphy->default_initialgain[0],540 rtlphy->default_initialgain[1],541 rtlphy->default_initialgain[2],542 rtlphy->default_initialgain[3]);543 544 rtlphy->framesync = (u8) rtl_get_bbreg(hw,545 ROFDM0_RXDETECTOR3, MASKBYTE0);546 rtlphy->framesync_c34 = rtl_get_bbreg(hw,547 ROFDM0_RXDETECTOR2, MASKDWORD);548 549 rtl_dbg(rtlpriv, COMP_INIT, DBG_TRACE,550 "Default framesync (0x%x) = 0x%x\n",551 ROFDM0_RXDETECTOR3, rtlphy->framesync);552}553 554void rtl8723e_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel)555{556 struct rtl_priv *rtlpriv = rtl_priv(hw);557 struct rtl_phy *rtlphy = &rtlpriv->phy;558 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));559 u8 txpwr_level;560 long txpwr_dbm;561 562 txpwr_level = rtlphy->cur_cck_txpwridx;563 txpwr_dbm = rtl8723_phy_txpwr_idx_to_dbm(hw,564 WIRELESS_MODE_B, txpwr_level);565 txpwr_level = rtlphy->cur_ofdm24g_txpwridx +566 rtlefuse->legacy_ht_txpowerdiff;567 if (rtl8723_phy_txpwr_idx_to_dbm(hw,568 WIRELESS_MODE_G,569 txpwr_level) > txpwr_dbm)570 txpwr_dbm =571 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_G,572 txpwr_level);573 txpwr_level = rtlphy->cur_ofdm24g_txpwridx;574 if (rtl8723_phy_txpwr_idx_to_dbm(hw,575 WIRELESS_MODE_N_24G,576 txpwr_level) > txpwr_dbm)577 txpwr_dbm =578 rtl8723_phy_txpwr_idx_to_dbm(hw, WIRELESS_MODE_N_24G,579 txpwr_level);580 *powerlevel = txpwr_dbm;581}582 583static void _rtl8723e_get_txpower_index(struct ieee80211_hw *hw, u8 channel,584 u8 *cckpowerlevel, u8 *ofdmpowerlevel)585{586 struct rtl_priv *rtlpriv = rtl_priv(hw);587 struct rtl_phy *rtlphy = &rtlpriv->phy;588 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));589 u8 index = (channel - 1);590 591 cckpowerlevel[RF90_PATH_A] =592 rtlefuse->txpwrlevel_cck[RF90_PATH_A][index];593 cckpowerlevel[RF90_PATH_B] =594 rtlefuse->txpwrlevel_cck[RF90_PATH_B][index];595 if (get_rf_type(rtlphy) == RF_1T2R || get_rf_type(rtlphy) == RF_1T1R) {596 ofdmpowerlevel[RF90_PATH_A] =597 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_A][index];598 ofdmpowerlevel[RF90_PATH_B] =599 rtlefuse->txpwrlevel_ht40_1s[RF90_PATH_B][index];600 } else if (get_rf_type(rtlphy) == RF_2T2R) {601 ofdmpowerlevel[RF90_PATH_A] =602 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_A][index];603 ofdmpowerlevel[RF90_PATH_B] =604 rtlefuse->txpwrlevel_ht40_2s[RF90_PATH_B][index];605 }606}607 608static void _rtl8723e_ccxpower_index_check(struct ieee80211_hw *hw,609 u8 channel, u8 *cckpowerlevel,610 u8 *ofdmpowerlevel)611{612 struct rtl_priv *rtlpriv = rtl_priv(hw);613 struct rtl_phy *rtlphy = &rtlpriv->phy;614 615 rtlphy->cur_cck_txpwridx = cckpowerlevel[0];616 rtlphy->cur_ofdm24g_txpwridx = ofdmpowerlevel[0];617 618}619 620void rtl8723e_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)621{622 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));623 u8 cckpowerlevel[2], ofdmpowerlevel[2];624 625 if (!rtlefuse->txpwr_fromeprom)626 return;627 _rtl8723e_get_txpower_index(hw, channel,628 &cckpowerlevel[0], &ofdmpowerlevel[0]);629 _rtl8723e_ccxpower_index_check(hw,630 channel, &cckpowerlevel[0],631 &ofdmpowerlevel[0]);632 rtl8723e_phy_rf6052_set_cck_txpower(hw, &cckpowerlevel[0]);633 rtl8723e_phy_rf6052_set_ofdm_txpower(hw, &ofdmpowerlevel[0], channel);634}635 636bool rtl8723e_phy_update_txpower_dbm(struct ieee80211_hw *hw, long power_indbm)637{638 struct rtl_priv *rtlpriv = rtl_priv(hw);639 struct rtl_phy *rtlphy = &rtlpriv->phy;640 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));641 u8 idx;642 u8 rf_path;643 u8 ccktxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw,644 WIRELESS_MODE_B,645 power_indbm);646 u8 ofdmtxpwridx = _rtl8723e_phy_dbm_to_txpwr_idx(hw,647 WIRELESS_MODE_N_24G,648 power_indbm);649 if (ofdmtxpwridx - rtlefuse->legacy_ht_txpowerdiff > 0)650 ofdmtxpwridx -= rtlefuse->legacy_ht_txpowerdiff;651 else652 ofdmtxpwridx = 0;653 rtl_dbg(rtlpriv, COMP_TXAGC, DBG_TRACE,654 "%lx dBm, ccktxpwridx = %d, ofdmtxpwridx = %d\n",655 power_indbm, ccktxpwridx, ofdmtxpwridx);656 for (idx = 0; idx < 14; idx++) {657 for (rf_path = 0; rf_path < 2; rf_path++) {658 rtlefuse->txpwrlevel_cck[rf_path][idx] = ccktxpwridx;659 rtlefuse->txpwrlevel_ht40_1s[rf_path][idx] =660 ofdmtxpwridx;661 rtlefuse->txpwrlevel_ht40_2s[rf_path][idx] =662 ofdmtxpwridx;663 }664 }665 rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel);666 return true;667}668 669static u8 _rtl8723e_phy_dbm_to_txpwr_idx(struct ieee80211_hw *hw,670 enum wireless_mode wirelessmode,671 long power_indbm)672{673 u8 txpwridx;674 long offset;675 676 switch (wirelessmode) {677 case WIRELESS_MODE_B:678 offset = -7;679 break;680 case WIRELESS_MODE_G:681 case WIRELESS_MODE_N_24G:682 offset = -8;683 break;684 default:685 offset = -8;686 break;687 }688 689 if ((power_indbm - offset) > 0)690 txpwridx = (u8)((power_indbm - offset) * 2);691 else692 txpwridx = 0;693 694 if (txpwridx > MAX_TXPWR_IDX_NMODE_92S)695 txpwridx = MAX_TXPWR_IDX_NMODE_92S;696 697 return txpwridx;698}699 700void rtl8723e_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)701{702 struct rtl_priv *rtlpriv = rtl_priv(hw);703 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));704 enum io_type iotype;705 706 if (!is_hal_stop(rtlhal)) {707 switch (operation) {708 case SCAN_OPT_BACKUP_BAND0:709 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;710 rtlpriv->cfg->ops->set_hw_reg(hw,711 HW_VAR_IO_CMD,712 (u8 *)&iotype);713 714 break;715 case SCAN_OPT_RESTORE:716 iotype = IO_CMD_RESUME_DM_BY_SCAN;717 rtlpriv->cfg->ops->set_hw_reg(hw,718 HW_VAR_IO_CMD,719 (u8 *)&iotype);720 break;721 default:722 pr_err("Unknown Scan Backup operation.\n");723 break;724 }725 }726}727 728void rtl8723e_phy_set_bw_mode_callback(struct ieee80211_hw *hw)729{730 struct rtl_priv *rtlpriv = rtl_priv(hw);731 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));732 struct rtl_phy *rtlphy = &rtlpriv->phy;733 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));734 u8 reg_bw_opmode;735 u8 reg_prsr_rsc;736 737 rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,738 "Switch to %s bandwidth\n",739 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?740 "20MHz" : "40MHz");741 742 if (is_hal_stop(rtlhal)) {743 rtlphy->set_bwmode_inprogress = false;744 return;745 }746 747 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);748 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);749 750 switch (rtlphy->current_chan_bw) {751 case HT_CHANNEL_WIDTH_20:752 reg_bw_opmode |= BW_OPMODE_20MHZ;753 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);754 break;755 case HT_CHANNEL_WIDTH_20_40:756 reg_bw_opmode &= ~BW_OPMODE_20MHZ;757 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);758 reg_prsr_rsc =759 (reg_prsr_rsc & 0x90) | (mac->cur_40_prime_sc << 5);760 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);761 break;762 default:763 pr_err("unknown bandwidth: %#X\n",764 rtlphy->current_chan_bw);765 break;766 }767 768 switch (rtlphy->current_chan_bw) {769 case HT_CHANNEL_WIDTH_20:770 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);771 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);772 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);773 break;774 case HT_CHANNEL_WIDTH_20_40:775 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);776 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);777 778 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,779 (mac->cur_40_prime_sc >> 1));780 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);781 rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);782 783 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),784 (mac->cur_40_prime_sc ==785 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);786 break;787 default:788 pr_err("unknown bandwidth: %#X\n",789 rtlphy->current_chan_bw);790 break;791 }792 rtl8723e_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);793 rtlphy->set_bwmode_inprogress = false;794 rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");795}796 797void rtl8723e_phy_set_bw_mode(struct ieee80211_hw *hw,798 enum nl80211_channel_type ch_type)799{800 struct rtl_priv *rtlpriv = rtl_priv(hw);801 struct rtl_phy *rtlphy = &rtlpriv->phy;802 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));803 u8 tmp_bw = rtlphy->current_chan_bw;804 805 if (rtlphy->set_bwmode_inprogress)806 return;807 rtlphy->set_bwmode_inprogress = true;808 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {809 rtl8723e_phy_set_bw_mode_callback(hw);810 } else {811 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,812 "false driver sleep or unload\n");813 rtlphy->set_bwmode_inprogress = false;814 rtlphy->current_chan_bw = tmp_bw;815 }816}817 818void rtl8723e_phy_sw_chnl_callback(struct ieee80211_hw *hw)819{820 struct rtl_priv *rtlpriv = rtl_priv(hw);821 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));822 struct rtl_phy *rtlphy = &rtlpriv->phy;823 u32 delay;824 825 rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE,826 "switch to channel%d\n", rtlphy->current_channel);827 if (is_hal_stop(rtlhal))828 return;829 do {830 if (!rtlphy->sw_chnl_inprogress)831 break;832 if (!_rtl8723e_phy_sw_chnl_step_by_step833 (hw, rtlphy->current_channel, &rtlphy->sw_chnl_stage,834 &rtlphy->sw_chnl_step, &delay)) {835 if (delay > 0)836 mdelay(delay);837 else838 continue;839 } else {840 rtlphy->sw_chnl_inprogress = false;841 }842 break;843 } while (true);844 rtl_dbg(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");845}846 847u8 rtl8723e_phy_sw_chnl(struct ieee80211_hw *hw)848{849 struct rtl_priv *rtlpriv = rtl_priv(hw);850 struct rtl_phy *rtlphy = &rtlpriv->phy;851 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));852 853 if (rtlphy->sw_chnl_inprogress)854 return 0;855 if (rtlphy->set_bwmode_inprogress)856 return 0;857 WARN_ONCE((rtlphy->current_channel > 14),858 "rtl8723ae: WIRELESS_MODE_G but channel>14");859 rtlphy->sw_chnl_inprogress = true;860 rtlphy->sw_chnl_stage = 0;861 rtlphy->sw_chnl_step = 0;862 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {863 rtl8723e_phy_sw_chnl_callback(hw);864 rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,865 "sw_chnl_inprogress false schedule workitem\n");866 rtlphy->sw_chnl_inprogress = false;867 } else {868 rtl_dbg(rtlpriv, COMP_CHAN, DBG_LOUD,869 "sw_chnl_inprogress false driver sleep or unload\n");870 rtlphy->sw_chnl_inprogress = false;871 }872 return 1;873}874 875static void _rtl8723e_phy_sw_rf_seting(struct ieee80211_hw *hw, u8 channel)876{877 struct rtl_priv *rtlpriv = rtl_priv(hw);878 struct rtl_phy *rtlphy = &rtlpriv->phy;879 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));880 881 if (IS_81XXC_VENDOR_UMC_B_CUT(rtlhal->version)) {882 if (channel == 6 && rtlphy->current_chan_bw ==883 HT_CHANNEL_WIDTH_20)884 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1,885 MASKDWORD, 0x00255);886 else{887 u32 backuprf0x1a = (u32)rtl_get_rfreg(hw,888 RF90_PATH_A, RF_RX_G1,889 RFREG_OFFSET_MASK);890 rtl_set_rfreg(hw, RF90_PATH_A, RF_RX_G1,891 MASKDWORD, backuprf0x1a);892 }893 }894}895 896static bool _rtl8723e_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,897 u8 channel, u8 *stage, u8 *step,898 u32 *delay)899{900 struct rtl_priv *rtlpriv = rtl_priv(hw);901 struct rtl_phy *rtlphy = &rtlpriv->phy;902 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];903 u32 precommoncmdcnt;904 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];905 u32 postcommoncmdcnt;906 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];907 u32 rfdependcmdcnt;908 struct swchnlcmd *currentcmd = NULL;909 u8 rfpath;910 u8 num_total_rfpath = rtlphy->num_total_rfpath;911 912 precommoncmdcnt = 0;913 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,914 MAX_PRECMD_CNT,915 CMDID_SET_TXPOWEROWER_LEVEL, 0, 0, 0);916 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,917 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);918 919 postcommoncmdcnt = 0;920 921 rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,922 MAX_POSTCMD_CNT, CMDID_END, 0, 0, 0);923 924 rfdependcmdcnt = 0;925 926 WARN_ONCE((channel < 1 || channel > 14),927 "rtl8723ae: illegal channel for Zebra: %d\n", channel);928 929 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,930 MAX_RFDEPENDCMD_CNT, CMDID_RF_WRITEREG,931 RF_CHNLBW, channel, 10);932 933 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,934 MAX_RFDEPENDCMD_CNT, CMDID_END, 0, 0,935 0);936 937 do {938 switch (*stage) {939 case 0:940 currentcmd = &precommoncmd[*step];941 break;942 case 1:943 currentcmd = &rfdependcmd[*step];944 break;945 case 2:946 currentcmd = &postcommoncmd[*step];947 break;948 default:949 pr_err("Invalid 'stage' = %d, Check it!\n",950 *stage);951 return true;952 }953 954 if (currentcmd->cmdid == CMDID_END) {955 if ((*stage) == 2) {956 return true;957 } else {958 (*stage)++;959 (*step) = 0;960 continue;961 }962 }963 964 switch (currentcmd->cmdid) {965 case CMDID_SET_TXPOWEROWER_LEVEL:966 rtl8723e_phy_set_txpower_level(hw, channel);967 break;968 case CMDID_WRITEPORT_ULONG:969 rtl_write_dword(rtlpriv, currentcmd->para1,970 currentcmd->para2);971 break;972 case CMDID_WRITEPORT_USHORT:973 rtl_write_word(rtlpriv, currentcmd->para1,974 (u16) currentcmd->para2);975 break;976 case CMDID_WRITEPORT_UCHAR:977 rtl_write_byte(rtlpriv, currentcmd->para1,978 (u8) currentcmd->para2);979 break;980 case CMDID_RF_WRITEREG:981 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {982 rtlphy->rfreg_chnlval[rfpath] =983 ((rtlphy->rfreg_chnlval[rfpath] &984 0xfffffc00) | currentcmd->para2);985 986 rtl_set_rfreg(hw, (enum radio_path)rfpath,987 currentcmd->para1,988 RFREG_OFFSET_MASK,989 rtlphy->rfreg_chnlval[rfpath]);990 }991 _rtl8723e_phy_sw_rf_seting(hw, channel);992 break;993 default:994 rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,995 "switch case %#x not processed\n",996 currentcmd->cmdid);997 break;998 }999 1000 break;1001 } while (true);1002 1003 (*delay) = currentcmd->msdelay;1004 (*step)++;1005 return false;1006}1007 1008static u8 _rtl8723e_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb)1009{1010 u32 reg_eac, reg_e94, reg_e9c, reg_ea4;1011 u8 result = 0x00;1012 1013 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1f);1014 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x10008c1f);1015 rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x82140102);1016 rtl_set_bbreg(hw, 0xe3c, MASKDWORD,1017 config_pathb ? 0x28160202 : 0x28160502);1018 1019 if (config_pathb) {1020 rtl_set_bbreg(hw, 0xe50, MASKDWORD, 0x10008c22);1021 rtl_set_bbreg(hw, 0xe54, MASKDWORD, 0x10008c22);1022 rtl_set_bbreg(hw, 0xe58, MASKDWORD, 0x82140102);1023 rtl_set_bbreg(hw, 0xe5c, MASKDWORD, 0x28160202);1024 }1025 1026 rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x001028d1);1027 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000);1028 rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000);1029 1030 mdelay(IQK_DELAY_TIME);1031 1032 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);1033 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);1034 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);1035 reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD);1036 1037 if (!(reg_eac & BIT(28)) &&1038 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&1039 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))1040 result |= 0x01;1041 else1042 return result;1043 1044 if (!(reg_eac & BIT(27)) &&1045 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&1046 (((reg_eac & 0x03FF0000) >> 16) != 0x36))1047 result |= 0x02;1048 return result;1049}1050 1051static u8 _rtl8723e_phy_path_b_iqk(struct ieee80211_hw *hw)1052{1053 u32 reg_eac, reg_eb4, reg_ebc, reg_ec4, reg_ecc;1054 u8 result = 0x00;1055 1056 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000002);1057 rtl_set_bbreg(hw, 0xe60, MASKDWORD, 0x00000000);1058 mdelay(IQK_DELAY_TIME);1059 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);1060 reg_eb4 = rtl_get_bbreg(hw, 0xeb4, MASKDWORD);1061 reg_ebc = rtl_get_bbreg(hw, 0xebc, MASKDWORD);1062 reg_ec4 = rtl_get_bbreg(hw, 0xec4, MASKDWORD);1063 reg_ecc = rtl_get_bbreg(hw, 0xecc, MASKDWORD);1064 1065 if (!(reg_eac & BIT(31)) &&1066 (((reg_eb4 & 0x03FF0000) >> 16) != 0x142) &&1067 (((reg_ebc & 0x03FF0000) >> 16) != 0x42))1068 result |= 0x01;1069 else1070 return result;1071 if (!(reg_eac & BIT(30)) &&1072 (((reg_ec4 & 0x03FF0000) >> 16) != 0x132) &&1073 (((reg_ecc & 0x03FF0000) >> 16) != 0x36))1074 result |= 0x02;1075 return result;1076}1077 1078static bool _rtl8723e_phy_simularity_compare(struct ieee80211_hw *hw,1079 long result[][8], u8 c1, u8 c2)1080{1081 u32 i, j, diff, simularity_bitmap, bound;1082 1083 u8 final_candidate[2] = { 0xFF, 0xFF };1084 bool bresult = true;1085 1086 bound = 4;1087 1088 simularity_bitmap = 0;1089 1090 for (i = 0; i < bound; i++) {1091 diff = (result[c1][i] > result[c2][i]) ?1092 (result[c1][i] - result[c2][i]) :1093 (result[c2][i] - result[c1][i]);1094 1095 if (diff > MAX_TOLERANCE) {1096 if ((i == 2 || i == 6) && !simularity_bitmap) {1097 if (result[c1][i] + result[c1][i + 1] == 0)1098 final_candidate[(i / 4)] = c2;1099 else if (result[c2][i] + result[c2][i + 1] == 0)1100 final_candidate[(i / 4)] = c1;1101 else1102 simularity_bitmap = simularity_bitmap |1103 (1 << i);1104 } else1105 simularity_bitmap =1106 simularity_bitmap | (1 << i);1107 }1108 }1109 1110 if (simularity_bitmap == 0) {1111 for (i = 0; i < (bound / 4); i++) {1112 if (final_candidate[i] != 0xFF) {1113 for (j = i * 4; j < (i + 1) * 4 - 2; j++)1114 result[3][j] =1115 result[final_candidate[i]][j];1116 bresult = false;1117 }1118 }1119 return bresult;1120 } else if (!(simularity_bitmap & 0x0F)) {1121 for (i = 0; i < 4; i++)1122 result[3][i] = result[c1][i];1123 return false;1124 } else {1125 return false;1126 }1127 1128}1129 1130static void _rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw,1131 long result[][8], u8 t, bool is2t)1132{1133 struct rtl_priv *rtlpriv = rtl_priv(hw);1134 struct rtl_phy *rtlphy = &rtlpriv->phy;1135 u32 i;1136 u8 patha_ok, pathb_ok;1137 u32 adda_reg[IQK_ADDA_REG_NUM] = {1138 0x85c, 0xe6c, 0xe70, 0xe74,1139 0xe78, 0xe7c, 0xe80, 0xe84,1140 0xe88, 0xe8c, 0xed0, 0xed4,1141 0xed8, 0xedc, 0xee0, 0xeec1142 };1143 1144 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {1145 0x522, 0x550, 0x551, 0x0401146 };1147 1148 const u32 retrycount = 2;1149 1150 if (t == 0) {1151 rtl_get_bbreg(hw, 0x800, MASKDWORD);1152 1153 rtl8723_save_adda_registers(hw, adda_reg,1154 rtlphy->adda_backup, 16);1155 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,1156 rtlphy->iqk_mac_backup);1157 }1158 rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);1159 if (t == 0) {1160 rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw,1161 RFPGA0_XA_HSSIPARAMETER1,1162 BIT(8));1163 }1164 1165 if (!rtlphy->rfpi_enable)1166 rtl8723_phy_pi_mode_switch(hw, true);1167 if (t == 0) {1168 rtlphy->reg_c04 = rtl_get_bbreg(hw, 0xc04, MASKDWORD);1169 rtlphy->reg_c08 = rtl_get_bbreg(hw, 0xc08, MASKDWORD);1170 rtlphy->reg_874 = rtl_get_bbreg(hw, 0x874, MASKDWORD);1171 }1172 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);1173 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);1174 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);1175 if (is2t) {1176 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00010000);1177 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00010000);1178 }1179 rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,1180 rtlphy->iqk_mac_backup);1181 rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x00080000);1182 if (is2t)1183 rtl_set_bbreg(hw, 0xb6c, MASKDWORD, 0x00080000);1184 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000);1185 rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00);1186 rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x01004800);1187 for (i = 0; i < retrycount; i++) {1188 patha_ok = _rtl8723e_phy_path_a_iqk(hw, is2t);1189 if (patha_ok == 0x03) {1190 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &1191 0x3FF0000) >> 16;1192 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &1193 0x3FF0000) >> 16;1194 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &1195 0x3FF0000) >> 16;1196 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &1197 0x3FF0000) >> 16;1198 break;1199 } else if (i == (retrycount - 1) && patha_ok == 0x01)1200 1201 result[t][0] = (rtl_get_bbreg(hw, 0xe94,1202 MASKDWORD) & 0x3FF0000) >>1203 16;1204 result[t][1] =1205 (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16;1206 1207 }1208 1209 if (is2t) {1210 rtl8723_phy_path_a_standby(hw);1211 rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t);1212 for (i = 0; i < retrycount; i++) {1213 pathb_ok = _rtl8723e_phy_path_b_iqk(hw);1214 if (pathb_ok == 0x03) {1215 result[t][4] = (rtl_get_bbreg(hw,1216 0xeb4,1217 MASKDWORD) &1218 0x3FF0000) >> 16;1219 result[t][5] =1220 (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &1221 0x3FF0000) >> 16;1222 result[t][6] =1223 (rtl_get_bbreg(hw, 0xec4, MASKDWORD) &1224 0x3FF0000) >> 16;1225 result[t][7] =1226 (rtl_get_bbreg(hw, 0xecc, MASKDWORD) &1227 0x3FF0000) >> 16;1228 break;1229 } else if (i == (retrycount - 1) && pathb_ok == 0x01) {1230 result[t][4] = (rtl_get_bbreg(hw,1231 0xeb4,1232 MASKDWORD) &1233 0x3FF0000) >> 16;1234 }1235 result[t][5] = (rtl_get_bbreg(hw, 0xebc, MASKDWORD) &1236 0x3FF0000) >> 16;1237 }1238 }1239 rtl_set_bbreg(hw, 0xc04, MASKDWORD, rtlphy->reg_c04);1240 rtl_set_bbreg(hw, 0x874, MASKDWORD, rtlphy->reg_874);1241 rtl_set_bbreg(hw, 0xc08, MASKDWORD, rtlphy->reg_c08);1242 rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0);1243 rtl_set_bbreg(hw, 0x840, MASKDWORD, 0x00032ed3);1244 if (is2t)1245 rtl_set_bbreg(hw, 0x844, MASKDWORD, 0x00032ed3);1246 if (t != 0) {1247 if (!rtlphy->rfpi_enable)1248 rtl8723_phy_pi_mode_switch(hw, false);1249 rtl8723_phy_reload_adda_registers(hw, adda_reg,1250 rtlphy->adda_backup, 16);1251 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,1252 rtlphy->iqk_mac_backup);1253 }1254}1255 1256static void _rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)1257{1258 u8 tmpreg;1259 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;1260 struct rtl_priv *rtlpriv = rtl_priv(hw);1261 1262 tmpreg = rtl_read_byte(rtlpriv, 0xd03);1263 1264 if ((tmpreg & 0x70) != 0)1265 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);1266 else1267 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);1268 1269 if ((tmpreg & 0x70) != 0) {1270 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);1271 1272 if (is2t)1273 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,1274 MASK12BITS);1275 1276 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,1277 (rf_a_mode & 0x8FFFF) | 0x10000);1278 1279 if (is2t)1280 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,1281 (rf_b_mode & 0x8FFFF) | 0x10000);1282 }1283 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);1284 1285 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, lc_cal | 0x08000);1286 1287 mdelay(100);1288 1289 if ((tmpreg & 0x70) != 0) {1290 rtl_write_byte(rtlpriv, 0xd03, tmpreg);1291 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);1292 1293 if (is2t)1294 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,1295 rf_b_mode);1296 } else {1297 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);1298 }1299}1300 1301static void _rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw,1302 bool bmain, bool is2t)1303{1304 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));1305 1306 if (is_hal_stop(rtlhal)) {1307 rtl_set_bbreg(hw, REG_LEDCFG0, BIT(23), 0x01);1308 rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01);1309 }1310 if (is2t) {1311 if (bmain)1312 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,1313 BIT(5) | BIT(6), 0x1);1314 else1315 rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE,1316 BIT(5) | BIT(6), 0x2);1317 } else {1318 if (bmain)1319 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x2);1320 else1321 rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, 0x300, 0x1);1322 1323 }1324 1325}1326 1327#undef IQK_ADDA_REG_NUM1328#undef IQK_DELAY_TIME1329 1330void rtl8723e_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)1331{1332 struct rtl_priv *rtlpriv = rtl_priv(hw);1333 struct rtl_phy *rtlphy = &rtlpriv->phy;1334 1335 long result[4][8];1336 u8 i, final_candidate;1337 bool b_patha_ok;1338 long reg_e94, reg_e9c, reg_ea4, reg_eb4, reg_ebc,1339 reg_tmp = 0;1340 bool is12simular, is13simular, is23simular;1341 u32 iqk_bb_reg[10] = {1342 ROFDM0_XARXIQIMBALANCE,1343 ROFDM0_XBRXIQIMBALANCE,1344 ROFDM0_ECCATHRESHOLD,1345 ROFDM0_AGCRSSITABLE,1346 ROFDM0_XATXIQIMBALANCE,1347 ROFDM0_XBTXIQIMBALANCE,1348 ROFDM0_XCTXIQIMBALANCE,1349 ROFDM0_XCTXAFE,1350 ROFDM0_XDTXAFE,1351 ROFDM0_RXIQEXTANTA1352 };1353 1354 if (b_recovery) {1355 rtl8723_phy_reload_adda_registers(hw,1356 iqk_bb_reg,1357 rtlphy->iqk_bb_backup, 10);1358 return;1359 }1360 for (i = 0; i < 8; i++) {1361 result[0][i] = 0;1362 result[1][i] = 0;1363 result[2][i] = 0;1364 result[3][i] = 0;1365 }1366 final_candidate = 0xff;1367 b_patha_ok = false;1368 is12simular = false;1369 is23simular = false;1370 is13simular = false;1371 for (i = 0; i < 3; i++) {1372 _rtl8723e_phy_iq_calibrate(hw, result, i, false);1373 if (i == 1) {1374 is12simular =1375 _rtl8723e_phy_simularity_compare(hw, result, 0, 1);1376 if (is12simular) {1377 final_candidate = 0;1378 break;1379 }1380 }1381 if (i == 2) {1382 is13simular =1383 _rtl8723e_phy_simularity_compare(hw, result, 0, 2);1384 if (is13simular) {1385 final_candidate = 0;1386 break;1387 }1388 is23simular =1389 _rtl8723e_phy_simularity_compare(hw, result, 1, 2);1390 if (is23simular)1391 final_candidate = 1;1392 else {1393 for (i = 0; i < 8; i++)1394 reg_tmp += result[3][i];1395 1396 if (reg_tmp != 0)1397 final_candidate = 3;1398 else1399 final_candidate = 0xFF;1400 }1401 }1402 }1403 for (i = 0; i < 4; i++) {1404 reg_e94 = result[i][0];1405 reg_e9c = result[i][1];1406 reg_ea4 = result[i][2];1407 reg_eb4 = result[i][4];1408 reg_ebc = result[i][5];1409 }1410 if (final_candidate != 0xff) {1411 rtlphy->reg_e94 = reg_e94 = result[final_candidate][0];1412 rtlphy->reg_e9c = reg_e9c = result[final_candidate][1];1413 reg_ea4 = result[final_candidate][2];1414 rtlphy->reg_eb4 = reg_eb4 = result[final_candidate][4];1415 rtlphy->reg_ebc = reg_ebc = result[final_candidate][5];1416 b_patha_ok = true;1417 } else {1418 rtlphy->reg_e94 = rtlphy->reg_eb4 = 0x100;1419 rtlphy->reg_e9c = rtlphy->reg_ebc = 0x0;1420 }1421 if (reg_e94 != 0)1422 rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,1423 final_candidate,1424 (reg_ea4 == 0));1425 rtl8723_save_adda_registers(hw, iqk_bb_reg,1426 rtlphy->iqk_bb_backup, 10);1427}1428 1429void rtl8723e_phy_lc_calibrate(struct ieee80211_hw *hw)1430{1431 _rtl8723e_phy_lc_calibrate(hw, false);1432}1433 1434void rtl8723e_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)1435{1436 _rtl8723e_phy_set_rfpath_switch(hw, bmain, false);1437}1438 1439bool rtl8723e_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)1440{1441 struct rtl_priv *rtlpriv = rtl_priv(hw);1442 struct rtl_phy *rtlphy = &rtlpriv->phy;1443 bool postprocessing = false;1444 1445 rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,1446 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",1447 iotype, rtlphy->set_io_inprogress);1448 do {1449 switch (iotype) {1450 case IO_CMD_RESUME_DM_BY_SCAN:1451 rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,1452 "[IO CMD] Resume DM after scan.\n");1453 postprocessing = true;1454 break;1455 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:1456 rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,1457 "[IO CMD] Pause DM before scan.\n");1458 postprocessing = true;1459 break;1460 default:1461 rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,1462 "switch case %#x not processed\n", iotype);1463 break;1464 }1465 } while (false);1466 if (postprocessing && !rtlphy->set_io_inprogress) {1467 rtlphy->set_io_inprogress = true;1468 rtlphy->current_io_type = iotype;1469 } else {1470 return false;1471 }1472 rtl8723e_phy_set_io(hw);1473 rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);1474 return true;1475}1476 1477static void rtl8723e_phy_set_io(struct ieee80211_hw *hw)1478{1479 struct rtl_priv *rtlpriv = rtl_priv(hw);1480 struct rtl_phy *rtlphy = &rtlpriv->phy;1481 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;1482 1483 rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,1484 "--->Cmd(%#x), set_io_inprogress(%d)\n",1485 rtlphy->current_io_type, rtlphy->set_io_inprogress);1486 switch (rtlphy->current_io_type) {1487 case IO_CMD_RESUME_DM_BY_SCAN:1488 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;1489 rtl8723e_dm_write_dig(hw);1490 rtl8723e_phy_set_txpower_level(hw, rtlphy->current_channel);1491 break;1492 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:1493 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;1494 dm_digtable->cur_igvalue = 0x17;1495 rtl8723e_dm_write_dig(hw);1496 break;1497 default:1498 rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,1499 "switch case %#x not processed\n",1500 rtlphy->current_io_type);1501 break;1502 }1503 rtlphy->set_io_inprogress = false;1504 rtl_dbg(rtlpriv, COMP_CMD, DBG_TRACE,1505 "(%#x)\n", rtlphy->current_io_type);1506}1507 1508static void rtl8723e_phy_set_rf_on(struct ieee80211_hw *hw)1509{1510 struct rtl_priv *rtlpriv = rtl_priv(hw);1511 1512 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);1513 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);1514 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);1515 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);1516 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);1517 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);1518}1519 1520static void _rtl8723e_phy_set_rf_sleep(struct ieee80211_hw *hw)1521{1522 u32 u4b_tmp;1523 u8 delay = 5;1524 struct rtl_priv *rtlpriv = rtl_priv(hw);1525 1526 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);1527 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);1528 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);1529 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);1530 while (u4b_tmp != 0 && delay > 0) {1531 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x0);1532 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);1533 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x40);1534 u4b_tmp = rtl_get_rfreg(hw, RF90_PATH_A, 0, RFREG_OFFSET_MASK);1535 delay--;1536 }1537 if (delay == 0) {1538 rtl_write_byte(rtlpriv, REG_APSD_CTRL, 0x00);1539 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);1540 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);1541 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);1542 rtl_dbg(rtlpriv, COMP_POWER, DBG_TRACE,1543 "Switch RF timeout !!!.\n");1544 return;1545 }1546 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);1547 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);1548}1549 1550static bool _rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw,1551 enum rf_pwrstate rfpwr_state)1552{1553 struct rtl_priv *rtlpriv = rtl_priv(hw);1554 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);1555 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));1556 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));1557 bool bresult = true;1558 u8 i, queue_id;1559 struct rtl8192_tx_ring *ring = NULL;1560 1561 switch (rfpwr_state) {1562 case ERFON:1563 if ((ppsc->rfpwr_state == ERFOFF) &&1564 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {1565 bool rtstatus;1566 u32 initializecount = 0;1567 1568 do {1569 initializecount++;1570 rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,1571 "IPS Set eRf nic enable\n");1572 rtstatus = rtl_ps_enable_nic(hw);1573 } while (!rtstatus && (initializecount < 10));1574 RT_CLEAR_PS_LEVEL(ppsc,1575 RT_RF_OFF_LEVL_HALT_NIC);1576 } else {1577 rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,1578 "Set ERFON slept:%d ms\n",1579 jiffies_to_msecs(jiffies -1580 ppsc->last_sleep_jiffies));1581 ppsc->last_awake_jiffies = jiffies;1582 rtl8723e_phy_set_rf_on(hw);1583 }1584 if (mac->link_state == MAC80211_LINKED) {1585 rtlpriv->cfg->ops->led_control(hw,1586 LED_CTL_LINK);1587 } else {1588 rtlpriv->cfg->ops->led_control(hw,1589 LED_CTL_NO_LINK);1590 }1591 break;1592 case ERFOFF:1593 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {1594 rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,1595 "IPS Set eRf nic disable\n");1596 rtl_ps_disable_nic(hw);1597 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);1598 } else {1599 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {1600 rtlpriv->cfg->ops->led_control(hw,1601 LED_CTL_NO_LINK);1602 } else {1603 rtlpriv->cfg->ops->led_control(hw,1604 LED_CTL_POWER_OFF);1605 }1606 }1607 break;1608 case ERFSLEEP:1609 if (ppsc->rfpwr_state == ERFOFF)1610 break;1611 for (queue_id = 0, i = 0;1612 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {1613 ring = &pcipriv->dev.tx_ring[queue_id];1614 if (queue_id == BEACON_QUEUE ||1615 skb_queue_len(&ring->queue) == 0) {1616 queue_id++;1617 continue;1618 } else {1619 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,1620 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",1621 (i + 1), queue_id,1622 skb_queue_len(&ring->queue));1623 1624 udelay(10);1625 i++;1626 }1627 if (i >= MAX_DOZE_WAITING_TIMES_9x) {1628 rtl_dbg(rtlpriv, COMP_ERR, DBG_WARNING,1629 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",1630 MAX_DOZE_WAITING_TIMES_9x,1631 queue_id,1632 skb_queue_len(&ring->queue));1633 break;1634 }1635 }1636 rtl_dbg(rtlpriv, COMP_RF, DBG_DMESG,1637 "Set ERFSLEEP awaked:%d ms\n",1638 jiffies_to_msecs(jiffies -1639 ppsc->last_awake_jiffies));1640 ppsc->last_sleep_jiffies = jiffies;1641 _rtl8723e_phy_set_rf_sleep(hw);1642 break;1643 default:1644 rtl_dbg(rtlpriv, COMP_ERR, DBG_LOUD,1645 "switch case %#x not processed\n", rfpwr_state);1646 bresult = false;1647 break;1648 }1649 if (bresult)1650 ppsc->rfpwr_state = rfpwr_state;1651 return bresult;1652}1653 1654bool rtl8723e_phy_set_rf_power_state(struct ieee80211_hw *hw,1655 enum rf_pwrstate rfpwr_state)1656{1657 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));1658 1659 bool bresult = false;1660 1661 if (rfpwr_state == ppsc->rfpwr_state)1662 return bresult;1663 bresult = _rtl8723e_phy_set_rf_power_state(hw, rfpwr_state);1664 return bresult;1665}1666