1 /******************************************************************************
3 * Copyright(c) 2009-2014 Realtek Corporation.
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.
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
14 * The full GNU General Public License is included in this distribution in the
15 * file called LICENSE.
17 * Contact Information:
18 * wlanfae <wlanfae@realtek.com>
19 * Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
20 * Hsinchu 300, Taiwan.
22 * Larry Finger <Larry.Finger@lwfinger.net>
24 *****************************************************************************/
32 #include "../rtl8723com/phy_common.h"
35 #include "../rtl8723com/dm_common.h"
39 static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw);
40 static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw);
41 static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
43 static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
45 static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
46 u8 channel, u8 *stage,
47 u8 *step, u32 *delay);
49 static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw);
50 static void rtl8723be_phy_set_io(struct ieee80211_hw *hw);
52 u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath,
53 u32 regaddr, u32 bitmask)
55 struct rtl_priv *rtlpriv = rtl_priv(hw);
56 u32 original_value, readback_value, bitshift;
59 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
60 "regaddr(%#x), rfpath(%#x), bitmask(%#x)\n",
61 regaddr, rfpath, bitmask);
63 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
65 original_value = rtl8723_phy_rf_serial_read(hw, rfpath, regaddr);
66 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
67 readback_value = (original_value & bitmask) >> bitshift;
69 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
71 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
72 "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n",
73 regaddr, rfpath, bitmask, original_value);
75 return readback_value;
78 void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path,
79 u32 regaddr, u32 bitmask, u32 data)
81 struct rtl_priv *rtlpriv = rtl_priv(hw);
82 u32 original_value, bitshift;
85 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
86 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
87 regaddr, bitmask, data, path);
89 spin_lock_irqsave(&rtlpriv->locks.rf_lock, flags);
91 if (bitmask != RFREG_OFFSET_MASK) {
92 original_value = rtl8723_phy_rf_serial_read(hw, path,
94 bitshift = rtl8723_phy_calculate_bit_shift(bitmask);
95 data = ((original_value & (~bitmask)) |
99 rtl8723_phy_rf_serial_write(hw, path, regaddr, data);
101 spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags);
103 RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE,
104 "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n",
105 regaddr, bitmask, data, path);
109 bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw)
111 struct rtl_priv *rtlpriv = rtl_priv(hw);
112 bool rtstatus = _rtl8723be_phy_config_mac_with_headerfile(hw);
114 rtl_write_byte(rtlpriv, 0x04CA, 0x0B);
118 bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw)
120 bool rtstatus = true;
121 struct rtl_priv *rtlpriv = rtl_priv(hw);
123 u8 b_reg_hwparafile = 1;
125 u8 crystalcap = rtlpriv->efuse.crystalcap;
126 rtl8723_phy_init_bb_rf_reg_def(hw);
127 regval = rtl_read_word(rtlpriv, REG_SYS_FUNC_EN);
128 rtl_write_word(rtlpriv, REG_SYS_FUNC_EN,
129 regval | BIT(13) | BIT(0) | BIT(1));
131 rtl_write_byte(rtlpriv, REG_RF_CTRL, RF_EN | RF_RSTB | RF_SDMRSTB);
132 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN,
133 FEN_PPLL | FEN_PCIEA | FEN_DIO_PCIE |
134 FEN_BB_GLB_RSTN | FEN_BBRSTB);
135 tmp = rtl_read_dword(rtlpriv, 0x4c);
136 rtl_write_dword(rtlpriv, 0x4c, tmp | BIT(23));
138 rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80);
140 if (b_reg_hwparafile == 1)
141 rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw);
143 crystalcap = crystalcap & 0x3F;
144 rtl_set_bbreg(hw, REG_MAC_PHY_CTRL, 0xFFF000,
145 (crystalcap | crystalcap << 6));
150 bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw)
152 return rtl8723be_phy_rf6052_config(hw);
155 static bool _rtl8723be_check_positive(struct ieee80211_hw *hw,
156 const u32 condition1,
157 const u32 condition2)
159 struct rtl_priv *rtlpriv = rtl_priv(hw);
160 struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
161 u32 cut_ver = ((rtlhal->version & CHIP_VER_RTL_MASK)
162 >> CHIP_VER_RTL_SHIFT);
163 u32 intf = (rtlhal->interface == INTF_USB ? BIT(1) : BIT(0));
165 u8 board_type = ((rtlhal->board_type & BIT(4)) >> 4) << 0 | /* _GLNA */
166 ((rtlhal->board_type & BIT(3)) >> 3) << 1 | /* _GPA */
167 ((rtlhal->board_type & BIT(7)) >> 7) << 2 | /* _ALNA */
168 ((rtlhal->board_type & BIT(6)) >> 6) << 3 | /* _APA */
169 ((rtlhal->board_type & BIT(2)) >> 2) << 4; /* _BT */
171 u32 cond1 = condition1, cond2 = condition2;
172 u32 driver1 = cut_ver << 24 | /* CUT ver */
173 0 << 20 | /* interface 2/2 */
174 0x04 << 16 | /* platform */
175 rtlhal->package_type << 12 |
176 intf << 8 | /* interface 1/2 */
179 u32 driver2 = rtlhal->type_glna << 0 |
180 rtlhal->type_gpa << 8 |
181 rtlhal->type_alna << 16 |
182 rtlhal->type_apa << 24;
184 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
185 "===> [8812A] CheckPositive (cond1, cond2) = (0x%X 0x%X)\n",
187 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
188 "===> [8812A] CheckPositive (driver1, driver2) = (0x%X 0x%X)\n",
191 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
192 " (Platform, Interface) = (0x%X, 0x%X)\n", 0x04, intf);
193 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
194 " (Board, Package) = (0x%X, 0x%X)\n",
195 rtlhal->board_type, rtlhal->package_type);
197 /*============== Value Defined Check ===============*/
198 /*QFN Type [15:12] and Cut Version [27:24] need to do value check*/
200 if (((cond1 & 0x0000F000) != 0) && ((cond1 & 0x0000F000) !=
201 (driver1 & 0x0000F000)))
203 if (((cond1 & 0x0F000000) != 0) && ((cond1 & 0x0F000000) !=
204 (driver1 & 0x0F000000)))
207 /*=============== Bit Defined Check ================*/
208 /* We don't care [31:28] */
211 driver1 &= 0x00FF0FFF;
213 if ((cond1 & driver1) == cond1) {
216 if ((cond1 & 0x0F) == 0) /* BoardType is DONTCARE*/
219 if ((cond1 & BIT(0)) != 0) /*GLNA*/
221 if ((cond1 & BIT(1)) != 0) /*GPA*/
223 if ((cond1 & BIT(2)) != 0) /*ALNA*/
225 if ((cond1 & BIT(3)) != 0) /*APA*/
228 /* BoardType of each RF path is matched*/
229 if ((cond2 & mask) == (driver2 & mask))
237 static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr,
238 u32 data, enum radio_path rfpath,
241 if (addr == 0xfe || addr == 0xffe) {
242 /* In order not to disturb BT music
243 * when wifi init.(1ant NIC only)
247 rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data);
251 static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw,
254 u32 content = 0x1000; /*RF Content: radio_a_txt*/
255 u32 maskforphyset = (u32)(content & 0xE000);
257 _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A,
258 addr | maskforphyset);
262 static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw)
264 struct rtl_priv *rtlpriv = rtl_priv(hw);
265 struct rtl_phy *rtlphy = &rtlpriv->phy;
267 u8 band, path, txnum, section;
269 for (band = BAND_ON_2_4G; band <= BAND_ON_5G; ++band)
270 for (path = 0; path < TX_PWR_BY_RATE_NUM_RF; ++path)
271 for (txnum = 0; txnum < TX_PWR_BY_RATE_NUM_RF; ++txnum)
273 section < TX_PWR_BY_RATE_NUM_SECTION;
275 rtlphy->tx_power_by_rate_offset
276 [band][path][txnum][section] = 0;
279 static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw,
284 } else if (addr == 0xfd) {
286 } else if (addr == 0xfc) {
288 } else if (addr == 0xfb) {
290 } else if (addr == 0xfa) {
292 } else if (addr == 0xf9) {
295 rtl_set_bbreg(hw, addr, MASKDWORD, data);
300 static void _rtl8723be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw,
302 u8 path, u8 rate_section,
305 struct rtl_priv *rtlpriv = rtl_priv(hw);
306 struct rtl_phy *rtlphy = &rtlpriv->phy;
308 if (path > RF90_PATH_D) {
309 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
310 "Invalid Rf Path %d in phy_SetTxPowerByRatBase()\n",
315 if (band == BAND_ON_2_4G) {
316 switch (rate_section) {
318 rtlphy->txpwr_by_rate_base_24g[path][txnum][0] = value;
321 rtlphy->txpwr_by_rate_base_24g[path][txnum][1] = value;
324 rtlphy->txpwr_by_rate_base_24g[path][txnum][2] = value;
327 rtlphy->txpwr_by_rate_base_24g[path][txnum][3] = value;
330 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
331 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n",
332 rate_section, path, txnum);
336 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
337 "Invalid Band %d in PHY_SetTxPowerByRateBase()\n",
343 static u8 _rtl8723be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw,
344 u8 band, u8 path, u8 txnum,
347 struct rtl_priv *rtlpriv = rtl_priv(hw);
348 struct rtl_phy *rtlphy = &rtlpriv->phy;
350 if (path > RF90_PATH_D) {
351 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
352 "Invalid Rf Path %d in PHY_GetTxPowerByRateBase()\n",
357 if (band == BAND_ON_2_4G) {
358 switch (rate_section) {
360 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][0];
363 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][1];
366 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][2];
369 value = rtlphy->txpwr_by_rate_base_24g[path][txnum][3];
372 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
373 "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n",
374 rate_section, path, txnum);
378 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
379 "Invalid Band %d in PHY_GetTxPowerByRateBase()\n",
386 static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw)
388 struct rtl_priv *rtlpriv = rtl_priv(hw);
389 struct rtl_phy *rtlphy = &rtlpriv->phy;
391 u8 base = 0, path = 0;
393 for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) {
394 if (path == RF90_PATH_A) {
395 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
396 [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF;
397 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
398 _rtl8723be_phy_set_txpower_by_rate_base(hw,
399 BAND_ON_2_4G, path, CCK, RF_1TX, base);
400 } else if (path == RF90_PATH_B) {
401 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
402 [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF;
403 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
404 _rtl8723be_phy_set_txpower_by_rate_base(hw,
409 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
410 [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF;
411 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
412 _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
416 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
417 [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF;
418 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
419 _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
423 rawvalue = (u16)(rtlphy->tx_power_by_rate_offset
424 [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF;
425 base = (rawvalue >> 4) * 10 + (rawvalue & 0xF);
426 _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G,
432 static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start,
439 for (i = 3; i >= 0; --i) {
440 if (i >= start && i <= end) {
441 /* Get the exact value */
442 temp_value = (u8)(*data >> (i * 8)) & 0xF;
443 temp_value += ((u8)((*data >> (i*8 + 4)) & 0xF)) * 10;
445 /* Change the value to a relative value */
446 temp_value = (temp_value > base_val) ?
447 temp_value - base_val :
448 base_val - temp_value;
450 temp_value = (u8)(*data >> (i * 8)) & 0xFF;
453 temp_data |= temp_value;
458 static void _rtl8723be_phy_convert_txpower_dbm_to_relative_value(
459 struct ieee80211_hw *hw)
461 struct rtl_priv *rtlpriv = rtl_priv(hw);
462 struct rtl_phy *rtlphy = &rtlpriv->phy;
463 u8 base = 0, rfpath = RF90_PATH_A;
465 base = _rtl8723be_phy_get_txpower_by_rate_base(hw,
466 BAND_ON_2_4G, rfpath, RF_1TX, CCK);
467 _phy_convert_txpower_dbm_to_relative_value(
468 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2],
470 _phy_convert_txpower_dbm_to_relative_value(
471 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3],
474 base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath,
476 _phy_convert_txpower_dbm_to_relative_value(
477 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0],
479 _phy_convert_txpower_dbm_to_relative_value(
480 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1],
483 base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
484 rfpath, RF_1TX, HT_MCS0_MCS7);
485 _phy_convert_txpower_dbm_to_relative_value(
486 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4],
488 _phy_convert_txpower_dbm_to_relative_value(
489 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][5],
492 base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G,
495 _phy_convert_txpower_dbm_to_relative_value(
496 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6],
499 _phy_convert_txpower_dbm_to_relative_value(
500 &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][7],
503 RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE,
504 "<===_rtl8723be_phy_convert_txpower_dbm_to_relative_value()\n");
507 static void phy_txpower_by_rate_config(struct ieee80211_hw *hw)
509 _rtl8723be_phy_store_txpower_by_rate_base(hw);
510 _rtl8723be_phy_convert_txpower_dbm_to_relative_value(hw);
513 static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw)
515 struct rtl_priv *rtlpriv = rtl_priv(hw);
516 struct rtl_phy *rtlphy = &rtlpriv->phy;
517 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
520 /* switch ant to BT */
521 if (rtlpriv->rtlhal.interface == INTF_USB) {
522 rtl_write_dword(rtlpriv, 0x948, 0x0);
524 if (rtlpriv->btcoexist.btc_info.single_ant_path == 0)
525 rtl_write_dword(rtlpriv, 0x948, 0x280);
527 rtl_write_dword(rtlpriv, 0x948, 0x0);
530 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
531 BASEBAND_CONFIG_PHY_REG);
533 pr_err("Write BB Reg Fail!!\n");
536 _rtl8723be_phy_init_tx_power_by_rate(hw);
537 if (!rtlefuse->autoload_failflag) {
538 rtlphy->pwrgroup_cnt = 0;
539 rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw,
540 BASEBAND_CONFIG_PHY_REG);
542 phy_txpower_by_rate_config(hw);
544 pr_err("BB_PG Reg Fail!!\n");
547 rtstatus = _rtl8723be_phy_config_bb_with_headerfile(hw,
548 BASEBAND_CONFIG_AGC_TAB);
550 pr_err("AGC Table Fail\n");
553 rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw,
554 RFPGA0_XA_HSSIPARAMETER2,
559 static bool rtl8723be_phy_config_with_headerfile(struct ieee80211_hw *hw,
562 void (*set_reg)(struct ieee80211_hw *hw, u32 regaddr, u32 data))
569 bool matched = true, skipped = false;
571 while ((i + 1) < arraylen) {
572 u32 v1 = array_table[i];
573 u32 v2 = array_table[i + 1];
575 if (v1 & (BIT(31) | BIT(30))) {/*positive & negative condition*/
576 if (v1 & BIT(31)) {/* positive condition*/
577 cond = (u8)((v1 & (BIT(29) | BIT(28))) >> 28);
578 if (cond == COND_ENDIF) { /*end*/
581 } else if (cond == COND_ELSE) { /*else*/
582 matched = skipped ? false : true;
583 } else {/*if , else if*/
587 if (_rtl8723be_check_positive(
597 } else if (v1 & BIT(30)) { /*negative condition*/
610 static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw)
612 struct rtl_priv *rtlpriv = rtl_priv(hw);
614 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n");
616 return rtl8723be_phy_config_with_headerfile(hw,
617 RTL8723BEMAC_1T_ARRAY, RTL8723BEMAC_1T_ARRAYLEN,
618 rtl_write_byte_with_val32);
621 static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw,
625 if (configtype == BASEBAND_CONFIG_PHY_REG)
626 return rtl8723be_phy_config_with_headerfile(hw,
627 RTL8723BEPHY_REG_1TARRAY,
628 RTL8723BEPHY_REG_1TARRAYLEN,
629 _rtl8723be_config_bb_reg);
630 else if (configtype == BASEBAND_CONFIG_AGC_TAB)
631 return rtl8723be_phy_config_with_headerfile(hw,
632 RTL8723BEAGCTAB_1TARRAY,
633 RTL8723BEAGCTAB_1TARRAYLEN,
634 rtl_set_bbreg_with_dwmask);
639 static u8 _rtl8723be_get_rate_section_index(u32 regaddr)
644 case RTXAGC_A_RATE18_06:
647 case RTXAGC_A_RATE54_24:
650 case RTXAGC_A_CCK1_MCS32:
653 case RTXAGC_B_CCK11_A_CCK2_11:
656 case RTXAGC_A_MCS03_MCS00:
659 case RTXAGC_A_MCS07_MCS04:
662 case RTXAGC_A_MCS11_MCS08:
665 case RTXAGC_A_MCS15_MCS12:
668 case RTXAGC_B_RATE18_06:
671 case RTXAGC_B_RATE54_24:
674 case RTXAGC_B_CCK1_55_MCS32:
677 case RTXAGC_B_MCS03_MCS00:
680 case RTXAGC_B_MCS07_MCS04:
683 case RTXAGC_B_MCS11_MCS08:
686 case RTXAGC_B_MCS15_MCS12:
691 if (regaddr >= 0xC20 && regaddr <= 0xC4C)
692 index = (u8)((regaddr - 0xC20) / 4);
693 else if (regaddr >= 0xE20 && regaddr <= 0xE4C)
694 index = (u8)((regaddr - 0xE20) / 4);
700 static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw,
701 u32 band, u32 rfpath,
702 u32 txnum, u32 regaddr,
703 u32 bitmask, u32 data)
705 struct rtl_priv *rtlpriv = rtl_priv(hw);
706 struct rtl_phy *rtlphy = &rtlpriv->phy;
707 u8 rate_section = _rtl8723be_get_rate_section_index(regaddr);
709 if (band != BAND_ON_2_4G && band != BAND_ON_5G) {
710 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band);
713 if (rfpath > MAX_RF_PATH - 1) {
714 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR,
715 "Invalid RfPath %d\n", rfpath);
718 if (txnum > MAX_RF_PATH - 1) {
719 RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum);
723 rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] =
728 static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw,
731 struct rtl_priv *rtlpriv = rtl_priv(hw);
733 u32 *phy_regarray_table_pg;
734 u16 phy_regarray_pg_len;
735 u32 v1 = 0, v2 = 0, v3 = 0, v4 = 0, v5 = 0, v6 = 0;
737 phy_regarray_pg_len = RTL8723BEPHY_REG_ARRAY_PGLEN;
738 phy_regarray_table_pg = RTL8723BEPHY_REG_ARRAY_PG;
740 if (configtype == BASEBAND_CONFIG_PHY_REG) {
741 for (i = 0; i < phy_regarray_pg_len; i = i + 6) {
742 v1 = phy_regarray_table_pg[i];
743 v2 = phy_regarray_table_pg[i+1];
744 v3 = phy_regarray_table_pg[i+2];
745 v4 = phy_regarray_table_pg[i+3];
746 v5 = phy_regarray_table_pg[i+4];
747 v6 = phy_regarray_table_pg[i+5];
749 if (v1 < 0xcdcdcdcd) {
750 if (phy_regarray_table_pg[i] == 0xfe ||
751 phy_regarray_table_pg[i] == 0xffe)
754 _rtl8723be_store_tx_power_by_rate(hw,
755 v1, v2, v3, v4, v5, v6);
760 RT_TRACE(rtlpriv, COMP_SEND, DBG_TRACE,
761 "configtype != BaseBand_Config_PHY_REG\n");
766 bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw,
767 enum radio_path rfpath)
769 struct rtl_priv *rtlpriv = rtl_priv(hw);
770 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
773 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Radio No %x\n", rfpath);
776 ret = rtl8723be_phy_config_with_headerfile(hw,
777 RTL8723BE_RADIOA_1TARRAY,
778 RTL8723BE_RADIOA_1TARRAYLEN,
779 _rtl8723be_config_rf_radio_a);
781 if (rtlhal->oem_id == RT_CID_819X_HP)
782 _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD);
788 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
789 "switch case %#x not processed\n", rfpath);
795 void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw)
797 struct rtl_priv *rtlpriv = rtl_priv(hw);
798 struct rtl_phy *rtlphy = &rtlpriv->phy;
800 rtlphy->default_initialgain[0] =
801 (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0);
802 rtlphy->default_initialgain[1] =
803 (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0);
804 rtlphy->default_initialgain[2] =
805 (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0);
806 rtlphy->default_initialgain[3] =
807 (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0);
809 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
810 "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n",
811 rtlphy->default_initialgain[0],
812 rtlphy->default_initialgain[1],
813 rtlphy->default_initialgain[2],
814 rtlphy->default_initialgain[3]);
816 rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3,
818 rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2,
821 RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE,
822 "Default framesync (0x%x) = 0x%x\n",
823 ROFDM0_RXDETECTOR3, rtlphy->framesync);
826 static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path,
837 case DESC92C_RATE5_5M:
838 if (path == RF90_PATH_A)
840 else if (path == RF90_PATH_B)
844 case DESC92C_RATE11M:
850 case DESC92C_RATE12M:
851 case DESC92C_RATE18M:
855 case DESC92C_RATE24M:
856 case DESC92C_RATE36M:
857 case DESC92C_RATE48M:
858 case DESC92C_RATE54M:
862 case DESC92C_RATEMCS0:
863 case DESC92C_RATEMCS1:
864 case DESC92C_RATEMCS2:
865 case DESC92C_RATEMCS3:
869 case DESC92C_RATEMCS4:
870 case DESC92C_RATEMCS5:
871 case DESC92C_RATEMCS6:
872 case DESC92C_RATEMCS7:
876 case DESC92C_RATEMCS8:
877 case DESC92C_RATEMCS9:
878 case DESC92C_RATEMCS10:
879 case DESC92C_RATEMCS11:
883 case DESC92C_RATEMCS12:
884 case DESC92C_RATEMCS13:
885 case DESC92C_RATEMCS14:
886 case DESC92C_RATEMCS15:
891 WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n");
898 static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw,
900 enum radio_path rfpath, u8 rate)
902 struct rtl_priv *rtlpriv = rtl_priv(hw);
903 struct rtl_phy *rtlphy = &rtlpriv->phy;
904 u8 shift = 0, rate_section, tx_num;
907 rate_section = _rtl8723be_phy_get_ratesection_intxpower_byrate(rfpath,
909 tx_num = RF_TX_NUM_NONIMPLEMENT;
911 if (tx_num == RF_TX_NUM_NONIMPLEMENT) {
912 if (rate >= DESC92C_RATEMCS8 && rate <= DESC92C_RATEMCS15)
920 case DESC92C_RATE24M:
921 case DESC92C_RATEMCS0:
922 case DESC92C_RATEMCS4:
923 case DESC92C_RATEMCS8:
924 case DESC92C_RATEMCS12:
930 case DESC92C_RATE36M:
931 case DESC92C_RATEMCS1:
932 case DESC92C_RATEMCS5:
933 case DESC92C_RATEMCS9:
934 case DESC92C_RATEMCS13:
937 case DESC92C_RATE5_5M:
938 case DESC92C_RATE12M:
939 case DESC92C_RATE48M:
940 case DESC92C_RATEMCS2:
941 case DESC92C_RATEMCS6:
942 case DESC92C_RATEMCS10:
943 case DESC92C_RATEMCS14:
946 case DESC92C_RATE11M:
947 case DESC92C_RATE18M:
948 case DESC92C_RATE54M:
949 case DESC92C_RATEMCS3:
950 case DESC92C_RATEMCS7:
951 case DESC92C_RATEMCS11:
952 case DESC92C_RATEMCS15:
956 WARN_ONCE(true, "rtl8723be: Rate_Section is Illegal\n");
959 tx_pwr_diff = (u8)(rtlphy->tx_power_by_rate_offset[band][rfpath][tx_num]
960 [rate_section] >> shift) & 0xff;
965 static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path,
966 u8 rate, u8 bandwidth, u8 channel)
968 struct rtl_priv *rtlpriv = rtl_priv(hw);
969 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
970 u8 index = (channel - 1);
972 u8 power_diff_byrate = 0;
974 if (channel > 14 || channel < 1) {
976 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
977 "Illegal channel!\n");
979 if (RX_HAL_IS_CCK_RATE(rate))
980 txpower = rtlefuse->txpwrlevel_cck[path][index];
981 else if (DESC92C_RATE6M <= rate)
982 txpower = rtlefuse->txpwrlevel_ht40_1s[path][index];
984 RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD,
987 if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M &&
988 !RX_HAL_IS_CCK_RATE(rate))
989 txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S];
991 if (bandwidth == HT_CHANNEL_WIDTH_20) {
992 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
993 txpower += rtlefuse->txpwr_ht20diff[0][TX_1S];
994 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
995 txpower += rtlefuse->txpwr_ht20diff[0][TX_2S];
996 } else if (bandwidth == HT_CHANNEL_WIDTH_20_40) {
997 if (DESC92C_RATEMCS0 <= rate && rate <= DESC92C_RATEMCS15)
998 txpower += rtlefuse->txpwr_ht40diff[0][TX_1S];
999 if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15)
1000 txpower += rtlefuse->txpwr_ht40diff[0][TX_2S];
1003 if (rtlefuse->eeprom_regulatory != 2)
1004 power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw,
1008 txpower += power_diff_byrate;
1010 if (txpower > MAX_POWER_INDEX)
1011 txpower = MAX_POWER_INDEX;
1016 static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw,
1017 u8 power_index, u8 path, u8 rate)
1019 struct rtl_priv *rtlpriv = rtl_priv(hw);
1020 if (path == RF90_PATH_A) {
1022 case DESC92C_RATE1M:
1023 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_CCK1_MCS32,
1024 MASKBYTE1, power_index);
1026 case DESC92C_RATE2M:
1027 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1028 MASKBYTE1, power_index);
1030 case DESC92C_RATE5_5M:
1031 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1032 MASKBYTE2, power_index);
1034 case DESC92C_RATE11M:
1035 rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11,
1036 MASKBYTE3, power_index);
1039 case DESC92C_RATE6M:
1040 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1041 MASKBYTE0, power_index);
1043 case DESC92C_RATE9M:
1044 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1045 MASKBYTE1, power_index);
1047 case DESC92C_RATE12M:
1048 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1049 MASKBYTE2, power_index);
1051 case DESC92C_RATE18M:
1052 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06,
1053 MASKBYTE3, power_index);
1056 case DESC92C_RATE24M:
1057 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1058 MASKBYTE0, power_index);
1060 case DESC92C_RATE36M:
1061 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1062 MASKBYTE1, power_index);
1064 case DESC92C_RATE48M:
1065 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1066 MASKBYTE2, power_index);
1068 case DESC92C_RATE54M:
1069 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24,
1070 MASKBYTE3, power_index);
1073 case DESC92C_RATEMCS0:
1074 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1075 MASKBYTE0, power_index);
1077 case DESC92C_RATEMCS1:
1078 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1079 MASKBYTE1, power_index);
1081 case DESC92C_RATEMCS2:
1082 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1083 MASKBYTE2, power_index);
1085 case DESC92C_RATEMCS3:
1086 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00,
1087 MASKBYTE3, power_index);
1090 case DESC92C_RATEMCS4:
1091 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1092 MASKBYTE0, power_index);
1094 case DESC92C_RATEMCS5:
1095 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1096 MASKBYTE1, power_index);
1098 case DESC92C_RATEMCS6:
1099 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1100 MASKBYTE2, power_index);
1102 case DESC92C_RATEMCS7:
1103 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04,
1104 MASKBYTE3, power_index);
1107 case DESC92C_RATEMCS8:
1108 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1109 MASKBYTE0, power_index);
1111 case DESC92C_RATEMCS9:
1112 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1113 MASKBYTE1, power_index);
1115 case DESC92C_RATEMCS10:
1116 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1117 MASKBYTE2, power_index);
1119 case DESC92C_RATEMCS11:
1120 rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08,
1121 MASKBYTE3, power_index);
1125 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n");
1129 RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid RFPath!!\n");
1133 void rtl8723be_phy_set_txpower_level(struct ieee80211_hw *hw, u8 channel)
1135 struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
1136 u8 cck_rates[] = {DESC92C_RATE1M, DESC92C_RATE2M,
1137 DESC92C_RATE5_5M, DESC92C_RATE11M};
1138 u8 ofdm_rates[] = {DESC92C_RATE6M, DESC92C_RATE9M,
1139 DESC92C_RATE12M, DESC92C_RATE18M,
1140 DESC92C_RATE24M, DESC92C_RATE36M,
1141 DESC92C_RATE48M, DESC92C_RATE54M};
1142 u8 ht_rates_1t[] = {DESC92C_RATEMCS0, DESC92C_RATEMCS1,
1143 DESC92C_RATEMCS2, DESC92C_RATEMCS3,
1144 DESC92C_RATEMCS4, DESC92C_RATEMCS5,
1145 DESC92C_RATEMCS6, DESC92C_RATEMCS7};
1149 if (!rtlefuse->txpwr_fromeprom)
1152 size = sizeof(cck_rates) / sizeof(u8);
1153 for (i = 0; i < size; i++) {
1154 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1156 rtl_priv(hw)->phy.current_chan_bw,
1158 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1161 size = sizeof(ofdm_rates) / sizeof(u8);
1162 for (i = 0; i < size; i++) {
1163 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1165 rtl_priv(hw)->phy.current_chan_bw,
1167 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1170 size = sizeof(ht_rates_1t) / sizeof(u8);
1171 for (i = 0; i < size; i++) {
1172 power_index = _rtl8723be_get_txpower_index(hw, RF90_PATH_A,
1174 rtl_priv(hw)->phy.current_chan_bw,
1176 _rtl8723be_phy_set_txpower_index(hw, power_index, RF90_PATH_A,
1181 void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation)
1183 struct rtl_priv *rtlpriv = rtl_priv(hw);
1184 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1185 enum io_type iotype;
1187 if (!is_hal_stop(rtlhal)) {
1188 switch (operation) {
1189 case SCAN_OPT_BACKUP_BAND0:
1190 iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN;
1191 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1195 case SCAN_OPT_RESTORE:
1196 iotype = IO_CMD_RESUME_DM_BY_SCAN;
1197 rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD,
1201 pr_err("Unknown Scan Backup operation.\n");
1207 void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw)
1209 struct rtl_priv *rtlpriv = rtl_priv(hw);
1210 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1211 struct rtl_phy *rtlphy = &rtlpriv->phy;
1212 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
1216 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1217 "Switch to %s bandwidth\n",
1218 rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ?
1221 if (is_hal_stop(rtlhal)) {
1222 rtlphy->set_bwmode_inprogress = false;
1226 reg_bw_opmode = rtl_read_byte(rtlpriv, REG_BWOPMODE);
1227 reg_prsr_rsc = rtl_read_byte(rtlpriv, REG_RRSR + 2);
1229 switch (rtlphy->current_chan_bw) {
1230 case HT_CHANNEL_WIDTH_20:
1231 reg_bw_opmode |= BW_OPMODE_20MHZ;
1232 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1234 case HT_CHANNEL_WIDTH_20_40:
1235 reg_bw_opmode &= ~BW_OPMODE_20MHZ;
1236 rtl_write_byte(rtlpriv, REG_BWOPMODE, reg_bw_opmode);
1237 reg_prsr_rsc = (reg_prsr_rsc & 0x90) |
1238 (mac->cur_40_prime_sc << 5);
1239 rtl_write_byte(rtlpriv, REG_RRSR + 2, reg_prsr_rsc);
1242 pr_err("unknown bandwidth: %#X\n",
1243 rtlphy->current_chan_bw);
1247 switch (rtlphy->current_chan_bw) {
1248 case HT_CHANNEL_WIDTH_20:
1249 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0);
1250 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0);
1251 /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/
1253 case HT_CHANNEL_WIDTH_20_40:
1254 rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1);
1255 rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1);
1257 rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND,
1258 (mac->cur_40_prime_sc >> 1));
1259 rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc);
1260 /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/
1262 rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)),
1263 (mac->cur_40_prime_sc ==
1264 HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1);
1267 pr_err("unknown bandwidth: %#X\n",
1268 rtlphy->current_chan_bw);
1271 rtl8723be_phy_rf6052_set_bandwidth(hw, rtlphy->current_chan_bw);
1272 rtlphy->set_bwmode_inprogress = false;
1273 RT_TRACE(rtlpriv, COMP_SCAN, DBG_LOUD, "\n");
1276 void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw,
1277 enum nl80211_channel_type ch_type)
1279 struct rtl_priv *rtlpriv = rtl_priv(hw);
1280 struct rtl_phy *rtlphy = &rtlpriv->phy;
1281 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1282 u8 tmp_bw = rtlphy->current_chan_bw;
1284 if (rtlphy->set_bwmode_inprogress)
1286 rtlphy->set_bwmode_inprogress = true;
1287 if ((!is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1288 rtl8723be_phy_set_bw_mode_callback(hw);
1290 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
1291 "false driver sleep or unload\n");
1292 rtlphy->set_bwmode_inprogress = false;
1293 rtlphy->current_chan_bw = tmp_bw;
1297 void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw)
1299 struct rtl_priv *rtlpriv = rtl_priv(hw);
1300 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1301 struct rtl_phy *rtlphy = &rtlpriv->phy;
1304 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE,
1305 "switch to channel%d\n", rtlphy->current_channel);
1306 if (is_hal_stop(rtlhal))
1309 if (!rtlphy->sw_chnl_inprogress)
1311 if (!_rtl8723be_phy_sw_chnl_step_by_step(hw,
1312 rtlphy->current_channel,
1313 &rtlphy->sw_chnl_stage,
1314 &rtlphy->sw_chnl_step,
1321 rtlphy->sw_chnl_inprogress = false;
1325 RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "\n");
1328 u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw)
1330 struct rtl_priv *rtlpriv = rtl_priv(hw);
1331 struct rtl_phy *rtlphy = &rtlpriv->phy;
1332 struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
1334 if (rtlphy->sw_chnl_inprogress)
1336 if (rtlphy->set_bwmode_inprogress)
1338 WARN_ONCE((rtlphy->current_channel > 14),
1339 "rtl8723be: WIRELESS_MODE_G but channel>14");
1340 rtlphy->sw_chnl_inprogress = true;
1341 rtlphy->sw_chnl_stage = 0;
1342 rtlphy->sw_chnl_step = 0;
1343 if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) {
1344 rtl8723be_phy_sw_chnl_callback(hw);
1345 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1346 "sw_chnl_inprogress false schedule workitem current channel %d\n",
1347 rtlphy->current_channel);
1348 rtlphy->sw_chnl_inprogress = false;
1350 RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD,
1351 "sw_chnl_inprogress false driver sleep or unload\n");
1352 rtlphy->sw_chnl_inprogress = false;
1357 static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw,
1358 u8 channel, u8 *stage,
1359 u8 *step, u32 *delay)
1361 struct rtl_priv *rtlpriv = rtl_priv(hw);
1362 struct rtl_phy *rtlphy = &rtlpriv->phy;
1363 struct swchnlcmd precommoncmd[MAX_PRECMD_CNT];
1364 u32 precommoncmdcnt;
1365 struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT];
1366 u32 postcommoncmdcnt;
1367 struct swchnlcmd rfdependcmd[MAX_RFDEPENDCMD_CNT];
1369 struct swchnlcmd *currentcmd = NULL;
1371 u8 num_total_rfpath = rtlphy->num_total_rfpath;
1373 precommoncmdcnt = 0;
1374 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1376 CMDID_SET_TXPOWEROWER_LEVEL,
1378 rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++,
1379 MAX_PRECMD_CNT, CMDID_END, 0, 0, 0);
1381 postcommoncmdcnt = 0;
1383 rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++,
1384 MAX_POSTCMD_CNT, CMDID_END,
1389 WARN_ONCE((channel < 1 || channel > 14),
1390 "rtl8723be: illegal channel for Zebra: %d\n", channel);
1392 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1393 MAX_RFDEPENDCMD_CNT,
1395 RF_CHNLBW, channel, 10);
1397 rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++,
1398 MAX_RFDEPENDCMD_CNT,
1399 CMDID_END, 0, 0, 0);
1404 currentcmd = &precommoncmd[*step];
1407 currentcmd = &rfdependcmd[*step];
1410 currentcmd = &postcommoncmd[*step];
1413 pr_err("Invalid 'stage' = %d, Check it!\n",
1418 if (currentcmd->cmdid == CMDID_END) {
1419 if ((*stage) == 2) {
1428 switch (currentcmd->cmdid) {
1429 case CMDID_SET_TXPOWEROWER_LEVEL:
1430 rtl8723be_phy_set_txpower_level(hw, channel);
1432 case CMDID_WRITEPORT_ULONG:
1433 rtl_write_dword(rtlpriv, currentcmd->para1,
1436 case CMDID_WRITEPORT_USHORT:
1437 rtl_write_word(rtlpriv, currentcmd->para1,
1438 (u16)currentcmd->para2);
1440 case CMDID_WRITEPORT_UCHAR:
1441 rtl_write_byte(rtlpriv, currentcmd->para1,
1442 (u8)currentcmd->para2);
1444 case CMDID_RF_WRITEREG:
1445 for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) {
1446 rtlphy->rfreg_chnlval[rfpath] =
1447 ((rtlphy->rfreg_chnlval[rfpath] &
1448 0xfffffc00) | currentcmd->para2);
1450 rtl_set_rfreg(hw, (enum radio_path)rfpath,
1453 rtlphy->rfreg_chnlval[rfpath]);
1457 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
1458 "switch case %#x not processed\n",
1466 (*delay) = currentcmd->msdelay;
1471 static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw)
1473 u32 reg_eac, reg_e94, reg_e9c, tmp;
1476 /* leave IQK mode */
1477 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1478 /* switch to path A */
1479 rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1480 /* enable path A PA in TXIQK mode */
1481 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1482 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000);
1483 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f);
1484 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87);
1487 /* path-A IQK setting */
1489 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1490 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1491 /* path-A IQK setting */
1492 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1493 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1494 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1495 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1497 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1498 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000);
1499 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1500 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1501 /* LO calibration setting */
1502 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1503 /* enter IQK mode */
1504 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1506 /* One shot, path A LOK & IQK */
1507 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1508 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1510 mdelay(IQK_DELAY_TIME);
1512 /* leave IQK mode */
1513 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1516 reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD);
1517 reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD);
1518 reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD);
1520 if (!(reg_eac & BIT(28)) &&
1521 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1522 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1524 else /* if Tx not OK, ignore Rx */
1527 /* Allen 20131125 */
1528 tmp = (reg_e9c & 0x03FF0000) >> 16;
1529 if ((tmp & 0x200) > 0)
1532 if (!(reg_eac & BIT(28)) &&
1533 (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1534 (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1537 else /* if Tx not OK, ignore Rx */
1543 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1544 static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw)
1546 u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp;
1549 /* leave IQK mode */
1550 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1552 /* switch to path A */
1553 rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000);
1555 /* 1 Get TXIMR setting */
1556 /* modify RXIQK mode table */
1557 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1558 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1559 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1560 /* LNA2 off, PA on for Dcut */
1561 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7);
1562 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1565 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1566 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1568 /* path-A IQK setting */
1569 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1570 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1571 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1572 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1574 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1575 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1576 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1577 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1579 /* LO calibration setting */
1580 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1582 /* enter IQK mode */
1583 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1585 /* One shot, path A LOK & IQK */
1586 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1587 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1589 mdelay(IQK_DELAY_TIME);
1591 /* leave IQK mode */
1592 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1595 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1596 reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1597 reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1599 if (!(reg_eac & BIT(28)) &&
1600 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1601 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1603 else /* if Tx not OK, ignore Rx */
1606 /* Allen 20131125 */
1607 tmp = (reg_e9c & 0x03FF0000) >> 16;
1608 if ((tmp & 0x200) > 0)
1611 if (!(reg_eac & BIT(28)) &&
1612 (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1613 (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1616 else /* if Tx not OK, ignore Rx */
1619 u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1620 ((reg_e9c & 0x3FF0000) >> 16);
1621 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1624 /* modify RXIQK mode table */
1625 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1626 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1627 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1628 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1629 /* LAN2 on, PA off for Dcut */
1630 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1632 /* PA, PAD setting */
1633 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80);
1634 rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f);
1637 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1639 /* path-A IQK setting */
1640 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1641 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1642 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1643 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1645 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1646 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1647 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1648 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1650 /* LO calibration setting */
1651 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1653 /* enter IQK mode */
1654 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1656 /* One shot, path A LOK & IQK */
1657 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1658 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1660 mdelay(IQK_DELAY_TIME);
1662 /* leave IQK mode */
1663 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1666 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1667 reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1669 /* leave IQK mode */
1670 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1671 rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780);
1673 /* Allen 20131125 */
1674 tmp = (reg_eac & 0x03FF0000) >> 16;
1675 if ((tmp & 0x200) > 0)
1677 /* if Tx is OK, check whether Rx is OK */
1678 if (!(reg_eac & BIT(27)) &&
1679 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1680 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1682 else if (!(reg_eac & BIT(27)) &&
1683 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1684 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1691 static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw)
1693 u32 reg_eac, reg_e94, reg_e9c, tmp;
1696 /* leave IQK mode */
1697 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1698 /* switch to path B */
1699 rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1701 /* enable path B PA in TXIQK mode */
1702 rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1703 rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1);
1707 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1708 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1709 /* path-A IQK setting */
1710 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1711 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1712 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1713 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1715 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea);
1716 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1717 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1718 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1720 /* LO calibration setting */
1721 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911);
1723 /* enter IQK mode */
1724 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1726 /* One shot, path B LOK & IQK */
1727 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1728 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1730 mdelay(IQK_DELAY_TIME);
1732 /* leave IQK mode */
1733 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1736 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1737 reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1738 reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1740 if (!(reg_eac & BIT(28)) &&
1741 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1742 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1747 /* Allen 20131125 */
1748 tmp = (reg_e9c & 0x03FF0000) >> 16;
1749 if ((tmp & 0x200) > 0)
1752 if (!(reg_eac & BIT(28)) &&
1753 (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1754 (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1763 /* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */
1764 static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw)
1766 u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp;
1769 /* leave IQK mode */
1770 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1771 /* switch to path B */
1772 rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280);
1774 /* 1 Get TXIMR setting */
1775 /* modify RXIQK mode table */
1776 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0);
1777 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1778 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1779 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7);
1781 /* open PA S1 & SMIXER */
1782 rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1783 rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed);
1786 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00);
1787 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1789 /* path-B IQK setting */
1790 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1791 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1792 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1793 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1795 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0);
1796 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000);
1797 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1798 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1800 /* LO calibration setting */
1801 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911);
1802 /* enter IQK mode */
1803 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1805 /* One shot, path B TXIQK @ RXIQK */
1806 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1807 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1809 mdelay(IQK_DELAY_TIME);
1811 /* leave IQK mode */
1812 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1814 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1815 reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD);
1816 reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD);
1818 if (!(reg_eac & BIT(28)) &&
1819 (((reg_e94 & 0x03FF0000) >> 16) != 0x142) &&
1820 (((reg_e9c & 0x03FF0000) >> 16) != 0x42))
1822 else /* if Tx not OK, ignore Rx */
1825 /* Allen 20131125 */
1826 tmp = (reg_e9c & 0x03FF0000) >> 16;
1827 if ((tmp & 0x200) > 0)
1830 if (!(reg_eac & BIT(28)) &&
1831 (((reg_e94 & 0x03FF0000) >> 16) < 0x110) &&
1832 (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) &&
1838 u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) |
1839 ((reg_e9c & 0x3FF0000) >> 16);
1840 rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp);
1844 /* <20121009, Kordan> RF Mode = 3 */
1845 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1846 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1);
1847 rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000);
1848 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f);
1849 rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77);
1850 rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0);
1852 /* open PA S1 & close SMIXER */
1853 rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020);
1854 rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd);
1857 rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800);
1859 /* path-B IQK setting */
1860 rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c);
1861 rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c);
1862 rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1863 rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c);
1865 rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000);
1866 rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f);
1867 rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000);
1868 rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000);
1870 /* LO calibration setting */
1871 rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1);
1872 /* enter IQK mode */
1873 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000);
1875 /* One shot, path B LOK & IQK */
1876 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000);
1877 rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000);
1879 mdelay(IQK_DELAY_TIME);
1881 /* leave IQK mode */
1882 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000);
1884 reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD);
1885 reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD);
1887 /* Allen 20131125 */
1888 tmp = (reg_eac & 0x03FF0000) >> 16;
1889 if ((tmp & 0x200) > 0)
1892 /* if Tx is OK, check whether Rx is OK */
1893 if (!(reg_eac & BIT(27)) &&
1894 (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) &&
1895 (((reg_eac & 0x03FF0000) >> 16) != 0x36))
1897 else if (!(reg_eac & BIT(27)) &&
1898 (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) &&
1899 (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) &&
1908 static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw,
1914 u32 oldval_1, x, tx1_a, reg;
1917 if (final_candidate == 0xFF) {
1919 } else if (b_iqk_ok) {
1920 oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE,
1921 MASKDWORD) >> 22) & 0x3FF;
1922 x = result[final_candidate][4];
1923 if ((x & 0x00000200) != 0)
1925 tx1_a = (x * oldval_1) >> 8;
1926 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a);
1927 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27),
1928 ((x * oldval_1 >> 7) & 0x1));
1929 y = result[final_candidate][5];
1930 if ((y & 0x00000200) != 0)
1932 tx1_c = (y * oldval_1) >> 8;
1933 rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000,
1934 ((tx1_c & 0x3C0) >> 6));
1935 rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000,
1937 rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25),
1938 ((y * oldval_1 >> 7) & 0x1));
1941 reg = result[final_candidate][6];
1942 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg);
1943 reg = result[final_candidate][7] & 0x3F;
1944 rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg);
1945 reg = (result[final_candidate][7] >> 6) & 0xF;
1946 /* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */
1950 static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw,
1951 long result[][8], u8 c1, u8 c2)
1953 u32 i, j, diff, simularity_bitmap, bound = 0;
1955 u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */
1956 bool bresult = true; /* is2t = true*/
1957 s32 tmp1 = 0, tmp2 = 0;
1961 simularity_bitmap = 0;
1963 for (i = 0; i < bound; i++) {
1964 if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) {
1965 if ((result[c1][i] & 0x00000200) != 0)
1966 tmp1 = result[c1][i] | 0xFFFFFC00;
1968 tmp1 = result[c1][i];
1970 if ((result[c2][i] & 0x00000200) != 0)
1971 tmp2 = result[c2][i] | 0xFFFFFC00;
1973 tmp2 = result[c2][i];
1975 tmp1 = result[c1][i];
1976 tmp2 = result[c2][i];
1979 diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1);
1981 if (diff > MAX_TOLERANCE) {
1982 if ((i == 2 || i == 6) && !simularity_bitmap) {
1983 if (result[c1][i] + result[c1][i + 1] == 0)
1984 final_candidate[(i / 4)] = c2;
1985 else if (result[c2][i] + result[c2][i + 1] == 0)
1986 final_candidate[(i / 4)] = c1;
1988 simularity_bitmap |= (1 << i);
1990 simularity_bitmap |= (1 << i);
1994 if (simularity_bitmap == 0) {
1995 for (i = 0; i < (bound / 4); i++) {
1996 if (final_candidate[i] != 0xFF) {
1997 for (j = i * 4; j < (i + 1) * 4 - 2; j++)
1999 result[final_candidate[i]][j];
2005 if (!(simularity_bitmap & 0x03)) { /* path A TX OK */
2006 for (i = 0; i < 2; i++)
2007 result[3][i] = result[c1][i];
2009 if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */
2010 for (i = 2; i < 4; i++)
2011 result[3][i] = result[c1][i];
2013 if (!(simularity_bitmap & 0x30)) { /* path B TX OK */
2014 for (i = 4; i < 6; i++)
2015 result[3][i] = result[c1][i];
2017 if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */
2018 for (i = 6; i < 8; i++)
2019 result[3][i] = result[c1][i];
2025 static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw,
2026 long result[][8], u8 t, bool is2t)
2028 struct rtl_priv *rtlpriv = rtl_priv(hw);
2029 struct rtl_phy *rtlphy = &rtlpriv->phy;
2031 u8 patha_ok, pathb_ok;
2032 u32 adda_reg[IQK_ADDA_REG_NUM] = {
2033 0x85c, 0xe6c, 0xe70, 0xe74,
2034 0xe78, 0xe7c, 0xe80, 0xe84,
2035 0xe88, 0xe8c, 0xed0, 0xed4,
2036 0xed8, 0xedc, 0xee0, 0xeec
2039 u32 iqk_mac_reg[IQK_MAC_REG_NUM] = {
2040 0x522, 0x550, 0x551, 0x040
2042 u32 iqk_bb_reg[IQK_BB_REG_NUM] = {
2043 ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR,
2044 RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c,
2048 const u32 retrycount = 2;
2050 u32 path_sel_bb;/* path_sel_rf */
2052 u8 tmp_reg_c50, tmp_reg_c58;
2054 tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0);
2055 tmp_reg_c58 = rtl_get_bbreg(hw, 0xc58, MASKBYTE0);
2058 rtl8723_save_adda_registers(hw, adda_reg,
2059 rtlphy->adda_backup, 16);
2060 rtl8723_phy_save_mac_registers(hw, iqk_mac_reg,
2061 rtlphy->iqk_mac_backup);
2062 rtl8723_save_adda_registers(hw, iqk_bb_reg,
2063 rtlphy->iqk_bb_backup,
2066 rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t);
2068 rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw,
2069 RFPGA0_XA_HSSIPARAMETER1,
2073 path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2075 rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg,
2076 rtlphy->iqk_mac_backup);
2078 rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf);
2079 rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600);
2080 rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4);
2081 rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000);
2084 for (i = 0; i < retrycount; i++) {
2085 patha_ok = _rtl8723be_phy_path_a_iqk(hw);
2086 if (patha_ok == 0x01) {
2087 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2088 "Path A Tx IQK Success!!\n");
2089 result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) &
2091 result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) &
2095 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2096 "Path A Tx IQK Fail!!\n");
2100 for (i = 0; i < retrycount; i++) {
2101 patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw);
2102 if (patha_ok == 0x03) {
2103 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2104 "Path A Rx IQK Success!!\n");
2105 result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) &
2107 result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) &
2111 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2112 "Path A Rx IQK Fail!!\n");
2115 if (0x00 == patha_ok)
2116 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n");
2120 for (i = 0; i < retrycount; i++) {
2121 pathb_ok = _rtl8723be_phy_path_b_iqk(hw);
2122 if (pathb_ok == 0x01) {
2123 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2124 "Path B Tx IQK Success!!\n");
2125 result[t][4] = (rtl_get_bbreg(hw, 0xe94,
2128 result[t][5] = (rtl_get_bbreg(hw, 0xe9c,
2133 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2134 "Path B Tx IQK Fail!!\n");
2137 for (i = 0; i < retrycount; i++) {
2138 pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw);
2139 if (pathb_ok == 0x03) {
2140 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2141 "Path B Rx IQK Success!!\n");
2142 result[t][6] = (rtl_get_bbreg(hw, 0xea4,
2145 result[t][7] = (rtl_get_bbreg(hw, 0xeac,
2150 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD,
2151 "Path B Rx IQK Fail!!\n");
2155 /* Back to BB mode, load original value */
2156 rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0);
2159 rtl8723_phy_reload_adda_registers(hw, adda_reg,
2160 rtlphy->adda_backup, 16);
2161 rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg,
2162 rtlphy->iqk_mac_backup);
2163 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2164 rtlphy->iqk_bb_backup,
2167 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2168 /*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/
2170 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50);
2171 rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50);
2173 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, 0x50);
2174 rtl_set_bbreg(hw, 0xc58, MASKBYTE0, tmp_reg_c58);
2176 rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x01008c00);
2177 rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x01008c00);
2179 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n");
2182 static u8 _get_right_chnl_place_for_iqk(u8 chnl)
2184 u8 channel_all[TARGET_CHNL_NUM_2G_5G] = {
2185 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
2186 13, 14, 36, 38, 40, 42, 44, 46,
2187 48, 50, 52, 54, 56, 58, 60, 62, 64,
2188 100, 102, 104, 106, 108, 110,
2189 112, 114, 116, 118, 120, 122,
2190 124, 126, 128, 130, 132, 134, 136,
2191 138, 140, 149, 151, 153, 155, 157,
2192 159, 161, 163, 165};
2196 for (place = 14; place < sizeof(channel_all); place++) {
2197 if (channel_all[place] == chnl)
2204 static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t)
2207 u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal;
2208 struct rtl_priv *rtlpriv = rtl_priv(hw);
2210 tmpreg = rtl_read_byte(rtlpriv, 0xd03);
2212 if ((tmpreg & 0x70) != 0)
2213 rtl_write_byte(rtlpriv, 0xd03, tmpreg & 0x8F);
2215 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2217 if ((tmpreg & 0x70) != 0) {
2218 rf_a_mode = rtl_get_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS);
2221 rf_b_mode = rtl_get_rfreg(hw, RF90_PATH_B, 0x00,
2224 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS,
2225 (rf_a_mode & 0x8FFFF) | 0x10000);
2228 rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASK12BITS,
2229 (rf_b_mode & 0x8FFFF) | 0x10000);
2231 lc_cal = rtl_get_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS);
2233 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0);
2234 rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a);
2236 /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2238 /* In order not to disturb BT music when wifi init.(1ant NIC only) */
2241 rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0);
2243 if ((tmpreg & 0x70) != 0) {
2244 rtl_write_byte(rtlpriv, 0xd03, tmpreg);
2245 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, MASK12BITS, rf_a_mode);
2248 rtl_set_rfreg(hw, RF90_PATH_B, 0x00,
2249 MASK12BITS, rf_b_mode);
2251 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2253 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2256 static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw,
2257 bool bmain, bool is2t)
2259 struct rtl_priv *rtlpriv = rtl_priv(hw);
2260 RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n");
2262 if (bmain) /* left antenna */
2263 rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1);
2265 rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2);
2268 #undef IQK_ADDA_REG_NUM
2269 #undef IQK_DELAY_TIME
2270 /* IQK is merge from Merge Temp */
2271 void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery)
2273 struct rtl_priv *rtlpriv = rtl_priv(hw);
2274 struct rtl_phy *rtlphy = &rtlpriv->phy;
2276 u8 i, final_candidate, idx;
2277 bool b_patha_ok, b_pathb_ok;
2278 long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4;
2279 long reg_ecc, reg_tmp = 0;
2280 bool is12simular, is13simular, is23simular;
2281 u32 iqk_bb_reg[9] = {
2282 ROFDM0_XARXIQIMBALANCE,
2283 ROFDM0_XBRXIQIMBALANCE,
2284 ROFDM0_ECCATHRESHOLD,
2285 ROFDM0_AGCRSSITABLE,
2286 ROFDM0_XATXIQIMBALANCE,
2287 ROFDM0_XBTXIQIMBALANCE,
2292 u32 path_sel_bb = 0; /* path_sel_rf = 0 */
2294 if (rtlphy->lck_inprogress)
2297 spin_lock(&rtlpriv->locks.iqk_lock);
2298 rtlphy->lck_inprogress = true;
2299 spin_unlock(&rtlpriv->locks.iqk_lock);
2302 rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg,
2303 rtlphy->iqk_bb_backup, 9);
2307 path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD);
2308 /* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */
2310 for (i = 0; i < 8; i++) {
2316 final_candidate = 0xff;
2319 is12simular = false;
2320 is23simular = false;
2321 is13simular = false;
2322 for (i = 0; i < 3; i++) {
2323 _rtl8723be_phy_iq_calibrate(hw, result, i, true);
2325 is12simular = _rtl8723be_phy_simularity_compare(hw,
2329 final_candidate = 0;
2334 is13simular = _rtl8723be_phy_simularity_compare(hw,
2338 final_candidate = 0;
2341 is23simular = _rtl8723be_phy_simularity_compare(hw,
2345 final_candidate = 1;
2347 for (i = 0; i < 8; i++)
2348 reg_tmp += result[3][i];
2351 final_candidate = 3;
2353 final_candidate = 0xFF;
2357 for (i = 0; i < 4; i++) {
2358 reg_e94 = result[i][0];
2359 reg_e9c = result[i][1];
2360 reg_ea4 = result[i][2];
2361 reg_eac = result[i][3];
2362 reg_eb4 = result[i][4];
2363 reg_ebc = result[i][5];
2364 reg_ec4 = result[i][6];
2365 reg_ecc = result[i][7];
2367 if (final_candidate != 0xff) {
2368 reg_e94 = result[final_candidate][0];
2369 rtlphy->reg_e94 = reg_e94;
2370 reg_e9c = result[final_candidate][1];
2371 rtlphy->reg_e9c = reg_e9c;
2372 reg_ea4 = result[final_candidate][2];
2373 reg_eac = result[final_candidate][3];
2374 reg_eb4 = result[final_candidate][4];
2375 rtlphy->reg_eb4 = reg_eb4;
2376 reg_ebc = result[final_candidate][5];
2377 rtlphy->reg_ebc = reg_ebc;
2378 reg_ec4 = result[final_candidate][6];
2379 reg_ecc = result[final_candidate][7];
2383 rtlphy->reg_e94 = 0x100;
2384 rtlphy->reg_eb4 = 0x100;
2385 rtlphy->reg_e9c = 0x0;
2386 rtlphy->reg_ebc = 0x0;
2389 rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result,
2393 _rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result,
2397 idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel);
2399 if (final_candidate < 4) {
2400 for (i = 0; i < IQK_MATRIX_REG_NUM; i++)
2401 rtlphy->iqk_matrix[idx].value[0][i] =
2402 result[final_candidate][i];
2403 rtlphy->iqk_matrix[idx].iqk_done = true;
2406 rtl8723_save_adda_registers(hw, iqk_bb_reg,
2407 rtlphy->iqk_bb_backup, 9);
2409 rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb);
2410 /* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */
2413 spin_lock(&rtlpriv->locks.iqk_lock);
2414 rtlphy->lck_inprogress = false;
2415 spin_unlock(&rtlpriv->locks.iqk_lock);
2418 void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw)
2420 struct rtl_priv *rtlpriv = rtl_priv(hw);
2421 struct rtl_phy *rtlphy = &rtlpriv->phy;
2422 struct rtl_hal *rtlhal = &rtlpriv->rtlhal;
2423 u32 timeout = 2000, timecount = 0;
2425 while (rtlpriv->mac80211.act_scanning && timecount < timeout) {
2430 rtlphy->lck_inprogress = true;
2431 RTPRINT(rtlpriv, FINIT, INIT_IQK,
2432 "LCK:Start!!! currentband %x delay %d ms\n",
2433 rtlhal->current_bandtype, timecount);
2435 _rtl8723be_phy_lc_calibrate(hw, false);
2437 rtlphy->lck_inprogress = false;
2440 void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain)
2442 _rtl8723be_phy_set_rfpath_switch(hw, bmain, true);
2445 bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype)
2447 struct rtl_priv *rtlpriv = rtl_priv(hw);
2448 struct rtl_phy *rtlphy = &rtlpriv->phy;
2449 bool b_postprocessing = false;
2451 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2452 "-->IO Cmd(%#x), set_io_inprogress(%d)\n",
2453 iotype, rtlphy->set_io_inprogress);
2456 case IO_CMD_RESUME_DM_BY_SCAN:
2457 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2458 "[IO CMD] Resume DM after scan.\n");
2459 b_postprocessing = true;
2461 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2462 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2463 "[IO CMD] Pause DM before scan.\n");
2464 b_postprocessing = true;
2467 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2468 "switch case %#x not processed\n", iotype);
2472 if (b_postprocessing && !rtlphy->set_io_inprogress) {
2473 rtlphy->set_io_inprogress = true;
2474 rtlphy->current_io_type = iotype;
2478 rtl8723be_phy_set_io(hw);
2479 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "IO Type(%#x)\n", iotype);
2483 static void rtl8723be_phy_set_io(struct ieee80211_hw *hw)
2485 struct rtl_priv *rtlpriv = rtl_priv(hw);
2486 struct dig_t *dm_digtable = &rtlpriv->dm_digtable;
2487 struct rtl_phy *rtlphy = &rtlpriv->phy;
2489 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2490 "--->Cmd(%#x), set_io_inprogress(%d)\n",
2491 rtlphy->current_io_type, rtlphy->set_io_inprogress);
2492 switch (rtlphy->current_io_type) {
2493 case IO_CMD_RESUME_DM_BY_SCAN:
2494 dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1;
2495 /*rtl92c_dm_write_dig(hw);*/
2496 rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel);
2497 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83);
2499 case IO_CMD_PAUSE_BAND0_DM_BY_SCAN:
2500 rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue;
2501 dm_digtable->cur_igvalue = 0x17;
2502 rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40);
2505 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2506 "switch case %#x not processed\n",
2507 rtlphy->current_io_type);
2510 rtlphy->set_io_inprogress = false;
2511 RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE,
2512 "(%#x)\n", rtlphy->current_io_type);
2515 static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw)
2517 struct rtl_priv *rtlpriv = rtl_priv(hw);
2519 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x2b);
2520 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2521 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2522 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE3);
2523 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00);
2526 static void _rtl8723be_phy_set_rf_sleep(struct ieee80211_hw *hw)
2528 struct rtl_priv *rtlpriv = rtl_priv(hw);
2530 rtl_write_byte(rtlpriv, REG_TXPAUSE, 0xFF);
2531 rtl_set_rfreg(hw, RF90_PATH_A, 0x00, RFREG_OFFSET_MASK, 0x00);
2532 rtl_write_byte(rtlpriv, REG_SYS_FUNC_EN, 0xE2);
2533 rtl_write_byte(rtlpriv, REG_SPS0_CTRL, 0x22);
2536 static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2537 enum rf_pwrstate rfpwr_state)
2539 struct rtl_priv *rtlpriv = rtl_priv(hw);
2540 struct rtl_pci_priv *pcipriv = rtl_pcipriv(hw);
2541 struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
2542 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2543 bool bresult = true;
2545 struct rtl8192_tx_ring *ring = NULL;
2547 switch (rfpwr_state) {
2549 if ((ppsc->rfpwr_state == ERFOFF) &&
2550 RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) {
2552 u32 initializecount = 0;
2555 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2556 "IPS Set eRf nic enable\n");
2557 rtstatus = rtl_ps_enable_nic(hw);
2558 } while (!rtstatus && (initializecount < 10));
2559 RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2561 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2562 "Set ERFON sleeped:%d ms\n",
2563 jiffies_to_msecs(jiffies -
2564 ppsc->last_sleep_jiffies));
2565 ppsc->last_awake_jiffies = jiffies;
2566 rtl8723be_phy_set_rf_on(hw);
2568 if (mac->link_state == MAC80211_LINKED)
2569 rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK);
2571 rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK);
2576 for (queue_id = 0, i = 0;
2577 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2578 ring = &pcipriv->dev.tx_ring[queue_id];
2579 /* Don't check BEACON Q.
2580 * BEACON Q is always not empty,
2581 * because '_rtl8723be_cmd_send_packet'
2583 if (queue_id == BEACON_QUEUE ||
2584 skb_queue_len(&ring->queue) == 0) {
2588 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2589 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2591 skb_queue_len(&ring->queue));
2596 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2597 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2598 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2599 MAX_DOZE_WAITING_TIMES_9x,
2601 skb_queue_len(&ring->queue));
2606 if (ppsc->reg_rfps_level & RT_RF_OFF_LEVL_HALT_NIC) {
2607 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2608 "IPS Set eRf nic disable\n");
2609 rtl_ps_disable_nic(hw);
2610 RT_SET_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC);
2612 if (ppsc->rfoff_reason == RF_CHANGE_BY_IPS) {
2613 rtlpriv->cfg->ops->led_control(hw,
2616 rtlpriv->cfg->ops->led_control(hw,
2623 if (ppsc->rfpwr_state == ERFOFF)
2625 for (queue_id = 0, i = 0;
2626 queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) {
2627 ring = &pcipriv->dev.tx_ring[queue_id];
2628 if (skb_queue_len(&ring->queue) == 0) {
2632 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2633 "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n",
2635 skb_queue_len(&ring->queue));
2640 if (i >= MAX_DOZE_WAITING_TIMES_9x) {
2641 RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING,
2642 "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n",
2643 MAX_DOZE_WAITING_TIMES_9x,
2645 skb_queue_len(&ring->queue));
2649 RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG,
2650 "Set ERFSLEEP awaked:%d ms\n",
2651 jiffies_to_msecs(jiffies -
2652 ppsc->last_awake_jiffies));
2653 ppsc->last_sleep_jiffies = jiffies;
2654 _rtl8723be_phy_set_rf_sleep(hw);
2658 RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD,
2659 "switch case %#x not processed\n", rfpwr_state);
2664 ppsc->rfpwr_state = rfpwr_state;
2668 bool rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw,
2669 enum rf_pwrstate rfpwr_state)
2671 struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
2673 bool bresult = false;
2675 if (rfpwr_state == ppsc->rfpwr_state)
2677 bresult = _rtl8723be_phy_set_rf_power_state(hw, rfpwr_state);