diff options
Diffstat (limited to 'drivers/net/wireless/rtlwifi/rtl8723be/phy.c')
-rw-r--r-- | drivers/net/wireless/rtlwifi/rtl8723be/phy.c | 1783 |
1 files changed, 1191 insertions, 592 deletions
diff --git a/drivers/net/wireless/rtlwifi/rtl8723be/phy.c b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c index 1575ef9ece9f..20dcc25c506c 100644 --- a/drivers/net/wireless/rtlwifi/rtl8723be/phy.c +++ b/drivers/net/wireless/rtlwifi/rtl8723be/phy.c @@ -26,224 +26,28 @@ #include "../wifi.h" #include "../pci.h" #include "../ps.h" -#include "../core.h" #include "reg.h" #include "def.h" #include "phy.h" #include "../rtl8723com/phy_common.h" #include "rf.h" #include "dm.h" +#include "../rtl8723com/dm_common.h" #include "table.h" #include "trx.h" static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw); +static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw); +static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype); static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, u8 configtype); -static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw, - u8 channel, u8 *stage, - u8 *step, u32 *delay); -static bool _rtl8723be_check_condition(struct ieee80211_hw *hw, - const u32 condition) -{ - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); - u32 _board = rtlefuse->board_type; /*need efuse define*/ - u32 _interface = rtlhal->interface; - u32 _platform = 0x08;/*SupportPlatform */ - u32 cond = condition; - - if (condition == 0xCDCDCDCD) - return true; - - cond = condition & 0xFF; - if ((_board & cond) == 0 && cond != 0x1F) - return false; - - cond = condition & 0xFF00; - cond = cond >> 8; - if ((_interface & cond) == 0 && cond != 0x07) - return false; - - cond = condition & 0xFF0000; - cond = cond >> 16; - if ((_platform & cond) == 0 && cond != 0x0F) - return false; - return true; -} - -static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 i; - u32 arraylength; - u32 *ptrarray; - - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n"); - arraylength = RTL8723BEMAC_1T_ARRAYLEN; - ptrarray = RTL8723BEMAC_1T_ARRAY; - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength); - for (i = 0; i < arraylength; i = i + 2) - rtl_write_byte(rtlpriv, ptrarray[i], (u8) ptrarray[i + 1]); - return true; -} - -static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, - u8 configtype) -{ - #define READ_NEXT_PAIR(v1, v2, i) \ - do { \ - i += 2; \ - v1 = array_table[i];\ - v2 = array_table[i+1]; \ - } while (0) - - int i; - u32 *array_table; - u16 arraylen; - struct rtl_priv *rtlpriv = rtl_priv(hw); - u32 v1 = 0, v2 = 0; - - if (configtype == BASEBAND_CONFIG_PHY_REG) { - arraylen = RTL8723BEPHY_REG_1TARRAYLEN; - array_table = RTL8723BEPHY_REG_1TARRAY; - - for (i = 0; i < arraylen; i = i + 2) { - v1 = array_table[i]; - v2 = array_table[i+1]; - if (v1 < 0xcdcdcdcd) { - rtl_bb_delay(hw, v1, v2); - } else {/*This line is the start line of branch.*/ - if (!_rtl8723be_check_condition(hw, array_table[i])) { - /*Discard the following (offset, data) pairs*/ - READ_NEXT_PAIR(v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && - i < arraylen - 2) { - READ_NEXT_PAIR(v1, v2, i); - } - i -= 2; /* prevent from for-loop += 2*/ - /* Configure matched pairs and - * skip to end of if-else. - */ - } else { - READ_NEXT_PAIR(v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && - i < arraylen - 2) { - rtl_bb_delay(hw, - v1, v2); - READ_NEXT_PAIR(v1, v2, i); - } +static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, + u8 *step, u32 *delay); - while (v2 != 0xDEAD && i < arraylen - 2) - READ_NEXT_PAIR(v1, v2, i); - } - } - } - } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { - arraylen = RTL8723BEAGCTAB_1TARRAYLEN; - array_table = RTL8723BEAGCTAB_1TARRAY; - - for (i = 0; i < arraylen; i = i + 2) { - v1 = array_table[i]; - v2 = array_table[i+1]; - if (v1 < 0xCDCDCDCD) { - rtl_set_bbreg(hw, array_table[i], - MASKDWORD, - array_table[i + 1]); - udelay(1); - continue; - } else {/*This line is the start line of branch.*/ - if (!_rtl8723be_check_condition(hw, array_table[i])) { - /* Discard the following - * (offset, data) pairs - */ - READ_NEXT_PAIR(v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && - i < arraylen - 2) { - READ_NEXT_PAIR(v1, v2, i); - } - i -= 2; /* prevent from for-loop += 2*/ - /*Configure matched pairs and - *skip to end of if-else. - */ - } else { - READ_NEXT_PAIR(v1, v2, i); - while (v2 != 0xDEAD && - v2 != 0xCDEF && - v2 != 0xCDCD && - i < arraylen - 2) { - rtl_set_bbreg(hw, array_table[i], - MASKDWORD, - array_table[i + 1]); - udelay(1); - READ_NEXT_PAIR(v1, v2, i); - } - - while (v2 != 0xDEAD && i < arraylen - 2) - READ_NEXT_PAIR(v1, v2, i); - } - } - RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "The agctab_array_table[0] is " - "%x Rtl818EEPHY_REGArray[1] is %x\n", - array_table[i], array_table[i + 1]); - } - } - return true; -} - -static u8 _rtl8723be_get_rate_section_index(u32 regaddr) -{ - u8 index = 0; - - switch (regaddr) { - case RTXAGC_A_RATE18_06: - case RTXAGC_B_RATE18_06: - index = 0; - break; - case RTXAGC_A_RATE54_24: - case RTXAGC_B_RATE54_24: - index = 1; - break; - case RTXAGC_A_CCK1_MCS32: - case RTXAGC_B_CCK1_55_MCS32: - index = 2; - break; - case RTXAGC_B_CCK11_A_CCK2_11: - index = 3; - break; - case RTXAGC_A_MCS03_MCS00: - case RTXAGC_B_MCS03_MCS00: - index = 4; - break; - case RTXAGC_A_MCS07_MCS04: - case RTXAGC_B_MCS07_MCS04: - index = 5; - break; - case RTXAGC_A_MCS11_MCS08: - case RTXAGC_B_MCS11_MCS08: - index = 6; - break; - case RTXAGC_A_MCS15_MCS12: - case RTXAGC_B_MCS15_MCS12: - index = 7; - break; - default: - regaddr &= 0xFFF; - if (regaddr >= 0xC20 && regaddr <= 0xC4C) - index = (u8) ((regaddr - 0xC20) / 4); - else if (regaddr >= 0xE20 && regaddr <= 0xE4C) - index = (u8) ((regaddr - 0xE20) / 4); - break; - }; - return index; -} +static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw); +static void rtl8723be_phy_set_io(struct ieee80211_hw *hw); u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, u32 regaddr, u32 bitmask) @@ -265,9 +69,8 @@ u32 rtl8723be_phy_query_rf_reg(struct ieee80211_hw *hw, enum radio_path rfpath, spin_unlock_irqrestore(&rtlpriv->locks.rf_lock, flags); RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, - "regaddr(%#x), rfpath(%#x), " - "bitmask(%#x), original_value(%#x)\n", - regaddr, rfpath, bitmask, original_value); + "regaddr(%#x), rfpath(%#x), bitmask(%#x), original_value(%#x)\n", + regaddr, rfpath, bitmask, original_value); return readback_value; } @@ -300,6 +103,7 @@ void rtl8723be_phy_set_rf_reg(struct ieee80211_hw *hw, enum radio_path path, RT_TRACE(rtlpriv, COMP_RF, DBG_TRACE, "regaddr(%#x), bitmask(%#x), data(%#x), rfpath(%#x)\n", regaddr, bitmask, data, path); + } bool rtl8723be_phy_mac_config(struct ieee80211_hw *hw) @@ -316,7 +120,7 @@ bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw) bool rtstatus = true; struct rtl_priv *rtlpriv = rtl_priv(hw); u16 regval; - u8 reg_hwparafile = 1; + u8 b_reg_hwparafile = 1; u32 tmp; u8 crystalcap = rtlpriv->efuse.crystalcap; rtl8723_phy_init_bb_rf_reg_def(hw); @@ -333,7 +137,7 @@ bool rtl8723be_phy_bb_config(struct ieee80211_hw *hw) rtl_write_byte(rtlpriv, REG_AFE_XTAL_CTRL + 1, 0x80); - if (reg_hwparafile == 1) + if (b_reg_hwparafile == 1) rtstatus = _rtl8723be_phy_bb8723b_config_parafile(hw); crystalcap = crystalcap & 0x3F; @@ -348,18 +152,49 @@ bool rtl8723be_phy_rf_config(struct ieee80211_hw *hw) return rtl8723be_phy_rf6052_config(hw); } +static bool _rtl8723be_check_condition(struct ieee80211_hw *hw, + const u32 condition) +{ + struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); + u32 _board = rtlefuse->board_type; /*need efuse define*/ + u32 _interface = rtlhal->interface; + u32 _platform = 0x08;/*SupportPlatform */ + u32 cond = condition; + + if (condition == 0xCDCDCDCD) + return true; + + cond = condition & 0xFF; + if ((_board & cond) == 0 && cond != 0x1F) + return false; + + cond = condition & 0xFF00; + cond = cond >> 8; + if ((_interface & cond) == 0 && cond != 0x07) + return false; + + cond = condition & 0xFF0000; + cond = cond >> 16; + if ((_platform & cond) == 0 && cond != 0x0F) + return false; + return true; +} + static void _rtl8723be_config_rf_reg(struct ieee80211_hw *hw, u32 addr, u32 data, enum radio_path rfpath, u32 regaddr) { if (addr == 0xfe || addr == 0xffe) { + /* In order not to disturb BT music + * when wifi init.(1ant NIC only) + */ mdelay(50); } else { rtl_set_rfreg(hw, rfpath, regaddr, RFREG_OFFSET_MASK, data); udelay(1); } } - static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw, u32 addr, u32 data) { @@ -368,12 +203,13 @@ static void _rtl8723be_config_rf_radio_a(struct ieee80211_hw *hw, _rtl8723be_config_rf_reg(hw, addr, data, RF90_PATH_A, addr | maskforphyset); + } static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; u8 band, path, txnum, section; @@ -383,16 +219,38 @@ static void _rtl8723be_phy_init_tx_power_by_rate(struct ieee80211_hw *hw) for (section = 0; section < TX_PWR_BY_RATE_NUM_SECTION; ++section) - rtlphy->tx_power_by_rate_offset[band] - [path][txnum][section] = 0; + rtlphy->tx_power_by_rate_offset + [band][path][txnum][section] = 0; +} + +static void _rtl8723be_config_bb_reg(struct ieee80211_hw *hw, + u32 addr, u32 data) +{ + if (addr == 0xfe) { + mdelay(50); + } else if (addr == 0xfd) { + mdelay(5); + } else if (addr == 0xfc) { + mdelay(1); + } else if (addr == 0xfb) { + udelay(50); + } else if (addr == 0xfa) { + udelay(5); + } else if (addr == 0xf9) { + udelay(1); + } else { + rtl_set_bbreg(hw, addr, MASKDWORD, data); + udelay(1); + } } -static void phy_set_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, - u8 path, u8 rate_section, - u8 txnum, u8 value) +static void _rtl8723be_phy_set_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, + u8 path, u8 rate_section, + u8 txnum, u8 value) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; if (path > RF90_PATH_D) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, @@ -417,23 +275,24 @@ static void phy_set_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, break; default: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Invalid RateSection %d in Band 2.4G, Rf Path" - " %d, %dTx in PHY_SetTxPowerByRateBase()\n", - rate_section, path, txnum); + "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_SetTxPowerByRateBase()\n", + rate_section, path, txnum); break; }; } else { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Invalid Band %d in PHY_SetTxPowerByRateBase()\n", - band); + band); } + } -static u8 phy_get_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, u8 path, - u8 txnum, u8 rate_section) +static u8 _rtl8723be_phy_get_txpower_by_rate_base(struct ieee80211_hw *hw, + u8 band, u8 path, u8 txnum, + u8 rate_section) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; u8 value = 0; if (path > RF90_PATH_D) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, @@ -458,15 +317,14 @@ static u8 phy_get_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, u8 path, break; default: RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Invalid RateSection %d in Band 2.4G, Rf Path" - " %d, %dTx in PHY_GetTxPowerByRateBase()\n", - rate_section, path, txnum); + "Invalid RateSection %d in Band 2.4G, Rf Path %d, %dTx in PHY_GetTxPowerByRateBase()\n", + rate_section, path, txnum); break; }; } else { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Invalid Band %d in PHY_GetTxPowerByRateBase()\n", - band); + band); } return value; @@ -475,45 +333,51 @@ static u8 phy_get_txpwr_by_rate_base(struct ieee80211_hw *hw, u8 band, u8 path, static void _rtl8723be_phy_store_txpower_by_rate_base(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - u16 raw_value = 0; + struct rtl_phy *rtlphy = &rtlpriv->phy; + u16 rawvalue = 0; u8 base = 0, path = 0; for (path = RF90_PATH_A; path <= RF90_PATH_B; ++path) { if (path == RF90_PATH_A) { - raw_value = (u16) (rtlphy->tx_power_by_rate_offset + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset [BAND_ON_2_4G][path][RF_1TX][3] >> 24) & 0xFF; - base = (raw_value >> 4) * 10 + (raw_value & 0xF); - phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, CCK, - RF_1TX, base); + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, + BAND_ON_2_4G, path, CCK, RF_1TX, base); } else if (path == RF90_PATH_B) { - raw_value = (u16) (rtlphy->tx_power_by_rate_offset + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset [BAND_ON_2_4G][path][RF_1TX][3] >> 0) & 0xFF; - base = (raw_value >> 4) * 10 + (raw_value & 0xF); - phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, - CCK, RF_1TX, base); + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, + BAND_ON_2_4G, + path, CCK, + RF_1TX, base); } - raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [path][RF_1TX][1] >> 24) & 0xFF; - base = (raw_value >> 4) * 10 + (raw_value & 0xF); - phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, OFDM, RF_1TX, - base); - - raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [path][RF_1TX][5] >> 24) & 0xFF; - base = (raw_value >> 4) * 10 + (raw_value & 0xF); - phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, HT_MCS0_MCS7, - RF_1TX, base); - - raw_value = (u16) (rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [path][RF_2TX][7] >> 24) & 0xFF; - base = (raw_value >> 4) * 10 + (raw_value & 0xF); - phy_set_txpwr_by_rate_base(hw, BAND_ON_2_4G, path, - HT_MCS8_MCS15, RF_2TX, base); + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][1] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, + path, OFDM, RF_1TX, + base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_1TX][5] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, + path, HT_MCS0_MCS7, + RF_1TX, base); + + rawvalue = (u16)(rtlphy->tx_power_by_rate_offset + [BAND_ON_2_4G][path][RF_2TX][7] >> 24) & 0xFF; + base = (rawvalue >> 4) * 10 + (rawvalue & 0xF); + _rtl8723be_phy_set_txpower_by_rate_base(hw, BAND_ON_2_4G, + path, HT_MCS8_MCS15, + RF_2TX, base); } } -static void phy_conv_dbm_to_rel(u32 *data, u8 start, u8 end, u8 base_val) +static void _phy_convert_txpower_dbm_to_relative_value(u32 *data, u8 start, + u8 end, u8 base_val) { char i = 0; u8 temp_value = 0; @@ -522,15 +386,15 @@ static void phy_conv_dbm_to_rel(u32 *data, u8 start, u8 end, u8 base_val) for (i = 3; i >= 0; --i) { if (i >= start && i <= end) { /* Get the exact value */ - temp_value = (u8) (*data >> (i * 8)) & 0xF; - temp_value += ((u8) ((*data >> (i*8 + 4)) & 0xF)) * 10; + temp_value = (u8)(*data >> (i * 8)) & 0xF; + temp_value += ((u8)((*data >> (i*8 + 4)) & 0xF)) * 10; /* Change the value to a relative value */ temp_value = (temp_value > base_val) ? temp_value - base_val : base_val - temp_value; } else { - temp_value = (u8) (*data >> (i * 8)) & 0xFF; + temp_value = (u8)(*data >> (i * 8)) & 0xFF; } temp_data <<= 8; temp_data |= temp_value; @@ -538,56 +402,65 @@ static void phy_conv_dbm_to_rel(u32 *data, u8 start, u8 end, u8 base_val) *data = temp_data; } -static void conv_dbm_to_rel(struct ieee80211_hw *hw) +static void _rtl8723be_phy_convert_txpower_dbm_to_relative_value( + struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; u8 base = 0, rfpath = RF90_PATH_A; - base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath, - RF_1TX, CCK); - phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [rfpath][RF_1TX][2]), 1, 1, base); - phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [rfpath][RF_1TX][3]), 1, 3, base); - - base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath, - RF_1TX, OFDM); - phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [rfpath][RF_1TX][0]), 0, 3, base); - phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [rfpath][RF_1TX][1]), 0, 3, base); - - base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath, - RF_1TX, HT_MCS0_MCS7); - phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [rfpath][RF_1TX][4]), 0, 3, base); - phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [rfpath][RF_1TX][5]), 0, 3, base); - - base = phy_get_txpwr_by_rate_base(hw, BAND_ON_2_4G, rfpath, - RF_2TX, HT_MCS8_MCS15); - phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [rfpath][RF_2TX][6]), 0, 3, base); - - phy_conv_dbm_to_rel(&(rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G] - [rfpath][RF_2TX][7]), 0, 3, base); + base = _rtl8723be_phy_get_txpower_by_rate_base(hw, + BAND_ON_2_4G, rfpath, RF_1TX, CCK); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][2], + 1, 1, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][3], + 1, 3, base); + + base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, rfpath, + RF_1TX, OFDM); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][0], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][1], + 0, 3, base); + + base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, + rfpath, RF_1TX, HT_MCS0_MCS7); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][4], + 0, 3, base); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_1TX][5], + 0, 3, base); + + base = _rtl8723be_phy_get_txpower_by_rate_base(hw, BAND_ON_2_4G, + rfpath, RF_2TX, + HT_MCS8_MCS15); + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][6], + 0, 3, base); + + _phy_convert_txpower_dbm_to_relative_value( + &rtlphy->tx_power_by_rate_offset[BAND_ON_2_4G][rfpath][RF_2TX][7], + 0, 3, base); RT_TRACE(rtlpriv, COMP_POWER, DBG_TRACE, - "<=== conv_dbm_to_rel()\n"); + "<===_rtl8723be_phy_convert_txpower_dbm_to_relative_value()\n"); } -static void _rtl8723be_phy_txpower_by_rate_configuration( - struct ieee80211_hw *hw) +static void phy_txpower_by_rate_config(struct ieee80211_hw *hw) { _rtl8723be_phy_store_txpower_by_rate_base(hw); - conv_dbm_to_rel(hw); + _rtl8723be_phy_convert_txpower_dbm_to_relative_value(hw); } static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); bool rtstatus; @@ -603,7 +476,7 @@ static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw) rtstatus = _rtl8723be_phy_config_bb_with_pgheaderfile(hw, BASEBAND_CONFIG_PHY_REG); } - _rtl8723be_phy_txpower_by_rate_configuration(hw); + phy_txpower_by_rate_config(hw); if (!rtstatus) { RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "BB_PG Reg Fail!!"); return false; @@ -614,39 +487,237 @@ static bool _rtl8723be_phy_bb8723b_config_parafile(struct ieee80211_hw *hw) RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, "AGC Table Fail\n"); return false; } - rtlphy->cck_high_power = (bool) (rtl_get_bbreg(hw, - RFPGA0_XA_HSSIPARAMETER2, - 0x200)); + rtlphy->cck_high_power = (bool)(rtl_get_bbreg(hw, + RFPGA0_XA_HSSIPARAMETER2, + 0x200)); return true; } +static bool _rtl8723be_phy_config_mac_with_headerfile(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 i; + u32 arraylength; + u32 *ptrarray; + + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, "Read rtl8723beMACPHY_Array\n"); + arraylength = RTL8723BEMAC_1T_ARRAYLEN; + ptrarray = RTL8723BEMAC_1T_ARRAY; + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Img:RTL8723bEMAC_1T_ARRAY LEN %d\n", arraylength); + for (i = 0; i < arraylength; i = i + 2) + rtl_write_byte(rtlpriv, ptrarray[i], (u8)ptrarray[i + 1]); + return true; +} + +static bool _rtl8723be_phy_config_bb_with_headerfile(struct ieee80211_hw *hw, + u8 configtype) +{ + #define READ_NEXT_PAIR(v1, v2, i) \ + do { \ + i += 2; \ + v1 = array_table[i];\ + v2 = array_table[i+1]; \ + } while (0) + + int i; + u32 *array_table; + u16 arraylen; + struct rtl_priv *rtlpriv = rtl_priv(hw); + u32 v1 = 0, v2 = 0; + + if (configtype == BASEBAND_CONFIG_PHY_REG) { + arraylen = RTL8723BEPHY_REG_1TARRAYLEN; + array_table = RTL8723BEPHY_REG_1TARRAY; + + for (i = 0; i < arraylen; i = i + 2) { + v1 = array_table[i]; + v2 = array_table[i+1]; + if (v1 < 0xcdcdcdcd) { + _rtl8723be_config_bb_reg(hw, v1, v2); + } else {/*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= arraylen - 2) + break; + + if (!_rtl8723be_check_condition(hw, + array_table[i])) { + /*Discard the following + *(offset, data) pairs + */ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && + i < arraylen - 2) { + READ_NEXT_PAIR(v1, v2, i); + } + i -= 2; /* prevent from for-loop += 2*/ + /*Configure matched pairs and + *skip to end of if-else. + */ + } else { + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && + i < arraylen - 2) { + _rtl8723be_config_bb_reg(hw, + v1, v2); + READ_NEXT_PAIR(v1, v2, i); + } + + while (v2 != 0xDEAD && i < arraylen - 2) + READ_NEXT_PAIR(v1, v2, i); + } + } + } + } else if (configtype == BASEBAND_CONFIG_AGC_TAB) { + arraylen = RTL8723BEAGCTAB_1TARRAYLEN; + array_table = RTL8723BEAGCTAB_1TARRAY; + + for (i = 0; i < arraylen; i = i + 2) { + v1 = array_table[i]; + v2 = array_table[i+1]; + if (v1 < 0xCDCDCDCD) { + rtl_set_bbreg(hw, array_table[i], + MASKDWORD, + array_table[i + 1]); + udelay(1); + continue; + } else {/*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= arraylen - 2) + break; + + if (!_rtl8723be_check_condition(hw, + array_table[i])) { + /*Discard the following + *(offset, data) pairs + */ + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && + i < arraylen - 2) { + READ_NEXT_PAIR(v1, v2, i); + } + i -= 2; /* prevent from for-loop += 2*/ + /*Configure matched pairs and + *skip to end of if-else. + */ + } else { + READ_NEXT_PAIR(v1, v2, i); + while (v2 != 0xDEAD && + v2 != 0xCDEF && + v2 != 0xCDCD && + i < arraylen - 2) { + rtl_set_bbreg(hw, array_table[i], + MASKDWORD, + array_table[i + 1]); + udelay(1); + READ_NEXT_PAIR(v1, v2, i); + } + + while (v2 != 0xDEAD && i < arraylen - 2) + READ_NEXT_PAIR(v1, v2, i); + } + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, + "The agctab_array_table[0] is %x Rtl818EEPHY_REGArray[1] is %x\n", + array_table[i], array_table[i + 1]); + } + } + return true; +} + +static u8 _rtl8723be_get_rate_section_index(u32 regaddr) +{ + u8 index = 0; + + switch (regaddr) { + case RTXAGC_A_RATE18_06: + index = 0; + break; + case RTXAGC_A_RATE54_24: + index = 1; + break; + case RTXAGC_A_CCK1_MCS32: + index = 2; + break; + case RTXAGC_B_CCK11_A_CCK2_11: + index = 3; + break; + case RTXAGC_A_MCS03_MCS00: + index = 4; + break; + case RTXAGC_A_MCS07_MCS04: + index = 5; + break; + case RTXAGC_A_MCS11_MCS08: + index = 6; + break; + case RTXAGC_A_MCS15_MCS12: + index = 7; + break; + case RTXAGC_B_RATE18_06: + index = 0; + break; + case RTXAGC_B_RATE54_24: + index = 1; + break; + case RTXAGC_B_CCK1_55_MCS32: + index = 2; + break; + case RTXAGC_B_MCS03_MCS00: + index = 4; + break; + case RTXAGC_B_MCS07_MCS04: + index = 5; + break; + case RTXAGC_B_MCS11_MCS08: + index = 6; + break; + case RTXAGC_B_MCS15_MCS12: + index = 7; + break; + default: + regaddr &= 0xFFF; + if (regaddr >= 0xC20 && regaddr <= 0xC4C) + index = (u8)((regaddr - 0xC20) / 4); + else if (regaddr >= 0xE20 && regaddr <= 0xE4C) + index = (u8)((regaddr - 0xE20) / 4); + break; + }; + return index; +} + static void _rtl8723be_store_tx_power_by_rate(struct ieee80211_hw *hw, u32 band, u32 rfpath, u32 txnum, u32 regaddr, u32 bitmask, u32 data) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; u8 rate_section = _rtl8723be_get_rate_section_index(regaddr); if (band != BAND_ON_2_4G && band != BAND_ON_5G) { - RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR, - "Invalid Band %d\n", band); + RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid Band %d\n", band); return; } - - if (rfpath > TX_PWR_BY_RATE_NUM_RF) { - RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR, + if (rfpath > MAX_RF_PATH - 1) { + RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid RfPath %d\n", rfpath); return; } - if (txnum > TX_PWR_BY_RATE_NUM_RF) { - RT_TRACE(rtlpriv, COMP_POWER, PHY_TXPWR, - "Invalid TxNum %d\n", txnum); + if (txnum > MAX_RF_PATH - 1) { + RT_TRACE(rtlpriv, FPHY, PHY_TXPWR, "Invalid TxNum %d\n", txnum); return; } + rtlphy->tx_power_by_rate_offset[band][rfpath][txnum][rate_section] = data; + } static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, @@ -678,21 +749,6 @@ static bool _rtl8723be_phy_config_bb_with_pgheaderfile(struct ieee80211_hw *hw, _rtl8723be_store_tx_power_by_rate(hw, v1, v2, v3, v4, v5, v6); continue; - } else { - /*don't need the hw_body*/ - if (!_rtl8723be_check_condition(hw, - phy_regarray_table_pg[i])) { - i += 2; /* skip the pair of expression*/ - v1 = phy_regarray_table_pg[i]; - v2 = phy_regarray_table_pg[i+1]; - v3 = phy_regarray_table_pg[i+2]; - while (v2 != 0xDEAD) { - i += 3; - v1 = phy_regarray_table_pg[i]; - v2 = phy_regarray_table_pg[i+1]; - v3 = phy_regarray_table_pg[i+2]; - } - } } } } else { @@ -733,22 +789,27 @@ bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, v2 = radioa_array_table[i+1]; if (v1 < 0xcdcdcdcd) { _rtl8723be_config_rf_radio_a(hw, v1, v2); - } else { /*This line is the start line of branch.*/ + } else {/*This line is the start line of branch.*/ + /* to protect READ_NEXT_PAIR not overrun */ + if (i >= radioa_arraylen - 2) + break; + if (!_rtl8723be_check_condition(hw, radioa_array_table[i])) { - /* Discard the following - * (offset, data) pairs + /*Discard the following + *(offset, data) pairs */ READ_NEXT_RF_PAIR(v1, v2, i); while (v2 != 0xDEAD && v2 != 0xCDEF && v2 != 0xCDCD && - i < radioa_arraylen - 2) + i < radioa_arraylen - 2) { READ_NEXT_RF_PAIR(v1, v2, i); + } i -= 2; /* prevent from for-loop += 2*/ } else { - /* Configure matched pairs - * and skip to end of if-else. + /*Configure matched pairs + *and skip to end of if-else. */ READ_NEXT_RF_PAIR(v1, v2, i); while (v2 != 0xDEAD && @@ -770,18 +831,12 @@ bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, if (rtlhal->oem_id == RT_CID_819X_HP) _rtl8723be_config_rf_radio_a(hw, 0x52, 0x7E4BD); - break; case RF90_PATH_B: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; case RF90_PATH_C: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); break; case RF90_PATH_D: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, "switch case not process\n"); break; } @@ -791,26 +846,25 @@ bool rtl8723be_phy_config_rf_with_headerfile(struct ieee80211_hw *hw, void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; rtlphy->default_initialgain[0] = - (u8) rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); + (u8)rtl_get_bbreg(hw, ROFDM0_XAAGCCORE1, MASKBYTE0); rtlphy->default_initialgain[1] = - (u8) rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); + (u8)rtl_get_bbreg(hw, ROFDM0_XBAGCCORE1, MASKBYTE0); rtlphy->default_initialgain[2] = - (u8) rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); + (u8)rtl_get_bbreg(hw, ROFDM0_XCAGCCORE1, MASKBYTE0); rtlphy->default_initialgain[3] = - (u8) rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); + (u8)rtl_get_bbreg(hw, ROFDM0_XDAGCCORE1, MASKBYTE0); RT_TRACE(rtlpriv, COMP_INIT, DBG_TRACE, - "Default initial gain (c50 = 0x%x, " - "c58 = 0x%x, c60 = 0x%x, c68 = 0x%x\n", - rtlphy->default_initialgain[0], - rtlphy->default_initialgain[1], - rtlphy->default_initialgain[2], - rtlphy->default_initialgain[3]); - - rtlphy->framesync = (u8) rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, + "Default initial gain (c50=0x%x, c58=0x%x, c60=0x%x, c68=0x%x\n", + rtlphy->default_initialgain[0], + rtlphy->default_initialgain[1], + rtlphy->default_initialgain[2], + rtlphy->default_initialgain[3]); + + rtlphy->framesync = (u8)rtl_get_bbreg(hw, ROFDM0_RXDETECTOR3, MASKBYTE0); rtlphy->framesync_c34 = rtl_get_bbreg(hw, ROFDM0_RXDETECTOR2, MASKDWORD); @@ -823,7 +877,7 @@ void rtl8723be_phy_get_hw_reg_originalvalue(struct ieee80211_hw *hw) void rtl8723be_phy_get_txpower_level(struct ieee80211_hw *hw, long *powerlevel) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; u8 txpwr_level; long txpwr_dbm; @@ -854,6 +908,7 @@ static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path, case DESC92C_RATE1M: rate_section = 2; break; + case DESC92C_RATE2M: case DESC92C_RATE5_5M: if (path == RF90_PATH_A) @@ -861,49 +916,58 @@ static u8 _rtl8723be_phy_get_ratesection_intxpower_byrate(enum radio_path path, else if (path == RF90_PATH_B) rate_section = 2; break; + case DESC92C_RATE11M: rate_section = 3; break; + case DESC92C_RATE6M: case DESC92C_RATE9M: case DESC92C_RATE12M: case DESC92C_RATE18M: rate_section = 0; break; + case DESC92C_RATE24M: case DESC92C_RATE36M: case DESC92C_RATE48M: case DESC92C_RATE54M: rate_section = 1; break; + case DESC92C_RATEMCS0: case DESC92C_RATEMCS1: case DESC92C_RATEMCS2: case DESC92C_RATEMCS3: rate_section = 4; break; + case DESC92C_RATEMCS4: case DESC92C_RATEMCS5: case DESC92C_RATEMCS6: case DESC92C_RATEMCS7: rate_section = 5; break; + case DESC92C_RATEMCS8: case DESC92C_RATEMCS9: case DESC92C_RATEMCS10: case DESC92C_RATEMCS11: rate_section = 6; break; + case DESC92C_RATEMCS12: case DESC92C_RATEMCS13: case DESC92C_RATEMCS14: case DESC92C_RATEMCS15: rate_section = 7; break; + default: RT_ASSERT(true, "Rate_Section is Illegal\n"); break; } + return rate_section; } @@ -912,7 +976,7 @@ static u8 _rtl8723be_get_txpower_by_rate(struct ieee80211_hw *hw, enum radio_path rfpath, u8 rate) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; u8 shift = 0, rate_section, tx_num; char tx_pwr_diff = 0; @@ -988,7 +1052,7 @@ static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path, RT_TRACE(rtlpriv, COMP_POWER_TRACKING, DBG_LOUD, "Illegal channel!\n"); } - if (RTL8723E_RX_HAL_IS_CCK_RATE(rate)) + if (RX_HAL_IS_CCK_RATE(rate)) txpower = rtlefuse->txpwrlevel_cck[path][index]; else if (DESC92C_RATE6M <= rate) txpower = rtlefuse->txpwrlevel_ht40_1s[path][index]; @@ -997,7 +1061,7 @@ static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path, "invalid rate\n"); if (DESC92C_RATE6M <= rate && rate <= DESC92C_RATE54M && - !RTL8723E_RX_HAL_IS_CCK_RATE(rate)) + !RX_HAL_IS_CCK_RATE(rate)) txpower += rtlefuse->txpwr_legacyhtdiff[0][TX_1S]; if (bandwidth == HT_CHANNEL_WIDTH_20) { @@ -1011,6 +1075,7 @@ static u8 _rtl8723be_get_txpower_index(struct ieee80211_hw *hw, u8 path, if (DESC92C_RATEMCS8 <= rate && rate <= DESC92C_RATEMCS15) txpower += rtlefuse->txpwr_ht40diff[0][TX_2S]; } + if (rtlefuse->eeprom_regulatory != 2) power_diff_byrate = _rtl8723be_get_txpower_by_rate(hw, BAND_ON_2_4G, @@ -1046,6 +1111,7 @@ static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw, rtl8723_phy_set_bb_reg(hw, RTXAGC_B_CCK11_A_CCK2_11, MASKBYTE3, power_index); break; + case DESC92C_RATE6M: rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, MASKBYTE0, power_index); @@ -1062,6 +1128,7 @@ static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw, rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE18_06, MASKBYTE3, power_index); break; + case DESC92C_RATE24M: rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, MASKBYTE0, power_index); @@ -1078,6 +1145,7 @@ static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw, rtl8723_phy_set_bb_reg(hw, RTXAGC_A_RATE54_24, MASKBYTE3, power_index); break; + case DESC92C_RATEMCS0: rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE0, power_index); @@ -1094,6 +1162,7 @@ static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw, rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS03_MCS00, MASKBYTE3, power_index); break; + case DESC92C_RATEMCS4: rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE0, power_index); @@ -1110,6 +1179,7 @@ static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw, rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS07_MCS04, MASKBYTE3, power_index); break; + case DESC92C_RATEMCS8: rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE0, power_index); @@ -1126,9 +1196,9 @@ static void _rtl8723be_phy_set_txpower_index(struct ieee80211_hw *hw, rtl8723_phy_set_bb_reg(hw, RTXAGC_A_MCS11_MCS08, MASKBYTE3, power_index); break; + default: - RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, - "Invalid Rate!!\n"); + RT_TRACE(rtlpriv, COMP_POWER, DBG_LOUD, "Invalid Rate!!\n"); break; } } else { @@ -1192,10 +1262,11 @@ void rtl8723be_phy_scan_operation_backup(struct ieee80211_hw *hw, u8 operation) if (!is_hal_stop(rtlhal)) { switch (operation) { - case SCAN_OPT_BACKUP: - iotype = IO_CMD_PAUSE_DM_BY_SCAN; + case SCAN_OPT_BACKUP_BAND0: + iotype = IO_CMD_PAUSE_BAND0_DM_BY_SCAN; rtlpriv->cfg->ops->set_hw_reg(hw, HW_VAR_IO_CMD, (u8 *)&iotype); + break; case SCAN_OPT_RESTORE: iotype = IO_CMD_RESUME_DM_BY_SCAN; @@ -1214,15 +1285,15 @@ void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; struct rtl_mac *mac = rtl_mac(rtl_priv(hw)); u8 reg_bw_opmode; u8 reg_prsr_rsc; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, "Switch to %s bandwidth\n", - rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? - "20MHz" : "40MHz"); + rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20 ? + "20MHz" : "40MHz"); if (is_hal_stop(rtlhal)) { rtlphy->set_bwmode_inprogress = false; @@ -1254,13 +1325,17 @@ void rtl8723be_phy_set_bw_mode_callback(struct ieee80211_hw *hw) case HT_CHANNEL_WIDTH_20: rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x0); rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x0); + /* rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 1);*/ break; case HT_CHANNEL_WIDTH_20_40: rtl_set_bbreg(hw, RFPGA0_RFMOD, BRFMOD, 0x1); rtl_set_bbreg(hw, RFPGA1_RFMOD, BRFMOD, 0x1); + rtl_set_bbreg(hw, RCCK0_SYSTEM, BCCK_SIDEBAND, (mac->cur_40_prime_sc >> 1)); rtl_set_bbreg(hw, ROFDM1_LSTF, 0xC00, mac->cur_40_prime_sc); + /*rtl_set_bbreg(hw, RFPGA0_ANALOGPARAMETER2, BIT(10), 0);*/ + rtl_set_bbreg(hw, 0x818, (BIT(26) | BIT(27)), (mac->cur_40_prime_sc == HAL_PRIME_CHNL_OFFSET_LOWER) ? 2 : 1); @@ -1279,7 +1354,7 @@ void rtl8723be_phy_set_bw_mode(struct ieee80211_hw *hw, enum nl80211_channel_type ch_type) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); u8 tmp_bw = rtlphy->current_chan_bw; @@ -1300,7 +1375,7 @@ void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; u32 delay; RT_TRACE(rtlpriv, COMP_SCAN, DBG_TRACE, @@ -1310,11 +1385,11 @@ void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw) do { if (!rtlphy->sw_chnl_inprogress) break; - if (!rtl8723be_phy_sw_chn_step_by_step(hw, - rtlphy->current_channel, - &rtlphy->sw_chnl_stage, - &rtlphy->sw_chnl_step, - &delay)) { + if (!_rtl8723be_phy_sw_chnl_step_by_step(hw, + rtlphy->current_channel, + &rtlphy->sw_chnl_stage, + &rtlphy->sw_chnl_step, + &delay)) { if (delay > 0) mdelay(delay); else @@ -1330,7 +1405,7 @@ void rtl8723be_phy_sw_chnl_callback(struct ieee80211_hw *hw) u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); if (rtlphy->sw_chnl_inprogress) @@ -1345,25 +1420,23 @@ u8 rtl8723be_phy_sw_chnl(struct ieee80211_hw *hw) if (!(is_hal_stop(rtlhal)) && !(RT_CANNOT_IO(hw))) { rtl8723be_phy_sw_chnl_callback(hw); RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - "sw_chnl_inprogress false schdule " - "workitem current channel %d\n", - rtlphy->current_channel); + "sw_chnl_inprogress false schdule workitem current channel %d\n", + rtlphy->current_channel); rtlphy->sw_chnl_inprogress = false; } else { RT_TRACE(rtlpriv, COMP_CHAN, DBG_LOUD, - "sw_chnl_inprogress false driver sleep or" - " unload\n"); + "sw_chnl_inprogress false driver sleep or unload\n"); rtlphy->sw_chnl_inprogress = false; } return 1; } -static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw, - u8 channel, u8 *stage, - u8 *step, u32 *delay) +static bool _rtl8723be_phy_sw_chnl_step_by_step(struct ieee80211_hw *hw, + u8 channel, u8 *stage, + u8 *step, u32 *delay) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; struct swchnlcmd precommoncmd[MAX_PRECMD_CNT]; u32 precommoncmdcnt; struct swchnlcmd postcommoncmd[MAX_POSTCMD_CNT]; @@ -1381,10 +1454,13 @@ static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw, 0, 0, 0); rtl8723_phy_set_sw_chnl_cmdarray(precommoncmd, precommoncmdcnt++, MAX_PRECMD_CNT, CMDID_END, 0, 0, 0); + postcommoncmdcnt = 0; + rtl8723_phy_set_sw_chnl_cmdarray(postcommoncmd, postcommoncmdcnt++, MAX_POSTCMD_CNT, CMDID_END, - 0, 0, 0); + 0, 0, 0); + rfdependcmdcnt = 0; RT_ASSERT((channel >= 1 && channel <= 14), @@ -1397,7 +1473,7 @@ static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw, rtl8723_phy_set_sw_chnl_cmdarray(rfdependcmd, rfdependcmdcnt++, MAX_RFDEPENDCMD_CNT, - CMDID_END, 0, 0, 0); + CMDID_END, 0, 0, 0); do { switch (*stage) { @@ -1410,6 +1486,10 @@ static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw, case 2: currentcmd = &postcommoncmd[*step]; break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + "Invalid 'stage' = %d, Check it!\n", *stage); + return true; } if (currentcmd->cmdid == CMDID_END) { @@ -1432,11 +1512,11 @@ static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw, break; case CMDID_WRITEPORT_USHORT: rtl_write_word(rtlpriv, currentcmd->para1, - (u16) currentcmd->para2); + (u16)currentcmd->para2); break; case CMDID_WRITEPORT_UCHAR: rtl_write_byte(rtlpriv, currentcmd->para1, - (u8) currentcmd->para2); + (u8)currentcmd->para2); break; case CMDID_RF_WRITEREG: for (rfpath = 0; rfpath < num_total_rfpath; rfpath++) { @@ -1451,7 +1531,7 @@ static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw, } break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, "switch case not process\n"); break; } @@ -1464,54 +1544,515 @@ static bool rtl8723be_phy_sw_chn_step_by_step(struct ieee80211_hw *hw, return false; } -static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw, bool config_pathb) +static u8 _rtl8723be_phy_path_a_iqk(struct ieee80211_hw *hw) { - u32 reg_eac, reg_e94, reg_e9c, reg_ea4; + u32 reg_eac, reg_e94, reg_e9c, tmp; u8 result = 0x00; - rtl_set_bbreg(hw, 0xe30, MASKDWORD, 0x10008c1c); - rtl_set_bbreg(hw, 0xe34, MASKDWORD, 0x30008c1c); - rtl_set_bbreg(hw, 0xe38, MASKDWORD, 0x8214032a); - rtl_set_bbreg(hw, 0xe3c, MASKDWORD, 0x28160000); - - rtl_set_bbreg(hw, 0xe4c, MASKDWORD, 0x00462911); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf9000000); - rtl_set_bbreg(hw, 0xe48, MASKDWORD, 0xf8000000); + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* switch to path A */ + rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000); + /* enable path A PA in TXIQK mode */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x20000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0003f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xc7f87); + + /* 1. TX IQK */ + /* path-A IQK setting */ + /* IQK setting */ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + /* path-A IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28160000); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path A LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); mdelay(IQK_DELAY_TIME); + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* Check failed */ reg_eac = rtl_get_bbreg(hw, 0xeac, MASKDWORD); reg_e94 = rtl_get_bbreg(hw, 0xe94, MASKDWORD); reg_e9c = rtl_get_bbreg(hw, 0xe9c, MASKDWORD); - reg_ea4 = rtl_get_bbreg(hw, 0xea4, MASKDWORD); if (!(reg_eac & BIT(28)) && (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + + /* Allen 20131125 */ + tmp = (reg_e9c & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && + (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + return result; } -static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8], - u8 c1, u8 c2) +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl8723be_phy_path_a_rx_iqk(struct ieee80211_hw *hw) { - u32 i, j, diff, simularity_bitmap, bound; - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); + u32 reg_eac, reg_e94, reg_e9c, reg_ea4, u32tmp, tmp; + u8 result = 0x00; + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* switch to path A */ + rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000000); + + /* 1 Get TXIMR setting */ + /* modify RXIQK mode table */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); + /* LNA2 off, PA on for Dcut */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7fb7); + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* IQK setting */ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /* path-A IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); + + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path A LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + + /* Allen 20131125 */ + tmp = (reg_e9c & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && + (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; + + u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) | + ((reg_e9c & 0x3FF0000) >> 16); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp); + + /* 1 RX IQK */ + /* modify RXIQK mode table */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); + /* LAN2 on, PA off for Dcut */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77); + + /* PA, PAD setting */ + rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0xf80); + rtl_set_rfreg(hw, RF90_PATH_A, 0x55, RFREG_OFFSET_MASK, 0x4021f); + + /* IQK setting */ + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /* path-A IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1); + + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path A LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, 0xdf, RFREG_OFFSET_MASK, 0x780); + + /* Allen 20131125 */ + tmp = (reg_eac & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + /* if Tx is OK, check whether Rx is OK */ + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) && + (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x02; + + return result; +} + +static u8 _rtl8723be_phy_path_b_iqk(struct ieee80211_hw *hw) +{ + u32 reg_eac, reg_e94, reg_e9c, tmp; + u8 result = 0x00; + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* switch to path B */ + rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280); + + /* enable path B PA in TXIQK mode */ + rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020); + rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x40fc1); + + /* 1 Tx IQK */ + /* IQK setting */ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + /* path-A IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x821403ea); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x00462911); + + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path B LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else + return result; + + /* Allen 20131125 */ + tmp = (reg_e9c & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && + (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x01; + else + return result; + + return result; +} + +/* bit0 = 1 => Tx OK, bit1 = 1 => Rx OK */ +static u8 _rtl8723be_phy_path_b_rx_iqk(struct ieee80211_hw *hw) +{ + u32 reg_e94, reg_e9c, reg_ea4, reg_eac, u32tmp, tmp; + u8 result = 0x00; + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* switch to path B */ + rtl_set_bbreg(hw, 0x948, MASKDWORD, 0x00000280); + + /* 1 Get TXIMR setting */ + /* modify RXIQK mode table */ + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, RFREG_OFFSET_MASK, 0x800a0); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7ff7); + + /* open PA S1 & SMIXER */ + rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020); + rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fed); + + /* IQK setting */ + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, 0x01007c00); + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /* path-B IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82160ff0); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x28110000); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a911); + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path B TXIQK @ RXIQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_e94 = rtl_get_bbreg(hw, RTX_POWER_BEFORE_IQK_A, MASKDWORD); + reg_e9c = rtl_get_bbreg(hw, RTX_POWER_AFTER_IQK_A, MASKDWORD); + + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) != 0x142) && + (((reg_e9c & 0x03FF0000) >> 16) != 0x42)) + result |= 0x01; + else /* if Tx not OK, ignore Rx */ + return result; - u8 final_candidate[2] = { 0xFF, 0xFF }; - bool bresult = true, is2t = IS_92C_SERIAL(rtlhal->version); + /* Allen 20131125 */ + tmp = (reg_e9c & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; - if (is2t) - bound = 8; + if (!(reg_eac & BIT(28)) && + (((reg_e94 & 0x03FF0000) >> 16) < 0x110) && + (((reg_e94 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x01; + else + return result; + + u32tmp = 0x80007C00 | (reg_e94 & 0x3FF0000) | + ((reg_e9c & 0x3FF0000) >> 16); + rtl_set_bbreg(hw, RTX_IQK, MASKDWORD, u32tmp); + + /* 1 RX IQK */ + + /* <20121009, Kordan> RF Mode = 3 */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x1); + rtl_set_rfreg(hw, RF90_PATH_A, RF_RCK_OS, RFREG_OFFSET_MASK, 0x30000); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G1, RFREG_OFFSET_MASK, 0x0001f); + rtl_set_rfreg(hw, RF90_PATH_A, RF_TXPA_G2, RFREG_OFFSET_MASK, 0xf7d77); + rtl_set_rfreg(hw, RF90_PATH_A, RF_WE_LUT, 0x80000, 0x0); + + /* open PA S1 & close SMIXER */ + rtl_set_rfreg(hw, RF90_PATH_A, 0xed, RFREG_OFFSET_MASK, 0x00020); + rtl_set_rfreg(hw, RF90_PATH_A, 0x43, RFREG_OFFSET_MASK, 0x60fbd); + + /* IQK setting */ + rtl_set_bbreg(hw, RRX_IQK, MASKDWORD, 0x01004800); + + /* path-B IQK setting */ + rtl_set_bbreg(hw, RTX_IQK_TONE_A, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_A, MASKDWORD, 0x18008c1c); + rtl_set_bbreg(hw, RTX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + rtl_set_bbreg(hw, RRX_IQK_TONE_B, MASKDWORD, 0x38008c1c); + + rtl_set_bbreg(hw, RTX_IQK_PI_A, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_A, MASKDWORD, 0x2816001f); + rtl_set_bbreg(hw, RTX_IQK_PI_B, MASKDWORD, 0x82110000); + rtl_set_bbreg(hw, RRX_IQK_PI_B, MASKDWORD, 0x28110000); + + /* LO calibration setting */ + rtl_set_bbreg(hw, RIQK_AGC_RSP, MASKDWORD, 0x0046a8d1); + /* enter IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x80800000); + + /* One shot, path B LOK & IQK */ + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf9000000); + rtl_set_bbreg(hw, RIQK_AGC_PTS, MASKDWORD, 0xf8000000); + + mdelay(IQK_DELAY_TIME); + + /* leave IQK mode */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0x00000000); + /* Check failed */ + reg_eac = rtl_get_bbreg(hw, RRX_POWER_AFTER_IQK_A_2, MASKDWORD); + reg_ea4 = rtl_get_bbreg(hw, RRX_POWER_BEFORE_IQK_A_2, MASKDWORD); + + /* Allen 20131125 */ + tmp = (reg_eac & 0x03FF0000) >> 16; + if ((tmp & 0x200) > 0) + tmp = 0x400 - tmp; + + /* if Tx is OK, check whether Rx is OK */ + if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) != 0x132) && + (((reg_eac & 0x03FF0000) >> 16) != 0x36)) + result |= 0x02; + else if (!(reg_eac & BIT(27)) && + (((reg_ea4 & 0x03FF0000) >> 16) < 0x110) && + (((reg_ea4 & 0x03FF0000) >> 16) > 0xf0) && + (tmp < 0xf)) + result |= 0x02; else - bound = 4; + return result; + + return result; +} + +static void _rtl8723be_phy_path_b_fill_iqk_matrix(struct ieee80211_hw *hw, + bool b_iqk_ok, + long result[][8], + u8 final_candidate, + bool btxonly) +{ + u32 oldval_1, x, tx1_a, reg; + long y, tx1_c; + + if (final_candidate == 0xFF) { + return; + } else if (b_iqk_ok) { + oldval_1 = (rtl_get_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, + MASKDWORD) >> 22) & 0x3FF; + x = result[final_candidate][4]; + if ((x & 0x00000200) != 0) + x = x | 0xFFFFFC00; + tx1_a = (x * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x3FF, tx1_a); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(27), + ((x * oldval_1 >> 7) & 0x1)); + y = result[final_candidate][5]; + if ((y & 0x00000200) != 0) + y = y | 0xFFFFFC00; + tx1_c = (y * oldval_1) >> 8; + rtl_set_bbreg(hw, ROFDM0_XDTXAFE, 0xF0000000, + ((tx1_c & 0x3C0) >> 6)); + rtl_set_bbreg(hw, ROFDM0_XBTXIQIMBALANCE, 0x003F0000, + (tx1_c & 0x3F)); + rtl_set_bbreg(hw, ROFDM0_ECCATHRESHOLD, BIT(25), + ((y * oldval_1 >> 7) & 0x1)); + if (btxonly) + return; + reg = result[final_candidate][6]; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0x3FF, reg); + reg = result[final_candidate][7] & 0x3F; + rtl_set_bbreg(hw, ROFDM0_XBRXIQIMBALANCE, 0xFC00, reg); + reg = (result[final_candidate][7] >> 6) & 0xF; + /* rtl_set_bbreg(hw, 0xca0, 0xF0000000, reg); */ + } +} + +static bool _rtl8723be_phy_simularity_compare(struct ieee80211_hw *hw, + long result[][8], u8 c1, u8 c2) +{ + u32 i, j, diff, simularity_bitmap, bound = 0; + + u8 final_candidate[2] = {0xFF, 0xFF}; /* for path A and path B */ + bool bresult = true; /* is2t = true*/ + s32 tmp1 = 0, tmp2 = 0; + + bound = 8; simularity_bitmap = 0; for (i = 0; i < bound; i++) { - diff = (result[c1][i] > result[c2][i]) ? - (result[c1][i] - result[c2][i]) : - (result[c2][i] - result[c1][i]); + if ((i == 1) || (i == 3) || (i == 5) || (i == 7)) { + if ((result[c1][i] & 0x00000200) != 0) + tmp1 = result[c1][i] | 0xFFFFFC00; + else + tmp1 = result[c1][i]; + + if ((result[c2][i] & 0x00000200) != 0) + tmp2 = result[c2][i] | 0xFFFFFC00; + else + tmp2 = result[c2][i]; + } else { + tmp1 = result[c1][i]; + tmp2 = result[c2][i]; + } + + diff = (tmp1 > tmp2) ? (tmp1 - tmp2) : (tmp2 - tmp1); if (diff > MAX_TOLERANCE) { if ((i == 2 || i == 6) && !simularity_bitmap) { @@ -1521,9 +2062,8 @@ static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8], final_candidate[(i / 4)] = c1; else simularity_bitmap |= (1 << i); - } else { + } else simularity_bitmap |= (1 << i); - } } } @@ -1537,15 +2077,23 @@ static bool phy_similarity_cmp(struct ieee80211_hw *hw, long result[][8], } } return bresult; - } else if (!(simularity_bitmap & 0x0F)) { - for (i = 0; i < 4; i++) - result[3][i] = result[c1][i]; - return false; - } else if (!(simularity_bitmap & 0xF0) && is2t) { - for (i = 4; i < 8; i++) - result[3][i] = result[c1][i]; - return false; } else { + if (!(simularity_bitmap & 0x03)) { /* path A TX OK */ + for (i = 0; i < 2; i++) + result[3][i] = result[c1][i]; + } + if (!(simularity_bitmap & 0x0c)) { /* path A RX OK */ + for (i = 2; i < 4; i++) + result[3][i] = result[c1][i]; + } + if (!(simularity_bitmap & 0x30)) { /* path B TX OK */ + for (i = 4; i < 6; i++) + result[3][i] = result[c1][i]; + } + if (!(simularity_bitmap & 0xc0)) { /* path B RX OK */ + for (i = 6; i < 8; i++) + result[3][i] = result[c1][i]; + } return false; } } @@ -1554,9 +2102,9 @@ static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, long result[][8], u8 t, bool is2t) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; u32 i; - u8 patha_ok; + u8 patha_ok, pathb_ok; u32 adda_reg[IQK_ADDA_REG_NUM] = { 0x85c, 0xe6c, 0xe70, 0xe74, 0xe78, 0xe7c, 0xe80, 0xe84, @@ -1571,10 +2119,12 @@ static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, ROFDM0_TRXPATHENABLE, ROFDM0_TRMUXPAR, RFPGA0_XCD_RFINTERFACESW, 0xb68, 0xb6c, 0x870, 0x860, - 0x864, 0x800 + 0x864, 0xa04 }; const u32 retrycount = 2; - u32 path_sel_bb, path_sel_rf; + + u32 path_sel_bb;/* path_sel_rf */ + u8 tmp_reg_c50, tmp_reg_c58; tmp_reg_c50 = rtl_get_bbreg(hw, 0xc50, MASKBYTE0); @@ -1591,62 +2141,97 @@ static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, } rtl8723_phy_path_adda_on(hw, adda_reg, true, is2t); if (t == 0) { - rtlphy->rfpi_enable = (u8) rtl_get_bbreg(hw, + rtlphy->rfpi_enable = (u8)rtl_get_bbreg(hw, RFPGA0_XA_HSSIPARAMETER1, BIT(8)); } - if (!rtlphy->rfpi_enable) - rtl8723_phy_pi_mode_switch(hw, true); path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD); - path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); + rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg, + rtlphy->iqk_mac_backup); /*BB Setting*/ - rtl_set_bbreg(hw, 0x800, BIT(24), 0x00); + rtl_set_bbreg(hw, 0xa04, 0x0f000000, 0xf); rtl_set_bbreg(hw, 0xc04, MASKDWORD, 0x03a05600); rtl_set_bbreg(hw, 0xc08, MASKDWORD, 0x000800e4); rtl_set_bbreg(hw, 0x874, MASKDWORD, 0x22204000); - rtl_set_bbreg(hw, 0x870, BIT(10), 0x01); - rtl_set_bbreg(hw, 0x870, BIT(26), 0x01); - rtl_set_bbreg(hw, 0x860, BIT(10), 0x00); - rtl_set_bbreg(hw, 0x864, BIT(10), 0x00); - - if (is2t) - rtl_set_rfreg(hw, RF90_PATH_B, 0x00, MASKDWORD, 0x10000); - rtl8723_phy_mac_setting_calibration(hw, iqk_mac_reg, - rtlphy->iqk_mac_backup); - rtl_set_bbreg(hw, 0xb68, MASKDWORD, 0x0f600000); - - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0x80800000); - rtl_set_bbreg(hw, 0xe40, MASKDWORD, 0x01007c00); - rtl_set_bbreg(hw, 0xe44, MASKDWORD, 0x81004800); + /* path A TX IQK */ for (i = 0; i < retrycount; i++) { - patha_ok = _rtl8723be_phy_path_a_iqk(hw, is2t); + patha_ok = _rtl8723be_phy_path_a_iqk(hw); if (patha_ok == 0x01) { RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Path A Tx IQK Success!!\n"); + "Path A Tx IQK Success!!\n"); result[t][0] = (rtl_get_bbreg(hw, 0xe94, MASKDWORD) & 0x3FF0000) >> 16; result[t][1] = (rtl_get_bbreg(hw, 0xe9c, MASKDWORD) & 0x3FF0000) >> 16; break; + } else { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Path A Tx IQK Fail!!\n"); } } - - if (0 == patha_ok) + /* path A RX IQK */ + for (i = 0; i < retrycount; i++) { + patha_ok = _rtl8723be_phy_path_a_rx_iqk(hw); + if (patha_ok == 0x03) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Path A Rx IQK Success!!\n"); + result[t][2] = (rtl_get_bbreg(hw, 0xea4, MASKDWORD) & + 0x3FF0000) >> 16; + result[t][3] = (rtl_get_bbreg(hw, 0xeac, MASKDWORD) & + 0x3FF0000) >> 16; + break; + } RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, - "Path A IQK Success!!\n"); + "Path A Rx IQK Fail!!\n"); + } + + if (0x00 == patha_ok) + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "Path A IQK Fail!!\n"); + if (is2t) { - rtl8723_phy_path_a_standby(hw); - rtl8723_phy_path_adda_on(hw, adda_reg, false, is2t); + /* path B TX IQK */ + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl8723be_phy_path_b_iqk(hw); + if (pathb_ok == 0x01) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Path B Tx IQK Success!!\n"); + result[t][4] = (rtl_get_bbreg(hw, 0xe94, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][5] = (rtl_get_bbreg(hw, 0xe9c, + MASKDWORD) & + 0x3FF0000) >> 16; + break; + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Path B Tx IQK Fail!!\n"); + } + /* path B RX IQK */ + for (i = 0; i < retrycount; i++) { + pathb_ok = _rtl8723be_phy_path_b_rx_iqk(hw); + if (pathb_ok == 0x03) { + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Path B Rx IQK Success!!\n"); + result[t][6] = (rtl_get_bbreg(hw, 0xea4, + MASKDWORD) & + 0x3FF0000) >> 16; + result[t][7] = (rtl_get_bbreg(hw, 0xeac, + MASKDWORD) & + 0x3FF0000) >> 16; + break; + } + RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, + "Path B Rx IQK Fail!!\n"); + } } - rtl_set_bbreg(hw, 0xe28, MASKDWORD, 0); + /* Back to BB mode, load original value */ + rtl_set_bbreg(hw, RFPGA0_IQK, MASKDWORD, 0); if (t != 0) { - if (!rtlphy->rfpi_enable) - rtl8723_phy_pi_mode_switch(hw, false); rtl8723_phy_reload_adda_registers(hw, adda_reg, rtlphy->adda_backup, 16); rtl8723_phy_reload_mac_registers(hw, iqk_mac_reg, @@ -1656,7 +2241,7 @@ static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, IQK_BB_REG_NUM); rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb); - rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf); + /*rtl_set_rfreg(hw, RF90_PATH_B, 0xb0, 0xfffff, path_sel_rf);*/ rtl_set_bbreg(hw, 0xc50, MASKBYTE0, 0x50); rtl_set_bbreg(hw, 0xc50, MASKBYTE0, tmp_reg_c50); @@ -1670,11 +2255,33 @@ static void _rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "8723be IQK Finish!!\n"); } +static u8 _get_right_chnl_place_for_iqk(u8 chnl) +{ + u8 channel_all[TARGET_CHNL_NUM_2G_5G] = { + 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, + 13, 14, 36, 38, 40, 42, 44, 46, + 48, 50, 52, 54, 56, 58, 60, 62, 64, + 100, 102, 104, 106, 108, 110, + 112, 114, 116, 118, 120, 122, + 124, 126, 128, 130, 132, 134, 136, + 138, 140, 149, 151, 153, 155, 157, + 159, 161, 163, 165}; + u8 place = chnl; + + if (chnl > 14) { + for (place = 14; place < sizeof(channel_all); place++) { + if (channel_all[place] == chnl) + return place - 13; + } + } + return 0; +} + static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) { - struct rtl_priv *rtlpriv = rtl_priv(hw); u8 tmpreg; u32 rf_a_mode = 0, rf_b_mode = 0, lc_cal; + struct rtl_priv *rtlpriv = rtl_priv(hw); tmpreg = rtl_read_byte(rtlpriv, 0xd03); @@ -1702,7 +2309,10 @@ static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdfbe0); rtl_set_rfreg(hw, RF90_PATH_A, 0x18, MASK12BITS, 0x8c0a); - mdelay(100); + /* In order not to disturb BT music when wifi init.(1ant NIC only) */ + /*mdelay(100);*/ + /* In order not to disturb BT music when wifi init.(1ant NIC only) */ + mdelay(50); rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, RFREG_OFFSET_MASK, 0xdffe0); @@ -1716,68 +2326,34 @@ static void _rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw, bool is2t) } else { rtl_write_byte(rtlpriv, REG_TXPAUSE, 0x00); } - RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); +RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); + } static void _rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain, bool is2t) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw)); - struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw)); RT_TRACE(rtlpriv, COMP_INIT, DBG_LOUD, "\n"); - if (is_hal_stop(rtlhal)) { - u8 u1btmp; - u1btmp = rtl_read_byte(rtlpriv, REG_LEDCFG0); - rtl_write_byte(rtlpriv, REG_LEDCFG0, u1btmp | BIT(7)); - rtl_set_bbreg(hw, RFPGA0_XAB_RFPARAMETER, BIT(13), 0x01); - } - if (is2t) { - if (bmain) - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x1); - else - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(6), 0x2); - } else { - rtl_set_bbreg(hw, RFPGA0_XAB_RFINTERFACESW, BIT(8) | BIT(9), 0); - rtl_set_bbreg(hw, 0x914, MASKLWORD, 0x0201); - - /* We use the RF definition of MAIN and AUX, - * left antenna and right antenna repectively. - * Default output at AUX. - */ - if (bmain) { - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, - BIT(14) | BIT(13) | BIT(12), 0); - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(4) | BIT(3), 0); - if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) - rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 0); - } else { - rtl_set_bbreg(hw, RFPGA0_XA_RFINTERFACEOE, - BIT(14) | BIT(13) | BIT(12), 1); - rtl_set_bbreg(hw, RFPGA0_XB_RFINTERFACEOE, - BIT(5) | BIT(4) | BIT(3), 1); - if (rtlefuse->antenna_div_type == CGCS_RX_HW_ANTDIV) - rtl_set_bbreg(hw, CONFIG_RAM64X16, BIT(31), 1); - } - } + if (bmain) /* left antenna */ + rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x1); + else + rtl_set_bbreg(hw, 0x92C, MASKDWORD, 0x2); } #undef IQK_ADDA_REG_NUM #undef IQK_DELAY_TIME - -void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) +/* IQK is merge from Merge Temp */ +void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool b_recovery) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); + struct rtl_phy *rtlphy = &rtlpriv->phy; long result[4][8]; - u8 i, final_candidate; - bool patha_ok, pathb_ok; - long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4, - reg_ecc, reg_tmp = 0; + u8 i, final_candidate, idx; + bool b_patha_ok, b_pathb_ok; + long reg_e94, reg_e9c, reg_ea4, reg_eac, reg_eb4, reg_ebc, reg_ec4; + long reg_ecc, reg_tmp = 0; bool is12simular, is13simular, is23simular; u32 iqk_bb_reg[9] = { ROFDM0_XARXIQIMBALANCE, @@ -1790,12 +2366,23 @@ void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) ROFDM0_XDTXAFE, ROFDM0_RXIQEXTANTA }; + u32 path_sel_bb = 0; /* path_sel_rf = 0 */ - if (recovery) { + if (rtlphy->lck_inprogress) + return; + + spin_lock(&rtlpriv->locks.iqk_lock); + rtlphy->lck_inprogress = true; + spin_unlock(&rtlpriv->locks.iqk_lock); + + if (b_recovery) { rtl8723_phy_reload_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9); return; } + /* Save RF Path */ + path_sel_bb = rtl_get_bbreg(hw, 0x948, MASKDWORD); + /* path_sel_rf = rtl_get_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff); */ for (i = 0; i < 8; i++) { result[0][i] = 0; @@ -1804,30 +2391,33 @@ void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) result[3][i] = 0; } final_candidate = 0xff; - patha_ok = false; - pathb_ok = false; + b_patha_ok = false; + b_pathb_ok = false; is12simular = false; is23simular = false; is13simular = false; for (i = 0; i < 3; i++) { - if (get_rf_type(rtlphy) == RF_2T2R) - _rtl8723be_phy_iq_calibrate(hw, result, i, true); - else - _rtl8723be_phy_iq_calibrate(hw, result, i, false); + _rtl8723be_phy_iq_calibrate(hw, result, i, true); if (i == 1) { - is12simular = phy_similarity_cmp(hw, result, 0, 1); + is12simular = _rtl8723be_phy_simularity_compare(hw, + result, + 0, 1); if (is12simular) { final_candidate = 0; break; } } if (i == 2) { - is13simular = phy_similarity_cmp(hw, result, 0, 2); + is13simular = _rtl8723be_phy_simularity_compare(hw, + result, + 0, 2); if (is13simular) { final_candidate = 0; break; } - is23simular = phy_similarity_cmp(hw, result, 1, 2); + is23simular = _rtl8723be_phy_simularity_compare(hw, + result, + 1, 2); if (is23simular) { final_candidate = 1; } else { @@ -1864,32 +2454,48 @@ void rtl8723be_phy_iq_calibrate(struct ieee80211_hw *hw, bool recovery) rtlphy->reg_ebc = reg_ebc; reg_ec4 = result[final_candidate][6]; reg_ecc = result[final_candidate][7]; - patha_ok = true; - pathb_ok = true; + b_patha_ok = true; + b_pathb_ok = true; } else { rtlphy->reg_e94 = 0x100; rtlphy->reg_eb4 = 0x100; rtlphy->reg_e9c = 0x0; rtlphy->reg_ebc = 0x0; } - if (reg_e94 != 0) /*&&(reg_ea4 != 0) */ - rtl8723_phy_path_a_fill_iqk_matrix(hw, patha_ok, result, + if (reg_e94 != 0) + rtl8723_phy_path_a_fill_iqk_matrix(hw, b_patha_ok, result, final_candidate, (reg_ea4 == 0)); - if (final_candidate != 0xFF) { + if (reg_eb4 != 0) + _rtl8723be_phy_path_b_fill_iqk_matrix(hw, b_pathb_ok, result, + final_candidate, + (reg_ec4 == 0)); + + idx = _get_right_chnl_place_for_iqk(rtlphy->current_channel); + + if (final_candidate < 4) { for (i = 0; i < IQK_MATRIX_REG_NUM; i++) - rtlphy->iqk_matrix[0].value[0][i] = + rtlphy->iqk_matrix[idx].value[0][i] = result[final_candidate][i]; - rtlphy->iqk_matrix[0].iqk_done = true; + rtlphy->iqk_matrix[idx].iqk_done = true; + } - rtl8723_save_adda_registers(hw, iqk_bb_reg, rtlphy->iqk_bb_backup, 9); + rtl8723_save_adda_registers(hw, iqk_bb_reg, + rtlphy->iqk_bb_backup, 9); + + rtl_set_bbreg(hw, 0x948, MASKDWORD, path_sel_bb); + /* rtl_set_rfreg(hw, RF90_PATH_A, 0xb0, 0xfffff, path_sel_rf); */ + + spin_lock(&rtlpriv->locks.iqk_lock); + rtlphy->lck_inprogress = false; + spin_unlock(&rtlpriv->locks.iqk_lock); } void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - struct rtl_hal *rtlhal = &(rtlpriv->rtlhal); + struct rtl_phy *rtlphy = &rtlpriv->phy; + struct rtl_hal *rtlhal = &rtlpriv->rtlhal; u32 timeout = 2000, timecount = 0; while (rtlpriv->mac80211.act_scanning && timecount < timeout) { @@ -1898,68 +2504,25 @@ void rtl8723be_phy_lc_calibrate(struct ieee80211_hw *hw) } rtlphy->lck_inprogress = true; - RTPRINT(rtlpriv, FINIT, INIT_EEPROM, + RTPRINT(rtlpriv, FINIT, INIT_IQK, "LCK:Start!!! currentband %x delay %d ms\n", - rtlhal->current_bandtype, timecount); + rtlhal->current_bandtype, timecount); _rtl8723be_phy_lc_calibrate(hw, false); rtlphy->lck_inprogress = false; } -void rtl23b_phy_ap_calibrate(struct ieee80211_hw *hw, char delta) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - if (rtlphy->apk_done) - return; - - return; -} - void rtl8723be_phy_set_rfpath_switch(struct ieee80211_hw *hw, bool bmain) { - _rtl8723be_phy_set_rfpath_switch(hw, bmain, false); -} - -static void rtl8723be_phy_set_io(struct ieee80211_hw *hw) -{ - struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "--->Cmd(%#x), set_io_inprogress(%d)\n", - rtlphy->current_io_type, rtlphy->set_io_inprogress); - switch (rtlphy->current_io_type) { - case IO_CMD_RESUME_DM_BY_SCAN: - rtlpriv->dm_digtable.cur_igvalue = - rtlphy->initgain_backup.xaagccore1; - /*rtl92c_dm_write_dig(hw);*/ - rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel); - rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83); - break; - case IO_CMD_PAUSE_DM_BY_SCAN: - rtlphy->initgain_backup.xaagccore1 = - rtlpriv->dm_digtable.cur_igvalue; - rtlpriv->dm_digtable.cur_igvalue = 0x17; - rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40); - break; - default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, - "switch case not process\n"); - break; - } - rtlphy->set_io_inprogress = false; - RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, - "(%#x)\n", rtlphy->current_io_type); + _rtl8723be_phy_set_rfpath_switch(hw, bmain, true); } bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) { struct rtl_priv *rtlpriv = rtl_priv(hw); - struct rtl_phy *rtlphy = &(rtlpriv->phy); - bool postprocessing = false; + struct rtl_phy *rtlphy = &rtlpriv->phy; + bool b_postprocessing = false; RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "-->IO Cmd(%#x), set_io_inprogress(%d)\n", @@ -1969,20 +2532,20 @@ bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) case IO_CMD_RESUME_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "[IO CMD] Resume DM after scan.\n"); - postprocessing = true; + b_postprocessing = true; break; - case IO_CMD_PAUSE_DM_BY_SCAN: + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, "[IO CMD] Pause DM before scan.\n"); - postprocessing = true; + b_postprocessing = true; break; default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, "switch case not process\n"); break; } } while (false); - if (postprocessing && !rtlphy->set_io_inprogress) { + if (b_postprocessing && !rtlphy->set_io_inprogress) { rtlphy->set_io_inprogress = true; rtlphy->current_io_type = iotype; } else { @@ -1993,6 +2556,37 @@ bool rtl8723be_phy_set_io_cmd(struct ieee80211_hw *hw, enum io_type iotype) return true; } +static void rtl8723be_phy_set_io(struct ieee80211_hw *hw) +{ + struct rtl_priv *rtlpriv = rtl_priv(hw); + struct dig_t *dm_digtable = &rtlpriv->dm_digtable; + struct rtl_phy *rtlphy = &rtlpriv->phy; + + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "--->Cmd(%#x), set_io_inprogress(%d)\n", + rtlphy->current_io_type, rtlphy->set_io_inprogress); + switch (rtlphy->current_io_type) { + case IO_CMD_RESUME_DM_BY_SCAN: + dm_digtable->cur_igvalue = rtlphy->initgain_backup.xaagccore1; + /*rtl92c_dm_write_dig(hw);*/ + rtl8723be_phy_set_txpower_level(hw, rtlphy->current_channel); + rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x83); + break; + case IO_CMD_PAUSE_BAND0_DM_BY_SCAN: + rtlphy->initgain_backup.xaagccore1 = dm_digtable->cur_igvalue; + dm_digtable->cur_igvalue = 0x17; + rtl_set_bbreg(hw, RCCK0_CCA, 0xff0000, 0x40); + break; + default: + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, + "switch case not process\n"); + break; + } + rtlphy->set_io_inprogress = false; + RT_TRACE(rtlpriv, COMP_CMD, DBG_TRACE, + "(%#x)\n", rtlphy->current_io_type); +} + static void rtl8723be_phy_set_rf_on(struct ieee80211_hw *hw) { struct rtl_priv *rtlpriv = rtl_priv(hw); @@ -2028,15 +2622,15 @@ static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, switch (rfpwr_state) { case ERFON: if ((ppsc->rfpwr_state == ERFOFF) && - RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { + RT_IN_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC)) { bool rtstatus; - u32 initialize_count = 0; + u32 initializecount = 0; do { - initialize_count++; + initializecount++; RT_TRACE(rtlpriv, COMP_RF, DBG_DMESG, "IPS Set eRf nic enable\n"); rtstatus = rtl_ps_enable_nic(hw); - } while (!rtstatus && (initialize_count < 10)); + } while (!rtstatus && (initializecount < 10)); RT_CLEAR_PS_LEVEL(ppsc, RT_RF_OFF_LEVL_HALT_NIC); } else { @@ -2051,28 +2645,33 @@ static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, rtlpriv->cfg->ops->led_control(hw, LED_CTL_LINK); else rtlpriv->cfg->ops->led_control(hw, LED_CTL_NO_LINK); + break; + case ERFOFF: for (queue_id = 0, i = 0; queue_id < RTL_PCI_MAX_TX_QUEUE_COUNT;) { ring = &pcipriv->dev.tx_ring[queue_id]; - if (skb_queue_len(&ring->queue) == 0) { + /* Don't check BEACON Q. + * BEACON Q is always not empty, + * because '_rtl8723be_cmd_send_packet' + */ + if (queue_id == BEACON_QUEUE || + skb_queue_len(&ring->queue) == 0) { queue_id++; continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue)); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "\n ERFSLEEP: %d times " - "TcbBusyQueue[%d] = %d !\n", + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", MAX_DOZE_WAITING_TIMES_9x, queue_id, skb_queue_len(&ring->queue)); @@ -2095,6 +2694,7 @@ static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, } } break; + case ERFSLEEP: if (ppsc->rfpwr_state == ERFOFF) break; @@ -2106,21 +2706,19 @@ static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, continue; } else { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "eRf Off/Sleep: %d times " - "TcbBusyQueue[%d] =%d before " - "doze!\n", (i + 1), queue_id, - skb_queue_len(&ring->queue)); + "eRf Off/Sleep: %d times TcbBusyQueue[%d] =%d before doze!\n", + (i + 1), queue_id, + skb_queue_len(&ring->queue)); udelay(10); i++; } if (i >= MAX_DOZE_WAITING_TIMES_9x) { RT_TRACE(rtlpriv, COMP_ERR, DBG_WARNING, - "\n ERFSLEEP: %d times " - "TcbBusyQueue[%d] = %d !\n", - MAX_DOZE_WAITING_TIMES_9x, - queue_id, - skb_queue_len(&ring->queue)); + "ERFSLEEP: %d times TcbBusyQueue[%d] = %d !\n", + MAX_DOZE_WAITING_TIMES_9x, + queue_id, + skb_queue_len(&ring->queue)); break; } } @@ -2131,8 +2729,9 @@ static bool _rtl8723be_phy_set_rf_power_state(struct ieee80211_hw *hw, ppsc->last_sleep_jiffies = jiffies; _rtl8723be_phy_set_rf_sleep(hw); break; + default: - RT_TRACE(rtlpriv, COMP_ERR, DBG_EMERG, + RT_TRACE(rtlpriv, COMP_ERR, DBG_LOUD, "switch case not process\n"); bresult = false; break; |