forked from Minki/linux
c592e631bc
This patch is the addition of files for a new driver to handle the Realtek RTL8723AE wireless device. Signed-off-by: Larry Finger <Larry.Finger@lwfinger.net> Cc: <chaoming_li@realsil.com.cn> Signed-off-by: John W. Linville <linville@tuxdriver.com>
543 lines
17 KiB
C
543 lines
17 KiB
C
/******************************************************************************
|
|
*
|
|
* Copyright(c) 2009-2012 Realtek Corporation.
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of version 2 of the GNU General Public License as
|
|
* published by the Free Software Foundation.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but WITHOUT
|
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
|
* more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License along with
|
|
* this program; if not, write to the Free Software Foundation, Inc.,
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
|
|
*
|
|
* The full GNU General Public License is included in this distribution in the
|
|
* file called LICENSE.
|
|
*
|
|
* Contact Information:
|
|
* wlanfae <wlanfae@realtek.com>
|
|
* Realtek Corporation, No. 2, Innovation Road II, Hsinchu Science Park,
|
|
* Hsinchu 300, Taiwan.
|
|
*
|
|
* Larry Finger <Larry.Finger@lwfinger.net>
|
|
*
|
|
*****************************************************************************/
|
|
|
|
#include "hal_bt_coexist.h"
|
|
#include "../pci.h"
|
|
#include "dm.h"
|
|
#include "fw.h"
|
|
#include "phy.h"
|
|
#include "reg.h"
|
|
#include "hal_btc.h"
|
|
|
|
void rtl8723ae_dm_bt_reject_ap_aggregated_packet(struct ieee80211_hw *hw,
|
|
bool reject)
|
|
{
|
|
}
|
|
|
|
void _rtl8723_dm_bt_check_wifi_state(struct ieee80211_hw *hw)
|
|
{
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
struct rtl_phy *rtlphy = &(rtlpriv->phy);
|
|
|
|
if (rtlpriv->link_info.busytraffic) {
|
|
rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_IDLE;
|
|
|
|
if (rtlpriv->link_info.tx_busy_traffic)
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_UPLINK;
|
|
else
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_UPLINK;
|
|
|
|
if (rtlpriv->link_info.rx_busy_traffic)
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_DOWNLINK;
|
|
else
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_DOWNLINK;
|
|
} else {
|
|
rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_IDLE;
|
|
rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_UPLINK;
|
|
rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_DOWNLINK;
|
|
}
|
|
|
|
if (rtlpriv->mac80211.mode == WIRELESS_MODE_G ||
|
|
rtlpriv->mac80211.mode == WIRELESS_MODE_B) {
|
|
rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_WIFI_LEGACY;
|
|
rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT20;
|
|
rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_HT40;
|
|
} else {
|
|
rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_WIFI_LEGACY;
|
|
if (rtlphy->current_chan_bw == HT_CHANNEL_WIDTH_20_40) {
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_HT40;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_HT20;
|
|
} else {
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_HT20;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_HT40;
|
|
}
|
|
}
|
|
|
|
if (rtlpriv->bt_operation_on)
|
|
rtlpcipriv->bt_coexist.cstate |= BT_COEX_STATE_BT30;
|
|
else
|
|
rtlpcipriv->bt_coexist.cstate &= ~BT_COEX_STATE_BT30;
|
|
}
|
|
|
|
u8 rtl8723ae_dm_bt_check_coex_rssi_state1(struct ieee80211_hw *hw,
|
|
u8 level_num, u8 rssi_thresh,
|
|
u8 rssi_thresh1)
|
|
|
|
{
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
long smooth;
|
|
u8 bt_rssi_state = 0;
|
|
|
|
smooth = rtl8723ae_dm_bt_get_rx_ss(hw);
|
|
|
|
if (level_num == 2) {
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
|
|
|
|
if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_LOW) ||
|
|
(rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_STAY_LOW)) {
|
|
if (smooth >= (rssi_thresh +
|
|
BT_FW_COEX_THRESH_TOL)) {
|
|
bt_rssi_state = BT_RSSI_STATE_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_RSSI_1_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_LOW;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state switch to High\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state stay at Low\n");
|
|
}
|
|
} else {
|
|
if (smooth < rssi_thresh) {
|
|
bt_rssi_state = BT_RSSI_STATE_LOW;
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_RSSI_1_LOW;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state switch to Low\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state stay at High\n");
|
|
}
|
|
}
|
|
} else if (level_num == 3) {
|
|
if (rssi_thresh > rssi_thresh1) {
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 thresh error!!\n");
|
|
return rtlpcipriv->bt_coexist.bt_pre_rssi_state;
|
|
}
|
|
|
|
if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_LOW) ||
|
|
(rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_STAY_LOW)) {
|
|
if (smooth >=
|
|
(rssi_thresh+BT_FW_COEX_THRESH_TOL)) {
|
|
bt_rssi_state = BT_RSSI_STATE_MEDIUM;
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_LOW;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state switch to Medium\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state stay at Low\n");
|
|
}
|
|
} else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_MEDIUM) ||
|
|
(rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_STAY_MEDIUM)) {
|
|
if (smooth >= (rssi_thresh1 +
|
|
BT_FW_COEX_THRESH_TOL)) {
|
|
bt_rssi_state = BT_RSSI_STATE_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_RSSI_1_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_LOW;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state switch to High\n");
|
|
} else if (smooth < rssi_thresh) {
|
|
bt_rssi_state = BT_RSSI_STATE_LOW;
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_RSSI_1_LOW;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state switch to Low\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state stay at Medium\n");
|
|
}
|
|
} else {
|
|
if (smooth < rssi_thresh1) {
|
|
bt_rssi_state = BT_RSSI_STATE_MEDIUM;
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_RSSI_1_MEDIUM;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_1_LOW;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state switch to Medium\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI_1 state stay at High\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
rtlpcipriv->bt_coexist.bt_pre_rssi_state1 = bt_rssi_state;
|
|
|
|
return bt_rssi_state;
|
|
}
|
|
|
|
u8 rtl8723ae_dm_bt_check_coex_rssi_state(struct ieee80211_hw *hw,
|
|
u8 level_num, u8 rssi_thresh,
|
|
u8 rssi_thresh1)
|
|
{
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
long smooth;
|
|
u8 bt_rssi_state = 0;
|
|
|
|
smooth = rtl8723ae_dm_bt_get_rx_ss(hw);
|
|
|
|
if (level_num == 2) {
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
|
|
|
|
if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_LOW) ||
|
|
(rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_STAY_LOW)){
|
|
if (smooth >=
|
|
(rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
|
|
bt_rssi_state = BT_RSSI_STATE_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_RSSI_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_LOW;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state switch to High\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state stay at Low\n");
|
|
}
|
|
} else {
|
|
if (smooth < rssi_thresh) {
|
|
bt_rssi_state = BT_RSSI_STATE_LOW;
|
|
rtlpcipriv->bt_coexist.cstate |=
|
|
BT_COEX_STATE_WIFI_RSSI_LOW;
|
|
rtlpcipriv->bt_coexist.cstate &=
|
|
~BT_COEX_STATE_WIFI_RSSI_HIGH;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state switch to Low\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state stay at High\n");
|
|
}
|
|
}
|
|
} else if (level_num == 3) {
|
|
if (rssi_thresh > rssi_thresh1) {
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI thresh error!!\n");
|
|
return rtlpcipriv->bt_coexist.bt_pre_rssi_state;
|
|
}
|
|
if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_LOW) ||
|
|
(rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_STAY_LOW)) {
|
|
if (smooth >=
|
|
(rssi_thresh + BT_FW_COEX_THRESH_TOL)) {
|
|
bt_rssi_state = BT_RSSI_STATE_MEDIUM;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
|= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
&= ~BT_COEX_STATE_WIFI_RSSI_LOW;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
&= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state switch to Medium\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_LOW;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state stay at Low\n");
|
|
}
|
|
} else if ((rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_MEDIUM) ||
|
|
(rtlpcipriv->bt_coexist.bt_pre_rssi_state ==
|
|
BT_RSSI_STATE_STAY_MEDIUM)) {
|
|
if (smooth >=
|
|
(rssi_thresh1 + BT_FW_COEX_THRESH_TOL)) {
|
|
bt_rssi_state = BT_RSSI_STATE_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
|= BT_COEX_STATE_WIFI_RSSI_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
&= ~BT_COEX_STATE_WIFI_RSSI_LOW;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
&= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state switch to High\n");
|
|
} else if (smooth < rssi_thresh) {
|
|
bt_rssi_state = BT_RSSI_STATE_LOW;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
|= BT_COEX_STATE_WIFI_RSSI_LOW;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
&= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
&= ~BT_COEX_STATE_WIFI_RSSI_MEDIUM;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state switch to Low\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_MEDIUM;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state stay at Medium\n");
|
|
}
|
|
} else {
|
|
if (smooth < rssi_thresh1) {
|
|
bt_rssi_state = BT_RSSI_STATE_MEDIUM;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
|= BT_COEX_STATE_WIFI_RSSI_MEDIUM;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
&= ~BT_COEX_STATE_WIFI_RSSI_HIGH;
|
|
rtlpcipriv->bt_coexist.cstate
|
|
&= ~BT_COEX_STATE_WIFI_RSSI_LOW;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state switch to Medium\n");
|
|
} else {
|
|
bt_rssi_state = BT_RSSI_STATE_STAY_HIGH;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], RSSI state stay at High\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
rtlpcipriv->bt_coexist.bt_pre_rssi_state = bt_rssi_state;
|
|
return bt_rssi_state;
|
|
}
|
|
|
|
long rtl8723ae_dm_bt_get_rx_ss(struct ieee80211_hw *hw)
|
|
{
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
long smooth = 0;
|
|
|
|
if (rtlpriv->mac80211.link_state >= MAC80211_LINKED)
|
|
smooth = GET_UNDECORATED_AVERAGE_RSSI(rtlpriv);
|
|
else
|
|
smooth = rtlpriv->dm.entry_min_undec_sm_pwdb;
|
|
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"rtl8723ae_dm_bt_get_rx_ss() = %ld\n", smooth);
|
|
|
|
return smooth;
|
|
}
|
|
|
|
void rtl8723ae_dm_bt_balance(struct ieee80211_hw *hw,
|
|
bool balance_on, u8 ms0, u8 ms1)
|
|
{
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
u8 h2c_parameter[3] = {0};
|
|
|
|
if (balance_on) {
|
|
h2c_parameter[2] = 1;
|
|
h2c_parameter[1] = ms1;
|
|
h2c_parameter[0] = ms0;
|
|
rtlpcipriv->bt_coexist.fw_coexist_all_off = false;
|
|
} else {
|
|
h2c_parameter[2] = 0;
|
|
h2c_parameter[1] = 0;
|
|
h2c_parameter[0] = 0;
|
|
}
|
|
rtlpcipriv->bt_coexist.balance_on = balance_on;
|
|
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[DM][BT], Balance=[%s:%dms:%dms], write 0xc=0x%x\n",
|
|
balance_on ? "ON" : "OFF", ms0, ms1,
|
|
h2c_parameter[0]<<16 | h2c_parameter[1]<<8 | h2c_parameter[2]);
|
|
|
|
rtl8723ae_fill_h2c_cmd(hw, 0xc, 3, h2c_parameter);
|
|
}
|
|
|
|
|
|
void rtl8723ae_dm_bt_agc_table(struct ieee80211_hw *hw, u8 type)
|
|
{
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
|
|
if (type == BT_AGCTABLE_OFF) {
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[BT]AGCTable Off!\n");
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x641c0001);
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x631d0001);
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x621e0001);
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x611f0001);
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x60200001);
|
|
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_AGC_HP, 0xfffff, 0x32000);
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_AGC_HP, 0xfffff, 0x71000);
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_AGC_HP, 0xfffff, 0xb0000);
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_AGC_HP, 0xfffff, 0xfc000);
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_G1, 0xfffff, 0x30355);
|
|
} else if (type == BT_AGCTABLE_ON) {
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[BT]AGCTable On!\n");
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x4e1c0001);
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x4d1d0001);
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x4c1e0001);
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x4b1f0001);
|
|
rtl_write_dword(rtlpriv, 0xc78, 0x4a200001);
|
|
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_AGC_HP, 0xfffff, 0xdc000);
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_AGC_HP, 0xfffff, 0x90000);
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_AGC_HP, 0xfffff, 0x51000);
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_AGC_HP, 0xfffff, 0x12000);
|
|
rtl8723ae_phy_set_rf_reg(hw, RF90_PATH_A,
|
|
RF_RX_G1, 0xfffff, 0x00355);
|
|
|
|
rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
|
|
}
|
|
}
|
|
|
|
void rtl8723ae_dm_bt_bback_off_level(struct ieee80211_hw *hw, u8 type)
|
|
{
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
|
|
if (type == BT_BB_BACKOFF_OFF) {
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[BT]BBBackOffLevel Off!\n");
|
|
rtl_write_dword(rtlpriv, 0xc04, 0x3a05611);
|
|
} else if (type == BT_BB_BACKOFF_ON) {
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"[BT]BBBackOffLevel On!\n");
|
|
rtl_write_dword(rtlpriv, 0xc04, 0x3a07611);
|
|
rtlpcipriv->bt_coexist.sw_coexist_all_off = false;
|
|
}
|
|
}
|
|
|
|
void rtl8723ae_dm_bt_fw_coex_all_off(struct ieee80211_hw *hw)
|
|
{
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"rtl8723ae_dm_bt_fw_coex_all_off()\n");
|
|
|
|
if (rtlpcipriv->bt_coexist.fw_coexist_all_off)
|
|
return;
|
|
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"rtl8723ae_dm_bt_fw_coex_all_off(), real Do\n");
|
|
rtl8723ae_dm_bt_fw_coex_all_off_8723a(hw);
|
|
rtlpcipriv->bt_coexist.fw_coexist_all_off = true;
|
|
}
|
|
|
|
void rtl8723ae_dm_bt_sw_coex_all_off(struct ieee80211_hw *hw)
|
|
{
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"rtl8723ae_dm_bt_sw_coex_all_off()\n");
|
|
|
|
if (rtlpcipriv->bt_coexist.sw_coexist_all_off)
|
|
return;
|
|
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"rtl8723ae_dm_bt_sw_coex_all_off(), real Do\n");
|
|
rtl8723ae_dm_bt_sw_coex_all_off_8723a(hw);
|
|
rtlpcipriv->bt_coexist.sw_coexist_all_off = true;
|
|
}
|
|
|
|
void rtl8723ae_dm_bt_hw_coex_all_off(struct ieee80211_hw *hw)
|
|
{
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"rtl8723ae_dm_bt_hw_coex_all_off()\n");
|
|
|
|
if (rtlpcipriv->bt_coexist.hw_coexist_all_off)
|
|
return;
|
|
RT_TRACE(rtlpriv, COMP_BT_COEXIST, DBG_TRACE,
|
|
"rtl8723ae_dm_bt_hw_coex_all_off(), real Do\n");
|
|
|
|
rtl8723ae_dm_bt_hw_coex_all_off_8723a(hw);
|
|
|
|
rtlpcipriv->bt_coexist.hw_coexist_all_off = true;
|
|
}
|
|
|
|
void rtl8723ae_btdm_coex_all_off(struct ieee80211_hw *hw)
|
|
{
|
|
rtl8723ae_dm_bt_fw_coex_all_off(hw);
|
|
rtl8723ae_dm_bt_sw_coex_all_off(hw);
|
|
rtl8723ae_dm_bt_hw_coex_all_off(hw);
|
|
}
|
|
|
|
bool rtl8723ae_dm_bt_is_coexist_state_changed(struct ieee80211_hw *hw)
|
|
{
|
|
struct rtl_pci_priv *rtlpcipriv = rtl_pcipriv(hw);
|
|
|
|
if ((rtlpcipriv->bt_coexist.previous_state ==
|
|
rtlpcipriv->bt_coexist.cstate) &&
|
|
(rtlpcipriv->bt_coexist.previous_state_h ==
|
|
rtlpcipriv->bt_coexist.cstate_h))
|
|
return false;
|
|
else
|
|
return true;
|
|
}
|
|
|
|
bool rtl8723ae_dm_bt_is_wifi_up_link(struct ieee80211_hw *hw)
|
|
{
|
|
struct rtl_priv *rtlpriv = rtl_priv(hw);
|
|
|
|
if (rtlpriv->link_info.tx_busy_traffic)
|
|
return true;
|
|
else
|
|
return false;
|
|
}
|