aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-02-01 10:29:59 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2014-02-01 10:29:59 -0800
commitfea8893da7c52906caa1a8dc3199f4b2ed3b8dbd (patch)
tree56e3482be95e2f1bd1386ecb3bc104a55f68f5e7
parent04480094de7242d08bb62088e713fd7fe00443b4 (diff)
parentd7216f8f02da54f8f235c5cca562a55b7f52210d (diff)
downloadlinux-linaro-stable-fea8893da7c52906caa1a8dc3199f4b2ed3b8dbd.tar.gz
Merge tag 'staging-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging
Pull rtl8812ae staging wireless driver from Greg KH: "Here's a single staging driver for a wireless chipset that has shown up in the SteamBox hardware. It is merged separately from the "main" staging pull request to sync up with the wireless api changes that came in from the networking tree. It's self-contained and works for me and others. Larry will be replacing it with a "real" driver for 3.15, but for now this one is needed" * tag 'staging-3.14-rc1' of git://git.kernel.org/pub/scm/linux/kernel/git/gregkh/staging: staging: r8821ae: Enable build by reverting BROKEN marking staging: r8821ae: Fix build problems Staging: rtl8812ae: disable due to build errors Staging: rtl8821ae: add TODO file Staging: rtl8821ae: removed unused functions and variables Staging: rtl8821ae: rc.c: fix up function prototypes Staging: rtl8812ae: Add Realtek 8821 PCI WIFI driver
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/rtl8821ae/Kconfig11
-rw-r--r--drivers/staging/rtl8821ae/Makefile35
-rw-r--r--drivers/staging/rtl8821ae/TODO10
-rw-r--r--drivers/staging/rtl8821ae/base.c1873
-rw-r--r--drivers/staging/rtl8821ae/base.h159
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c3976
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.h205
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.c1614
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.h176
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbt_precomp.h99
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.c3891
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.h226
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.c4242
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h162
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8723a2ant.c3780
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8723a2ant.h179
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8723b1ant.c4104
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8723b1ant.h175
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8723b2ant.c4185
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtc8723b2ant.h145
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.c1181
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/halbtcoutsrc.h549
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/rtl_btc.c236
-rw-r--r--drivers/staging/rtl8821ae/btcoexist/rtl_btc.h66
-rw-r--r--drivers/staging/rtl8821ae/cam.c354
-rw-r--r--drivers/staging/rtl8821ae/cam.h56
-rw-r--r--drivers/staging/rtl8821ae/compat.h125
-rw-r--r--drivers/staging/rtl8821ae/core.c1464
-rw-r--r--drivers/staging/rtl8821ae/core.h43
-rw-r--r--drivers/staging/rtl8821ae/debug.c988
-rw-r--r--drivers/staging/rtl8821ae/debug.h227
-rw-r--r--drivers/staging/rtl8821ae/efuse.c1285
-rw-r--r--drivers/staging/rtl8821ae/efuse.h130
-rw-r--r--drivers/staging/rtl8821ae/pci.c2549
-rw-r--r--drivers/staging/rtl8821ae/pci.h353
-rw-r--r--drivers/staging/rtl8821ae/ps.c1025
-rw-r--r--drivers/staging/rtl8821ae/ps.h55
-rw-r--r--drivers/staging/rtl8821ae/rc.c309
-rw-r--r--drivers/staging/rtl8821ae/rc.h47
-rw-r--r--drivers/staging/rtl8821ae/regd.c503
-rw-r--r--drivers/staging/rtl8821ae/regd.h75
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/btc.h87
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/def.h442
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/dm.c3045
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/dm.h426
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/fw.c1349
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/fw.h321
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/hal_bt_coexist.c519
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/hal_bt_coexist.h169
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/hal_btc.c2069
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/hal_btc.h160
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/hw.c3346
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/hw.h75
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/led.c239
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/led.h40
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/phy.c5525
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/phy.h258
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/pwrseq.c199
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/pwrseq.h413
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/pwrseqcmd.c140
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/pwrseqcmd.h71
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/reg.h2427
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/rf.c464
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/rf.h46
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/sw.c499
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/sw.h39
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/table.c4002
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/table.h62
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/trx.c1050
-rw-r--r--drivers/staging/rtl8821ae/rtl8821ae/trx.h641
-rw-r--r--drivers/staging/rtl8821ae/stats.c283
-rw-r--r--drivers/staging/rtl8821ae/stats.h46
-rw-r--r--drivers/staging/rtl8821ae/wifi.h2532
75 files changed, 71854 insertions, 0 deletions
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index 040a51525b42..99375f0a9440 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -52,6 +52,8 @@ source "drivers/staging/rtl8712/Kconfig"
source "drivers/staging/rtl8188eu/Kconfig"
+source "drivers/staging/rtl8821ae/Kconfig"
+
source "drivers/staging/rts5139/Kconfig"
source "drivers/staging/rts5208/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index dea056bf7ff2..ddc3c4a5d39d 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/
obj-$(CONFIG_R8188EU) += rtl8188eu/
+obj-$(CONFIG_R8821AE) += rtl8821ae/
obj-$(CONFIG_RTS5139) += rts5139/
obj-$(CONFIG_RTS5208) += rts5208/
obj-$(CONFIG_TRANZPORT) += frontier/
diff --git a/drivers/staging/rtl8821ae/Kconfig b/drivers/staging/rtl8821ae/Kconfig
new file mode 100644
index 000000000000..2aa5dac2f1df
--- /dev/null
+++ b/drivers/staging/rtl8821ae/Kconfig
@@ -0,0 +1,11 @@
+config R8821AE
+ tristate "RealTek RTL8821AE Wireless LAN NIC driver"
+ depends on PCI && WLAN
+ depends on m
+ select WIRELESS_EXT
+ select WEXT_PRIV
+ select EEPROM_93CX6
+ select CRYPTO
+ default N
+ ---help---
+ If built as a module, it will be called r8821ae.ko.
diff --git a/drivers/staging/rtl8821ae/Makefile b/drivers/staging/rtl8821ae/Makefile
new file mode 100644
index 000000000000..8a23bd7e8842
--- /dev/null
+++ b/drivers/staging/rtl8821ae/Makefile
@@ -0,0 +1,35 @@
+PCI_MAIN_OBJS := base.o \
+ rc.o \
+ debug.o \
+ regd.o \
+ efuse.o \
+ cam.o \
+ ps.o \
+ core.o \
+ stats.o \
+ pci.o \
+
+BT_COEXIST_OBJS:= btcoexist/halbtc8192e2ant.o\
+ btcoexist/halbtc8723b1ant.o\
+ btcoexist/halbtc8723b2ant.o\
+ btcoexist/halbtcoutsrc.o\
+ btcoexist/rtl_btc.o \
+
+PCI_8821AE_HAL_OBJS:= \
+ rtl8821ae/hw.o \
+ rtl8821ae/table.o \
+ rtl8821ae/sw.o \
+ rtl8821ae/trx.o \
+ rtl8821ae/led.o \
+ rtl8821ae/fw.o \
+ rtl8821ae/phy.o \
+ rtl8821ae/rf.o \
+ rtl8821ae/dm.o \
+ rtl8821ae/pwrseq.o \
+ rtl8821ae/pwrseqcmd.o \
+ rtl8821ae/hal_btc.o \
+ rtl8821ae/hal_bt_coexist.o \
+
+rtl8821ae-objs += $(BT_COEXIST_OBJS) $(PCI_MAIN_OBJS) $(PCI_8821AE_HAL_OBJS)
+
+obj-$(CONFIG_R8821AE) += rtl8821ae.o
diff --git a/drivers/staging/rtl8821ae/TODO b/drivers/staging/rtl8821ae/TODO
new file mode 100644
index 000000000000..3ee7529d4ed5
--- /dev/null
+++ b/drivers/staging/rtl8821ae/TODO
@@ -0,0 +1,10 @@
+Realtek 8821AE PCI wifi driver TODO:
+ - remove built-in btcoexist module when the "real" one gets upstream
+ - remove built-in rtlwifi code by porting driver to use the "real" one
+ in the drivers/net/ directory.
+ - fix up coding style issues
+
+Please send any patches for this driver to:
+ Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+and the <devel@driverdev.osuosl.org> mailing list.
+
diff --git a/drivers/staging/rtl8821ae/base.c b/drivers/staging/rtl8821ae/base.c
new file mode 100644
index 000000000000..18c936fbdf1e
--- /dev/null
+++ b/drivers/staging/rtl8821ae/base.c
@@ -0,0 +1,1873 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 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 <linux/ip.h>
+#include <linux/module.h>
+#include "wifi.h"
+#include "rc.h"
+#include "base.h"
+#include "efuse.h"
+#include "cam.h"
+#include "ps.h"
+#include "regd.h"
+#include "pci.h"
+
+/*
+ *NOTICE!!!: This file will be very big, we hsould
+ *keep it clear under follwing roles:
+ *
+ *This file include follwing part, so, if you add new
+ *functions into this file, please check which part it
+ *should includes. or check if you should add new part
+ *for this file:
+ *
+ *1) mac80211 init functions
+ *2) tx information functions
+ *3) functions called by core.c
+ *4) wq & timer callback functions
+ *5) frame process functions
+ *6) IOT functions
+ *7) sysfs functions
+ *8) vif functions
+ *9) ...
+ */
+
+/*********************************************************
+ *
+ * mac80211 init functions
+ *
+ *********************************************************/
+static struct ieee80211_channel rtl_channeltable_2g[] = {
+ {.center_freq = 2412,.hw_value = 1,},
+ {.center_freq = 2417,.hw_value = 2,},
+ {.center_freq = 2422,.hw_value = 3,},
+ {.center_freq = 2427,.hw_value = 4,},
+ {.center_freq = 2432,.hw_value = 5,},
+ {.center_freq = 2437,.hw_value = 6,},
+ {.center_freq = 2442,.hw_value = 7,},
+ {.center_freq = 2447,.hw_value = 8,},
+ {.center_freq = 2452,.hw_value = 9,},
+ {.center_freq = 2457,.hw_value = 10,},
+ {.center_freq = 2462,.hw_value = 11,},
+ {.center_freq = 2467,.hw_value = 12,},
+ {.center_freq = 2472,.hw_value = 13,},
+ {.center_freq = 2484,.hw_value = 14,},
+};
+
+static struct ieee80211_channel rtl_channeltable_5g[] = {
+ {.center_freq = 5180,.hw_value = 36,},
+ {.center_freq = 5200,.hw_value = 40,},
+ {.center_freq = 5220,.hw_value = 44,},
+ {.center_freq = 5240,.hw_value = 48,},
+ {.center_freq = 5260,.hw_value = 52,},
+ {.center_freq = 5280,.hw_value = 56,},
+ {.center_freq = 5300,.hw_value = 60,},
+ {.center_freq = 5320,.hw_value = 64,},
+ {.center_freq = 5500,.hw_value = 100,},
+ {.center_freq = 5520,.hw_value = 104,},
+ {.center_freq = 5540,.hw_value = 108,},
+ {.center_freq = 5560,.hw_value = 112,},
+ {.center_freq = 5580,.hw_value = 116,},
+ {.center_freq = 5600,.hw_value = 120,},
+ {.center_freq = 5620,.hw_value = 124,},
+ {.center_freq = 5640,.hw_value = 128,},
+ {.center_freq = 5660,.hw_value = 132,},
+ {.center_freq = 5680,.hw_value = 136,},
+ {.center_freq = 5700,.hw_value = 140,},
+ {.center_freq = 5745,.hw_value = 149,},
+ {.center_freq = 5765,.hw_value = 153,},
+ {.center_freq = 5785,.hw_value = 157,},
+ {.center_freq = 5805,.hw_value = 161,},
+ {.center_freq = 5825,.hw_value = 165,},
+};
+
+static struct ieee80211_rate rtl_ratetable_2g[] = {
+ {.bitrate = 10,.hw_value = 0x00,},
+ {.bitrate = 20,.hw_value = 0x01,},
+ {.bitrate = 55,.hw_value = 0x02,},
+ {.bitrate = 110,.hw_value = 0x03,},
+ {.bitrate = 60,.hw_value = 0x04,},
+ {.bitrate = 90,.hw_value = 0x05,},
+ {.bitrate = 120,.hw_value = 0x06,},
+ {.bitrate = 180,.hw_value = 0x07,},
+ {.bitrate = 240,.hw_value = 0x08,},
+ {.bitrate = 360,.hw_value = 0x09,},
+ {.bitrate = 480,.hw_value = 0x0a,},
+ {.bitrate = 540,.hw_value = 0x0b,},
+};
+
+static struct ieee80211_rate rtl_ratetable_5g[] = {
+ {.bitrate = 60,.hw_value = 0x04,},
+ {.bitrate = 90,.hw_value = 0x05,},
+ {.bitrate = 120,.hw_value = 0x06,},
+ {.bitrate = 180,.hw_value = 0x07,},
+ {.bitrate = 240,.hw_value = 0x08,},
+ {.bitrate = 360,.hw_value = 0x09,},
+ {.bitrate = 480,.hw_value = 0x0a,},
+ {.bitrate = 540,.hw_value = 0x0b,},
+};
+
+static const struct ieee80211_supported_band rtl_band_2ghz = {
+ .band = IEEE80211_BAND_2GHZ,
+
+ .channels = rtl_channeltable_2g,
+ .n_channels = ARRAY_SIZE(rtl_channeltable_2g),
+
+ .bitrates = rtl_ratetable_2g,
+ .n_bitrates = ARRAY_SIZE(rtl_ratetable_2g),
+
+ .ht_cap = {0},
+};
+
+static struct ieee80211_supported_band rtl_band_5ghz = {
+ .band = IEEE80211_BAND_5GHZ,
+
+ .channels = rtl_channeltable_5g,
+ .n_channels = ARRAY_SIZE(rtl_channeltable_5g),
+
+ .bitrates = rtl_ratetable_5g,
+ .n_bitrates = ARRAY_SIZE(rtl_ratetable_5g),
+
+ .ht_cap = {0},
+};
+
+static const u8 tid_to_ac[] = {
+ 2, /* IEEE80211_AC_BE */
+ 3, /* IEEE80211_AC_BK */
+ 3, /* IEEE80211_AC_BK */
+ 2, /* IEEE80211_AC_BE */
+ 1, /* IEEE80211_AC_VI */
+ 1, /* IEEE80211_AC_VI */
+ 0, /* IEEE80211_AC_VO */
+ 0, /* IEEE80211_AC_VO */
+};
+
+u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid)
+{
+ return tid_to_ac[tid];
+}
+
+static void _rtl_init_hw_ht_capab(struct ieee80211_hw *hw,
+ struct ieee80211_sta_ht_cap *ht_cap)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+
+ ht_cap->ht_supported = true;
+ ht_cap->cap = IEEE80211_HT_CAP_SUP_WIDTH_20_40 |
+ IEEE80211_HT_CAP_SGI_40 |
+ IEEE80211_HT_CAP_SGI_20 |
+ IEEE80211_HT_CAP_DSSSCCK40 | IEEE80211_HT_CAP_MAX_AMSDU;
+
+ if (rtlpriv->rtlhal.disable_amsdu_8k)
+ ht_cap->cap &= ~IEEE80211_HT_CAP_MAX_AMSDU;
+
+ /*
+ *Maximum length of AMPDU that the STA can receive.
+ *Length = 2 ^ (13 + max_ampdu_length_exp) - 1 (octets)
+ */
+ ht_cap->ampdu_factor = IEEE80211_HT_MAX_AMPDU_64K;
+
+ /*Minimum MPDU start spacing , */
+ ht_cap->ampdu_density = IEEE80211_HT_MPDU_DENSITY_16;
+
+ ht_cap->mcs.tx_params = IEEE80211_HT_MCS_TX_DEFINED;
+
+ /*
+ *hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ *base on ant_num
+ *rx_mask: RX mask
+ *if rx_ant =1 rx_mask[0]=0xff;==>MCS0-MCS7
+ *if rx_ant =2 rx_mask[1]=0xff;==>MCS8-MCS15
+ *if rx_ant >=3 rx_mask[2]=0xff;
+ *if BW_40 rx_mask[4]=0x01;
+ *highest supported RX rate
+ */
+ if (rtlpriv->dm.supp_phymode_switch) {
+ RT_TRACE(COMP_INIT, DBG_EMERG, ("Support phy mode switch\n"));
+
+ ht_cap->mcs.rx_mask[0] = 0xFF;
+ ht_cap->mcs.rx_mask[1] = 0xFF;
+ ht_cap->mcs.rx_mask[4] = 0x01;
+
+ ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
+ } else {
+ if (get_rf_type(rtlphy) == RF_1T2R ||
+ get_rf_type(rtlphy) == RF_2T2R) {
+
+ RT_TRACE(COMP_INIT, DBG_DMESG, ("1T2R or 2T2R\n"));
+
+ ht_cap->mcs.rx_mask[0] = 0xFF;
+ ht_cap->mcs.rx_mask[1] = 0xFF;
+ ht_cap->mcs.rx_mask[4] = 0x01;
+
+ ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS15;
+ } else if (get_rf_type(rtlphy) == RF_1T1R) {
+
+ RT_TRACE(COMP_INIT, DBG_DMESG, ("1T1R\n"));
+
+ ht_cap->mcs.rx_mask[0] = 0xFF;
+ ht_cap->mcs.rx_mask[1] = 0x00;
+ ht_cap->mcs.rx_mask[4] = 0x01;
+
+ ht_cap->mcs.rx_highest = MAX_BIT_RATE_40MHZ_MCS7;
+ }
+ }
+}
+
+static void _rtl_init_mac80211(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtlpriv);
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct ieee80211_supported_band *sband;
+
+
+ if (rtlhal->macphymode == SINGLEMAC_SINGLEPHY &&
+ rtlhal->bandset == BAND_ON_BOTH) {
+ /* 1: 2.4 G bands */
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]), &rtl_band_2ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+
+ /* 2: 5 G bands */
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]), &rtl_band_5ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+ } else {
+ if (rtlhal->current_bandtype == BAND_ON_2_4G) {
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_2GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_2GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_2GHZ]),
+ &rtl_band_2ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_2GHZ] = sband;
+ } else if (rtlhal->current_bandtype == BAND_ON_5G) {
+ /* <1> use mac->bands as mem for hw->wiphy->bands */
+ sband = &(rtlmac->bands[IEEE80211_BAND_5GHZ]);
+
+ /* <2> set hw->wiphy->bands[IEEE80211_BAND_5GHZ]
+ * to default value(1T1R) */
+ memcpy(&(rtlmac->bands[IEEE80211_BAND_5GHZ]),
+ &rtl_band_5ghz,
+ sizeof(struct ieee80211_supported_band));
+
+ /* <3> init ht cap base on ant_num */
+ _rtl_init_hw_ht_capab(hw, &sband->ht_cap);
+
+ /* <4> set mac->sband to wiphy->sband */
+ hw->wiphy->bands[IEEE80211_BAND_5GHZ] = sband;
+ } else {
+ RT_TRACE(COMP_INIT, DBG_EMERG, ("Err BAND %d\n",
+ rtlhal->current_bandtype));
+ }
+ }
+ /* <5> set hw caps */
+ hw->flags = IEEE80211_HW_SIGNAL_DBM |
+ IEEE80211_HW_RX_INCLUDES_FCS |
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,4,0))
+ IEEE80211_HW_BEACON_FILTER |
+#endif
+ IEEE80211_HW_AMPDU_AGGREGATION |
+ IEEE80211_HW_REPORTS_TX_ACK_STATUS |
+ IEEE80211_HW_CONNECTION_MONITOR |
+ /* IEEE80211_HW_SUPPORTS_CQM_RSSI | */
+ IEEE80211_HW_MFP_CAPABLE | 0;
+
+ /* swlps or hwlps has been set in diff chip in init_sw_vars */
+ if (rtlpriv->psc.b_swctrl_lps)
+ hw->flags |= IEEE80211_HW_SUPPORTS_PS |
+ IEEE80211_HW_PS_NULLFUNC_STACK |
+ /* IEEE80211_HW_SUPPORTS_DYNAMIC_PS | */
+ 0;
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_MESH_POINT) |
+ BIT(NL80211_IFTYPE_P2P_CLIENT) |
+ BIT(NL80211_IFTYPE_P2P_GO);
+#else
+/*<delete in kernel end>*/
+ hw->wiphy->interface_modes =
+ BIT(NL80211_IFTYPE_AP) |
+ BIT(NL80211_IFTYPE_STATION) |
+ BIT(NL80211_IFTYPE_ADHOC) |
+ BIT(NL80211_IFTYPE_MESH_POINT) ;
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+#if (LINUX_VERSION_CODE > KERNEL_VERSION(2,6,39))
+ hw->wiphy->flags |= WIPHY_FLAG_IBSS_RSN;
+#endif
+
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,3,0))
+ hw->wiphy->flags |= WIPHY_FLAG_HAS_REMAIN_ON_CHANNEL;
+#endif
+
+ hw->wiphy->rts_threshold = 2347;
+
+ hw->queues = AC_MAX;
+ hw->extra_tx_headroom = RTL_TX_HEADER_SIZE;
+
+ /* TODO: Correct this value for our hw */
+ /* TODO: define these hard code value */
+ hw->max_listen_interval = 10;
+ hw->max_rate_tries = 4;
+ /* hw->max_rates = 1; */
+ hw->sta_data_size = sizeof(struct rtl_sta_info);
+#ifdef VIF_TODO
+ hw->vif_data_size = sizeof(struct rtl_vif_info);
+#endif
+
+ /* <6> mac address */
+ if (is_valid_ether_addr(rtlefuse->dev_addr)) {
+ SET_IEEE80211_PERM_ADDR(hw, rtlefuse->dev_addr);
+ } else {
+ u8 rtlmac[] = { 0x00, 0xe0, 0x4c, 0x81, 0x92, 0x00 };
+ get_random_bytes((rtlmac + (ETH_ALEN - 1)), 1);
+ SET_IEEE80211_PERM_ADDR(hw, rtlmac);
+ }
+
+}
+
+static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ /* <1> timer */
+ init_timer(&rtlpriv->works.watchdog_timer);
+ setup_timer(&rtlpriv->works.watchdog_timer,
+ rtl_watch_dog_timer_callback, (unsigned long)hw);
+ init_timer(&rtlpriv->works.dualmac_easyconcurrent_retrytimer);
+ setup_timer(&rtlpriv->works.dualmac_easyconcurrent_retrytimer,
+ rtl_easy_concurrent_retrytimer_callback, (unsigned long)hw);
+ /* <2> work queue */
+ rtlpriv->works.hw = hw;
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,37))
+/*<delete in kernel end>*/
+ rtlpriv->works.rtl_wq = alloc_workqueue(rtlpriv->cfg->name, 0, 0);
+/*<delete in kernel start>*/
+#else
+ rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name);
+#endif
+/*<delete in kernel end>*/
+ INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
+ (void *)rtl_watchdog_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
+ (void *)rtl_ips_nic_off_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ps_work,
+ (void *)rtl_swlps_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.ps_rfon_wq,
+ (void *)rtl_swlps_rfon_wq_callback);
+ INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq,
+ (void *)rtl_fwevt_wq_callback);
+
+}
+
+void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ del_timer_sync(&rtlpriv->works.watchdog_timer);
+
+ cancel_delayed_work(&rtlpriv->works.watchdog_wq);
+ cancel_delayed_work(&rtlpriv->works.ips_nic_off_wq);
+ cancel_delayed_work(&rtlpriv->works.ps_work);
+ cancel_delayed_work(&rtlpriv->works.ps_rfon_wq);
+ cancel_delayed_work(&rtlpriv->works.fwevt_wq);
+}
+
+void rtl_init_rfkill(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ bool radio_state;
+ bool blocked;
+ u8 valid = 0;
+
+ /*set init state to on */
+ rtlpriv->rfkill.rfkill_state = 1;
+ wiphy_rfkill_set_hw_state(hw->wiphy, 0);
+
+ radio_state = rtlpriv->cfg->ops->radio_onoff_checking(hw, &valid);
+
+ if (valid) {
+ printk(KERN_INFO "rtlwifi: wireless switch is %s\n",
+ rtlpriv->rfkill.rfkill_state ? "on" : "off");
+
+ rtlpriv->rfkill.rfkill_state = radio_state;
+
+ blocked = (rtlpriv->rfkill.rfkill_state == 1) ? 0 : 1;
+ wiphy_rfkill_set_hw_state(hw->wiphy, blocked);
+ }
+
+ wiphy_rfkill_start_polling(hw->wiphy);
+}
+
+void rtl_deinit_rfkill(struct ieee80211_hw *hw)
+{
+ wiphy_rfkill_stop_polling(hw->wiphy);
+}
+
+#ifdef VIF_TODO
+static void rtl_init_vif(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ INIT_LIST_HEAD(&rtlpriv->vif_priv.vif_list);
+
+ rtlpriv->vif_priv.vifs = 0;
+}
+#endif
+
+int rtl_init_core(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+
+ /* <1> init mac80211 */
+ _rtl_init_mac80211(hw);
+ rtlmac->hw = hw;
+ rtlmac->link_state = MAC80211_NOLINK;
+
+ /* <2> rate control register */
+ hw->rate_control_algorithm = "rtl_rc";
+
+ /*
+ * <3> init CRDA must come after init
+ * mac80211 hw in _rtl_init_mac80211.
+ */
+ if (rtl_regd_init(hw, rtl_reg_notifier)) {
+ RT_TRACE(COMP_ERR, DBG_EMERG, ("REGD init failed\n"));
+ return 1;
+ }
+
+ /* <4> locks */
+ mutex_init(&rtlpriv->locks.conf_mutex);
+ spin_lock_init(&rtlpriv->locks.ips_lock);
+ spin_lock_init(&rtlpriv->locks.irq_th_lock);
+ spin_lock_init(&rtlpriv->locks.h2c_lock);
+ spin_lock_init(&rtlpriv->locks.rf_ps_lock);
+ spin_lock_init(&rtlpriv->locks.rf_lock);
+ spin_lock_init(&rtlpriv->locks.lps_lock);
+ spin_lock_init(&rtlpriv->locks.waitq_lock);
+ spin_lock_init(&rtlpriv->locks.entry_list_lock);
+ spin_lock_init(&rtlpriv->locks.cck_and_rw_pagea_lock);
+ spin_lock_init(&rtlpriv->locks.check_sendpkt_lock);
+ spin_lock_init(&rtlpriv->locks.fw_ps_lock);
+ spin_lock_init(&rtlpriv->locks.iqk_lock);
+ /* <5> init list */
+ INIT_LIST_HEAD(&rtlpriv->entry_list);
+
+ /* <6> init deferred work */
+ _rtl_init_deferred_work(hw);
+
+ /* <7> */
+#ifdef VIF_TODO
+ rtl_init_vif(hw);
+#endif
+
+ return 0;
+}
+
+void rtl_deinit_core(struct ieee80211_hw *hw)
+{
+}
+
+void rtl_init_rx_config(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ rtlpriv->cfg->ops->get_hw_reg(hw, HW_VAR_RCR, (u8 *) (&mac->rx_conf));
+}
+
+/*********************************************************
+ *
+ * tx information functions
+ *
+ *********************************************************/
+static void _rtl_qurey_shortpreamble_mode(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *tcb_desc,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 rate_flag = info->control.rates[0].flags;
+
+ tcb_desc->use_shortpreamble = false;
+
+ /* 1M can only use Long Preamble. 11B spec */
+ if (tcb_desc->hw_rate == rtlpriv->cfg->maps[RTL_RC_CCK_RATE1M])
+ return;
+ else if (rate_flag & IEEE80211_TX_RC_USE_SHORT_PREAMBLE)
+ tcb_desc->use_shortpreamble = true;
+
+ return;
+}
+
+static void _rtl_query_shortgi(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct rtl_tcb_desc *tcb_desc,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ u8 rate_flag = info->control.rates[0].flags;
+ u8 sgi_40 = 0, sgi_20 = 0, bw_40 = 0;
+ tcb_desc->use_shortgi = false;
+
+ if (sta == NULL)
+ return;
+
+ sgi_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_40;
+ sgi_20 = sta->ht_cap.cap & IEEE80211_HT_CAP_SGI_20;
+
+ if (!(sta->ht_cap.ht_supported))
+ return;
+
+ if (!sgi_40 && !sgi_20)
+ return;
+
+ if (mac->opmode == NL80211_IFTYPE_STATION)
+ bw_40 = mac->bw_40;
+ else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT)
+ bw_40 = sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40;
+
+ if ((bw_40 == true) && sgi_40)
+ tcb_desc->use_shortgi = true;
+ else if ((bw_40 == false) && sgi_20)
+ tcb_desc->use_shortgi = true;
+
+ if (!(rate_flag & IEEE80211_TX_RC_SHORT_GI))
+ tcb_desc->use_shortgi = false;
+}
+
+static void _rtl_query_protection_mode(struct ieee80211_hw *hw,
+ struct rtl_tcb_desc *tcb_desc,
+ struct ieee80211_tx_info *info)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u8 rate_flag = info->control.rates[0].flags;
+
+ /* Common Settings */
+ tcb_desc->b_rts_stbc = false;
+ tcb_desc->b_cts_enable = false;
+ tcb_desc->rts_sc = 0;
+ tcb_desc->b_rts_bw = false;
+ tcb_desc->b_rts_use_shortpreamble = false;
+ tcb_desc->b_rts_use_shortgi = false;
+
+ if (rate_flag & IEEE80211_TX_RC_USE_CTS_PROTECT) {
+ /* Use CTS-to-SELF in protection mode. */
+ tcb_desc->b_rts_enable = true;
+ tcb_desc->b_cts_enable = true;
+ tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
+ } else if (rate_flag & IEEE80211_TX_RC_USE_RTS_CTS) {
+ /* Use RTS-CTS in protection mode. */
+ tcb_desc->b_rts_enable = true;
+ tcb_desc->rts_rate = rtlpriv->cfg->maps[RTL_RC_OFDM_RATE24M];
+ }
+}
+
+static void _rtl_txrate_selectmode(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct rtl_tcb_desc *tcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_sta_info *sta_entry = NULL;
+ u8 ratr_index = 7;
+
+ if (sta) {
+ sta_entry = (struct rtl_sta_info *) sta->drv_priv;
+ ratr_index = sta_entry->ratr_index;
+ }
+ if (!tcb_desc->disable_ratefallback || !tcb_desc->use_driver_rate) {
+ if (mac->opmode == NL80211_IFTYPE_STATION) {
+ tcb_desc->ratr_index = 0;
+ } else if (mac->opmode == NL80211_IFTYPE_ADHOC ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ if (tcb_desc->b_multicast || tcb_desc->b_broadcast) {
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_CCK_RATE2M];
+ tcb_desc->use_driver_rate = 1;
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
+ } else {
+ tcb_desc->ratr_index = ratr_index;
+ }
+ } else if (mac->opmode == NL80211_IFTYPE_AP) {
+ tcb_desc->ratr_index = ratr_index;
+ }
+ }
+
+ if (rtlpriv->dm.b_useramask) {
+ tcb_desc->ratr_index = ratr_index;
+ /* TODO we will differentiate adhoc and station futrue */
+ if (mac->opmode == NL80211_IFTYPE_STATION ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ tcb_desc->mac_id = 0;
+
+ if (mac->mode == WIRELESS_MODE_N_24G) {
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_NGB;
+ } else if (mac->mode == WIRELESS_MODE_N_5G) {
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_NG;
+ } else if (mac->mode & WIRELESS_MODE_G) {
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_GB;
+ } else if (mac->mode & WIRELESS_MODE_B) {
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_B;
+ } else if (mac->mode & WIRELESS_MODE_A) {
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_G;
+ }
+ } else if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC) {
+ if (NULL != sta) {
+ if (sta->aid > 0) {
+ tcb_desc->mac_id = sta->aid + 1;
+ } else {
+ tcb_desc->mac_id = 1;
+ }
+ } else {
+ tcb_desc->mac_id = 0;
+ }
+ }
+ }
+}
+
+static void _rtl_query_bandwidth_mode(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ struct rtl_tcb_desc *tcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+
+ tcb_desc->b_packet_bw = false;
+ if (!sta)
+ return;
+ if (mac->opmode == NL80211_IFTYPE_AP ||
+ mac->opmode == NL80211_IFTYPE_ADHOC ||
+ mac->opmode == NL80211_IFTYPE_MESH_POINT) {
+ if (!(sta->ht_cap.ht_supported) ||
+ !(sta->ht_cap.cap & IEEE80211_HT_CAP_SUP_WIDTH_20_40))
+ return;
+ } else if (mac->opmode == NL80211_IFTYPE_STATION) {
+ if (!mac->bw_40 || !(sta->ht_cap.ht_supported))
+ return;
+ }
+ if (tcb_desc->b_multicast || tcb_desc->b_broadcast)
+ return;
+
+ /*use legency rate, shall use 20MHz */
+ if (tcb_desc->hw_rate <= rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M])
+ return;
+
+ tcb_desc->b_packet_bw = true;
+}
+
+static u8 _rtl_get_highest_n_rate(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_phy *rtlphy = &(rtlpriv->phy);
+ u8 hw_rate;
+
+ if ((get_rf_type(rtlphy) == RF_2T2R) && (sta->ht_cap.mcs.rx_mask[1]!=0))
+ hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS15];
+ else
+ hw_rate = rtlpriv->cfg->maps[RTL_RC_HT_RATEMCS7];
+
+ return hw_rate;
+}
+
+void rtl_get_tcb_desc(struct ieee80211_hw *hw,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *rtlmac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+ struct ieee80211_rate *txrate;
+ u16 fc = rtl_get_fc(skb);
+
+ txrate = ieee80211_get_tx_rate(hw, info);
+ if (txrate != NULL)
+ tcb_desc->hw_rate = txrate->hw_value;
+
+ if (ieee80211_is_data(fc)) {
+ /*
+ *we set data rate INX 0
+ *in rtl_rc.c if skb is special data or
+ *mgt which need low data rate.
+ */
+
+ /*
+ *So tcb_desc->hw_rate is just used for
+ *special data and mgt frames
+ */
+ if (info->control.rates[0].idx == 0 ||
+ ieee80211_is_nullfunc(fc)) {
+ tcb_desc->use_driver_rate = true;
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
+
+ tcb_desc->disable_ratefallback = 1;
+ } else {
+ /*
+ *because hw will nerver use hw_rate
+ *when tcb_desc->use_driver_rate = false
+ *so we never set highest N rate here,
+ *and N rate will all be controled by FW
+ *when tcb_desc->use_driver_rate = false
+ */
+ if (sta && (sta->ht_cap.ht_supported)) {
+ tcb_desc->hw_rate = _rtl_get_highest_n_rate(hw, sta);
+ } else {
+ if(rtlmac->mode == WIRELESS_MODE_B) {
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_CCK_RATE11M];
+ } else {
+ tcb_desc->hw_rate =
+ rtlpriv->cfg->maps[RTL_RC_OFDM_RATE54M];
+ }
+ }
+ }
+
+ if (is_multicast_ether_addr(ieee80211_get_DA(hdr)))
+ tcb_desc->b_multicast = 1;
+ else if (is_broadcast_ether_addr(ieee80211_get_DA(hdr)))
+ tcb_desc->b_broadcast = 1;
+
+ _rtl_txrate_selectmode(hw, sta, tcb_desc);
+ _rtl_query_bandwidth_mode(hw, sta, tcb_desc);
+ _rtl_qurey_shortpreamble_mode(hw, tcb_desc, info);
+ _rtl_query_shortgi(hw, sta, tcb_desc, info);
+ _rtl_query_protection_mode(hw, tcb_desc, info);
+ } else {
+ tcb_desc->use_driver_rate = true;
+ tcb_desc->ratr_index = RATR_INX_WIRELESS_MC;
+ tcb_desc->disable_ratefallback = 1;
+ tcb_desc->mac_id = 0;
+ tcb_desc->b_packet_bw = false;
+ }
+}
+//EXPORT_SYMBOL(rtl_get_tcb_desc);
+
+bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 fc = rtl_get_fc(skb);
+
+ if (rtlpriv->dm.supp_phymode_switch &&
+ mac->link_state < MAC80211_LINKED &&
+ (ieee80211_is_auth(fc) || ieee80211_is_probe_req(fc))) {
+ if (rtlpriv->cfg->ops->check_switch_to_dmdp)
+ rtlpriv->cfg->ops->check_switch_to_dmdp(hw);
+ }
+ if (ieee80211_is_auth(fc)) {
+ RT_TRACE(COMP_SEND, DBG_DMESG, ("MAC80211_LINKING\n"));
+ rtl_ips_nic_on(hw);
+
+ mac->link_state = MAC80211_LINKING;
+ /* Dul mac */
+ rtlpriv->phy.b_need_iqk = true;
+
+ }
+
+ return true;
+}
+
+struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw, u8 *sa,
+ u8 *bssid, u16 tid);
+bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
+{
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = rtl_get_hdr(skb);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ u16 fc = rtl_get_fc(skb);
+ u8 *act = (u8 *) (((u8 *) skb->data + MAC80211_3ADDR_LEN));
+ u8 category;
+
+ if (!ieee80211_is_action(fc))
+ return true;
+
+ category = *act;
+ act++;
+ switch (category) {
+ case ACT_CAT_BA:
+ switch (*act) {
+ case ACT_ADDBAREQ:
+ if (mac->act_scanning)
+ return false;
+
+ RT_TRACE((COMP_SEND | COMP_RECV), DBG_DMESG,
+ ("%s ACT_ADDBAREQ From :%pM\n",
+ is_tx ? "Tx" : "Rx", hdr->addr2));
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG, ("req \n"),
+ skb->data, skb->len);
+ if (!is_tx) {
+ struct ieee80211_sta *sta = NULL;
+ struct rtl_sta_info *sta_entry = NULL;
+ struct ieee80211_mgmt *mgmt = (void *)skb->data;
+ u16 capab = 0, tid = 0;
+ struct rtl_tid_data *tid_data;
+ struct sk_buff *skb_delba = NULL;
+ struct ieee80211_rx_status rx_status = { 0 };
+
+ rcu_read_lock();
+ sta = rtl_find_sta(hw, hdr->addr3);
+ if (sta == NULL) {
+ RT_TRACE((COMP_SEND | COMP_RECV),
+ DBG_EMERG, ("sta is NULL\n"));
+ rcu_read_unlock();
+ return true;
+ }
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ if (!sta_entry) {
+ rcu_read_unlock();
+ return true;
+ }
+ capab = le16_to_cpu(mgmt->u.action.u.addba_req.capab);
+ tid = (capab & IEEE80211_ADDBA_PARAM_TID_MASK) >> 2;
+ tid_data = &sta_entry->tids[tid];
+ if (tid_data->agg.rx_agg_state ==
+ RTL_RX_AGG_START) {
+ skb_delba = rtl_make_del_ba(hw,
+ hdr->addr2,
+ hdr->addr3,
+ tid);
+ if (skb_delba) {
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+ rx_status.freq = hw->conf.chandef.chan->center_freq;
+ rx_status.band = hw->conf.chandef.chan->band;
+#else
+ rx_status.freq = hw->conf.channel->center_freq;
+ rx_status.band = hw->conf.channel->band;
+#endif
+ rx_status.flag |= RX_FLAG_DECRYPTED;
+ rx_status.flag |= RX_FLAG_MACTIME_MPDU;
+ rx_status.rate_idx = 0;
+ rx_status.signal = 50 + 10;
+ memcpy(IEEE80211_SKB_RXCB(skb_delba), &rx_status,
+ sizeof(rx_status));
+ RT_PRINT_DATA(rtlpriv, COMP_INIT, DBG_DMESG,
+ ("fake del\n"), skb_delba->data,
+ skb_delba->len);
+ ieee80211_rx_irqsafe(hw, skb_delba);
+ }
+ }
+ rcu_read_unlock();
+ }
+ break;
+ case ACT_ADDBARSP:
+ RT_TRACE((COMP_SEND | COMP_RECV), DBG_DMESG,
+ ("%s ACT_ADDBARSP From :%pM\n",
+ is_tx ? "Tx" : "Rx", hdr->addr2));
+ break;
+ case ACT_DELBA:
+ RT_TRACE((COMP_SEND | COMP_RECV), DBG_DMESG,
+ ("ACT_ADDBADEL From :%pM\n", hdr->addr2));
+ break;
+ }
+ break;
+ default:
+ break;
+ }
+
+ return true;
+}
+
+/*should call before software enc*/
+u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ u16 fc = rtl_get_fc(skb);
+ u16 ether_type;
+ u8 mac_hdr_len = ieee80211_get_hdrlen_from_skb(skb);
+ const struct iphdr *ip;
+
+ if (!ieee80211_is_data(fc))
+ goto end;
+
+
+ ip = (struct iphdr *)((u8 *) skb->data + mac_hdr_len +
+ SNAP_SIZE + PROTOC_TYPE_SIZE);
+ ether_type = *(u16 *) ((u8 *) skb->data + mac_hdr_len + SNAP_SIZE);
+ ether_type = ntohs(ether_type);
+
+ if (ETH_P_IP == ether_type) {
+ if (IPPROTO_UDP == ip->protocol) {
+ struct udphdr *udp = (struct udphdr *)((u8 *) ip +
+ (ip->ihl << 2));
+ if (((((u8 *) udp)[1] == 68) &&
+ (((u8 *) udp)[3] == 67)) ||
+ ((((u8 *) udp)[1] == 67) &&
+ (((u8 *) udp)[3] == 68))) {
+ /*
+ * 68 : UDP BOOTP client
+ * 67 : UDP BOOTP server
+ */
+ RT_TRACE((COMP_SEND | COMP_RECV),
+ DBG_DMESG, ("dhcp %s !!\n",
+ (is_tx) ? "Tx" : "Rx"));
+
+ if (is_tx) {
+ rtlpriv->ra.is_special_data = true;
+ rtl_lps_leave(hw);
+ ppsc->last_delaylps_stamp_jiffies =
+ jiffies;
+ }
+
+ return true;
+ }
+ }
+ } else if (ETH_P_ARP == ether_type) {
+ if (is_tx) {
+ rtlpriv->ra.is_special_data = true;
+ rtl_lps_leave(hw);
+ ppsc->last_delaylps_stamp_jiffies = jiffies;
+ }
+
+ return true;
+ } else if (ETH_P_PAE == ether_type) {
+ RT_TRACE((COMP_SEND | COMP_RECV), DBG_DMESG,
+ ("802.1X %s EAPOL pkt!!\n", (is_tx) ? "Tx" : "Rx"));
+
+ if (is_tx) {
+ rtlpriv->ra.is_special_data = true;
+ rtl_lps_leave(hw);
+ ppsc->last_delaylps_stamp_jiffies = jiffies;
+ }
+
+ return true;
+ } else if (0x86DD == ether_type) {
+ return true;
+ }
+
+end:
+ rtlpriv->ra.is_special_data = false;
+ return false;
+}
+
+/*********************************************************
+ *
+ * functions called by core.c
+ *
+ *********************************************************/
+int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u16 tid, u16 *ssn)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (sta == NULL)
+ return -EINVAL;
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ if (!sta_entry)
+ return -ENXIO;
+ tid_data = &sta_entry->tids[tid];
+
+ RT_TRACE(COMP_SEND, DBG_DMESG,
+ ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid,
+ tid_data->seq_number));
+
+ *ssn = tid_data->seq_number;
+ tid_data->agg.agg_state = RTL_AGG_START;
+
+ ieee80211_start_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ return 0;
+}
+
+int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (sta == NULL)
+ return -EINVAL;
+
+ if (!sta->addr) {
+ RT_TRACE(COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+ return -EINVAL;
+ }
+
+ RT_TRACE(COMP_SEND, DBG_DMESG,
+ ("on ra = %pM tid = %d\n", sta->addr, tid));
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ tid_data = &sta_entry->tids[tid];
+ sta_entry->tids[tid].agg.agg_state = RTL_AGG_STOP;
+
+ ieee80211_stop_tx_ba_cb_irqsafe(vif, sta->addr, tid);
+ return 0;
+}
+
+int rtl_rx_agg_start(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (sta == NULL)
+ return -EINVAL;
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ if (!sta_entry)
+ return -ENXIO;
+ tid_data = &sta_entry->tids[tid];
+
+ RT_TRACE(COMP_RECV, DBG_DMESG,
+ ("on ra = %pM tid = %d seq:%d\n", sta->addr, tid,
+ tid_data->seq_number));
+
+ tid_data->agg.rx_agg_state = RTL_RX_AGG_START;
+ return 0;
+}
+
+int rtl_rx_agg_stop(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (sta == NULL)
+ return -EINVAL;
+
+ if (!sta->addr) {
+ RT_TRACE(COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+ return -EINVAL;
+ }
+
+ RT_TRACE(COMP_SEND, DBG_DMESG,
+ ("on ra = %pM tid = %d\n", sta->addr, tid));
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ tid_data = &sta_entry->tids[tid];
+ sta_entry->tids[tid].agg.rx_agg_state = RTL_RX_AGG_STOP;
+
+ return 0;
+}
+int rtl_tx_agg_oper(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_tid_data *tid_data;
+ struct rtl_sta_info *sta_entry = NULL;
+
+ if (sta == NULL)
+ return -EINVAL;
+
+ if (!sta->addr) {
+ RT_TRACE(COMP_ERR, DBG_EMERG, ("ra = NULL\n"));
+ return -EINVAL;
+ }
+
+ RT_TRACE(COMP_SEND, DBG_DMESG,
+ ("on ra = %pM tid = %d\n", sta->addr, tid));
+
+ if (unlikely(tid >= MAX_TID_COUNT))
+ return -EINVAL;
+
+ sta_entry = (struct rtl_sta_info *)sta->drv_priv;
+ tid_data = &sta_entry->tids[tid];
+ sta_entry->tids[tid].agg.agg_state = RTL_AGG_OPERATIONAL;
+
+ return 0;
+}
+
+/*********************************************************
+ *
+ * wq & timer callback functions
+ *
+ *********************************************************/
+/* this function is used for roaming */
+void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)skb->data;
+
+ if (rtlpriv->mac80211.opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (rtlpriv->mac80211.link_state < MAC80211_LINKED)
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control) &&
+ !ieee80211_is_probe_resp(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (skb->len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ rtlpriv->link_info.bcn_rx_inperiod ++;
+}
+
+void rtl_watchdog_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks = container_of_dwork_rtl(data,
+ struct rtl_works,
+ watchdog_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ bool b_busytraffic = false;
+ bool b_tx_busy_traffic = false;
+ bool b_rx_busy_traffic = false;
+ bool b_higher_busytraffic = false;
+ bool b_higher_busyrxtraffic = false;
+ u8 idx, tid;
+ u32 rx_cnt_inp4eriod = 0;
+ u32 tx_cnt_inp4eriod = 0;
+ u32 aver_rx_cnt_inperiod = 0;
+ u32 aver_tx_cnt_inperiod = 0;
+ u32 aver_tidtx_inperiod[MAX_TID_COUNT] = {0};
+ u32 tidtx_inp4eriod[MAX_TID_COUNT] = {0};
+ bool benter_ps = false;
+
+ if (is_hal_stop(rtlhal))
+ return;
+
+ /* <1> Determine if action frame is allowed */
+ if (mac->link_state > MAC80211_NOLINK) {
+ if (mac->cnt_after_linked < 20)
+ mac->cnt_after_linked++;
+ } else {
+ mac->cnt_after_linked = 0;
+ }
+
+ /* <2> to check if traffic busy, if
+ * busytraffic we don't change channel */
+ if (mac->link_state >= MAC80211_LINKED) {
+
+ /* (1) get aver_rx_cnt_inperiod & aver_tx_cnt_inperiod */
+ for (idx = 0; idx <= 2; idx++) {
+ rtlpriv->link_info.num_rx_in4period[idx] =
+ rtlpriv->link_info.num_rx_in4period[idx + 1];
+ rtlpriv->link_info.num_tx_in4period[idx] =
+ rtlpriv->link_info.num_tx_in4period[idx + 1];
+ }
+ rtlpriv->link_info.num_rx_in4period[3] =
+ rtlpriv->link_info.num_rx_inperiod;
+ rtlpriv->link_info.num_tx_in4period[3] =
+ rtlpriv->link_info.num_tx_inperiod;
+ for (idx = 0; idx <= 3; idx++) {
+ rx_cnt_inp4eriod +=
+ rtlpriv->link_info.num_rx_in4period[idx];
+ tx_cnt_inp4eriod +=
+ rtlpriv->link_info.num_tx_in4period[idx];
+ }
+ aver_rx_cnt_inperiod = rx_cnt_inp4eriod / 4;
+ aver_tx_cnt_inperiod = tx_cnt_inp4eriod / 4;
+
+ /* (2) check traffic busy */
+ if (aver_rx_cnt_inperiod > 100 || aver_tx_cnt_inperiod > 100) {
+ b_busytraffic = true;
+ if (aver_rx_cnt_inperiod > aver_tx_cnt_inperiod)
+ b_rx_busy_traffic = true;
+ else
+ b_tx_busy_traffic = false;
+ }
+
+ /* Higher Tx/Rx data. */
+ if (aver_rx_cnt_inperiod > 4000 ||
+ aver_tx_cnt_inperiod > 4000) {
+ b_higher_busytraffic = true;
+
+ /* Extremely high Rx data. */
+ if (aver_rx_cnt_inperiod > 5000)
+ b_higher_busyrxtraffic = true;
+ }
+
+ /* check every tid's tx traffic */
+ for (tid = 0; tid <= 7; tid++) {
+ for (idx = 0; idx <= 2; idx++)
+ rtlpriv->link_info.tidtx_in4period[tid][idx] =
+ rtlpriv->link_info.tidtx_in4period[tid]
+ [idx + 1];
+ rtlpriv->link_info.tidtx_in4period[tid][3] =
+ rtlpriv->link_info.tidtx_inperiod[tid];
+
+ for (idx = 0; idx <= 3; idx++)
+ tidtx_inp4eriod[tid] +=
+ rtlpriv->link_info.tidtx_in4period[tid][idx];
+ aver_tidtx_inperiod[tid] = tidtx_inp4eriod[tid] / 4;
+ if (aver_tidtx_inperiod[tid] > 5000)
+ rtlpriv->link_info.higher_busytxtraffic[tid] =
+ true;
+ else
+ rtlpriv->link_info.higher_busytxtraffic[tid] =
+ false;
+ }
+
+ if (((rtlpriv->link_info.num_rx_inperiod +
+ rtlpriv->link_info.num_tx_inperiod) > 8) ||
+ (rtlpriv->link_info.num_rx_inperiod > 2))
+ benter_ps = false;
+ else
+ benter_ps = true;
+
+ /* LeisurePS only work in infra mode. */
+ if (benter_ps)
+ rtl_lps_enter(hw);
+ else
+ rtl_lps_leave(hw);
+ }
+
+ rtlpriv->link_info.num_rx_inperiod = 0;
+ rtlpriv->link_info.num_tx_inperiod = 0;
+ for (tid = 0; tid <= 7; tid++)
+ rtlpriv->link_info.tidtx_inperiod[tid] = 0;
+
+ rtlpriv->link_info.b_busytraffic = b_busytraffic;
+ rtlpriv->link_info.b_rx_busy_traffic = b_rx_busy_traffic;
+ rtlpriv->link_info.b_tx_busy_traffic = b_tx_busy_traffic;
+ rtlpriv->link_info.b_higher_busytraffic = b_higher_busytraffic;
+ rtlpriv->link_info.b_higher_busyrxtraffic = b_higher_busyrxtraffic;
+
+ /* <3> DM */
+ rtlpriv->cfg->ops->dm_watchdog(hw);
+
+ /* <4> roaming */
+ if (mac->link_state == MAC80211_LINKED &&
+ mac->opmode == NL80211_IFTYPE_STATION) {
+ if ((rtlpriv->link_info.bcn_rx_inperiod +
+ rtlpriv->link_info.num_rx_inperiod) == 0) {
+ rtlpriv->link_info.roam_times++;
+ RT_TRACE(COMP_ERR, DBG_DMESG, ("AP off for %d s\n",
+ (rtlpriv->link_info.roam_times * 2)));
+
+ /* if we can't recv beacon for 10s,
+ * we should reconnect this AP */
+ if (rtlpriv->link_info.roam_times >= 5) {
+ RT_TRACE(COMP_ERR, DBG_EMERG,
+ ("AP off, try to reconnect now\n"));
+ rtlpriv->link_info.roam_times = 0;
+ ieee80211_connection_loss(rtlpriv->mac80211.vif);
+ }
+ } else {
+ rtlpriv->link_info.roam_times = 0;
+ }
+ }
+ rtlpriv->link_info.bcn_rx_inperiod = 0;
+}
+
+void rtl_watch_dog_timer_callback(unsigned long data)
+{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ queue_delayed_work(rtlpriv->works.rtl_wq,
+ &rtlpriv->works.watchdog_wq, 0);
+
+ mod_timer(&rtlpriv->works.watchdog_timer,
+ jiffies + MSECS(RTL_WATCH_DOG_TIME));
+}
+void rtl_fwevt_wq_callback(void *data)
+{
+ struct rtl_works *rtlworks =
+ container_of_dwork_rtl(data, struct rtl_works, fwevt_wq);
+ struct ieee80211_hw *hw = rtlworks->hw;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ rtlpriv->cfg->ops->c2h_command_handle(hw);
+}
+void rtl_easy_concurrent_retrytimer_callback(unsigned long data)
+{
+ struct ieee80211_hw *hw = (struct ieee80211_hw *)data;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_priv *buddy_priv = rtlpriv->buddy_priv;
+
+ if(buddy_priv == NULL)
+ return;
+
+ rtlpriv->cfg->ops->dualmac_easy_concurrent(hw);
+}
+/*********************************************************
+ *
+ * frame process functions
+ *
+ *********************************************************/
+u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos + 2 + pos[1] > end)
+ return NULL;
+
+ if (pos[0] == ie)
+ return pos;
+
+ pos += 2 + pos[1];
+ }
+ return NULL;
+}
+
+/* when we use 2 rx ants we send IEEE80211_SMPS_OFF */
+/* when we use 1 rx ant we send IEEE80211_SMPS_STATIC */
+struct sk_buff *rtl_make_smps_action(struct ieee80211_hw *hw,
+ enum ieee80211_smps_mode smps,
+ u8 *da, u8 *bssid)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct sk_buff *skb;
+ struct ieee80211_mgmt_compat *action_frame;
+
+ /* 27 = header + category + action + smps mode */
+ skb = dev_alloc_skb(27 + hw->extra_tx_headroom);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, hw->extra_tx_headroom);
+ action_frame = (void *)skb_put(skb, 27);
+ memset(action_frame, 0, 27);
+ memcpy(action_frame->da, da, ETH_ALEN);
+ memcpy(action_frame->sa, rtlefuse->dev_addr, ETH_ALEN);
+ memcpy(action_frame->bssid, bssid, ETH_ALEN);
+ action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+ action_frame->u.action.category = WLAN_CATEGORY_HT;
+ action_frame->u.action.u.ht_smps.action = WLAN_HT_ACTION_SMPS;
+ switch (smps) {
+ case IEEE80211_SMPS_AUTOMATIC:/* 0 */
+ case IEEE80211_SMPS_NUM_MODES:/* 4 */
+ WARN_ON(1);
+ case IEEE80211_SMPS_OFF:/* 1 */ /*MIMO_PS_NOLIMIT*/
+ action_frame->u.action.u.ht_smps.smps_control =
+ WLAN_HT_SMPS_CONTROL_DISABLED;/* 0 */
+ break;
+ case IEEE80211_SMPS_STATIC:/* 2 */ /*MIMO_PS_STATIC*/
+ action_frame->u.action.u.ht_smps.smps_control =
+ WLAN_HT_SMPS_CONTROL_STATIC;/* 1 */
+ break;
+ case IEEE80211_SMPS_DYNAMIC:/* 3 */ /*MIMO_PS_DYNAMIC*/
+ action_frame->u.action.u.ht_smps.smps_control =
+ WLAN_HT_SMPS_CONTROL_DYNAMIC;/* 3 */
+ break;
+ }
+
+ return skb;
+}
+
+int rtl_send_smps_action(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ enum ieee80211_smps_mode smps)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_hal *rtlhal = rtl_hal(rtl_priv(hw));
+ struct rtl_ps_ctl *ppsc = rtl_psc(rtl_priv(hw));
+ struct sk_buff *skb = NULL;
+ struct rtl_tcb_desc tcb_desc;
+ u8 bssid[ETH_ALEN] = {0};
+
+ memset(&tcb_desc, 0, sizeof(struct rtl_tcb_desc));
+
+ if (rtlpriv->mac80211.act_scanning)
+ goto err_free;
+
+ if (!sta)
+ goto err_free;
+
+ if (unlikely(is_hal_stop(rtlhal) || ppsc->rfpwr_state != ERFON))
+ goto err_free;
+
+ if (!test_bit(RTL_STATUS_INTERFACE_START, &rtlpriv->status))
+ goto err_free;
+
+ if (rtlpriv->mac80211.opmode == NL80211_IFTYPE_AP)
+ memcpy(bssid, rtlpriv->efuse.dev_addr, ETH_ALEN);
+ else
+ memcpy(bssid, rtlpriv->mac80211.bssid, ETH_ALEN);
+
+ skb = rtl_make_smps_action(hw, smps, sta->addr, bssid);
+ /* this is a type = mgmt * stype = action frame */
+ if (skb) {
+ struct ieee80211_tx_info *info = IEEE80211_SKB_CB(skb);
+ struct rtl_sta_info *sta_entry =
+ (struct rtl_sta_info *) sta->drv_priv;
+ sta_entry->mimo_ps = smps;
+ /* rtlpriv->cfg->ops->update_rate_tbl(hw, sta, 0); */
+
+ info->control.rates[0].idx = 0;
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(3,10,0))
+ info->band = hw->conf.chandef.chan->band;
+#else
+ info->band = hw->conf.channel->band;
+#endif
+/*<delete in kernel start>*/
+#if (LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0))
+ info->control.sta = sta;
+ rtlpriv->intf_ops->adapter_tx(hw, skb, &tcb_desc);
+#else
+/*<delete in kernel end>*/
+ rtlpriv->intf_ops->adapter_tx(hw, sta, skb, &tcb_desc);
+/*<delete in kernel start>*/
+#endif
+/*<delete in kernel end>*/
+ }
+ return 1;
+
+err_free:
+ return 0;
+}
+//EXPORT_SYMBOL(rtl_send_smps_action);
+
+/* because mac80211 have issues when can receive del ba
+ * so here we just make a fake del_ba if we receive a ba_req
+ * but rx_agg was opened to let mac80211 release some ba
+ * related resources, so please this del_ba for tx */
+struct sk_buff *rtl_make_del_ba(struct ieee80211_hw *hw,
+ u8 *sa, u8 *bssid, u16 tid)
+{
+ struct rtl_efuse *rtlefuse = rtl_efuse(rtl_priv(hw));
+ struct sk_buff *skb;
+ struct ieee80211_mgmt *action_frame;
+ u16 params;
+
+ /* 27 = header + category + action + smps mode */
+ skb = dev_alloc_skb(34 + hw->extra_tx_headroom);
+ if (!skb)
+ return NULL;
+
+ skb_reserve(skb, hw->extra_tx_headroom);
+ action_frame = (void *)skb_put(skb, 34);
+ memset(action_frame, 0, 34);
+ memcpy(action_frame->sa, sa, ETH_ALEN);
+ memcpy(action_frame->da, rtlefuse->dev_addr, ETH_ALEN);
+ memcpy(action_frame->bssid, bssid, ETH_ALEN);
+ action_frame->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
+ IEEE80211_STYPE_ACTION);
+ action_frame->u.action.category = WLAN_CATEGORY_BACK;
+ action_frame->u.action.u.delba.action_code = WLAN_ACTION_DELBA;
+ params = (u16)(1 << 11); /* bit 11 initiator */
+ params |= (u16)(tid << 12); /* bit 15:12 TID number */
+
+ action_frame->u.action.u.delba.params = cpu_to_le16(params);
+ action_frame->u.action.u.delba.reason_code =
+ cpu_to_le16(WLAN_REASON_QSTA_TIMEOUT);
+
+ return skb;
+}
+
+/*********************************************************
+ *
+ * IOT functions
+ *
+ *********************************************************/
+static bool rtl_chk_vendor_ouisub(struct ieee80211_hw *hw,
+ struct octet_string vendor_ie)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ bool matched = false;
+ static u8 athcap_1[] = { 0x00, 0x03, 0x7F };
+ static u8 athcap_2[] = { 0x00, 0x13, 0x74 };
+ static u8 broadcap_1[] = { 0x00, 0x10, 0x18 };
+ static u8 broadcap_2[] = { 0x00, 0x0a, 0xf7 };
+ static u8 broadcap_3[] = { 0x00, 0x05, 0xb5 };
+ static u8 racap[] = { 0x00, 0x0c, 0x43 };
+ static u8 ciscocap[] = { 0x00, 0x40, 0x96 };
+ static u8 marvcap[] = { 0x00, 0x50, 0x43 };
+
+ if (memcmp(vendor_ie.octet, athcap_1, 3) == 0 ||
+ memcmp(vendor_ie.octet, athcap_2, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_ATH;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, broadcap_1, 3) == 0 ||
+ memcmp(vendor_ie.octet, broadcap_2, 3) == 0 ||
+ memcmp(vendor_ie.octet, broadcap_3, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_BROAD;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, racap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_RAL;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, ciscocap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_CISCO;
+ matched = true;
+ } else if (memcmp(vendor_ie.octet, marvcap, 3) == 0) {
+ rtlpriv->mac80211.vendor = PEER_MARV;
+ matched = true;
+ }
+
+ return matched;
+}
+
+bool rtl_find_221_ie(struct ieee80211_hw *hw, u8 *data,
+ unsigned int len)
+{
+ struct ieee80211_mgmt *mgmt = (void *)data;
+ struct octet_string vendor_ie;
+ u8 *pos, *end;
+
+ pos = (u8 *)mgmt->u.beacon.variable;
+ end = data + len;
+ while (pos < end) {
+ if (pos[0] == 221) {
+ vendor_ie.length = pos[1];
+ vendor_ie.octet = &pos[2];
+ if (rtl_chk_vendor_ouisub(hw, vendor_ie))
+ return true;
+ }
+
+ if (pos + 2 + pos[1] > end)
+ return false;
+
+ pos += 2 + pos[1];
+ }
+ return false;
+}
+
+void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_mac *mac = rtl_mac(rtl_priv(hw));
+ struct ieee80211_hdr *hdr = (void *)data;
+ u32 vendor = PEER_UNKNOWN;
+
+ static u8 ap3_1[3] = { 0x00, 0x14, 0xbf };
+ static u8 ap3_2[3] = { 0x00, 0x1a, 0x70 };
+ static u8 ap3_3[3] = { 0x00, 0x1d, 0x7e };
+ static u8 ap4_1[3] = { 0x00, 0x90, 0xcc };
+ static u8 ap4_2[3] = { 0x00, 0x0e, 0x2e };
+ static u8 ap4_3[3] = { 0x00, 0x18, 0x02 };
+ static u8 ap4_4[3] = { 0x00, 0x17, 0x3f };
+ static u8 ap4_5[3] = { 0x00, 0x1c, 0xdf };
+ static u8 ap5_1[3] = { 0x00, 0x1c, 0xf0 };
+ static u8 ap5_2[3] = { 0x00, 0x21, 0x91 };
+ static u8 ap5_3[3] = { 0x00, 0x24, 0x01 };
+ static u8 ap5_4[3] = { 0x00, 0x15, 0xe9 };
+ static u8 ap5_5[3] = { 0x00, 0x17, 0x9A };
+ static u8 ap5_6[3] = { 0x00, 0x18, 0xE7 };
+ static u8 ap6_1[3] = { 0x00, 0x17, 0x94 };
+ static u8 ap7_1[3] = { 0x00, 0x14, 0xa4 };
+
+ if (mac->opmode != NL80211_IFTYPE_STATION)
+ return;
+
+ if (mac->link_state == MAC80211_NOLINK) {
+ mac->vendor = PEER_UNKNOWN;
+ return;
+ }
+
+ if (mac->cnt_after_linked > 2)
+ return;
+
+ /* check if this really is a beacon */
+ if (!ieee80211_is_beacon(hdr->frame_control))
+ return;
+
+ /* min. beacon length + FCS_LEN */
+ if (len <= 40 + FCS_LEN)
+ return;
+
+ /* and only beacons from the associated BSSID, please */
+ if (ether_addr_equal(hdr->addr3, rtlpriv->mac80211.bssid))
+ return;
+
+ if (rtl_find_221_ie(hw, data, len)) {
+ vendor = mac->vendor;
+ }
+
+ if ((memcmp(mac->bssid, ap5_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_3, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_4, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_5, 3) == 0) ||
+ (memcmp(mac->bssid, ap5_6, 3) == 0) ||
+ vendor == PEER_ATH) {
+ vendor = PEER_ATH;
+ RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>ath find\n"));
+ } else if ((memcmp(mac->bssid, ap4_4, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_5, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap4_3, 3) == 0) ||
+ vendor == PEER_RAL) {
+ RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>ral findn\n"));
+ vendor = PEER_RAL;
+ } else if (memcmp(mac->bssid, ap6_1, 3) == 0 ||
+ vendor == PEER_CISCO) {
+ vendor = PEER_CISCO;
+ RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>cisco find\n"));
+ } else if ((memcmp(mac->bssid, ap3_1, 3) == 0) ||
+ (memcmp(mac->bssid, ap3_2, 3) == 0) ||
+ (memcmp(mac->bssid, ap3_3, 3) == 0) ||
+ vendor == PEER_BROAD) {
+ RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>broad find\n"));
+ vendor = PEER_BROAD;
+ } else if (memcmp(mac->bssid, ap7_1, 3) == 0 ||
+ vendor == PEER_MARV) {
+ vendor = PEER_MARV;
+ RT_TRACE(COMP_MAC80211, DBG_LOUD, ("=>marv find\n"));
+ }
+
+ mac->vendor = vendor;
+}
+
+/*********************************************************
+ *
+ * sysfs functions
+ *
+ *********************************************************/
+static ssize_t rtl_show_debug_level(struct device *d,
+ struct device_attribute *attr, char *buf)
+{
+ struct ieee80211_hw *hw = dev_get_drvdata(d);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+
+ return sprintf(buf, "0x%08X\n", rtlpriv->dbg.global_debuglevel);
+}
+
+static ssize_t rtl_store_debug_level(struct device *d,
+ struct device_attribute *attr,
+ const char *buf, size_t count)
+{
+ struct ieee80211_hw *hw = dev_get_drvdata(d);
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ unsigned long val;
+ int ret;
+
+ ret = strict_strtoul(buf, 0, &val);
+ if (ret) {
+ printk(KERN_DEBUG "%s is not in hex or decimal form.\n", buf);
+ } else {
+ rtlpriv->dbg.global_debuglevel = val;
+ printk(KERN_DEBUG "debuglevel:%x\n",
+ rtlpriv->dbg.global_debuglevel);
+ }
+
+ return strnlen(buf, count);
+}
+
+static DEVICE_ATTR(debug_level, S_IWUSR | S_IRUGO,
+ rtl_show_debug_level, rtl_store_debug_level);
+
+static struct attribute *rtl_sysfs_entries[] = {
+
+ &dev_attr_debug_level.attr,
+
+ NULL
+};
+
+/*
+ * "name" is folder name witch will be
+ * put in device directory like :
+ * sys/devices/pci0000:00/0000:00:1c.4/
+ * 0000:06:00.0/rtl_sysfs
+ */
+struct attribute_group rtl_attribute_group = {
+ .name = "rtlsysfs",
+ .attrs = rtl_sysfs_entries,
+};
+
+#ifdef VIF_TODO
+/*********************************************************
+ *
+ * vif functions
+ *
+ *********************************************************/
+static inline struct ieee80211_vif *
+rtl_get_vif(struct rtl_vif_info *vif_priv)
+{
+ return container_of((void *)vif_priv, struct ieee80211_vif, drv_priv);
+}
+
+/* Protected by ar->mutex or RCU */
+struct ieee80211_vif *rtl_get_main_vif(struct ieee80211_hw *hw)
+{
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ struct rtl_vif_info *cvif;
+
+ list_for_each_entry_rcu(cvif, &rtlpriv->vif_priv.vif_list, list) {
+ if (cvif->active)
+ return rtl_get_vif(cvif);
+ }
+
+ return NULL;
+}
+
+static inline bool is_main_vif(struct ieee80211_hw *hw,
+ struct ieee80211_vif *vif)
+{
+ bool ret;
+
+ rcu_read_lock();
+ ret = (rtl_get_main_vif(hw) == vif);
+ rcu_read_unlock();
+ return ret;
+}
+
+bool rtl_set_vif_info(struct ieee80211_hw *hw, struct ieee80211_vif *vif)
+{
+ struct rtl_vif_info *vif_info = (void *) vif->drv_priv;
+ struct rtl_priv *rtlpriv = rtl_priv(hw);
+ int vif_id = -1;
+
+ if (rtlpriv->vif_priv.vifs >= MAX_VIRTUAL_MAC) {
+ RT_TRACE(COMP_ERR, DBG_WARNING,
+ ("vif number can not bigger than %d, now vifs is:%d\n",
+ MAX_VIRTUAL_MAC, rtlpriv->vif_priv.vifs));
+ return false;
+ }
+
+ rcu_read_lock();
+ vif_id = bitmap_find_free_region(&rtlpriv->vif_priv.vif_bitmap,
+ MAX_VIRTUAL_MAC, 0);
+ RT_TRACE(COMP_MAC80211, DBG_DMESG,
+ ("%s vid_id:%d\n", __func__, vif_id));
+
+ if (vif_id < 0) {
+ rcu_read_unlock();
+ return false;
+ }
+
+ BUG_ON(rtlpriv->vif_priv.vif[vif_id].id != vif_id);
+ vif_info->active = true;
+ vif_info->id = vif_id;
+ vif_info->enable_beacon = false;
+ rtlpriv->vif_priv.vifs++;
+ if (rtlpriv->vif_priv.vifs > 1) {
+ rtlpriv->psc.b_inactiveps = false;
+ rtlpriv->psc.b_swctrl_lps = false;
+ rtlpriv->psc.b_fwctrl_lps = false;
+ }
+
+ list_add_tail_rcu(&vif_info->list, &rtlpriv->vif_priv.vif_list);
+ rcu_assign_pointer(rtlpriv->vif_priv.vif[vif_id].vif, vif);
+
+ RT_TRACE(COMP_MAC80211, DBG_DMESG, ("vifaddress:%p %p %p\n",
+ rtlpriv->vif_priv.vif[vif_id].vif, vif, rtl_get_main_vif(hw)));
+
+ rcu_read_unlock();
+
+ return true;
+}
+#endif
+
+
+#if 0
+MODULE_AUTHOR("lizhaoming <chaoming_li@realsil.com.cn>");
+MODULE_AUTHOR("Realtek WlanFAE <wlanfae@realtek.com>");
+MODULE_AUTHOR("Larry Finger <Larry.FInger@lwfinger.net>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Realtek 802.11n PCI wireless core");
+#endif
+struct rtl_global_var global_var = {};
+
+int rtl_core_module_init(void)
+{
+ if (rtl_rate_control_register())
+ printk(KERN_DEBUG "rtl: Unable to register rtl_rc,"
+ "use default RC !!\n");
+
+ /* add proc for debug */
+ rtl_proc_add_topdir();
+
+ /* init some global vars */
+ INIT_LIST_HEAD(&global_var.glb_priv_list);
+ spin_lock_init(&global_var.glb_list_lock);
+
+ return 0;
+}
+
+void rtl_core_module_exit(void)
+{
+ /*RC*/
+ rtl_rate_control_unregister();
+
+ /* add proc for debug */
+ rtl_proc_remove_topdir();
+}
+
+#if 0
+module_init(rtl_core_module_init);
+module_exit(rtl_core_module_exit);
+#endif
diff --git a/drivers/staging/rtl8821ae/base.h b/drivers/staging/rtl8821ae/base.h
new file mode 100644
index 000000000000..629d14f42f0b
--- /dev/null
+++ b/drivers/staging/rtl8821ae/base.h
@@ -0,0 +1,159 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2009-2010 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>
+ *
+ *****************************************************************************/
+
+#ifndef __RTL_BASE_H__
+#define __RTL_BASE_H__
+
+#include "compat.h"
+
+enum ap_peer {
+ PEER_UNKNOWN = 0,
+ PEER_RTL = 1,
+ PEER_RTL_92SE = 2,
+ PEER_BROAD = 3,
+ PEER_RAL = 4,
+ PEER_ATH = 5,
+ PEER_CISCO = 6,
+ PEER_MARV = 7,
+ PEER_AIRGO = 9,
+ PEER_MAX = 10,
+} ;
+
+#define RTL_DUMMY_OFFSET 0
+#define RTL_DUMMY_UNIT 8
+#define RTL_TX_DUMMY_SIZE (RTL_DUMMY_OFFSET * RTL_DUMMY_UNIT)
+#define RTL_TX_DESC_SIZE 32
+#define RTL_TX_HEADER_SIZE (RTL_TX_DESC_SIZE + RTL_TX_DUMMY_SIZE)
+
+#define HT_AMSDU_SIZE_4K 3839
+#define HT_AMSDU_SIZE_8K 7935
+
+#define MAX_BIT_RATE_40MHZ_MCS15 300 /* Mbps */
+#define MAX_BIT_RATE_40MHZ_MCS7 150 /* Mbps */
+
+#define RTL_RATE_COUNT_LEGACY 12
+#define RTL_CHANNEL_COUNT 14
+
+#define FRAME_OFFSET_FRAME_CONTROL 0
+#define FRAME_OFFSET_DURATION 2
+#define FRAME_OFFSET_ADDRESS1 4
+#define FRAME_OFFSET_ADDRESS2 10
+#define FRAME_OFFSET_ADDRESS3 16
+#define FRAME_OFFSET_SEQUENCE 22
+#define FRAME_OFFSET_ADDRESS4 24
+
+#define SET_80211_HDR_FRAME_CONTROL(_hdr, _val) \
+ WRITEEF2BYTE(_hdr, _val)
+#define SET_80211_HDR_TYPE_AND_SUBTYPE(_hdr, _val) \
+ WRITEEF1BYTE(_hdr, _val)
+#define SET_80211_HDR_PWR_MGNT(_hdr, _val) \
+ SET_BITS_TO_LE_2BYTE(_hdr, 12, 1, _val)
+#define SET_80211_HDR_TO_DS(_hdr, _val) \
+ SET_BITS_TO_LE_2BYTE(_hdr, 8, 1, _val)
+
+#define SET_80211_PS_POLL_AID(_hdr, _val) \
+ WRITEEF2BYTE(((u8*)(_hdr))+2, _val)
+#define SET_80211_PS_POLL_BSSID(_hdr, _val) \
+ CP_MACADDR(((u8*)(_hdr))+4, (u8*)(_val))
+#define SET_80211_PS_POLL_TA(_hdr, _val) \
+ CP_MACADDR(((u8*)(_hdr))+10, (u8*)(_val))
+
+#define SET_80211_HDR_DURATION(_hdr, _val) \
+ WRITEEF2BYTE((u8*)(_hdr)+FRAME_OFFSET_DURATION, _val)
+#define SET_80211_HDR_ADDRESS1(_hdr, _val) \
+ CP_MACADDR((u8*)(_hdr)+FRAME_OFFSET_ADDRESS1, (u8*)(_val))
+#define SET_80211_HDR_ADDRESS2(_hdr, _val) \
+ CP_MACADDR((u8*)(_hdr)+FRAME_OFFSET_ADDRESS2, (u8*)(_val))
+#define SET_80211_HDR_ADDRESS3(_hdr, _val) \
+ CP_MACADDR((u8*)(_hdr)+FRAME_OFFSET_ADDRESS3, (u8*)(_val))
+#define SET_80211_HDR_FRAGMENT_SEQUENCE(_hdr, _val) \
+ WRITEEF2BYTE((u8*)(_hdr)+FRAME_OFFSET_SEQUENCE, _val)
+
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_LOW(__phdr, __val) \
+ WRITEEF4BYTE(((u8*)(__phdr)) + 24, __val)
+#define SET_BEACON_PROBE_RSP_TIME_STAMP_HIGH(__phdr, __val) \
+ WRITEEF4BYTE(((u8*)(__phdr)) + 28, __val)
+#define SET_BEACON_PROBE_RSP_BEACON_INTERVAL(__phdr, __val) \
+ WRITEEF2BYTE(((u8*)(__phdr)) + 32, __val)
+#define GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) \
+ READEF2BYTE(((u8*)(__phdr)) + 34)
+#define SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+ WRITEEF2BYTE(((u8*)(__phdr)) + 34, __val)
+#define MASK_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, __val) \
+ SET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr, \
+ (GET_BEACON_PROBE_RSP_CAPABILITY_INFO(__phdr) & (~(__val))))
+
+int rtl_init_core(struct ieee80211_hw *hw);
+void rtl_deinit_core(struct ieee80211_hw *hw);
+void rtl_init_rx_config(struct ieee80211_hw *hw);
+void rtl_init_rfkill(struct ieee80211_hw *hw);
+void rtl_deinit_rfkill(struct ieee80211_hw *hw);
+
+void rtl_watch_dog_timer_callback(unsigned long data);
+void rtl_deinit_deferred_work(struct ieee80211_hw *hw);
+
+bool rtl_action_proc(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
+bool rtl_tx_mgmt_proc(struct ieee80211_hw *hw, struct sk_buff *skb);
+u8 rtl_is_special_data(struct ieee80211_hw *hw, struct sk_buff *skb, u8 is_tx);
+
+void rtl_beacon_statistic(struct ieee80211_hw *hw, struct sk_buff *skb);
+void rtl_watch_dog_timer_callback(unsigned long data);
+int rtl_tx_agg_start(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u16 tid, u16 * ssn);
+int rtl_tx_agg_stop(struct ieee80211_hw *hw, struct ieee80211_vif *vif,
+ struct ieee80211_sta *sta, u16 tid);
+int rtl_tx_agg_oper(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid);
+int rtl_rx_agg_start(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid);
+int rtl_rx_agg_stop(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta, u16 tid);
+void rtl_watchdog_wq_callback(void *data);
+void rtl_fwevt_wq_callback(void *data);
+
+void rtl_get_tcb_desc(struct ieee80211_hw *hw,
+ struct ieee80211_tx_info *info,
+ struct ieee80211_sta *sta,
+ struct sk_buff *skb, struct rtl_tcb_desc *tcb_desc);
+
+int rtl_send_smps_action(struct ieee80211_hw *hw,
+ struct ieee80211_sta *sta,
+ enum ieee80211_smps_mode smps);
+u8 *rtl_find_ie(u8 *data, unsigned int len, u8 ie);
+void rtl_recognize_peer(struct ieee80211_hw *hw, u8 *data, unsigned int len);
+u8 rtl_tid_to_ac(struct ieee80211_hw *hw, u8 tid);
+extern struct attribute_group rtl_attribute_group;
+void rtl_easy_concurrent_retrytimer_callback(unsigned long data);
+extern struct rtl_global_var global_var;
+
+#ifdef VIF_TODO
+struct ieee80211_vif *rtl_get_main_vif(struct ieee80211_hw *hw);
+bool rtl_set_vif_info(struct ieee80211_hw *hw, struct ieee80211_vif *vif);
+#endif
+#endif
diff --git a/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c b/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c
new file mode 100644
index 000000000000..b30f17ae0215
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.c
@@ -0,0 +1,3976 @@
+//============================================================
+// Description:
+//
+// This file is for 8812a1ant Co-exist mechanism
+//
+// History
+// 2012/11/15 Cosa first check in.
+//
+//============================================================
+
+//============================================================
+// include files
+//============================================================
+#include "halbt_precomp.h"
+#if 1
+//============================================================
+// Global variables, these are static variables
+//============================================================
+static COEX_DM_8812A_1ANT GLCoexDm8812a1Ant;
+static PCOEX_DM_8812A_1ANT coex_dm=&GLCoexDm8812a1Ant;
+static COEX_STA_8812A_1ANT GLCoexSta8812a1Ant;
+static PCOEX_STA_8812A_1ANT coex_sta=&GLCoexSta8812a1Ant;
+
+const char *const GLBtInfoSrc8812a1Ant[]={
+ "BT Info[wifi fw]",
+ "BT Info[bt rsp]",
+ "BT Info[bt auto report]",
+};
+
+//============================================================
+// local function proto type if needed
+//============================================================
+//============================================================
+// local function start with halbtc8812a1ant_
+//============================================================
+#if 0
+void
+halbtc8812a1ant_Reg0x550Bit3(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN bSet
+ )
+{
+ u1Byte u1tmp=0;
+
+ u1tmp = btcoexist->btc_read_1byte(btcoexist, 0x550);
+ if(bSet)
+ {
+ u1tmp |= BIT3;
+ }
+ else
+ {
+ u1tmp &= ~BIT3;
+ }
+ btcoexist->btc_write_1byte(btcoexist, 0x550, u1tmp);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], set 0x550[3]=%d\n", (bSet? 1:0)));
+}
+#endif
+u1Byte
+halbtc8812a1ant_BtRssiState(
+ u1Byte level_num,
+ u1Byte rssi_thresh,
+ u1Byte rssi_thresh1
+ )
+{
+ s4Byte bt_rssi=0;
+ u1Byte bt_rssi_state;
+
+ bt_rssi = coex_sta->bt_rssi;
+
+ if(level_num == 2)
+ {
+ if( (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(bt_rssi >= (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT))
+ {
+ bt_rssi_state = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to High\n"));
+ }
+ else
+ {
+ bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at Low\n"));
+ }
+ }
+ else
+ {
+ if(bt_rssi < rssi_thresh)
+ {
+ bt_rssi_state = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Low\n"));
+ }
+ else
+ {
+ bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at High\n"));
+ }
+ }
+ }
+ else if(level_num == 3)
+ {
+ if(rssi_thresh > rssi_thresh1)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi thresh error!!\n"));
+ return coex_sta->pre_bt_rssi_state;
+ }
+
+ if( (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(bt_rssi >= (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT))
+ {
+ bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Medium\n"));
+ }
+ else
+ {
+ bt_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at Low\n"));
+ }
+ }
+ else if( (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_MEDIUM))
+ {
+ if(bt_rssi >= (rssi_thresh1+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT))
+ {
+ bt_rssi_state = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to High\n"));
+ }
+ else if(bt_rssi < rssi_thresh)
+ {
+ bt_rssi_state = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Low\n"));
+ }
+ else
+ {
+ bt_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at Medium\n"));
+ }
+ }
+ else
+ {
+ if(bt_rssi < rssi_thresh1)
+ {
+ bt_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Medium\n"));
+ }
+ else
+ {
+ bt_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at High\n"));
+ }
+ }
+ }
+
+ coex_sta->pre_bt_rssi_state = bt_rssi_state;
+
+ return bt_rssi_state;
+}
+
+u1Byte
+halbtc8812a1ant_WifiRssiState(
+ PBTC_COEXIST btcoexist,
+ u1Byte index,
+ u1Byte level_num,
+ u1Byte rssi_thresh,
+ u1Byte rssi_thresh1
+ )
+{
+ s4Byte wifi_rssi=0;
+ u1Byte wifi_rssi_state;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
+
+ if(level_num == 2)
+ {
+ if( (coex_sta->pre_wifi_rssi_state[index] == BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_wifi_rssi_state[index] == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(wifi_rssi >= (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT))
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to High\n"));
+ }
+ else
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at Low\n"));
+ }
+ }
+ else
+ {
+ if(wifi_rssi < rssi_thresh)
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Low\n"));
+ }
+ else
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at High\n"));
+ }
+ }
+ }
+ else if(level_num == 3)
+ {
+ if(rssi_thresh > rssi_thresh1)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI thresh error!!\n"));
+ return coex_sta->pre_wifi_rssi_state[index];
+ }
+
+ if( (coex_sta->pre_wifi_rssi_state[index] == BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_wifi_rssi_state[index] == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(wifi_rssi >= (rssi_thresh+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT))
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Medium\n"));
+ }
+ else
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at Low\n"));
+ }
+ }
+ else if( (coex_sta->pre_wifi_rssi_state[index] == BTC_RSSI_STATE_MEDIUM) ||
+ (coex_sta->pre_wifi_rssi_state[index] == BTC_RSSI_STATE_STAY_MEDIUM))
+ {
+ if(wifi_rssi >= (rssi_thresh1+BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT))
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to High\n"));
+ }
+ else if(wifi_rssi < rssi_thresh)
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Low\n"));
+ }
+ else
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at Medium\n"));
+ }
+ }
+ else
+ {
+ if(wifi_rssi < rssi_thresh1)
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Medium\n"));
+ }
+ else
+ {
+ wifi_rssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at High\n"));
+ }
+ }
+ }
+
+ coex_sta->pre_wifi_rssi_state[index] = wifi_rssi_state;
+
+ return wifi_rssi_state;
+}
+
+void
+halbtc8812a1ant_MonitorBtEnableDisable(
+ PBTC_COEXIST btcoexist
+ )
+{
+ static BOOLEAN pre_bt_disabled=false;
+ static u4Byte bt_disable_cnt=0;
+ BOOLEAN bt_active=true, bt_disable_by68=false, bt_disabled=false;
+ u4Byte u4_tmp=0;
+
+ // This function check if bt is disabled
+
+ if( coex_sta->high_priority_tx == 0 &&
+ coex_sta->high_priority_rx == 0 &&
+ coex_sta->low_priority_tx == 0 &&
+ coex_sta->low_priority_rx == 0)
+ {
+ bt_active = false;
+ }
+ if( coex_sta->high_priority_tx == 0xffff &&
+ coex_sta->high_priority_rx == 0xffff &&
+ coex_sta->low_priority_tx == 0xffff &&
+ coex_sta->low_priority_rx == 0xffff)
+ {
+ bt_active = false;
+ }
+ if(bt_active)
+ {
+ bt_disable_cnt = 0;
+ bt_disabled = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, &bt_disabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is enabled !!\n"));
+ }
+ else
+ {
+ bt_disable_cnt++;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], bt all counters=0, %d times!!\n",
+ bt_disable_cnt));
+ if(bt_disable_cnt >= 2 ||bt_disable_by68)
+ {
+ bt_disabled = true;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE, &bt_disabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is disabled !!\n"));
+ }
+ }
+ if(pre_bt_disabled != bt_disabled)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is from %s to %s!!\n",
+ (pre_bt_disabled ? "disabled":"enabled"),
+ (bt_disabled ? "disabled":"enabled")));
+ pre_bt_disabled = bt_disabled;
+ if(!bt_disabled)
+ {
+ }
+ else
+ {
+ }
+ }
+}
+
+void
+halbtc8812a1ant_MonitorBtCtr(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u4Byte reg_hp_tx_rx, reg_lp_tx_rx, u4_tmp;
+ u4Byte reg_hp_tx=0, reg_hp_rx=0, reg_lp_tx=0, reg_lp_rx=0;
+ u1Byte u1_tmp;
+
+ reg_hp_tx_rx = 0x770;
+ reg_lp_tx_rx = 0x774;
+
+ u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_tx_rx);
+ reg_hp_tx = u4_tmp & bMaskLWord;
+ reg_hp_rx = (u4_tmp & bMaskHWord)>>16;
+
+ u4_tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_tx_rx);
+ reg_lp_tx = u4_tmp & bMaskLWord;
+ reg_lp_rx = (u4_tmp & bMaskHWord)>>16;
+
+ coex_sta->high_priority_tx = reg_hp_tx;
+ coex_sta->high_priority_rx = reg_hp_rx;
+ coex_sta->low_priority_tx = reg_lp_tx;
+ coex_sta->low_priority_rx = reg_lp_rx;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n",
+ reg_hp_tx_rx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=%x(%d)/%x(%d)\n",
+ reg_lp_tx_rx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx));
+
+ // reset counter
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
+}
+
+void
+halbtc8812a1ant_QueryBtInfo(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte dataLen=3;
+ u1Byte buf[5] = {0};
+ static u4Byte btInfoCnt=0;
+
+ if(!btInfoCnt ||
+ (coex_sta->bt_info_c2h_cnt[BT_INFO_SRC_8812A_1ANT_BT_RSP]-btInfoCnt)>2)
+ {
+ buf[0] = dataLen;
+ buf[1] = 0x1; // polling enable, 1=enable, 0=disable
+ buf[2] = 0x2; // polling time in seconds
+ buf[3] = 0x1; // auto report enable, 1=enable, 0=disable
+
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_CTRL_BT_INFO, (PVOID)&buf[0]);
+ }
+ btInfoCnt = coex_sta->bt_info_c2h_cnt[BT_INFO_SRC_8812A_1ANT_BT_RSP];
+}
+u1Byte
+halbtc8812a1ant_ActionAlgorithm(
+ PBTC_COEXIST btcoexist
+ )
+{
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+ BOOLEAN bt_hs_on=false;
+ u1Byte algorithm=BT_8812A_1ANT_COEX_ALGO_UNDEFINED;
+ u1Byte num_of_diff_profile=0;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+
+ if(!stack_info->bt_link_exist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], No profile exists!!!\n"));
+ return algorithm;
+ }
+
+ if(stack_info->sco_exist)
+ num_of_diff_profile++;
+ if(stack_info->hid_exist)
+ num_of_diff_profile++;
+ if(stack_info->pan_exist)
+ num_of_diff_profile++;
+ if(stack_info->a2dp_exist)
+ num_of_diff_profile++;
+
+ if(num_of_diff_profile == 1)
+ {
+ if(stack_info->sco_exist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO only\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_SCO;
+ }
+ else
+ {
+ if(stack_info->hid_exist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID only\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_HID;
+ }
+ else if(stack_info->a2dp_exist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP only\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_A2DP;
+ }
+ else if(stack_info->pan_exist)
+ {
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN(HS) only\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_PANHS;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN(EDR) only\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR;
+ }
+ }
+ }
+ }
+ else if(num_of_diff_profile == 2)
+ {
+ if(stack_info->sco_exist)
+ {
+ if(stack_info->hid_exist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_HID;
+ }
+ else if(stack_info->a2dp_exist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + A2DP ==> SCO\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_SCO;
+ }
+ else if(stack_info->pan_exist)
+ {
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + PAN(HS)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_SCO;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + PAN(EDR)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ else
+ {
+ if( stack_info->hid_exist &&
+ stack_info->a2dp_exist )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + A2DP\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP;
+ }
+ else if( stack_info->hid_exist &&
+ stack_info->pan_exist )
+ {
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ else if( stack_info->pan_exist &&
+ stack_info->a2dp_exist )
+ {
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_A2DP_PANHS;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_A2DP;
+ }
+ }
+ }
+ }
+ else if(num_of_diff_profile == 3)
+ {
+ if(stack_info->sco_exist)
+ {
+ if( stack_info->hid_exist &&
+ stack_info->a2dp_exist )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + A2DP ==> HID\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_HID;
+ }
+ else if( stack_info->hid_exist &&
+ stack_info->pan_exist )
+ {
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + PAN(HS)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + PAN(EDR)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ else if( stack_info->pan_exist &&
+ stack_info->a2dp_exist )
+ {
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + A2DP + PAN(HS)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_SCO;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ else
+ {
+ if( stack_info->hid_exist &&
+ stack_info->pan_exist &&
+ stack_info->a2dp_exist )
+ {
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ }
+ }
+ }
+ }
+ else if(num_of_diff_profile >= 3)
+ {
+ if(stack_info->sco_exist)
+ {
+ if( stack_info->hid_exist &&
+ stack_info->pan_exist &&
+ stack_info->a2dp_exist )
+ {
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n"));
+
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n"));
+ algorithm = BT_8812A_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ }
+
+ return algorithm;
+}
+
+BOOLEAN
+halbtc8812a1ant_NeedToDecBtPwr(
+ PBTC_COEXIST btcoexist
+ )
+{
+ BOOLEAN ret=false;
+ BOOLEAN bt_hs_on=false, wifi_connected=false;
+ s4Byte bt_hs_rssi=0;
+
+ if(!btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on))
+ return false;
+ if(!btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected))
+ return false;
+ if(!btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi))
+ return false;
+
+ if(wifi_connected)
+ {
+ if(bt_hs_on)
+ {
+ if(bt_hs_rssi > 37)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], Need to decrease bt power for HS mode!!\n"));
+ ret = true;
+ }
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], Need to decrease bt power for Wifi is connected!!\n"));
+ ret = true;
+ }
+ }
+
+ return ret;
+}
+
+void
+halbtc8812a1ant_SetFwDacSwingLevel(
+ PBTC_COEXIST btcoexist,
+ u1Byte dac_swing_lvl
+ )
+{
+ u1Byte h2c_parameter[1] ={0};
+
+ // There are several type of dacswing
+ // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6
+ h2c_parameter[0] = dac_swing_lvl;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], Set Dac Swing Level=0x%x\n", dac_swing_lvl));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x64=0x%x\n", h2c_parameter[0]));
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter);
+}
+
+void
+halbtc8812a1ant_SetFwDecBtPwr(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN dec_bt_pwr
+ )
+{
+ u1Byte dataLen=3;
+ u1Byte buf[5] = {0};
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], decrease Bt Power : %s\n",
+ (dec_bt_pwr? "Yes!!":"No!!")));
+
+ buf[0] = dataLen;
+ buf[1] = 0x3; // OP_Code
+ buf[2] = 0x1; // OP_Code_Length
+ if(dec_bt_pwr)
+ buf[3] = 0x1; // OP_Code_Content
+ else
+ buf[3] = 0x0;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]);
+}
+
+void
+halbtc8812a1ant_DecBtPwr(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN dec_bt_pwr
+ )
+{
+ return;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s Dec BT power = %s\n",
+ (force_exec? "force to":""), ((dec_bt_pwr)? "ON":"OFF")));
+ coex_dm->cur_dec_bt_pwr = dec_bt_pwr;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], pre_dec_bt_pwr=%d, cur_dec_bt_pwr=%d\n",
+ coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr));
+
+ if(coex_dm->pre_dec_bt_pwr == coex_dm->cur_dec_bt_pwr)
+ return;
+ }
+ halbtc8812a1ant_SetFwDecBtPwr(btcoexist, coex_dm->cur_dec_bt_pwr);
+
+ coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr;
+}
+
+void
+halbtc8812a1ant_SetFwBtLnaConstrain(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN bt_lna_cons_on
+ )
+{
+ u1Byte dataLen=3;
+ u1Byte buf[5] = {0};
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], set BT LNA Constrain: %s\n",
+ (bt_lna_cons_on? "ON!!":"OFF!!")));
+
+ buf[0] = dataLen;
+ buf[1] = 0x2; // OP_Code
+ buf[2] = 0x1; // OP_Code_Length
+ if(bt_lna_cons_on)
+ buf[3] = 0x1; // OP_Code_Content
+ else
+ buf[3] = 0x0;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]);
+}
+
+void
+halbtc8812a1ant_SetBtLnaConstrain(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN bt_lna_cons_on
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s BT Constrain = %s\n",
+ (force_exec? "force":""), ((bt_lna_cons_on)? "ON":"OFF")));
+ coex_dm->bCurBtLnaConstrain = bt_lna_cons_on;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPreBtLnaConstrain=%d, bCurBtLnaConstrain=%d\n",
+ coex_dm->bPreBtLnaConstrain, coex_dm->bCurBtLnaConstrain));
+
+ if(coex_dm->bPreBtLnaConstrain == coex_dm->bCurBtLnaConstrain)
+ return;
+ }
+ halbtc8812a1ant_SetFwBtLnaConstrain(btcoexist, coex_dm->bCurBtLnaConstrain);
+
+ coex_dm->bPreBtLnaConstrain = coex_dm->bCurBtLnaConstrain;
+}
+
+void
+halbtc8812a1ant_SetFwBtPsdMode(
+ PBTC_COEXIST btcoexist,
+ u1Byte bt_psd_mode
+ )
+{
+ u1Byte dataLen=3;
+ u1Byte buf[5] = {0};
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], set BT PSD mode=0x%x\n",
+ bt_psd_mode));
+
+ buf[0] = dataLen;
+ buf[1] = 0x4; // OP_Code
+ buf[2] = 0x1; // OP_Code_Length
+ buf[3] = bt_psd_mode; // OP_Code_Content
+
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]);
+}
+
+
+void
+halbtc8812a1ant_SetBtPsdMode(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ u1Byte bt_psd_mode
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s BT PSD mode = 0x%x\n",
+ (force_exec? "force":""), bt_psd_mode));
+ coex_dm->bCurBtPsdMode = bt_psd_mode;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPreBtPsdMode=0x%x, bCurBtPsdMode=0x%x\n",
+ coex_dm->bPreBtPsdMode, coex_dm->bCurBtPsdMode));
+
+ if(coex_dm->bPreBtPsdMode == coex_dm->bCurBtPsdMode)
+ return;
+ }
+ halbtc8812a1ant_SetFwBtPsdMode(btcoexist, coex_dm->bCurBtPsdMode);
+
+ coex_dm->bPreBtPsdMode = coex_dm->bCurBtPsdMode;
+}
+
+
+void
+halbtc8812a1ant_SetBtAutoReport(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN enable_auto_report
+ )
+{
+#if 0
+ u1Byte h2c_parameter[1] ={0};
+
+ h2c_parameter[0] = 0;
+
+ if(enable_auto_report)
+ {
+ h2c_parameter[0] |= BIT0;
+ }
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n",
+ (enable_auto_report? "Enabled!!":"Disabled!!"), h2c_parameter[0]));
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter);
+#else
+
+#endif
+}
+
+void
+halbtc8812a1ant_BtAutoReport(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN enable_auto_report
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s BT Auto report = %s\n",
+ (force_exec? "force to":""), ((enable_auto_report)? "Enabled":"Disabled")));
+ coex_dm->cur_bt_auto_report = enable_auto_report;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], pre_bt_auto_report=%d, cur_bt_auto_report=%d\n",
+ coex_dm->pre_bt_auto_report, coex_dm->cur_bt_auto_report));
+
+ if(coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report)
+ return;
+ }
+ halbtc8812a1ant_SetBtAutoReport(btcoexist, coex_dm->cur_bt_auto_report);
+
+ coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
+}
+
+void
+halbtc8812a1ant_FwDacSwingLvl(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ u1Byte fw_dac_swing_lvl
+ )
+{
+ return;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s set FW Dac Swing level = %d\n",
+ (force_exec? "force to":""), fw_dac_swing_lvl));
+ coex_dm->cur_fw_dac_swing_lvl = fw_dac_swing_lvl;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], pre_fw_dac_swing_lvl=%d, cur_fw_dac_swing_lvl=%d\n",
+ coex_dm->pre_fw_dac_swing_lvl, coex_dm->cur_fw_dac_swing_lvl));
+
+ if(coex_dm->pre_fw_dac_swing_lvl == coex_dm->cur_fw_dac_swing_lvl)
+ return;
+ }
+
+ halbtc8812a1ant_SetFwDacSwingLevel(btcoexist, coex_dm->cur_fw_dac_swing_lvl);
+
+ coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
+}
+
+void
+halbtc8812a1ant_SetSwRfRxLpfCorner(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN rx_rf_shrink_on
+ )
+{
+ if(rx_rf_shrink_on)
+ {
+ //Shrink RF Rx LPF corner
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Shrink RF Rx LPF corner!!\n"));
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff, 0xf0ff7);
+ }
+ else
+ {
+ //Resume RF Rx LPF corner
+ // After initialized, we can use coex_dm->bt_rf0x1e_backup
+ if(btcoexist->bInitilized)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Resume RF Rx LPF corner!!\n"));
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff, coex_dm->bt_rf0x1e_backup);
+ }
+ }
+}
+
+void
+halbtc8812a1ant_RfShrink(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN rx_rf_shrink_on
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn Rx RF Shrink = %s\n",
+ (force_exec? "force to":""), ((rx_rf_shrink_on)? "ON":"OFF")));
+ coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], pre_rf_rx_lpf_shrink=%d, cur_rf_rx_lpf_shrink=%d\n",
+ coex_dm->pre_rf_rx_lpf_shrink, coex_dm->cur_rf_rx_lpf_shrink));
+
+ if(coex_dm->pre_rf_rx_lpf_shrink == coex_dm->cur_rf_rx_lpf_shrink)
+ return;
+ }
+ halbtc8812a1ant_SetSwRfRxLpfCorner(btcoexist, coex_dm->cur_rf_rx_lpf_shrink);
+
+ coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink;
+}
+
+void
+halbtc8812a1ant_SetSwPenaltyTxRateAdaptive(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN low_penalty_ra
+ )
+{
+ u1Byte u1_tmp;
+
+ u1_tmp = btcoexist->btc_read_1byte(btcoexist, 0x4fd);
+ u1_tmp |= BIT0;
+ if(low_penalty_ra)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Tx rate adaptive, set low penalty!!\n"));
+ u1_tmp &= ~BIT2;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Tx rate adaptive, set normal!!\n"));
+ u1_tmp |= BIT2;
+ }
+
+ btcoexist->btc_write_1byte(btcoexist, 0x4fd, u1_tmp);
+}
+
+void
+halbtc8812a1ant_LowPenaltyRa(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN low_penalty_ra
+ )
+{
+ return;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn LowPenaltyRA = %s\n",
+ (force_exec? "force to":""), ((low_penalty_ra)? "ON":"OFF")));
+ coex_dm->cur_low_penalty_ra = low_penalty_ra;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], pre_low_penalty_ra=%d, cur_low_penalty_ra=%d\n",
+ coex_dm->pre_low_penalty_ra, coex_dm->cur_low_penalty_ra));
+
+ if(coex_dm->pre_low_penalty_ra == coex_dm->cur_low_penalty_ra)
+ return;
+ }
+ halbtc8812a1ant_SetSwPenaltyTxRateAdaptive(btcoexist, coex_dm->cur_low_penalty_ra);
+
+ coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
+}
+
+void
+halbtc8812a1ant_SetDacSwingReg(
+ PBTC_COEXIST btcoexist,
+ u4Byte level
+ )
+{
+ u1Byte val=(u1Byte)level;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Write SwDacSwing = 0x%x\n", level));
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xc5b, 0x3e, val);
+}
+
+void
+halbtc8812a1ant_SetSwFullTimeDacSwing(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN sw_dac_swing_on,
+ u4Byte sw_dac_swing_lvl
+ )
+{
+ if(sw_dac_swing_on)
+ {
+ halbtc8812a1ant_SetDacSwingReg(btcoexist, sw_dac_swing_lvl);
+ }
+ else
+ {
+ halbtc8812a1ant_SetDacSwingReg(btcoexist, 0x18);
+ }
+}
+
+
+void
+halbtc8812a1ant_DacSwing(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN dac_swing_on,
+ u4Byte dac_swing_lvl
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn DacSwing=%s, dac_swing_lvl=0x%x\n",
+ (force_exec? "force to":""), ((dac_swing_on)? "ON":"OFF"), dac_swing_lvl));
+ coex_dm->cur_dac_swing_on = dac_swing_on;
+ coex_dm->cur_dac_swing_lvl = dac_swing_lvl;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], pre_dac_swing_on=%d, pre_dac_swing_lvl=0x%x, cur_dac_swing_on=%d, cur_dac_swing_lvl=0x%x\n",
+ coex_dm->pre_dac_swing_on, coex_dm->pre_dac_swing_lvl,
+ coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl));
+
+ if( (coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) &&
+ (coex_dm->pre_dac_swing_lvl == coex_dm->cur_dac_swing_lvl) )
+ return;
+ }
+ delay_ms(30);
+ halbtc8812a1ant_SetSwFullTimeDacSwing(btcoexist, dac_swing_on, dac_swing_lvl);
+
+ coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on;
+ coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl;
+}
+
+void
+halbtc8812a1ant_SetAdcBackOff(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN adc_back_off
+ )
+{
+ if(adc_back_off)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], BB BackOff Level On!\n"));
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x8db, 0x60, 0x3);
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], BB BackOff Level Off!\n"));
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x8db, 0x60, 0x1);
+ }
+}
+
+void
+halbtc8812a1ant_AdcBackOff(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN adc_back_off
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn AdcBackOff = %s\n",
+ (force_exec? "force to":""), ((adc_back_off)? "ON":"OFF")));
+ coex_dm->cur_adc_back_off = adc_back_off;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], pre_adc_back_off=%d, cur_adc_back_off=%d\n",
+ coex_dm->pre_adc_back_off, coex_dm->cur_adc_back_off));
+
+ if(coex_dm->pre_adc_back_off == coex_dm->cur_adc_back_off)
+ return;
+ }
+ halbtc8812a1ant_SetAdcBackOff(btcoexist, coex_dm->cur_adc_back_off);
+
+ coex_dm->pre_adc_back_off = coex_dm->cur_adc_back_off;
+}
+
+void
+halbtc8812a1ant_SetAgcTable(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN agc_table_en
+ )
+{
+ u1Byte rssi_adjust_val=0;
+
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000);
+ if(agc_table_en)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Agc Table On!\n"));
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, 0xfffff, 0x3fa58);
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, 0xfffff, 0x37a58);
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, 0xfffff, 0x2fa58);
+ rssi_adjust_val = 8;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Agc Table Off!\n"));
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, 0xfffff, 0x39258);
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, 0xfffff, 0x31258);
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x3b, 0xfffff, 0x29258);
+ }
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0xef, 0xfffff, 0x0);
+
+ // set rssi_adjust_val for wifi module.
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssi_adjust_val);
+}
+
+
+void
+halbtc8812a1ant_AgcTable(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN agc_table_en
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s %s Agc Table\n",
+ (force_exec? "force to":""), ((agc_table_en)? "Enable":"Disable")));
+ coex_dm->cur_agc_table_en = agc_table_en;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], pre_agc_table_en=%d, cur_agc_table_en=%d\n",
+ coex_dm->pre_agc_table_en, coex_dm->cur_agc_table_en));
+
+ if(coex_dm->pre_agc_table_en == coex_dm->cur_agc_table_en)
+ return;
+ }
+ halbtc8812a1ant_SetAgcTable(btcoexist, agc_table_en);
+
+ coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en;
+}
+
+void
+halbtc8812a1ant_SetCoexTable(
+ PBTC_COEXIST btcoexist,
+ u4Byte val0x6c0,
+ u4Byte val0x6c4,
+ u4Byte val0x6c8,
+ u1Byte val0x6cc
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0));
+ btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4));
+ btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8));
+ btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc));
+ btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
+}
+
+void
+halbtc8812a1ant_CoexTable(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ u4Byte val0x6c0,
+ u4Byte val0x6c4,
+ u4Byte val0x6c8,
+ u1Byte val0x6cc
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n",
+ (force_exec? "force to":""), val0x6c0, val0x6c4, val0x6c8, val0x6cc));
+ coex_dm->cur_val0x6c0 = val0x6c0;
+ coex_dm->cur_val0x6c4 = val0x6c4;
+ coex_dm->cur_val0x6c8 = val0x6c8;
+ coex_dm->cur_val0x6cc = val0x6cc;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], pre_val0x6c0=0x%x, pre_val0x6c4=0x%x, pre_val0x6c8=0x%x, pre_val0x6cc=0x%x !!\n",
+ coex_dm->pre_val0x6c0, coex_dm->pre_val0x6c4, coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], cur_val0x6c0=0x%x, cur_val0x6c4=0x%x, cur_val0x6c8=0x%x, cur_val0x6cc=0x%x !!\n",
+ coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4, coex_dm->cur_val0x6c8, coex_dm->cur_val0x6cc));
+
+ if( (coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) &&
+ (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) &&
+ (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) &&
+ (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc) )
+ return;
+ }
+ halbtc8812a1ant_SetCoexTable(btcoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc);
+
+ coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0;
+ coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4;
+ coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8;
+ coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
+}
+
+void
+halbtc8812a1ant_SetFwIgnoreWlanAct(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN enable
+ )
+{
+ u1Byte dataLen=3;
+ u1Byte buf[5] = {0};
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], %s BT Ignore Wlan_Act\n",
+ (enable? "Enable":"Disable")));
+
+ buf[0] = dataLen;
+ buf[1] = 0x1; // OP_Code
+ buf[2] = 0x1; // OP_Code_Length
+ if(enable)
+ buf[3] = 0x1; // OP_Code_Content
+ else
+ buf[3] = 0x0;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]);
+}
+
+void
+halbtc8812a1ant_IgnoreWlanAct(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN enable
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s turn Ignore WlanAct %s\n",
+ (force_exec? "force to":""), (enable? "ON":"OFF")));
+ coex_dm->cur_ignore_wlan_act = enable;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], pre_ignore_wlan_act = %d, cur_ignore_wlan_act = %d!!\n",
+ coex_dm->pre_ignore_wlan_act, coex_dm->cur_ignore_wlan_act));
+
+ if(coex_dm->pre_ignore_wlan_act == coex_dm->cur_ignore_wlan_act)
+ return;
+ }
+ halbtc8812a1ant_SetFwIgnoreWlanAct(btcoexist, enable);
+
+ coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
+}
+
+void
+halbtc8812a1ant_SetFwPstdma(
+ PBTC_COEXIST btcoexist,
+ u1Byte byte1,
+ u1Byte byte2,
+ u1Byte byte3,
+ u1Byte byte4,
+ u1Byte byte5
+ )
+{
+ u1Byte h2c_parameter[5] ={0};
+
+ h2c_parameter[0] = byte1;
+ h2c_parameter[1] = byte2;
+ h2c_parameter[2] = byte3;
+ h2c_parameter[3] = byte4;
+ h2c_parameter[4] = byte5;
+
+ coex_dm->ps_tdma_para[0] = byte1;
+ coex_dm->ps_tdma_para[1] = byte2;
+ coex_dm->ps_tdma_para[2] = byte3;
+ coex_dm->ps_tdma_para[3] = byte4;
+ coex_dm->ps_tdma_para[4] = byte5;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n",
+ h2c_parameter[0],
+ h2c_parameter[1]<<24|h2c_parameter[2]<<16|h2c_parameter[3]<<8|h2c_parameter[4]));
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
+}
+
+void
+halbtc8812a1ant_SetLpsRpwm(
+ PBTC_COEXIST btcoexist,
+ u1Byte lps_val,
+ u1Byte rpwm_val
+ )
+{
+ u1Byte lps=lps_val;
+ u1Byte rpwm=rpwm_val;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_1ANT_LPS, &lps);
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_1ANT_RPWM, &rpwm);
+
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_INC_FORCE_EXEC_PWR_CMD_CNT, NULL);
+}
+
+void
+halbtc8812a1ant_LpsRpwm(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ u1Byte lps_val,
+ u1Byte rpwm_val
+ )
+{
+ BOOLEAN bForceExecPwrCmd=false;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n",
+ (force_exec? "force to":""), lps_val, rpwm_val));
+ coex_dm->cur_lps = lps_val;
+ coex_dm->cur_rpwm = rpwm_val;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], pre_lps/cur_lps=0x%x/0x%x, pre_rpwm/cur_rpwm=0x%x/0x%x!!\n",
+ coex_dm->pre_lps, coex_dm->cur_lps, coex_dm->pre_rpwm, coex_dm->cur_rpwm));
+
+ if( (coex_dm->pre_lps == coex_dm->cur_lps) &&
+ (coex_dm->pre_rpwm == coex_dm->cur_rpwm) )
+ {
+ return;
+ }
+ }
+ halbtc8812a1ant_SetLpsRpwm(btcoexist, lps_val, rpwm_val);
+
+ coex_dm->pre_lps = coex_dm->cur_lps;
+ coex_dm->pre_rpwm = coex_dm->cur_rpwm;
+}
+
+void
+halbtc8812a1ant_SwMechanism1(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN shrink_rx_lpf,
+ BOOLEAN low_penalty_ra,
+ BOOLEAN limited_dig,
+ BOOLEAN bt_lna_constrain
+ )
+{
+ //halbtc8812a1ant_RfShrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf);
+ //halbtc8812a1ant_LowPenaltyRa(btcoexist, NORMAL_EXEC, low_penalty_ra);
+
+ //no limited DIG
+ //halbtc8812a1ant_SetBtLnaConstrain(btcoexist, NORMAL_EXEC, bt_lna_constrain);
+}
+
+void
+halbtc8812a1ant_SwMechanism2(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN agc_table_shift,
+ BOOLEAN adc_back_off,
+ BOOLEAN sw_dac_swing,
+ u4Byte dac_swing_lvl
+ )
+{
+ //halbtc8812a1ant_AgcTable(btcoexist, NORMAL_EXEC, agc_table_shift);
+ //halbtc8812a1ant_AdcBackOff(btcoexist, NORMAL_EXEC, adc_back_off);
+ //halbtc8812a1ant_DacSwing(btcoexist, NORMAL_EXEC, sw_dac_swing, dac_swing_lvl);
+}
+
+void
+halbtc8812a1ant_PsTdma(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN force_exec,
+ BOOLEAN turn_on,
+ u1Byte type
+ )
+{
+ BOOLEAN bTurnOnByCnt=false;
+ u1Byte psTdmaTypeByCnt=0, rssi_adjust_val=0;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s turn %s PS TDMA, type=%d\n",
+ (force_exec? "force to":""), (turn_on? "ON":"OFF"), type));
+ coex_dm->cur_ps_tdma_on = turn_on;
+ coex_dm->cur_ps_tdma = type;
+
+ if(!force_exec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], pre_ps_tdma_on = %d, cur_ps_tdma_on = %d!!\n",
+ coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], pre_ps_tdma = %d, cur_ps_tdma = %d!!\n",
+ coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma));
+
+ if( (coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
+ (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma) )
+ return;
+ }
+ if(turn_on)
+ {
+ switch(type)
+ {
+ default:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xd3, 0x1a, 0x1a, 0x0, 0x58);
+ break;
+ case 1:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xd3, 0x1a, 0x1a, 0x0, 0x48);
+ rssi_adjust_val = 11;
+ break;
+ case 2:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xd3, 0x12, 0x12, 0x0, 0x48);
+ rssi_adjust_val = 14;
+ break;
+ case 3:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x93, 0x25, 0x3, 0x10, 0x40);
+ break;
+ case 4:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x93, 0x15, 0x3, 0x14, 0x0);
+ rssi_adjust_val = 17;
+ break;
+ case 5:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x61, 0x15, 0x3, 0x31, 0x0);
+ break;
+ case 6:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x13, 0xa, 0x3, 0x0, 0x0);
+ break;
+ case 7:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x13, 0xc, 0x5, 0x0, 0x0);
+ break;
+ case 8:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x93, 0x25, 0x3, 0x10, 0x0);
+ break;
+ case 9:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xd3, 0xa, 0xa, 0x0, 0x48);
+ rssi_adjust_val = 18;
+ break;
+ case 10:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x13, 0xa, 0xa, 0x0, 0x40);
+ break;
+ case 11:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xd3, 0x5, 0x5, 0x0, 0x48);
+ rssi_adjust_val = 20;
+ break;
+ case 12:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xeb, 0xa, 0x3, 0x31, 0x18);
+ break;
+
+ case 15:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x13, 0xa, 0x3, 0x8, 0x0);
+ break;
+ case 16:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x93, 0x15, 0x3, 0x10, 0x0);
+ rssi_adjust_val = 18;
+ break;
+
+ case 18:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x93, 0x25, 0x3, 0x10, 0x0);
+ rssi_adjust_val = 14;
+ break;
+
+ case 20:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x13, 0x25, 0x25, 0x0, 0x0);
+ break;
+ case 21:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x93, 0x20, 0x3, 0x10, 0x40);
+ break;
+ case 22:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x13, 0x8, 0x8, 0x0, 0x40);
+ break;
+ case 23:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xe3, 0x25, 0x3, 0x31, 0x18);
+ rssi_adjust_val = 22;
+ break;
+ case 24:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xe3, 0x15, 0x3, 0x31, 0x18);
+ rssi_adjust_val = 22;
+ break;
+ case 25:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xe3, 0xa, 0x3, 0x31, 0x18);
+ rssi_adjust_val = 22;
+ break;
+ case 26:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xe3, 0xa, 0x3, 0x31, 0x18);
+ rssi_adjust_val = 22;
+ break;
+ case 27:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xe3, 0x25, 0x3, 0x31, 0x98);
+ rssi_adjust_val = 22;
+ break;
+ case 28:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x69, 0x25, 0x3, 0x31, 0x0);
+ break;
+ case 29:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xab, 0x1a, 0x1a, 0x1, 0x8);
+ break;
+ case 30:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x93, 0x15, 0x3, 0x14, 0x0);
+ break;
+ case 31:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xd3, 0x1a, 0x1a, 0, 0x58);
+ break;
+ case 32:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xab, 0xa, 0x3, 0x31, 0x88);
+ break;
+ case 33:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xa3, 0x25, 0x3, 0x30, 0x88);
+ break;
+ case 34:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xd3, 0x1a, 0x1a, 0x0, 0x8);
+ break;
+ case 35:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xe3, 0x1a, 0x1a, 0x0, 0x8);
+ break;
+ case 36:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0xd3, 0x12, 0x3, 0x14, 0x58);
+ break;
+ }
+ }
+ else
+ {
+ // disable PS tdma
+ switch(type)
+ {
+ case 8:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x8, 0x0, 0x0, 0x0, 0x0);
+ btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x4);
+ break;
+ case 0:
+ default:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x0, 0x0, 0x0, 0x0, 0x0);
+ delay_ms(5);
+ btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20);
+ break;
+ case 9:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x0, 0x0, 0x0, 0x0, 0x0);
+ btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x4);
+ break;
+ case 10:
+ halbtc8812a1ant_SetFwPstdma(btcoexist, 0x0, 0x0, 0x0, 0x8, 0x0);
+ delay_ms(5);
+ btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20);
+ break;
+ }
+ }
+ rssi_adjust_val =0;
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssi_adjust_val);
+
+ // update pre state
+ coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
+ coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
+}
+
+void
+halbtc8812a1ant_CoexAllOff(
+ PBTC_COEXIST btcoexist
+ )
+{
+ // fw all off
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ // sw all off
+ halbtc8812a1ant_SwMechanism1(btcoexist,false,false,false,false);
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+
+
+ // hw all off
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+}
+
+void
+halbtc8812a1ant_WifiParaAdjust(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN enable
+ )
+{
+ if(enable)
+ {
+ halbtc8812a1ant_LowPenaltyRa(btcoexist, NORMAL_EXEC, true);
+ }
+ else
+ {
+ halbtc8812a1ant_LowPenaltyRa(btcoexist, NORMAL_EXEC, false);
+ }
+}
+
+BOOLEAN
+halbtc8812a1ant_IsCommonAction(
+ PBTC_COEXIST btcoexist
+ )
+{
+ BOOLEAN common=false, wifi_connected=false, wifi_busy=false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ //halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+
+ if(!wifi_connected &&
+ BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n"));
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ halbtc8812a1ant_SwMechanism1(btcoexist,false,false,false,false);
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+
+ common = true;
+ }
+ else if(wifi_connected &&
+ (BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi connected + BT non connected-idle!!\n"));
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+
+ halbtc8812a1ant_SwMechanism1(btcoexist,false,false,false,false);
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+
+ common = true;
+ }
+ else if(!wifi_connected &&
+ (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi non connected-idle + BT connected-idle!!\n"));
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ halbtc8812a1ant_SwMechanism1(btcoexist,false,false,false,false);
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+
+ common = true;
+ }
+ else if(wifi_connected &&
+ (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi connected + BT connected-idle!!\n"));
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ halbtc8812a1ant_SwMechanism1(btcoexist,true,true,true,true);
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+
+ common = true;
+ }
+ else if(!wifi_connected &&
+ (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE != coex_dm->bt_status) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi non connected-idle + BT Busy!!\n"));
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ halbtc8812a1ant_SwMechanism1(btcoexist,false,false,false,false);
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+
+ common = true;
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism1(btcoexist,true,true,true,true);
+
+ common = false;
+ }
+
+ return common;
+}
+
+
+void
+halbtc8812a1ant_TdmaDurationAdjustForAcl(
+ PBTC_COEXIST btcoexist
+ )
+{
+ static s4Byte up,dn,m,n,wait_count;
+ s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration
+ u1Byte retry_count=0, bt_info_ext;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], halbtc8812a1ant_TdmaDurationAdjustForAcl()\n"));
+ if(coex_dm->reset_tdma_adjust)
+ {
+ coex_dm->reset_tdma_adjust = false;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], first run TdmaDurationAdjust()!!\n"));
+
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+ //============
+ up = 0;
+ dn = 0;
+ m = 1;
+ n= 3;
+ result = 0;
+ wait_count = 0;
+ }
+ else
+ {
+ //accquire the BT TRx retry count from BT_Info byte2
+ retry_count = coex_sta->bt_retry_cnt;
+ bt_info_ext = coex_sta->bt_info_ext;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], retry_count = %d\n", retry_count));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, wait_count=%d\n",
+ up, dn, m, n, wait_count));
+ result = 0;
+ wait_count++;
+
+ if(retry_count == 0) // no retry in the last 2-second duration
+ {
+ up++;
+ dn--;
+
+ if (dn <= 0)
+ dn = 0;
+
+ if(up >= n) // if 連續 n 個2秒 retry count為0, 則調寬WiFi duration
+ {
+ wait_count = 0;
+ n = 3;
+ up = 0;
+ dn = 0;
+ result = 1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], Increase wifi duration!!\n"));
+ }
+ }
+ else if (retry_count <= 3) // <=3 retry in the last 2-second duration
+ {
+ up--;
+ dn++;
+
+ if (up <= 0)
+ up = 0;
+
+ if (dn == 2) // if 連續 2 個2秒 retry count< 3, 則調窄WiFi duration
+ {
+ if (wait_count <= 2)
+ m++; // 避免一直在兩個level中來回
+ else
+ m = 1;
+
+ if ( m >= 20) //m 最大值 = 20 ' 最大120秒 recheck是否調整 WiFi duration.
+ m = 20;
+
+ n = 3*m;
+ up = 0;
+ dn = 0;
+ wait_count = 0;
+ result = -1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n"));
+ }
+ }
+ else //retry count > 3, 只要1次 retry count > 3, 則調窄WiFi duration
+ {
+ if (wait_count == 1)
+ m++; // 避免一直在兩個level中來回
+ else
+ m = 1;
+
+ if ( m >= 20) //m 最大值 = 20 ' 最大120秒 recheck是否調整 WiFi duration.
+ m = 20;
+
+ n = 3*m;
+ up = 0;
+ dn = 0;
+ wait_count = 0;
+ result = -1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n"));
+ }
+
+ if(result == -1)
+ {
+ if( (BT_INFO_8812A_1ANT_A2DP_BASIC_RATE(bt_info_ext)) &&
+ ((coex_dm->cur_ps_tdma == 1) ||(coex_dm->cur_ps_tdma == 2)) )
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 9);
+ coex_dm->ps_tdma_du_adj_type = 9;
+ }
+ else if(coex_dm->cur_ps_tdma == 1)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+ }
+ else if(coex_dm->cur_ps_tdma == 2)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 9);
+ coex_dm->ps_tdma_du_adj_type = 9;
+ }
+ else if(coex_dm->cur_ps_tdma == 9)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 11);
+ coex_dm->ps_tdma_du_adj_type = 11;
+ }
+ }
+ else if(result == 1)
+ {
+ if( (BT_INFO_8812A_1ANT_A2DP_BASIC_RATE(bt_info_ext)) &&
+ ((coex_dm->cur_ps_tdma == 1) ||(coex_dm->cur_ps_tdma == 2)) )
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 9);
+ coex_dm->ps_tdma_du_adj_type = 9;
+ }
+ else if(coex_dm->cur_ps_tdma == 11)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 9);
+ coex_dm->ps_tdma_du_adj_type = 9;
+ }
+ else if(coex_dm->cur_ps_tdma == 9)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+ }
+ else if(coex_dm->cur_ps_tdma == 2)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 1);
+ coex_dm->ps_tdma_du_adj_type = 1;
+ }
+ }
+
+ if( coex_dm->cur_ps_tdma != 1 &&
+ coex_dm->cur_ps_tdma != 2 &&
+ coex_dm->cur_ps_tdma != 9 &&
+ coex_dm->cur_ps_tdma != 11 )
+ {
+ // recover to previous adjust type
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, coex_dm->ps_tdma_du_adj_type);
+ }
+ }
+}
+
+u1Byte
+halbtc8812a1ant_PsTdmaTypeByWifiRssi(
+ s4Byte wifi_rssi,
+ s4Byte pre_wifi_rssi,
+ u1Byte wifi_rssi_thresh
+ )
+{
+ u1Byte ps_tdma_type=0;
+
+ if(wifi_rssi > pre_wifi_rssi)
+ {
+ if(wifi_rssi > (wifi_rssi_thresh+5))
+ {
+ ps_tdma_type = 26;
+ }
+ else
+ {
+ ps_tdma_type = 25;
+ }
+ }
+ else
+ {
+ if(wifi_rssi > wifi_rssi_thresh)
+ {
+ ps_tdma_type = 26;
+ }
+ else
+ {
+ ps_tdma_type = 25;
+ }
+ }
+
+ return ps_tdma_type;
+}
+
+void
+halbtc8812a1ant_PsTdmaCheckForPowerSaveState(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN new_ps_state
+ )
+{
+ u1Byte lps_mode=0x0;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_LPS_MODE, &lps_mode);
+
+ if(lps_mode) // already under LPS state
+ {
+ if(new_ps_state)
+ {
+ // keep state under LPS, do nothing.
+ }
+ else
+ {
+ // will leave LPS state, turn off psTdma first
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 0);
+ }
+ }
+ else // NO PS state
+ {
+ if(new_ps_state)
+ {
+ // will enter LPS state, turn off psTdma first
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 0);
+ }
+ else
+ {
+ // keep state under NO PS state, do nothing.
+ }
+ }
+}
+
+// SCO only or SCO+PAN(HS)
+void
+halbtc8812a1ant_ActionSco(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state;
+ u4Byte wifi_bw;
+
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 4);
+
+ if(halbtc8812a1ant_NeedToDecBtPwr(btcoexist))
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ else
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,true,false,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+
+void
+halbtc8812a1ant_ActionHid(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state, bt_rssi_state;
+ u4Byte wifi_bw;
+
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+ bt_rssi_state = halbtc8812a1ant_BtRssiState(2, 50, 0);
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+
+ if(halbtc8812a1ant_NeedToDecBtPwr(btcoexist))
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ else
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,false,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+//A2DP only / PAN(EDR) only/ A2DP+PAN(HS)
+void
+halbtc8812a1ant_ActionA2dp(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state, bt_rssi_state;
+ u4Byte wifi_bw;
+
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+ bt_rssi_state = halbtc8812a1ant_BtRssiState(2, 50, 0);
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+
+ if(halbtc8812a1ant_NeedToDecBtPwr(btcoexist))
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ else
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,true,false,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+void
+halbtc8812a1ant_ActionA2dpPanHs(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state, bt_rssi_state, bt_info_ext;
+ u4Byte wifi_bw;
+
+ bt_info_ext = coex_sta->bt_info_ext;
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+ bt_rssi_state = halbtc8812a1ant_BtRssiState(2, 50, 0);
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+
+ if(halbtc8812a1ant_NeedToDecBtPwr(btcoexist))
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ else
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,true,false,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+void
+halbtc8812a1ant_ActionPanEdr(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state, bt_rssi_state;
+ u4Byte wifi_bw;
+
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+ bt_rssi_state = halbtc8812a1ant_BtRssiState(2, 50, 0);
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+
+ if(halbtc8812a1ant_NeedToDecBtPwr(btcoexist))
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ else
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,true,false,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+
+//PAN(HS) only
+void
+halbtc8812a1ant_ActionPanHs(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state, bt_rssi_state;
+ u4Byte wifi_bw;
+
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+ bt_rssi_state = halbtc8812a1ant_BtRssiState(2, 50, 0);
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // fw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ }
+ else
+ {
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+ }
+
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,true,false,0x18);
+ }
+ }
+ else
+ {
+ // fw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ }
+ else
+ {
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+ }
+
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+//PAN(EDR)+A2DP
+void
+halbtc8812a1ant_ActionPanEdrA2dp(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state, bt_rssi_state, bt_info_ext;
+ u4Byte wifi_bw;
+
+ bt_info_ext = coex_sta->bt_info_ext;
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+ bt_rssi_state = halbtc8812a1ant_BtRssiState(2, 50, 0);
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+
+ if(halbtc8812a1ant_NeedToDecBtPwr(btcoexist))
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ else
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,true,false,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+void
+halbtc8812a1ant_ActionPanEdrHid(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state, bt_rssi_state;
+ u4Byte wifi_bw;
+
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+ bt_rssi_state = halbtc8812a1ant_BtRssiState(2, 50, 0);
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+
+ if(halbtc8812a1ant_NeedToDecBtPwr(btcoexist))
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ else
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,true,false,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+// HID+A2DP+PAN(EDR)
+void
+halbtc8812a1ant_ActionHidA2dpPanEdr(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state, bt_rssi_state, bt_info_ext;
+ u4Byte wifi_bw;
+
+ bt_info_ext = coex_sta->bt_info_ext;
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+ bt_rssi_state = halbtc8812a1ant_BtRssiState(2, 50, 0);
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, NORMAL_EXEC, 6);
+
+ if(halbtc8812a1ant_NeedToDecBtPwr(btcoexist))
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ else
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,true,false,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+void
+halbtc8812a1ant_ActionHidA2dp(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u1Byte wifi_rssi_state, bt_rssi_state, bt_info_ext;
+ u4Byte wifi_bw;
+
+ bt_info_ext = coex_sta->bt_info_ext;
+ wifi_rssi_state = halbtc8812a1ant_WifiRssiState(btcoexist, 0, 2, 25, 0);
+ bt_rssi_state = halbtc8812a1ant_BtRssiState(2, 50, 0);
+
+ if(halbtc8812a1ant_NeedToDecBtPwr(btcoexist))
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, true);
+ else
+ halbtc8812a1ant_DecBtPwr(btcoexist, NORMAL_EXEC, false);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,true,false,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifi_rssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifi_rssi_state == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,true,true,false,0x18);
+ }
+ else
+ {
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+ }
+ }
+}
+
+void
+halbtc8812a1ant_ActionHs(
+ PBTC_COEXIST btcoexist,
+ BOOLEAN hs_connecting
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action for HS, hs_connecting=%d!!!\n", hs_connecting));
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 8);
+
+ if(hs_connecting)
+ {
+ halbtc8812a1ant_CoexTable(btcoexist, FORCE_EXEC, 0xaaaaaaaa, 0xaaaaaaaa, 0xffff, 0x3);
+ }
+ else
+ {
+ if((coex_sta->high_priority_tx+coex_sta->high_priority_rx+
+ coex_sta->low_priority_tx+coex_sta->low_priority_rx)<=1200)
+ halbtc8812a1ant_CoexTable(btcoexist, FORCE_EXEC, 0xaaaaaaaa, 0xaaaaaaaa, 0xffff, 0x3);
+ else
+ halbtc8812a1ant_CoexTable(btcoexist, FORCE_EXEC, 0xffffffff, 0xffffffff, 0xffff, 0x3);
+ }
+}
+
+
+void
+halbtc8812a1ant_ActionWifiNotConnected(
+ PBTC_COEXIST btcoexist
+ )
+{
+ BOOLEAN hs_connecting=false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting);
+
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+
+ if(hs_connecting)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HS is connecting!!!\n"));
+ halbtc8812a1ant_ActionHs(btcoexist, hs_connecting);
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+}
+
+void
+halbtc8812a1ant_ActionWifiNotConnectedAssoAuthScan(
+ PBTC_COEXIST btcoexist
+ )
+{
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+ BOOLEAN hs_connecting=false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting);
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+
+ if(hs_connecting)
+ {
+ halbtc8812a1ant_ActionHs(btcoexist, hs_connecting);
+ }
+ else if(btcoexist->bt_info.bt_disabled)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_INQ_PAGE == coex_dm->bt_status)
+{
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 30);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else if( (BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) )
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 28);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status)
+ {
+ if(stack_info->hid_exist)
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 35);
+ else
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 29);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else if( (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status) )
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x5aea5aea, 0x5aea5aea, 0xffff, 0x3);
+ }
+ else
+ {
+ //error condition, should not reach here, record error number for debugging.
+ coex_dm->error_condition = 1;
+ }
+}
+
+void
+halbtc8812a1ant_ActionWifiConnectedScan(
+ PBTC_COEXIST btcoexist
+ )
+{
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], ActionConnectedScan()===>\n"));
+
+ if(btcoexist->bt_info.bt_disabled)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+ halbtc8812a1ant_LpsRpwm(btcoexist, NORMAL_EXEC, 0x0, 0x4);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+
+ // psTdma
+ if(BT_8812A_1ANT_BT_STATUS_INQ_PAGE == coex_dm->bt_status)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], ActionConnectedScan(), bt is under inquiry/page scan\n"));
+ if(stack_info->sco_exist)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 32);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 30);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ }
+ else if( (BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) )
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 5);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status)
+ {
+ if(stack_info->hid_exist)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 34);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 4);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ }
+ else if( (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status) )
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 33);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else
+ {
+ //error condition, should not reach here
+ coex_dm->error_condition = 2;
+ }
+ }
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], ActionConnectedScan()<===\n"));
+}
+
+void
+halbtc8812a1ant_ActionWifiConnectedSpecialPacket(
+ PBTC_COEXIST btcoexist
+ )
+{
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+
+ if(btcoexist->bt_info.bt_disabled)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else
+ {
+ if(BT_8812A_1ANT_BT_STATUS_INQ_PAGE == coex_dm->bt_status)
+ {
+ if(stack_info->sco_exist)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 32);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 30);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ }
+ else if( (BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status) )
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 28);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status)
+ {
+ if(stack_info->hid_exist)
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 35);
+ else
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 29);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else if( (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status) )
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x5aea5aea, 0x5aea5aea, 0xffff, 0x3);
+ }
+ else
+ {
+ //error condition, should not reach here
+ coex_dm->error_condition = 3;
+ }
+ }
+}
+
+void
+halbtc8812a1ant_ActionWifiConnected(
+ PBTC_COEXIST btcoexist
+ )
+{
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+ BOOLEAN wifi_connected=false, wifi_busy=false, bt_hs_on=false;
+ BOOLEAN scan=false, link=false, roam=false;
+ BOOLEAN hs_connecting=false, under4way=false;
+ u4Byte wifi_bw;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], CoexForWifiConnect()===>\n"));
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
+ if(!wifi_connected)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], CoexForWifiConnect(), return for wifi not connected<===\n"));
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &under4way);
+ if(under4way)
+ {
+ halbtc8812a1ant_ActionWifiConnectedSpecialPacket(btcoexist);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n"));
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_CONNECTING, &hs_connecting);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+ if(scan || link || roam)
+ {
+ halbtc8812a1ant_ActionWifiConnectedScan(btcoexist);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n"));
+ return;
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ if(!wifi_busy)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], wifi associated-idle!!!\n"));
+ if(btcoexist->bt_info.bt_disabled)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+ halbtc8812a1ant_LpsRpwm(btcoexist, NORMAL_EXEC, 0x0, 0x4);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else
+ {
+ if(BT_8812A_1ANT_BT_STATUS_INQ_PAGE == coex_dm->bt_status)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], bt is under inquiry/page scan!!!\n"));
+ if(stack_info->sco_exist)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 32);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+ halbtc8812a1ant_LpsRpwm(btcoexist, NORMAL_EXEC, 0x0, 0x4);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 30);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+ halbtc8812a1ant_LpsRpwm(btcoexist, NORMAL_EXEC, 0x26, 0x0);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+ halbtc8812a1ant_LpsRpwm(btcoexist, NORMAL_EXEC, 0x26, 0x0);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 0);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status)
+ {
+ if(stack_info->hid_exist && stack_info->numOfLink==1)
+ {
+ // hid only
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x5fff5fff, 0x5fff5fff, 0xffff, 0x3);
+ coex_dm->reset_tdma_adjust = true;
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+ halbtc8812a1ant_LpsRpwm(btcoexist, NORMAL_EXEC, 0x0, 0x4);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+
+ if(stack_info->hid_exist)
+ {
+ if(stack_info->a2dp_exist)
+ {
+ // hid+a2dp
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else if(stack_info->pan_exist)
+ {
+ if(bt_hs_on)
+ {
+ // hid+hs
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ }
+ else
+ {
+ // hid+pan
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ }
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else
+ {
+ coex_dm->error_condition = 4;
+ }
+ coex_dm->reset_tdma_adjust = true;
+ }
+ else if(stack_info->a2dp_exist)
+ {
+ if(stack_info->pan_exist)
+ {
+ if(bt_hs_on)
+ {
+ // a2dp+hs
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ }
+ else
+ {
+ // a2dp+pan
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 36);
+ }
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ coex_dm->reset_tdma_adjust = true;
+ }
+ else
+ {
+ // a2dp only
+ halbtc8812a1ant_TdmaDurationAdjustForAcl(btcoexist);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ }
+ else if(stack_info->pan_exist)
+ {
+ // pan only
+ if(bt_hs_on)
+ {
+ coex_dm->error_condition = 5;
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ coex_dm->reset_tdma_adjust = true;
+ }
+ else
+ {
+ // temp state, do nothing!!!
+ //DbgPrint("error 6, coex_dm->bt_status=%d\n", coex_dm->bt_status);
+ //DbgPrint("error 6, stack_info->numOfLink=%d, stack_info->hid_exist=%d, stack_info->a2dp_exist=%d, stack_info->pan_exist=%d, stack_info->sco_exist=%d\n",
+ //stack_info->numOfLink, stack_info->hid_exist, stack_info->a2dp_exist, stack_info->pan_exist, stack_info->sco_exist);
+ //coex_dm->error_condition = 6;
+ }
+ }
+ }
+ else if( (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status) )
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x5aea5aea, 0x5aea5aea, 0xffff, 0x3);
+ }
+ else
+ {
+ //error condition, should not reach here
+ coex_dm->error_condition = 7;
+ }
+ }
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], wifi busy!!!\n"));
+ if(btcoexist->bt_info.bt_disabled)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else
+ {
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HS is under progress!!!\n"));
+ //DbgPrint("coex_dm->bt_status = 0x%x\n", coex_dm->bt_status);
+ halbtc8812a1ant_ActionHs(btcoexist, hs_connecting);
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_INQ_PAGE == coex_dm->bt_status)
+ {
+ if(stack_info->sco_exist)
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 32);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+ halbtc8812a1ant_LpsRpwm(btcoexist, NORMAL_EXEC, 0x0, 0x4);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 30);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 5);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x5a5a5a5a, 0x5a5a5a5a, 0xffff, 0x3);
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ if(bt_hs_on)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HS is under progress!!!\n"));
+ halbtc8812a1ant_ActionHs(btcoexist, hs_connecting);
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 5);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x5a5a5a5a, 0x5a5a5a5a, 0xffff, 0x3);
+ }
+ }
+ else if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status)
+ {
+ if(stack_info->hid_exist && stack_info->numOfLink==1)
+ {
+ // hid only
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x5fff5fff, 0x5fff5fff, 0xffff, 0x3);
+ coex_dm->reset_tdma_adjust = true;
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+ halbtc8812a1ant_LpsRpwm(btcoexist, NORMAL_EXEC, 0x0, 0x4);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+
+ if(stack_info->hid_exist)
+ {
+ if(stack_info->a2dp_exist)
+ {
+ // hid+a2dp
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else if(stack_info->pan_exist)
+ {
+ if(bt_hs_on)
+ {
+ // hid+hs
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ }
+ else
+ {
+ // hid+pan
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ }
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ else
+ {
+ coex_dm->error_condition = 8;
+ }
+ coex_dm->reset_tdma_adjust = true;
+ }
+ else if(stack_info->a2dp_exist)
+ {
+ if(stack_info->pan_exist)
+ {
+ if(bt_hs_on)
+ {
+ // a2dp+hs
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ }
+ else
+ {
+ // a2dp+pan
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 36);
+ }
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ coex_dm->reset_tdma_adjust = true;
+ }
+ else
+ {
+ // a2dp only
+ halbtc8812a1ant_TdmaDurationAdjustForAcl(btcoexist);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ }
+ else if(stack_info->pan_exist)
+ {
+ // pan only
+ if(bt_hs_on)
+ {
+ coex_dm->error_condition = 9;
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, true, 2);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x5afa5afa, 0xffff, 0x3);
+ }
+ coex_dm->reset_tdma_adjust = true;
+ }
+ else
+ {
+ //DbgPrint("error 10, stack_info->numOfLink=%d, stack_info->hid_exist=%d, stack_info->a2dp_exist=%d, stack_info->pan_exist=%d, stack_info->sco_exist=%d\n",
+ //stack_info->numOfLink, stack_info->hid_exist, stack_info->a2dp_exist, stack_info->pan_exist, stack_info->sco_exist);
+ coex_dm->error_condition = 10;
+ }
+ }
+ }
+ else if( (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status) )
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 8);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x5aea5aea, 0x5aea5aea, 0xffff, 0x3);
+ }
+ else
+ {
+ //DbgPrint("error 11, coex_dm->bt_status=%d\n", coex_dm->bt_status);
+ //DbgPrint("error 11, stack_info->numOfLink=%d, stack_info->hid_exist=%d, stack_info->a2dp_exist=%d, stack_info->pan_exist=%d, stack_info->sco_exist=%d\n",
+ //stack_info->numOfLink, stack_info->hid_exist, stack_info->a2dp_exist, stack_info->pan_exist, stack_info->sco_exist);
+ //error condition, should not reach here
+ coex_dm->error_condition = 11;
+ }
+ }
+ }
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], CoexForWifiConnect()<===\n"));
+}
+
+void
+halbtc8812a1ant_RunSwCoexistMechanism(
+ PBTC_COEXIST btcoexist
+ )
+{
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+ BOOLEAN wifi_under5g=false, wifi_busy=false, wifi_connected=false;
+ u1Byte bt_info_original=0, bt_retry_cnt=0;
+ u1Byte algorithm=0;
+
+ return;
+ if(stack_info->bProfileNotified)
+ {
+ algorithm = halbtc8812a1ant_ActionAlgorithm(btcoexist);
+ coex_dm->cur_algorithm = algorithm;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Algorithm = %d \n", coex_dm->cur_algorithm));
+
+ if(halbtc8812a1ant_IsCommonAction(btcoexist))
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action common.\n"));
+ }
+ else
+ {
+ switch(coex_dm->cur_algorithm)
+ {
+ case BT_8812A_1ANT_COEX_ALGO_SCO:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = SCO.\n"));
+ halbtc8812a1ant_ActionSco(btcoexist);
+ break;
+ case BT_8812A_1ANT_COEX_ALGO_HID:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = HID.\n"));
+ halbtc8812a1ant_ActionHid(btcoexist);
+ break;
+ case BT_8812A_1ANT_COEX_ALGO_A2DP:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = A2DP.\n"));
+ halbtc8812a1ant_ActionA2dp(btcoexist);
+ break;
+ case BT_8812A_1ANT_COEX_ALGO_A2DP_PANHS:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = A2DP+PAN(HS).\n"));
+ halbtc8812a1ant_ActionA2dpPanHs(btcoexist);
+ break;
+ case BT_8812A_1ANT_COEX_ALGO_PANEDR:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = PAN(EDR).\n"));
+ halbtc8812a1ant_ActionPanEdr(btcoexist);
+ break;
+ case BT_8812A_1ANT_COEX_ALGO_PANHS:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = HS mode.\n"));
+ halbtc8812a1ant_ActionPanHs(btcoexist);
+ break;
+ case BT_8812A_1ANT_COEX_ALGO_PANEDR_A2DP:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = PAN+A2DP.\n"));
+ halbtc8812a1ant_ActionPanEdrA2dp(btcoexist);
+ break;
+ case BT_8812A_1ANT_COEX_ALGO_PANEDR_HID:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = PAN(EDR)+HID.\n"));
+ halbtc8812a1ant_ActionPanEdrHid(btcoexist);
+ break;
+ case BT_8812A_1ANT_COEX_ALGO_HID_A2DP_PANEDR:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = HID+A2DP+PAN.\n"));
+ halbtc8812a1ant_ActionHidA2dpPanEdr(btcoexist);
+ break;
+ case BT_8812A_1ANT_COEX_ALGO_HID_A2DP:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = HID+A2DP.\n"));
+ halbtc8812a1ant_ActionHidA2dp(btcoexist);
+ break;
+ default:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = coexist All Off!!\n"));
+ halbtc8812a1ant_CoexAllOff(btcoexist);
+ break;
+ }
+ coex_dm->pre_algorithm = coex_dm->cur_algorithm;
+ }
+ }
+}
+
+void
+halbtc8812a1ant_RunCoexistMechanism(
+ PBTC_COEXIST btcoexist
+ )
+{
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+ BOOLEAN wifi_under5g=false, wifi_busy=false, wifi_connected=false;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], RunCoexistMechanism()===>\n"));
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under5g);
+
+ if(wifi_under5g)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], RunCoexistMechanism(), return for 5G <===\n"));
+ return;
+ }
+
+ if(btcoexist->manual_control)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"));
+ return;
+ }
+
+ if(btcoexist->stop_coex_dm)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"));
+ return;
+ }
+
+ halbtc8812a1ant_RunSwCoexistMechanism(btcoexist);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
+ if(btcoexist->bt_info.bt_disabled)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], bt is disabled!!!\n"));
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ if(wifi_busy)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ }
+ else
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, true);
+ halbtc8812a1ant_LpsRpwm(btcoexist, NORMAL_EXEC, 0x0, 0x4);
+ // power save must executed before psTdma.
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ }
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ }
+ else if(coex_sta->under_ips)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], wifi is under IPS !!!\n"));
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 0);
+ halbtc8812a1ant_CoexTable(btcoexist, NORMAL_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+ halbtc8812a1ant_WifiParaAdjust(btcoexist, false);
+ }
+ else if(!wifi_connected)
+ {
+ BOOLEAN scan=false, link=false, roam=false;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], wifi is non connected-idle !!!\n"));
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+
+ if(scan || link || roam)
+ halbtc8812a1ant_ActionWifiNotConnectedAssoAuthScan(btcoexist);
+ else
+ halbtc8812a1ant_ActionWifiNotConnected(btcoexist);
+ }
+ else // wifi LPS/Busy
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], wifi is NOT under IPS!!!\n"));
+ halbtc8812a1ant_WifiParaAdjust(btcoexist, true);
+ halbtc8812a1ant_ActionWifiConnected(btcoexist);
+ }
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], RunCoexistMechanism()<===\n"));
+}
+
+void
+halbtc8812a1ant_InitCoexDm(
+ PBTC_COEXIST btcoexist
+ )
+{
+ BOOLEAN wifi_connected=false;
+ // force to reset coex mechanism
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
+ if(!wifi_connected) // non-connected scan
+ {
+ halbtc8812a1ant_ActionWifiNotConnected(btcoexist);
+ }
+ else // wifi is connected
+ {
+ halbtc8812a1ant_ActionWifiConnected(btcoexist);
+ }
+
+ halbtc8812a1ant_FwDacSwingLvl(btcoexist, FORCE_EXEC, 6);
+ halbtc8812a1ant_DecBtPwr(btcoexist, FORCE_EXEC, false);
+
+ // sw all off
+ halbtc8812a1ant_SwMechanism1(btcoexist,false,false,false,false);
+ halbtc8812a1ant_SwMechanism2(btcoexist,false,false,false,0x18);
+
+ halbtc8812a1ant_CoexTable(btcoexist, FORCE_EXEC, 0x55555555, 0x55555555, 0xffff, 0x3);
+}
+
+//============================================================
+// work around function start with wa_halbtc8812a1ant_
+//============================================================
+//============================================================
+// extern function start with EXhalbtc8812a1ant_
+//============================================================
+void
+EXhalbtc8812a1ant_InitHwConfig(
+ PBTC_COEXIST btcoexist
+ )
+{
+ u4Byte u4_tmp=0;
+ u2Byte u2Tmp=0;
+ u1Byte u1_tmp=0;
+
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], 1Ant Init HW Config!!\n"));
+
+ // backup rf 0x1e value
+ coex_dm->bt_rf0x1e_backup =
+ btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A, 0x1e, 0xfffff);
+
+ //ant sw control to BT
+ btcoexist->btc_write_4byte(btcoexist, 0x900, 0x00000400);
+ btcoexist->btc_write_1byte(btcoexist, 0x76d, 0x1);
+ btcoexist->btc_write_1byte(btcoexist, 0xcb3, 0x77);
+ btcoexist->btc_write_1byte(btcoexist, 0xcb7, 0x40);
+
+ // 0x790[5:0]=0x5
+ u1_tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
+ u1_tmp &= 0xc0;
+ u1_tmp |= 0x5;
+ btcoexist->btc_write_1byte(btcoexist, 0x790, u1_tmp);
+
+ // PTA parameter
+ btcoexist->btc_write_1byte(btcoexist, 0x6cc, 0x0);
+ btcoexist->btc_write_4byte(btcoexist, 0x6c8, 0xffff);
+ btcoexist->btc_write_4byte(btcoexist, 0x6c4, 0x55555555);
+ btcoexist->btc_write_4byte(btcoexist, 0x6c0, 0x55555555);
+
+ // coex parameters
+ btcoexist->btc_write_1byte(btcoexist, 0x778, 0x1);
+
+ // enable counter statistics
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4);
+
+ // enable PTA
+ btcoexist->btc_write_1byte(btcoexist, 0x40, 0x20);
+
+ // bt clock related
+ u1_tmp = btcoexist->btc_read_1byte(btcoexist, 0x4);
+ u1_tmp |= BIT7;
+ btcoexist->btc_write_1byte(btcoexist, 0x4, u1_tmp);
+
+ // bt clock related
+ u1_tmp = btcoexist->btc_read_1byte(btcoexist, 0x7);
+ u1_tmp |= BIT1;
+ btcoexist->btc_write_1byte(btcoexist, 0x7, u1_tmp);
+}
+
+void
+EXhalbtc8812a1ant_InitCoexDm(
+ PBTC_COEXIST btcoexist
+ )
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], Coex Mechanism Init!!\n"));
+
+ btcoexist->stop_coex_dm = false;
+
+ halbtc8812a1ant_InitCoexDm(btcoexist);
+}
+
+void
+EXhalbtc8812a1ant_DisplayCoexInfo(
+ PBTC_COEXIST btcoexist
+ )
+{
+ PBTC_BOARD_INFO board_info=&btcoexist->boardInfo;
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+ pu1Byte cli_buf=btcoexist->cli_buf;
+ u1Byte u1_tmp[4], i, bt_info_ext, psTdmaCase=0;
+ u4Byte u4_tmp[4];
+ BOOLEAN roam=false, scan=false, link=false, wifi_under5g=false;
+ BOOLEAN bt_hs_on=false, wifi_busy=false;
+ s4Byte wifi_rssi=0, bt_hs_rssi=0;
+ u4Byte wifi_bw, wifiTrafficDir;
+ u1Byte wifiDot11Chnl, wifiHsChnl;
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============");
+ CL_PRINTF(cli_buf);
+
+ if(btcoexist->manual_control)
+ {
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============");
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n ==========================================");
+ CL_PRINTF(cli_buf);
+ }
+ if(btcoexist->stop_coex_dm)
+ {
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n ============[Coex is STOPPED]============");
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n ==========================================");
+ CL_PRINTF(cli_buf);
+ }
+
+ if(!board_info->bBtExist)
+ {
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
+ CL_PRINTF(cli_buf);
+ return;
+ }
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \
+ board_info->pgAntNum, board_info->btdmAntNum);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \
+ ((stack_info->bProfileNotified)? "Yes":"No"), stack_info->hciVersion);
+ CL_PRINTF(cli_buf);
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_FW_VER);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hs_on);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \
+ wifiDot11Chnl, wifiHsChnl, bt_hs_on);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \
+ coex_dm->wifi_chnl_info[0], coex_dm->wifi_chnl_info[1],
+ coex_dm->wifi_chnl_info[2]);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifi_rssi);
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \
+ wifi_rssi, bt_hs_rssi);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi link/ roam/ scan", \
+ link, roam, scan);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under5g);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \
+ (wifi_under5g? "5G":"2.4G"),
+ ((BTC_WIFI_BW_LEGACY==wifi_bw)? "Legacy": (((BTC_WIFI_BW_HT40==wifi_bw)? "HT40":"HT20"))),
+ ((!wifi_busy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink")));
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \
+ ((coex_sta->c2h_bt_inquiry_page)?("inquiry/page scan"):((BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE == coex_dm->bt_status)? "non-connected idle":
+ ( (BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE == coex_dm->bt_status)? "connected-idle":"busy"))),
+ coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
+ CL_PRINTF(cli_buf);
+
+ if(stack_info->bProfileNotified)
+ {
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \
+ stack_info->sco_exist, stack_info->hid_exist, stack_info->pan_exist, stack_info->a2dp_exist);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
+ }
+
+ bt_info_ext = coex_sta->bt_info_ext;
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \
+ (bt_info_ext&BIT0)? "Basic rate":"EDR rate");
+ CL_PRINTF(cli_buf);
+
+ for(i=0; i<BT_INFO_SRC_8812A_1ANT_MAX; i++)
+ {
+ if(coex_sta->bt_info_c2h_cnt[i])
+ {
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8812a1Ant[i], \
+ coex_sta->bt_info_c2h[i][0], coex_sta->bt_info_c2h[i][1],
+ coex_sta->bt_info_c2h[i][2], coex_sta->bt_info_c2h[i][3],
+ coex_sta->bt_info_c2h[i][4], coex_sta->bt_info_c2h[i][5],
+ coex_sta->bt_info_c2h[i][6], coex_sta->bt_info_c2h_cnt[i]);
+ CL_PRINTF(cli_buf);
+ }
+ }
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s, (0x%x/0x%x)", "PS state, IPS/LPS, (lps/rpwm)", \
+ ((coex_sta->under_ips? "IPS ON":"IPS OFF")),
+ ((coex_sta->under_lps? "LPS ON":"LPS OFF")),
+ btcoexist->bt_info.lps1Ant,
+ btcoexist->bt_info.rpwm1Ant);
+ CL_PRINTF(cli_buf);
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
+
+ if(!btcoexist->manual_control)
+ {
+ // Sw mechanism
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============");
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d ", "SM1[ShRf/ LpRA/ LimDig/ btLna]", \
+ coex_dm->cur_rf_rx_lpf_shrink, coex_dm->cur_low_penalty_ra, coex_dm->limited_dig, coex_dm->bCurBtLnaConstrain);
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \
+ coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off, coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
+ CL_PRINTF(cli_buf);
+
+ // Fw mechanism
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============");
+ CL_PRINTF(cli_buf);
+
+ psTdmaCase = coex_dm->cur_ps_tdma;
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", "PS TDMA", \
+ coex_dm->ps_tdma_para[0], coex_dm->ps_tdma_para[1],
+ coex_dm->ps_tdma_para[2], coex_dm->ps_tdma_para[3],
+ coex_dm->ps_tdma_para[4], psTdmaCase);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Latest error condition(should be 0)", \
+ coex_dm->error_condition);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "DecBtPwr/ IgnWlanAct", \
+ coex_dm->cur_dec_bt_pwr, coex_dm->cur_ignore_wlan_act);
+ CL_PRINTF(cli_buf);
+ }
+
+ // Hw setting
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============");
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \
+ coex_dm->bt_rf0x1e_backup);
+ CL_PRINTF(cli_buf);
+
+ u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x778", \
+ u1_tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x92c);
+ u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x930);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x92c/ 0x930", \
+ (u1_tmp[0]), u4_tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
+ u1_tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x4f);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x40/ 0x4f", \
+ u1_tmp[0], u1_tmp[1]);
+ CL_PRINTF(cli_buf);
+
+ u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
+ u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \
+ u4_tmp[0], u1_tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \
+ u4_tmp[0]);
+ CL_PRINTF(cli_buf);
+
+#if 0
+ u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xf48);
+ u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xf4c);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0xf48/ 0xf4c (FA cnt)", \
+ u4_tmp[0], u4_tmp[1]);
+ CL_PRINTF(cli_buf);
+#endif
+
+ u4_tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
+ u4_tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
+ u4_tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
+ u1_tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \
+ u4_tmp[0], u4_tmp[1], u4_tmp[2], u1_tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(hp rx[31:16]/tx[15:0])", \
+ coex_sta->high_priority_rx, coex_sta->high_priority_tx);
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(lp rx[31:16]/tx[15:0])", \
+ coex_sta->low_priority_rx, coex_sta->low_priority_tx);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
+}
+
+
+void
+EXhalbtc8812a1ant_IpsNotify(
+ PBTC_COEXIST btcoexist,
+ u1Byte type
+ )
+{
+ u4Byte u4_tmp=0;
+
+ if(btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ if(BTC_IPS_ENTER == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], IPS ENTER notify\n"));
+ coex_sta->under_ips = true;
+
+ // 0x4c[23]=1
+ u4_tmp = btcoexist->btc_read_4byte(btcoexist, 0x4c);
+ u4_tmp |= BIT23;
+ btcoexist->btc_write_4byte(btcoexist, 0x4c, u4_tmp);
+
+ halbtc8812a1ant_CoexAllOff(btcoexist);
+ }
+ else if(BTC_IPS_LEAVE == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], IPS LEAVE notify\n"));
+ coex_sta->under_ips = false;
+ //halbtc8812a1ant_InitCoexDm(btcoexist);
+ }
+}
+
+void
+EXhalbtc8812a1ant_LpsNotify(
+ PBTC_COEXIST btcoexist,
+ u1Byte type
+ )
+{
+ if(btcoexist->manual_control || btcoexist->stop_coex_dm)
+ return;
+
+ if(BTC_LPS_ENABLE == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], LPS ENABLE notify\n"));
+ coex_sta->under_lps = true;
+ }
+ else if(BTC_IPS_LEAVE == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], LPS DISABLE notify\n"));
+ coex_sta->under_lps = false;
+ }
+}
+
+void
+EXhalbtc8812a1ant_ScanNotify(
+ PBTC_COEXIST btcoexist,
+ u1Byte type
+ )
+{
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+ BOOLEAN wifi_connected=false;
+
+ if(btcoexist->manual_control ||btcoexist->stop_coex_dm)
+ return;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
+ if(BTC_SCAN_START == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], SCAN START notify\n"));
+ if(!wifi_connected) // non-connected scan
+ {
+ //set 0x550[3]=1 before PsTdma
+ //halbtc8812a1ant_Reg0x550Bit3(btcoexist, true);
+ halbtc8812a1ant_ActionWifiNotConnectedAssoAuthScan(btcoexist);
+ }
+ else // wifi is connected
+ {
+ halbtc8812a1ant_ActionWifiConnectedScan(btcoexist);
+ }
+ }
+ else if(BTC_SCAN_FINISH == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], SCAN FINISH notify\n"));
+ if(!wifi_connected) // non-connected scan
+ {
+ //halbtc8812a1ant_Reg0x550Bit3(btcoexist, false);
+ halbtc8812a1ant_ActionWifiNotConnected(btcoexist);
+ }
+ else
+ {
+ halbtc8812a1ant_ActionWifiConnected(btcoexist);
+ }
+ }
+}
+
+void
+EXhalbtc8812a1ant_ConnectNotify(
+ PBTC_COEXIST btcoexist,
+ u1Byte type
+ )
+{
+ PBTC_STACK_INFO stack_info=&btcoexist->stack_info;
+ BOOLEAN wifi_connected=false;
+
+ if(btcoexist->manual_control ||btcoexist->stop_coex_dm)
+ return;
+
+ if(BTC_ASSOCIATE_START == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], CONNECT START notify\n"));
+ if(btcoexist->bt_info.bt_disabled)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ }
+ else
+ {
+ halbtc8812a1ant_ActionWifiNotConnectedAssoAuthScan(btcoexist);
+ }
+ }
+ else if(BTC_ASSOCIATE_FINISH == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], CONNECT FINISH notify\n"));
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
+ if(!wifi_connected) // non-connected scan
+ {
+ //halbtc8812a1ant_Reg0x550Bit3(btcoexist, false);
+ halbtc8812a1ant_ActionWifiNotConnected(btcoexist);
+ }
+ else
+ {
+ halbtc8812a1ant_ActionWifiConnected(btcoexist);
+ }
+ }
+}
+
+void
+EXhalbtc8812a1ant_MediaStatusNotify(
+ PBTC_COEXIST btcoexist,
+ u1Byte type
+ )
+{
+ u1Byte dataLen=5;
+ u1Byte buf[6] = {0};
+ u1Byte h2c_parameter[3] ={0};
+ BOOLEAN wifi_under5g=false;
+ u4Byte wifi_bw;
+ u1Byte wifi_central_chnl;
+
+ if(btcoexist->manual_control ||btcoexist->stop_coex_dm)
+ return;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under5g);
+
+ // only 2.4G we need to inform bt the chnl mask
+ if(!wifi_under5g)
+ {
+ if(BTC_MEDIA_CONNECT == type)
+ {
+ h2c_parameter[0] = 0x1;
+ }
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifi_central_chnl);
+ h2c_parameter[1] = wifi_central_chnl;
+ if(BTC_WIFI_BW_HT40 == wifi_bw)
+ h2c_parameter[2] = 0x30;
+ else
+ h2c_parameter[2] = 0x20;
+ }
+
+ coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
+ coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
+ coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
+
+ buf[0] = dataLen;
+ buf[1] = 0x5; // OP_Code
+ buf[2] = 0x3; // OP_Code_Length
+ buf[3] = h2c_parameter[0]; // OP_Code_Content
+ buf[4] = h2c_parameter[1];
+ buf[5] = h2c_parameter[2];
+
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_CTRL_BT_COEX, (PVOID)&buf[0]);
+}
+
+void
+EXhalbtc8812a1ant_SpecialPacketNotify(
+ PBTC_COEXIST btcoexist,
+ u1Byte type
+ )
+{
+ BOOLEAN bSecurityLink=false;
+
+ if(btcoexist->manual_control ||btcoexist->stop_coex_dm)
+ return;
+
+ //if(type == BTC_PACKET_DHCP)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], special Packet(%d) notify\n", type));
+ if(btcoexist->bt_info.bt_disabled)
+ {
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ }
+ else
+ {
+ halbtc8812a1ant_ActionWifiConnectedSpecialPacket(btcoexist);
+ }
+ }
+}
+
+void
+EXhalbtc8812a1ant_BtInfoNotify(
+ PBTC_COEXIST btcoexist,
+ pu1Byte tmp_buf,
+ u1Byte length
+ )
+{
+ u1Byte bt_info=0;
+ u1Byte i, rsp_source=0;
+ static u4Byte set_bt_lna_cnt=0, set_bt_psd_mode=0;
+ BOOLEAN bt_busy=false, limited_dig=false;
+ BOOLEAN wifi_connected=false;
+ BOOLEAN bRejApAggPkt=false;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify()===>\n"));
+
+
+ rsp_source = tmp_buf[0]&0xf;
+ if(rsp_source >= BT_INFO_SRC_8812A_1ANT_MAX)
+ rsp_source = BT_INFO_SRC_8812A_1ANT_WIFI_FW;
+ coex_sta->bt_info_c2h_cnt[rsp_source]++;
+
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rsp_source, length));
+ for(i=0; i<length; i++)
+ {
+ coex_sta->bt_info_c2h[rsp_source][i] = tmp_buf[i];
+ if(i == 1)
+ bt_info = tmp_buf[i];
+ if(i == length-1)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("0x%2x]\n", tmp_buf[i]));
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("0x%2x, ", tmp_buf[i]));
+ }
+ }
+
+ if(btcoexist->manual_control)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), return for Manual CTRL<===\n"));
+ return;
+ }
+ if(btcoexist->stop_coex_dm)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), return for Coex STOPPED!!<===\n"));
+ return;
+ }
+
+ if(BT_INFO_SRC_8812A_1ANT_WIFI_FW != rsp_source)
+ {
+ coex_sta->bt_retry_cnt =
+ coex_sta->bt_info_c2h[rsp_source][2];
+
+ coex_sta->bt_rssi =
+ coex_sta->bt_info_c2h[rsp_source][3]*2+10;
+
+ coex_sta->bt_info_ext =
+ coex_sta->bt_info_c2h[rsp_source][4];
+
+ // Here we need to resend some wifi info to BT
+ // because bt is reset and loss of the info.
+ if( (coex_sta->bt_info_ext & BIT1) )
+ {
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED, &wifi_connected);
+ if(wifi_connected)
+ {
+ EXhalbtc8812a1ant_MediaStatusNotify(btcoexist, BTC_MEDIA_CONNECT);
+ }
+ else
+ {
+ EXhalbtc8812a1ant_MediaStatusNotify(btcoexist, BTC_MEDIA_DISCONNECT);
+ }
+
+ set_bt_psd_mode = 0;
+ }
+
+ // test-chip bt patch doesn't support, temporary remove.
+ // need to add back when mp-chip. 12/20/2012
+#if 0
+ if(set_bt_psd_mode <= 3)
+ {
+ halbtc8812a1ant_SetBtPsdMode(btcoexist, FORCE_EXEC, 0xd);
+ set_bt_psd_mode++;
+ }
+
+ if(coex_dm->bCurBtLnaConstrain)
+ {
+ if( (coex_sta->bt_info_ext & BIT2) )
+ {
+ }
+ else
+ {
+ if(set_bt_lna_cnt <= 3)
+ {
+ halbtc8812a1ant_SetBtLnaConstrain(btcoexist, FORCE_EXEC, true);
+ set_bt_lna_cnt++;
+ }
+ }
+ }
+ else
+ {
+ set_bt_lna_cnt = 0;
+ }
+#endif
+ // test-chip bt patch only rsp the status for BT_RSP,
+ // so temporary we consider the following only under BT_RSP
+ if(BT_INFO_SRC_8812A_1ANT_BT_RSP == rsp_source)
+ {
+ if( (coex_sta->bt_info_ext & BIT3) )
+ {
+ #if 0// temp disable because bt patch report the wrong value.
+ halbtc8812a1ant_IgnoreWlanAct(btcoexist, FORCE_EXEC, false);
+ #endif
+ }
+ else
+ {
+ // BT already NOT ignore Wlan active, do nothing here.
+ }
+
+ if( (coex_sta->bt_info_ext & BIT4) )
+ {
+ // BT auto report already enabled, do nothing
+ }
+ else
+ {
+ halbtc8812a1ant_BtAutoReport(btcoexist, FORCE_EXEC, true);
+ }
+ }
+ }
+
+ // check BIT2 first ==> check if bt is under inquiry or page scan
+ if(bt_info & BT_INFO_8812A_1ANT_B_INQ_PAGE)
+ {
+ coex_sta->c2h_bt_inquiry_page = true;
+ coex_dm->bt_status = BT_8812A_1ANT_BT_STATUS_INQ_PAGE;
+ }
+ else
+ {
+ coex_sta->c2h_bt_inquiry_page = false;
+ if(!(bt_info&BT_INFO_8812A_1ANT_B_CONNECTION))
+ {
+ coex_dm->bt_status = BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt non-connected idle!!!\n"));
+ }
+ else if(bt_info == BT_INFO_8812A_1ANT_B_CONNECTION) // connection exists but no busy
+ {
+ coex_dm->bt_status = BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt connected-idle!!!\n"));
+ }
+ else if((bt_info&BT_INFO_8812A_1ANT_B_SCO_ESCO) ||
+ (bt_info&BT_INFO_8812A_1ANT_B_SCO_BUSY))
+ {
+ coex_dm->bt_status = BT_8812A_1ANT_BT_STATUS_SCO_BUSY;
+ bRejApAggPkt = true;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt sco busy!!!\n"));
+ }
+ else if(bt_info&BT_INFO_8812A_1ANT_B_ACL_BUSY)
+ {
+ if(BT_8812A_1ANT_BT_STATUS_ACL_BUSY != coex_dm->bt_status)
+ coex_dm->reset_tdma_adjust = true;
+ coex_dm->bt_status = BT_8812A_1ANT_BT_STATUS_ACL_BUSY;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt acl busy!!!\n"));
+ }
+#if 0
+ else if(bt_info&BT_INFO_8812A_1ANT_B_SCO_ESCO)
+ {
+ coex_dm->bt_status = BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt acl/sco busy!!!\n"));
+ }
+#endif
+ else
+ {
+ //DbgPrint("error, undefined bt_info=0x%x\n", bt_info);
+ coex_dm->bt_status = BT_8812A_1ANT_BT_STATUS_MAX;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt non-defined state!!!\n"));
+ }
+
+ // send delete BA to disable aggregation
+ //btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejApAggPkt);
+ }
+
+ if( (BT_8812A_1ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+ (BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status) )
+ {
+ bt_busy = true;
+ }
+ else
+ {
+ bt_busy = false;
+ }
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
+
+ if(bt_busy)
+ {
+ limited_dig = true;
+ }
+ else
+ {
+ limited_dig = false;
+ }
+ coex_dm->limited_dig = limited_dig;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
+
+ halbtc8812a1ant_RunCoexistMechanism(btcoexist);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify()<===\n"));
+}
+
+void
+EXhalbtc8812a1ant_StackOperationNotify(
+ PBTC_COEXIST btcoexist,
+ u1Byte type
+ )
+{
+ if(BTC_STACK_OP_INQ_PAGE_PAIR_START == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], StackOP Inquiry/page/pair start notify\n"));
+ }
+ else if(BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], StackOP Inquiry/page/pair finish notify\n"));
+ }
+}
+
+void
+EXhalbtc8812a1ant_HaltNotify(
+ PBTC_COEXIST btcoexist
+ )
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], Halt notify\n"));
+
+ halbtc8812a1ant_IgnoreWlanAct(btcoexist, FORCE_EXEC, true);
+ halbtc8812a1ant_PsTdma(btcoexist, FORCE_EXEC, false, 0);
+ btcoexist->btc_write_1byte(btcoexist, 0x4f, 0xf);
+ halbtc8812a1ant_WifiParaAdjust(btcoexist, false);
+}
+
+void
+EXhalbtc8812a1ant_PnpNotify(
+ PBTC_COEXIST btcoexist,
+ u1Byte pnpState
+ )
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], Pnp notify\n"));
+
+ if(BTC_WIFI_PNP_SLEEP == pnpState)
+ {
+ btcoexist->stop_coex_dm = true;
+ halbtc8812a1ant_IgnoreWlanAct(btcoexist, FORCE_EXEC, true);
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ }
+ else if(BTC_WIFI_PNP_WAKE_UP == pnpState)
+ {
+
+ }
+}
+
+void
+EXhalbtc8812a1ant_Periodical(
+ PBTC_COEXIST btcoexist
+ )
+{
+ BOOLEAN wifi_under5g=false;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Periodical()===>\n"));
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], 1Ant Periodical!!\n"));
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under5g);
+
+ if(wifi_under5g)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Periodical(), return for 5G<===\n"));
+ halbtc8812a1ant_CoexAllOff(btcoexist);
+ return;
+ }
+
+ halbtc8812a1ant_QueryBtInfo(btcoexist);
+ halbtc8812a1ant_MonitorBtCtr(btcoexist);
+ halbtc8812a1ant_MonitorBtEnableDisable(btcoexist);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Periodical()<===\n"));
+}
+
+void
+EXhalbtc8812a1ant_DbgControl(
+ PBTC_COEXIST btcoexist,
+ u1Byte opCode,
+ u1Byte opLen,
+ pu1Byte pData
+ )
+{
+ switch(opCode)
+ {
+ case BTC_DBG_SET_COEX_NORMAL:
+ btcoexist->manual_control = false;
+ halbtc8812a1ant_InitCoexDm(btcoexist);
+ break;
+ case BTC_DBG_SET_COEX_WIFI_ONLY:
+ btcoexist->manual_control = true;
+ halbtc8812a1ant_PsTdmaCheckForPowerSaveState(btcoexist, false);
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ halbtc8812a1ant_PsTdma(btcoexist, NORMAL_EXEC, false, 9);
+ break;
+ case BTC_DBG_SET_COEX_BT_ONLY:
+ // todo
+ break;
+ default:
+ break;
+ }
+}
+#endif
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.h b/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.h
new file mode 100644
index 000000000000..37bdab5ae9f1
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/HalBtc8812a1Ant.h
@@ -0,0 +1,205 @@
+//===========================================
+// The following is for 8812A_1ANT BT Co-exist definition
+//===========================================
+#define BT_INFO_8812A_1ANT_B_FTP BIT7
+#define BT_INFO_8812A_1ANT_B_A2DP BIT6
+#define BT_INFO_8812A_1ANT_B_HID BIT5
+#define BT_INFO_8812A_1ANT_B_SCO_BUSY BIT4
+#define BT_INFO_8812A_1ANT_B_ACL_BUSY BIT3
+#define BT_INFO_8812A_1ANT_B_INQ_PAGE BIT2
+#define BT_INFO_8812A_1ANT_B_SCO_ESCO BIT1
+#define BT_INFO_8812A_1ANT_B_CONNECTION BIT0
+
+#define BT_INFO_8812A_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \
+ (((_BT_INFO_EXT_&BIT0))? true:false)
+
+#define BTC_RSSI_COEX_THRESH_TOL_8812A_1ANT 2
+
+#define
+#define OUT
+
+typedef enum _BT_INFO_SRC_8812A_1ANT{
+ BT_INFO_SRC_8812A_1ANT_WIFI_FW = 0x0,
+ BT_INFO_SRC_8812A_1ANT_BT_RSP = 0x1,
+ BT_INFO_SRC_8812A_1ANT_BT_ACTIVE_SEND = 0x2,
+ BT_INFO_SRC_8812A_1ANT_MAX
+}BT_INFO_SRC_8812A_1ANT,*PBT_INFO_SRC_8812A_1ANT;
+
+typedef enum _BT_8812A_1ANT_BT_STATUS{
+ BT_8812A_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
+ BT_8812A_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
+ BT_8812A_1ANT_BT_STATUS_INQ_PAGE = 0x2,
+ BT_8812A_1ANT_BT_STATUS_ACL_BUSY = 0x3,
+ BT_8812A_1ANT_BT_STATUS_SCO_BUSY = 0x4,
+ BT_8812A_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
+ BT_8812A_1ANT_BT_STATUS_MAX
+}BT_8812A_1ANT_BT_STATUS,*PBT_8812A_1ANT_BT_STATUS;
+
+typedef enum _BT_8812A_1ANT_COEX_ALGO{
+ BT_8812A_1ANT_COEX_ALGO_UNDEFINED = 0x0,
+ BT_8812A_1ANT_COEX_ALGO_SCO = 0x1,
+ BT_8812A_1ANT_COEX_ALGO_HID = 0x2,
+ BT_8812A_1ANT_COEX_ALGO_A2DP = 0x3,
+ BT_8812A_1ANT_COEX_ALGO_A2DP_PANHS = 0x4,
+ BT_8812A_1ANT_COEX_ALGO_PANEDR = 0x5,
+ BT_8812A_1ANT_COEX_ALGO_PANHS = 0x6,
+ BT_8812A_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
+ BT_8812A_1ANT_COEX_ALGO_PANEDR_HID = 0x8,
+ BT_8812A_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
+ BT_8812A_1ANT_COEX_ALGO_HID_A2DP = 0xa,
+ BT_8812A_1ANT_COEX_ALGO_MAX = 0xb,
+}BT_8812A_1ANT_COEX_ALGO,*PBT_8812A_1ANT_COEX_ALGO;
+
+typedef struct _COEX_DM_8812A_1ANT{
+ // fw mechanism
+ bool pre_dec_bt_pwr;
+ bool cur_dec_bt_pwr;
+ bool bPreBtLnaConstrain;
+ bool bCurBtLnaConstrain;
+ u8 bPreBtPsdMode;
+ u8 bCurBtPsdMode;
+ u8 pre_fw_dac_swing_lvl;
+ u8 cur_fw_dac_swing_lvl;
+ bool cur_ignore_wlan_act;
+ bool pre_ignore_wlan_act;
+ u8 pre_ps_tdma;
+ u8 cur_ps_tdma;
+ u8 ps_tdma_para[5];
+ u8 ps_tdma_du_adj_type;
+ bool reset_tdma_adjust;
+ bool pre_ps_tdma_on;
+ bool cur_ps_tdma_on;
+ bool pre_bt_auto_report;
+ bool cur_bt_auto_report;
+ u8 pre_lps;
+ u8 cur_lps;
+ u8 pre_rpwm;
+ u8 cur_rpwm;
+
+ // sw mechanism
+ bool pre_rf_rx_lpf_shrink;
+ bool cur_rf_rx_lpf_shrink;
+ u32 bt_rf0x1e_backup;
+ bool pre_low_penalty_ra;
+ bool cur_low_penalty_ra;
+ bool pre_dac_swing_on;
+ u32 pre_dac_swing_lvl;
+ bool cur_dac_swing_on;
+ u32 cur_dac_swing_lvl;
+ bool pre_adc_back_off;
+ bool cur_adc_back_off;
+ bool pre_agc_table_en;
+ bool cur_agc_table_en;
+ u32 pre_val0x6c0;
+ u32 cur_val0x6c0;
+ u32 pre_val0x6c4;
+ u32 cur_val0x6c4;
+ u32 pre_val0x6c8;
+ u32 cur_val0x6c8;
+ u8 pre_val0x6cc;
+ u8 cur_val0x6cc;
+ bool limited_dig;
+
+ // algorithm related
+ u8 pre_algorithm;
+ u8 cur_algorithm;
+ u8 bt_status;
+ u8 wifi_chnl_info[3];
+
+ u8 error_condition;
+} COEX_DM_8812A_1ANT, *PCOEX_DM_8812A_1ANT;
+
+typedef struct _COEX_STA_8812A_1ANT{
+ bool under_lps;
+ bool under_ips;
+ u32 high_priority_tx;
+ u32 high_priority_rx;
+ u32 low_priority_tx;
+ u32 low_priority_rx;
+ u8 bt_rssi;
+ u8 pre_bt_rssi_state;
+ u8 pre_wifi_rssi_state[4];
+ bool c2h_bt_info_req_sent;
+ u8 bt_info_c2h[BT_INFO_SRC_8812A_1ANT_MAX][10];
+ u32 bt_info_c2h_cnt[BT_INFO_SRC_8812A_1ANT_MAX];
+ bool c2h_bt_inquiry_page;
+ u8 bt_retry_cnt;
+ u8 bt_info_ext;
+}COEX_STA_8812A_1ANT, *PCOEX_STA_8812A_1ANT;
+
+//===========================================
+// The following is interface which will notify coex module.
+//===========================================
+void
+EXhalbtc8812a1ant_InitHwConfig(
+ PBTC_COEXIST btcoexist
+ );
+void
+EXhalbtc8812a1ant_InitCoexDm(
+ PBTC_COEXIST btcoexist
+ );
+void
+EXhalbtc8812a1ant_IpsNotify(
+ PBTC_COEXIST btcoexist,
+ u8 type
+ );
+void
+EXhalbtc8812a1ant_LpsNotify(
+ PBTC_COEXIST btcoexist,
+ u8 type
+ );
+void
+EXhalbtc8812a1ant_ScanNotify(
+ PBTC_COEXIST btcoexist,
+ u8 type
+ );
+void
+EXhalbtc8812a1ant_ConnectNotify(
+ PBTC_COEXIST btcoexist,
+ u8 type
+ );
+void
+EXhalbtc8812a1ant_MediaStatusNotify(
+ PBTC_COEXIST btcoexist,
+ u8 type
+ );
+void
+EXhalbtc8812a1ant_SpecialPacketNotify(
+ PBTC_COEXIST btcoexist,
+ u8 type
+ );
+void
+EXhalbtc8812a1ant_BtInfoNotify(
+ PBTC_COEXIST btcoexist,
+ u8 *tmp_buf,
+ u8 length
+ );
+void
+EXhalbtc8812a1ant_StackOperationNotify(
+ PBTC_COEXIST btcoexist,
+ u8 type
+ );
+void
+EXhalbtc8812a1ant_HaltNotify(
+ PBTC_COEXIST btcoexist
+ );
+void
+EXhalbtc8812a1ant_PnpNotify(
+ PBTC_COEXIST btcoexist,
+ u8 pnpState
+ );
+void
+EXhalbtc8812a1ant_Periodical(
+ PBTC_COEXIST btcoexist
+ );
+void
+EXhalbtc8812a1ant_DisplayCoexInfo(
+ PBTC_COEXIST btcoexist
+ );
+void
+EXhalbtc8812a1ant_DbgControl(
+ PBTC_COEXIST btcoexist,
+ u8 opCode,
+ u8 opLen,
+ u8 *pData
+ );
diff --git a/drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.c b/drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.c
new file mode 100644
index 000000000000..e619923ef0ab
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.c
@@ -0,0 +1,1614 @@
+//============================================================
+// Description:
+//
+// This file is for RTL8723A Co-exist mechanism
+//
+// History
+// 2012/08/22 Cosa first check in.
+// 2012/11/14 Cosa Revise for 8723A 1Ant out sourcing.
+//
+//============================================================
+
+//============================================================
+// include files
+//============================================================
+#include "Mp_Precomp.h"
+#if(BT_30_SUPPORT == 1)
+//============================================================
+// Global variables, these are static variables
+//============================================================
+static COEX_DM_8723A_1ANT GLCoexDm8723a1Ant;
+static PCOEX_DM_8723A_1ANT pCoexDm=&GLCoexDm8723a1Ant;
+static COEX_STA_8723A_1ANT GLCoexSta8723a1Ant;
+static PCOEX_STA_8723A_1ANT pCoexSta=&GLCoexSta8723a1Ant;
+
+const char *const GLBtInfoSrc8723a1Ant[]={
+ "BT Info[wifi fw]",
+ "BT Info[bt rsp]",
+ "BT Info[bt auto report]",
+};
+
+//============================================================
+// local function proto type if needed
+//============================================================
+//============================================================
+// local function start with halbtc8723a1ant_
+//============================================================
+VOID
+halbtc8723a1ant_Reg0x550Bit3(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bSet
+ )
+{
+ u1Byte u1tmp=0;
+
+ u1tmp = pBtCoexist->btc_read_1byte(pBtCoexist, 0x550);
+ if(bSet)
+ {
+ u1tmp |= BIT3;
+ }
+ else
+ {
+ u1tmp &= ~BIT3;
+ }
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x550, u1tmp);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], set 0x550[3]=%d\n", (bSet? 1:0)));
+}
+
+VOID
+halbtc8723a1ant_NotifyFwScan(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte scanType
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ if(BTC_SCAN_START == scanType)
+ H2C_Parameter[0] = 0x1;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], Notify FW for wifi scan, write 0x3b=0x%x\n",
+ H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x3b, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8723a1ant_QueryBtInfo(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ pCoexSta->bC2hBtInfoReqSent = true;
+
+ H2C_Parameter[0] |= BIT0; // trigger
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], Query Bt Info, FW write 0x38=0x%x\n",
+ H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x38, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8723a1ant_SetSwRfRxLpfCorner(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bRxRfShrinkOn
+ )
+{
+ if(bRxRfShrinkOn)
+ {
+ //Shrink RF Rx LPF corner
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Shrink RF Rx LPF corner!!\n"));
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xf0ff7);
+ }
+ else
+ {
+ //Resume RF Rx LPF corner
+ // After initialized, we can use pCoexDm->btRf0x1eBackup
+ if(pBtCoexist->initilized)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Resume RF Rx LPF corner!!\n"));
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup);
+ }
+ }
+}
+
+VOID
+halbtc8723a1ant_RfShrink(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bRxRfShrinkOn
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn Rx RF Shrink = %s\n",
+ (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF")));
+ pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreRfRxLpfShrink=%d, bCurRfRxLpfShrink=%d\n",
+ pCoexDm->bPreRfRxLpfShrink, pCoexDm->bCurRfRxLpfShrink));
+
+ if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink)
+ return;
+ }
+ halbtc8723a1ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink);
+
+ pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink;
+}
+
+VOID
+halbtc8723a1ant_SetSwPenaltyTxRateAdaptive(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bLowPenaltyRa
+ )
+{
+ u1Byte tmpU1;
+
+ tmpU1 = pBtCoexist->btc_read_1byte(pBtCoexist, 0x4fd);
+ tmpU1 |= BIT0;
+ if(bLowPenaltyRa)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Tx rate adaptive, set low penalty!!\n"));
+ tmpU1 &= ~BIT2;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Tx rate adaptive, set normal!!\n"));
+ tmpU1 |= BIT2;
+ }
+
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x4fd, tmpU1);
+}
+
+VOID
+halbtc8723a1ant_LowPenaltyRa(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bLowPenaltyRa
+ )
+{
+ return;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn LowPenaltyRA = %s\n",
+ (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF")));
+ pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreLowPenaltyRa=%d, bCurLowPenaltyRa=%d\n",
+ pCoexDm->bPreLowPenaltyRa, pCoexDm->bCurLowPenaltyRa));
+
+ if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa)
+ return;
+ }
+ halbtc8723a1ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa);
+
+ pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa;
+}
+
+VOID
+halbtc8723a1ant_SetCoexTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u4Byte val0x6c0,
+ IN u4Byte val0x6c8,
+ IN u1Byte val0x6cc
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x6c0, val0x6c0);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x6c8, val0x6c8);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc));
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x6cc, val0x6cc);
+}
+
+VOID
+halbtc8723a1ant_CoexTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u4Byte val0x6c0,
+ IN u4Byte val0x6c8,
+ IN u1Byte val0x6cc
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n",
+ (bForceExec? "force to":""), val0x6c0, val0x6c8, val0x6cc));
+ pCoexDm->curVal0x6c0 = val0x6c0;
+ pCoexDm->curVal0x6c8 = val0x6c8;
+ pCoexDm->curVal0x6cc = val0x6cc;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], preVal0x6c0=0x%x, preVal0x6c8=0x%x, preVal0x6cc=0x%x !!\n",
+ pCoexDm->preVal0x6c0, pCoexDm->preVal0x6c8, pCoexDm->preVal0x6cc));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], curVal0x6c0=0x%x, curVal0x6c8=0x%x, curVal0x6cc=0x%x !!\n",
+ pCoexDm->curVal0x6c0, pCoexDm->curVal0x6c8, pCoexDm->curVal0x6cc));
+
+ if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) &&
+ (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) &&
+ (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) )
+ return;
+ }
+ halbtc8723a1ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c8, val0x6cc);
+
+ pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0;
+ pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8;
+ pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc;
+}
+
+VOID
+halbtc8723a1ant_SetFwIgnoreWlanAct(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bEnable
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ if(bEnable)
+ {
+ H2C_Parameter[0] |= BIT0; // function enable
+ }
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x25=0x%x\n",
+ H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x25, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8723a1ant_IgnoreWlanAct(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bEnable
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s turn Ignore WlanAct %s\n",
+ (bForceExec? "force to":""), (bEnable? "ON":"OFF")));
+ pCoexDm->bCurIgnoreWlanAct = bEnable;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPreIgnoreWlanAct = %d, bCurIgnoreWlanAct = %d!!\n",
+ pCoexDm->bPreIgnoreWlanAct, pCoexDm->bCurIgnoreWlanAct));
+
+ if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct)
+ return;
+ }
+ halbtc8723a1ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable);
+
+ pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct;
+}
+
+VOID
+halbtc8723a1ant_SetFwPstdma(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type,
+ IN u1Byte byte1,
+ IN u1Byte byte2,
+ IN u1Byte byte3,
+ IN u1Byte byte4,
+ IN u1Byte byte5
+ )
+{
+ u1Byte H2C_Parameter[5] ={0};
+ u1Byte realByte1=byte1, realByte5=byte5;
+ BOOLEAN bApEnable=FALSE;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_AP_MODE_ENABLE, &bApEnable);
+
+ // byte1[1:0] != 0 means enable pstdma
+ // for 2Ant bt coexist, if byte1 != 0 means enable pstdma
+ if(byte1)
+ {
+ if(bApEnable)
+ {
+ if(type != 5 && type != 12)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], FW for 1Ant AP mode\n"));
+ realByte1 &= ~BIT4;
+ realByte1 |= BIT5;
+
+ realByte5 |= BIT5;
+ realByte5 &= ~BIT6;
+ }
+ }
+ }
+ H2C_Parameter[0] = realByte1;
+ H2C_Parameter[1] = byte2;
+ H2C_Parameter[2] = byte3;
+ H2C_Parameter[3] = byte4;
+ H2C_Parameter[4] = realByte5;
+
+ pCoexDm->psTdmaPara[0] = realByte1;
+ pCoexDm->psTdmaPara[1] = byte2;
+ pCoexDm->psTdmaPara[2] = byte3;
+ pCoexDm->psTdmaPara[3] = byte4;
+ pCoexDm->psTdmaPara[4] = realByte5;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x3a(5bytes)=0x%x%08x\n",
+ H2C_Parameter[0],
+ H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x3a, 5, H2C_Parameter);
+}
+
+VOID
+halbtc8723a1ant_PsTdma(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bTurnOn,
+ IN u1Byte type
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s turn %s PS TDMA, type=%d\n",
+ (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type));
+ pCoexDm->bCurPsTdmaOn = bTurnOn;
+ pCoexDm->curPsTdma = type;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n",
+ pCoexDm->bPrePsTdmaOn, pCoexDm->bCurPsTdmaOn));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n",
+ pCoexDm->prePsTdma, pCoexDm->curPsTdma));
+
+ if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) &&
+ (pCoexDm->prePsTdma == pCoexDm->curPsTdma) )
+ return;
+ }
+ if(pCoexDm->bCurPsTdmaOn)
+ {
+ switch(pCoexDm->curPsTdma)
+ {
+ case 1:
+ default:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x1a, 0x1a, 0x0, 0x40);
+ break;
+ case 2:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x12, 0x12, 0x0, 0x40);
+ break;
+ case 3:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x3f, 0x3, 0x10, 0x40);
+ break;
+ case 4:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x15, 0x3, 0x10, 0x0);
+ break;
+ case 5:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0xa9, 0x15, 0x3, 0x35, 0xc0);
+ break;
+
+ case 8:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x25, 0x3, 0x10, 0x0);
+ break;
+ case 9:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0xa, 0xa, 0x0, 0x40);
+ break;
+ case 10:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0xa, 0xa, 0x0, 0x40);
+ break;
+ case 11:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x5, 0x5, 0x0, 0x40);
+ break;
+ case 12:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0xa9, 0xa, 0x3, 0x15, 0xc0);
+ break;
+
+ case 18:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x25, 0x3, 0x10, 0x0);
+ break;
+
+ case 20:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x2a, 0x2a, 0x0, 0x0);
+ break;
+ case 21:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x20, 0x3, 0x10, 0x40);
+ break;
+ case 22:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x1a, 0x1a, 0x2, 0x40);
+ break;
+ case 23:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x12, 0x12, 0x2, 0x40);
+ break;
+ case 24:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0xa, 0xa, 0x2, 0x40);
+ break;
+ case 25:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x5, 0x5, 0x2, 0x40);
+ break;
+ case 26:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x93, 0x25, 0x3, 0x10, 0x0);
+ break;
+ case 27:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x13, 0x5, 0x5, 0x2, 0x40);
+ break;
+ case 28:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x3, 0x2f, 0x2f, 0x0, 0x0);
+ break;
+
+ }
+ }
+ else
+ {
+ // disable PS tdma
+ switch(pCoexDm->curPsTdma)
+ {
+ case 8:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x8, 0x0, 0x0, 0x0, 0x0);
+ break;
+ case 0:
+ default:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x0, 0x0, 0x0, 0x0, 0x0);
+ pBtCoexist->btc_write_2byte(pBtCoexist, 0x860, 0x210);
+ break;
+ case 9:
+ halbtc8723a1ant_SetFwPstdma(pBtCoexist, type, 0x0, 0x0, 0x0, 0x0, 0x0);
+ pBtCoexist->btc_write_2byte(pBtCoexist, 0x860, 0x110);
+ break;
+
+ }
+ }
+
+ // update pre state
+ pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn;
+ pCoexDm->prePsTdma = pCoexDm->curPsTdma;
+}
+
+
+VOID
+halbtc8723a1ant_CoexAllOff(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ // fw all off
+ halbtc8723a1ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+
+ // sw all off
+ halbtc8723a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a1ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE);
+
+ // hw all off
+ halbtc8723a1ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+}
+
+VOID
+halbtc8723a1ant_InitCoexDm(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ // force to reset coex mechanism
+ halbtc8723a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE);
+}
+
+VOID
+halbtc8723a1ant_BtEnableAction(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ halbtc8723a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE);
+}
+
+VOID
+halbtc8723a1ant_MonitorBtCtr(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u4Byte regHPTxRx, regLPTxRx, u4Tmp;
+ u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0;
+ u1Byte u1Tmp;
+
+ regHPTxRx = 0x770;
+ regLPTxRx = 0x774;
+
+ u4Tmp = pBtCoexist->btc_read_4byte(pBtCoexist, regHPTxRx);
+ regHPTx = u4Tmp & MASKLWORD;
+ regHPRx = (u4Tmp & MASKHWORD)>>16;
+
+ u4Tmp = pBtCoexist->btc_read_4byte(pBtCoexist, regLPTxRx);
+ regLPTx = u4Tmp & MASKLWORD;
+ regLPRx = (u4Tmp & MASKHWORD)>>16;
+
+ pCoexSta->highPriorityTx = regHPTx;
+ pCoexSta->highPriorityRx = regHPRx;
+ pCoexSta->lowPriorityTx = regLPTx;
+ pCoexSta->lowPriorityRx = regLPRx;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
+ regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
+ regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx));
+
+ // reset counter
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x76e, 0xc);
+}
+
+VOID
+halbtc8723a1ant_MonitorBtEnableDisable(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ static BOOLEAN bPreBtDisabled=FALSE;
+ static u4Byte btDisableCnt=0;
+ BOOLEAN bBtActive=true, bBtDisabled=FALSE;
+
+ // This function check if bt is disabled
+
+ if( pCoexSta->highPriorityTx == 0 &&
+ pCoexSta->highPriorityRx == 0 &&
+ pCoexSta->lowPriorityTx == 0 &&
+ pCoexSta->lowPriorityRx == 0)
+ {
+ bBtActive = FALSE;
+ }
+ if( pCoexSta->highPriorityTx == 0xffff &&
+ pCoexSta->highPriorityRx == 0xffff &&
+ pCoexSta->lowPriorityTx == 0xffff &&
+ pCoexSta->lowPriorityRx == 0xffff)
+ {
+ bBtActive = FALSE;
+ }
+ if(bBtActive)
+ {
+ btDisableCnt = 0;
+ bBtDisabled = FALSE;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is enabled !!\n"));
+ }
+ else
+ {
+ btDisableCnt++;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], bt all counters=0, %d times!!\n",
+ btDisableCnt));
+ if(btDisableCnt >= 2)
+ {
+ bBtDisabled = true;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is disabled !!\n"));
+ }
+ }
+ if(bPreBtDisabled != bBtDisabled)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is from %s to %s!!\n",
+ (bPreBtDisabled ? "disabled":"enabled"),
+ (bBtDisabled ? "disabled":"enabled")));
+ bPreBtDisabled = bBtDisabled;
+ if(!bBtDisabled)
+ {
+ halbtc8723a1ant_BtEnableAction(pBtCoexist);
+ }
+ else
+ {
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
+ }
+ }
+}
+
+VOID
+halbtc8723a1ant_TdmaDurationAdjust(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ static s4Byte up,dn,m,n,WaitCount;
+ s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration
+ u1Byte retryCount=0;
+ u1Byte btState;
+ BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE;
+ u4Byte wifiBw;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+ btState = pCoexDm->btStatus;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], TdmaDurationAdjust()\n"));
+ if(pCoexDm->psTdmaGlobalCnt != pCoexDm->psTdmaMonitorCnt)
+ {
+ pCoexDm->psTdmaMonitorCnt = 0;
+ pCoexDm->psTdmaGlobalCnt = 0;
+ }
+ if(pCoexDm->psTdmaMonitorCnt == 0)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], first run BT A2DP + WiFi busy state!!\n"));
+ if(btState == BT_STATE_8723A_1ANT_ACL_ONLY_BUSY)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 1);
+ pCoexDm->psTdmaDuAdjType = 1;
+ }
+ else
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 22);
+ pCoexDm->psTdmaDuAdjType = 22;
+ }
+ //============
+ up = 0;
+ dn = 0;
+ m = 1;
+ n= 3;
+ result = 0;
+ WaitCount = 0;
+ }
+ else
+ {
+ //accquire the BT TRx retry count from BT_Info byte2
+ retryCount = pCoexSta->btRetryCnt;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], retryCount = %d\n", retryCount));
+ result = 0;
+ WaitCount++;
+
+ if(retryCount == 0) // no retry in the last 2-second duration
+ {
+ up++;
+ dn--;
+
+ if (dn <= 0)
+ dn = 0;
+
+ if(up >= n) // if 連續 n 個2秒 retry count為0, 則調寬WiFi duration
+ {
+ WaitCount = 0;
+ n = 3;
+ up = 0;
+ dn = 0;
+ result = 1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Increase wifi duration!!\n"));
+ }
+ }
+ else if (retryCount <= 3) // <=3 retry in the last 2-second duration
+ {
+ up--;
+ dn++;
+
+ if (up <= 0)
+ up = 0;
+
+ if (dn == 2) // if 連續 2 個2秒 retry count< 3, 則調窄WiFi duration
+ {
+ if (WaitCount <= 2)
+ m++; // 避免一直在兩個level中來回
+ else
+ m = 1;
+
+ if ( m >= 20) //m 最大值 = 20 ' 最大120秒 recheck是否調整 WiFi duration.
+ m = 20;
+
+ n = 3*m;
+ up = 0;
+ dn = 0;
+ WaitCount = 0;
+ result = -1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n"));
+ }
+ }
+ else //retry count > 3, 只要1次 retry count > 3, 則調窄WiFi duration
+ {
+ if (WaitCount == 1)
+ m++; // 避免一直在兩個level中來回
+ else
+ m = 1;
+
+ if ( m >= 20) //m 最大值 = 20 ' 最大120秒 recheck是否調整 WiFi duration.
+ m = 20;
+
+ n = 3*m;
+ up = 0;
+ dn = 0;
+ WaitCount = 0;
+ result = -1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n"));
+ }
+
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BT TxRx counter H+L <= 1200\n"));
+ if(btState != BT_STATE_8723A_1ANT_ACL_ONLY_BUSY)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], NOT ACL only busy!\n"));
+ if(BTC_WIFI_BW_HT40 != wifiBw)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], 20MHz\n"));
+ if(result == -1)
+ {
+ if(pCoexDm->curPsTdma == 22)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 23);
+ pCoexDm->psTdmaDuAdjType = 23;
+ }
+ else if(pCoexDm->curPsTdma == 23)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 24);
+ pCoexDm->psTdmaDuAdjType = 24;
+ }
+ else if(pCoexDm->curPsTdma == 24)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 25);
+ pCoexDm->psTdmaDuAdjType = 25;
+ }
+ }
+ else if (result == 1)
+ {
+ if(pCoexDm->curPsTdma == 25)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 24);
+ pCoexDm->psTdmaDuAdjType = 24;
+ }
+ else if(pCoexDm->curPsTdma == 24)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 23);
+ pCoexDm->psTdmaDuAdjType = 23;
+ }
+ else if(pCoexDm->curPsTdma == 23)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 22);
+ pCoexDm->psTdmaDuAdjType = 22;
+ }
+ }
+ // error handle, if not in the following state,
+ // set psTdma again.
+ if( (pCoexDm->psTdmaDuAdjType != 22) &&
+ (pCoexDm->psTdmaDuAdjType != 23) &&
+ (pCoexDm->psTdmaDuAdjType != 24) &&
+ (pCoexDm->psTdmaDuAdjType != 25) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], duration case out of handle!!\n"));
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 23);
+ pCoexDm->psTdmaDuAdjType = 23;
+ }
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], 40MHz\n"));
+ if(result == -1)
+ {
+ if(pCoexDm->curPsTdma == 23)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 24);
+ pCoexDm->psTdmaDuAdjType = 24;
+ }
+ else if(pCoexDm->curPsTdma == 24)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 25);
+ pCoexDm->psTdmaDuAdjType = 25;
+ }
+ else if(pCoexDm->curPsTdma == 25)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 27);
+ pCoexDm->psTdmaDuAdjType = 27;
+ }
+ }
+ else if (result == 1)
+ {
+ if(pCoexDm->curPsTdma == 27)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 25);
+ pCoexDm->psTdmaDuAdjType = 25;
+ }
+ else if(pCoexDm->curPsTdma == 25)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 24);
+ pCoexDm->psTdmaDuAdjType = 24;
+ }
+ else if(pCoexDm->curPsTdma == 24)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 23);
+ pCoexDm->psTdmaDuAdjType = 23;
+ }
+ }
+ // error handle, if not in the following state,
+ // set psTdma again.
+ if( (pCoexDm->psTdmaDuAdjType != 23) &&
+ (pCoexDm->psTdmaDuAdjType != 24) &&
+ (pCoexDm->psTdmaDuAdjType != 25) &&
+ (pCoexDm->psTdmaDuAdjType != 27) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], duration case out of handle!!\n"));
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 24);
+ pCoexDm->psTdmaDuAdjType = 24;
+ }
+ }
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], ACL only busy\n"));
+ if (result == -1)
+ {
+ if(pCoexDm->curPsTdma == 1)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+ pCoexDm->psTdmaDuAdjType = 2;
+ }
+ else if(pCoexDm->curPsTdma == 2)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+ pCoexDm->psTdmaDuAdjType = 9;
+ }
+ else if(pCoexDm->curPsTdma == 9)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+ pCoexDm->psTdmaDuAdjType = 11;
+ }
+ }
+ else if (result == 1)
+ {
+ if(pCoexDm->curPsTdma == 11)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+ pCoexDm->psTdmaDuAdjType = 9;
+ }
+ else if(pCoexDm->curPsTdma == 9)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+ pCoexDm->psTdmaDuAdjType = 2;
+ }
+ else if(pCoexDm->curPsTdma == 2)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 1);
+ pCoexDm->psTdmaDuAdjType = 1;
+ }
+ }
+
+ // error handle, if not in the following state,
+ // set psTdma again.
+ if( (pCoexDm->psTdmaDuAdjType != 1) &&
+ (pCoexDm->psTdmaDuAdjType != 2) &&
+ (pCoexDm->psTdmaDuAdjType != 9) &&
+ (pCoexDm->psTdmaDuAdjType != 11) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], duration case out of handle!!\n"));
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+ pCoexDm->psTdmaDuAdjType = 2;
+ }
+ }
+ }
+ }
+
+ // if current PsTdma not match with the recorded one (when scan, dhcp...),
+ // then we have to adjust it back to the previous record one.
+ if(pCoexDm->curPsTdma != pCoexDm->psTdmaDuAdjType)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PsTdma type dismatch!!!, curPsTdma=%d, recordPsTdma=%d\n",
+ pCoexDm->curPsTdma, pCoexDm->psTdmaDuAdjType));
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam);
+
+ if( !bScan && !bLink && !bRoam)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, pCoexDm->psTdmaDuAdjType);
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n"));
+ }
+ }
+ pCoexDm->psTdmaMonitorCnt++;
+}
+
+
+VOID
+halbtc8723a1ant_CoexForWifiConnect(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BOOLEAN bWifiConnected=FALSE, bWifiBusy=FALSE;
+ u1Byte btState, btInfoOriginal=0;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+
+ btState = pCoexDm->btStatus;
+ btInfoOriginal = pCoexSta->btInfoC2h[BT_INFO_SRC_8723A_1ANT_BT_RSP][0];
+
+ if(bWifiConnected)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], wifi connected!!\n"));
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
+
+ if( !bWifiBusy &&
+ ((BT_STATE_8723A_1ANT_NO_CONNECTION == btState) ||
+ (BT_STATE_8723A_1ANT_CONNECT_IDLE == btState)) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], [Wifi is idle] or [Bt is non connected idle or Bt is connected idle]!!\n"));
+
+ if(BT_STATE_8723A_1ANT_NO_CONNECTION == btState)
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9);
+ else if(BT_STATE_8723A_1ANT_CONNECT_IDLE == btState)
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+
+ pBtCoexist->btc_setBbReg(pBtCoexist, 0x880, 0xff000000, 0xc0);
+ }
+ else
+ {
+ if( (BT_STATE_8723A_1ANT_SCO_ONLY_BUSY == btState) ||
+ (BT_STATE_8723A_1ANT_ACL_SCO_BUSY == btState) ||
+ (BT_STATE_8723A_1ANT_HID_BUSY == btState) ||
+ (BT_STATE_8723A_1ANT_HID_SCO_BUSY == btState) )
+ {
+ pBtCoexist->btc_setBbReg(pBtCoexist, 0x880, 0xff000000, 0x60);
+ }
+ else
+ {
+ pBtCoexist->btc_setBbReg(pBtCoexist, 0x880, 0xff000000, 0xc0);
+ }
+ switch(btState)
+ {
+ case BT_STATE_8723A_1ANT_NO_CONNECTION:
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 5);
+ break;
+ case BT_STATE_8723A_1ANT_CONNECT_IDLE:
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 12);
+ break;
+ case BT_STATE_8723A_1ANT_INQ_OR_PAG:
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+ break;
+ case BT_STATE_8723A_1ANT_SCO_ONLY_BUSY:
+ case BT_STATE_8723A_1ANT_ACL_SCO_BUSY:
+ case BT_STATE_8723A_1ANT_HID_BUSY:
+ case BT_STATE_8723A_1ANT_HID_SCO_BUSY:
+ halbtc8723a1ant_TdmaDurationAdjust(pBtCoexist);
+ break;
+ case BT_STATE_8723A_1ANT_ACL_ONLY_BUSY:
+ if (btInfoOriginal&BT_INFO_8723A_1ANT_B_A2DP)
+ {
+ halbtc8723a1ant_TdmaDurationAdjust(pBtCoexist);
+ }
+ else if(btInfoOriginal&BT_INFO_8723A_1ANT_B_FTP)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 1);
+ }
+ else if( (btInfoOriginal&BT_INFO_8723A_1ANT_B_A2DP) &&
+ (btInfoOriginal&BT_INFO_8723A_1ANT_B_FTP) )
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+ }
+ else
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 1);
+ }
+ break;
+ default:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], error!!!, undefined case in halbtc8723a1ant_CoexForWifiConnect()!!\n"));
+ break;
+ }
+ }
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], wifi is disconnected!!\n"));
+ }
+
+ pCoexDm->psTdmaGlobalCnt++;
+}
+
+//============================================================
+// work around function start with wa_halbtc8723a1ant_
+//============================================================
+VOID
+wa_halbtc8723a1ant_MonitorC2h(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte tmp1b=0x0;
+ u4Byte curC2hTotalCnt=0x0;
+ static u4Byte preC2hTotalCnt=0x0, sameCntPollingTime=0x0;
+
+ curC2hTotalCnt+=pCoexSta->btInfoC2hCnt[BT_INFO_SRC_8723A_1ANT_BT_RSP];
+
+ if(curC2hTotalCnt == preC2hTotalCnt)
+ {
+ sameCntPollingTime++;
+ }
+ else
+ {
+ preC2hTotalCnt = curC2hTotalCnt;
+ sameCntPollingTime = 0;
+ }
+
+ if(sameCntPollingTime >= 2)
+ {
+ tmp1b = pBtCoexist->btc_read_1byte(pBtCoexist, 0x1af);
+ if(tmp1b != 0x0)
+ {
+ pCoexSta->c2hHangDetectCnt++;
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x1af, 0x0);
+ }
+ }
+}
+
+//============================================================
+// extern function start with EXhalbtc8723a1ant_
+//============================================================
+VOID
+EXhalbtc8723a1ant_InitHwConfig(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], 1Ant Init HW Config!!\n"));
+
+ // backup rf 0x1e value
+ pCoexDm->btRf0x1eBackup =
+ pBtCoexist->btc_get_rf_reg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff);
+
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x40, 0x20);
+
+ // enable counter statistics
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x76e, 0x4);
+
+ // coex table
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x6cc, 0x0); // 1-Ant coex
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x6c8, 0xffff); // wifi break table
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x6c4, 0x55555555); //coex table
+
+ // antenna switch control parameter
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x858, 0xaaaaaaaa);
+
+ pBtCoexist->btc_write_2byte(pBtCoexist, 0x860, 0x210); //set antenna at wifi side if ANTSW is software control
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x870, 0x300); //SPDT(connected with TRSW) control by hardware PTA
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x874, 0x22804000); //ANTSW keep by GNT_BT
+
+ // coexistence parameters
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x778, 0x1); // enable RTK mode PTA
+}
+
+VOID
+EXhalbtc8723a1ant_InitCoexDm(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], Coex Mechanism Init!!\n"));
+
+ halbtc8723a1ant_InitCoexDm(pBtCoexist);
+}
+
+VOID
+EXhalbtc8723a1ant_DisplayCoexInfo(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ struct btc_board_info * pBoardInfo=&pBtCoexist->board_info;
+ PBTC_STACK_INFO pStackInfo=&pBtCoexist->stack_info;
+ pu1Byte cliBuf=pBtCoexist->cli_buf;
+ u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0;
+ u4Byte u4Tmp[4];
+ BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE;
+ BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE;
+ s4Byte wifiRssi=0, btHsRssi=0;
+ u4Byte wifiBw, wifiTrafficDir;
+ u1Byte wifiDot11Chnl, wifiHsChnl;
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============");
+ CL_PRINTF(cliBuf);
+
+ if(!pBoardInfo->bt_exist)
+ {
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
+ CL_PRINTF(cliBuf);
+ return;
+ }
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \
+ pBoardInfo->pg_ant_num, pBoardInfo->btdm_ant_num);
+ CL_PRINTF(cliBuf);
+
+ if(pBtCoexist->manual_control)
+ {
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "[Action Manual control]!!");
+ CL_PRINTF(cliBuf);
+ }
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \
+ ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \
+ wifiDot11Chnl, wifiHsChnl, bBtHsOn);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \
+ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1],
+ pCoexDm->wifiChnlInfo[2]);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \
+ wifiRssi, btHsRssi);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \
+ bLink, bRoam, bScan);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \
+ (bWifiUnder5G? "5G":"2.4G"),
+ ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))),
+ ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink")));
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \
+ ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8723A_1ANT_BT_STATUS_IDLE == pCoexDm->btStatus)? "idle":( (BT_8723A_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy"))),
+ pCoexSta->btRssi, pCoexSta->btRetryCnt);
+ CL_PRINTF(cliBuf);
+
+ if(pStackInfo->bProfileNotified)
+ {
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \
+ pStackInfo->bScoExist, pStackInfo->bHidExist, pStackInfo->bPanExist, pStackInfo->bA2dpExist);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_disp_dbg_msg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO);
+ }
+
+ btInfoExt = pCoexSta->btInfoExt;
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \
+ (btInfoExt&BIT0)? "Basic rate":"EDR rate");
+ CL_PRINTF(cliBuf);
+
+ for(i=0; i<BT_INFO_SRC_8723A_1ANT_MAX; i++)
+ {
+ if(pCoexSta->btInfoC2hCnt[i])
+ {
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8723a1Ant[i], \
+ pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1],
+ pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3],
+ pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5],
+ pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]);
+ CL_PRINTF(cliBuf);
+ }
+ }
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d", "write 0x1af=0x0 num", \
+ pCoexSta->c2hHangDetectCnt);
+ CL_PRINTF(cliBuf);
+
+ // Sw mechanism
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============");
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d", "SM1[ShRf/ LpRA/ LimDig]", \
+ pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->limited_dig);
+ CL_PRINTF(cliBuf);
+
+ // Fw mechanism
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============");
+ CL_PRINTF(cliBuf);
+
+ if(!pBtCoexist->manual_control)
+ {
+ psTdmaCase = pCoexDm->curPsTdma;
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d", "PS TDMA", \
+ pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1],
+ pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3],
+ pCoexDm->psTdmaPara[4], psTdmaCase);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d ", "IgnWlanAct", \
+ pCoexDm->bCurIgnoreWlanAct);
+ CL_PRINTF(cliBuf);
+ }
+
+ // Hw setting
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============");
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \
+ pCoexDm->btRf0x1eBackup);
+ CL_PRINTF(cliBuf);
+
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x778);
+ u1Tmp[1] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x783);
+ u1Tmp[2] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x796);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0x778/ 0x783/ 0x796", \
+ u1Tmp[0], u1Tmp[1], u1Tmp[2]);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x880);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x880", \
+ u4Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x40);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x40", \
+ u1Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x550);
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x522);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \
+ u4Tmp[0], u1Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x484);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x484(rate adaptive)", \
+ u4Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0xc50);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \
+ u4Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0xda0);
+ u4Tmp[1] = pBtCoexist->btc_read_4byte(pBtCoexist, 0xda4);
+ u4Tmp[2] = pBtCoexist->btc_read_4byte(pBtCoexist, 0xda8);
+ u4Tmp[3] = pBtCoexist->btc_read_4byte(pBtCoexist, 0xdac);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0xda0/0xda4/0xda8/0xdac(FA cnt)", \
+ u4Tmp[0], u4Tmp[1], u4Tmp[2], u4Tmp[3]);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x6c0);
+ u4Tmp[1] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x6c4);
+ u4Tmp[2] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x6c8);
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x6cc);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \
+ u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770 (hp rx[31:16]/tx[15:0])", \
+ pCoexSta->highPriorityRx, pCoexSta->highPriorityTx);
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(lp rx[31:16]/tx[15:0])", \
+ pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx);
+ CL_PRINTF(cliBuf);
+
+ // Tx mgnt queue hang or not, 0x41b should = 0xf, ex: 0xd ==>hang
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x41b);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x41b (mgntQ hang chk == 0xf)", \
+ u1Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_disp_dbg_msg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS);
+}
+
+
+VOID
+EXhalbtc8723a1ant_IpsNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ if(BTC_IPS_ENTER == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], IPS ENTER notify\n"));
+ halbtc8723a1ant_CoexAllOff(pBtCoexist);
+ }
+ else if(BTC_IPS_LEAVE == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], IPS LEAVE notify\n"));
+ //halbtc8723a1ant_InitCoexDm(pBtCoexist);
+ }
+}
+
+VOID
+EXhalbtc8723a1ant_LpsNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ if(BTC_LPS_ENABLE == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], LPS ENABLE notify\n"));
+ }
+ else if(BTC_LPS_DISABLE == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], LPS DISABLE notify\n"));
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ }
+}
+
+VOID
+EXhalbtc8723a1ant_ScanNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ BOOLEAN bWifiConnected=FALSE;
+
+ halbtc8723a1ant_NotifyFwScan(pBtCoexist, type);
+
+ if(pBtCoexist->btInfo.bBtDisabled)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9);
+ }
+ else
+ {
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ if(BTC_SCAN_START == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], SCAN START notify\n"));
+ if(!bWifiConnected) // non-connected scan
+ {
+ //set 0x550[3]=1 before PsTdma
+ halbtc8723a1ant_Reg0x550Bit3(pBtCoexist, true);
+ }
+
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 4);
+ }
+ else if(BTC_SCAN_FINISH == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], SCAN FINISH notify\n"));
+ if(!bWifiConnected) // non-connected scan
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ }
+ else
+ {
+ halbtc8723a1ant_CoexForWifiConnect(pBtCoexist);
+ }
+ }
+ }
+}
+
+VOID
+EXhalbtc8723a1ant_ConnectNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ BOOLEAN bWifiConnected=FALSE;
+
+ if(pBtCoexist->btInfo.bBtDisabled)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9);
+ }
+ else
+ {
+ if(BTC_ASSOCIATE_START == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], CONNECT START notify\n"));
+ //set 0x550[3]=1 before PsTdma
+ halbtc8723a1ant_Reg0x550Bit3(pBtCoexist, true);
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8); // extend wifi slot
+ }
+ else if(BTC_ASSOCIATE_FINISH == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], CONNECT FINISH notify\n"));
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ if(!bWifiConnected) // non-connected scan
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ }
+ else
+ {
+ halbtc8723a1ant_CoexForWifiConnect(pBtCoexist);
+ }
+ }
+ }
+}
+
+VOID
+EXhalbtc8723a1ant_MediaStatusNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ if(BTC_MEDIA_CONNECT == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], MEDIA connect notify\n"));
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], MEDIA disconnect notify\n"));
+ }
+}
+
+VOID
+EXhalbtc8723a1ant_SpecialPacketNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ if(type == BTC_PACKET_DHCP)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], DHCP Packet notify\n"));
+ if(pBtCoexist->btInfo.bBtDisabled)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9);
+ }
+ else
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 18);
+ }
+ }
+}
+
+VOID
+EXhalbtc8723a1ant_BtInfoNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN pu1Byte tmpBuf,
+ IN u1Byte length
+ )
+{
+ u1Byte btInfo=0;
+ u1Byte i, rspSource=0;
+ BOOLEAN bBtHsOn=FALSE, bBtBusy=FALSE, bForceLps=FALSE;
+
+ pCoexSta->bC2hBtInfoReqSent = FALSE;
+
+ rspSource = BT_INFO_SRC_8723A_1ANT_BT_RSP;
+ pCoexSta->btInfoC2hCnt[rspSource]++;
+
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length));
+ for(i=0; i<length; i++)
+ {
+ pCoexSta->btInfoC2h[rspSource][i] = tmpBuf[i];
+ if(i == 0)
+ btInfo = tmpBuf[i];
+ if(i == length-1)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("0x%02x]\n", tmpBuf[i]));
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("0x%02x, ", tmpBuf[i]));
+ }
+ }
+
+ if(BT_INFO_SRC_8723A_1ANT_WIFI_FW != rspSource)
+ {
+ pCoexSta->btRetryCnt =
+ pCoexSta->btInfoC2h[rspSource][1];
+
+ pCoexSta->btRssi =
+ pCoexSta->btInfoC2h[rspSource][2]*2+10;
+
+ pCoexSta->btInfoExt =
+ pCoexSta->btInfoC2h[rspSource][3];
+ }
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+ // check BIT2 first ==> check if bt is under inquiry or page scan
+ if(btInfo & BT_INFO_8723A_1ANT_B_INQ_PAGE)
+ {
+ pCoexSta->bC2hBtInquiryPage = true;
+ }
+ else
+ {
+ pCoexSta->bC2hBtInquiryPage = FALSE;
+ }
+ btInfo &= ~BIT2;
+ if(!(btInfo & BIT0))
+ {
+ pCoexDm->btStatus = BT_STATE_8723A_1ANT_NO_CONNECTION;
+ bForceLps = FALSE;
+ }
+ else
+ {
+ bForceLps = true;
+ if(btInfo == 0x1)
+ {
+ pCoexDm->btStatus = BT_STATE_8723A_1ANT_CONNECT_IDLE;
+ }
+ else if(btInfo == 0x9)
+ {
+ pCoexDm->btStatus = BT_STATE_8723A_1ANT_ACL_ONLY_BUSY;
+ bBtBusy = true;
+ }
+ else if(btInfo == 0x13)
+ {
+ pCoexDm->btStatus = BT_STATE_8723A_1ANT_SCO_ONLY_BUSY;
+ bBtBusy = true;
+ }
+ else if(btInfo == 0x1b)
+ {
+ pCoexDm->btStatus = BT_STATE_8723A_1ANT_ACL_SCO_BUSY;
+ bBtBusy = true;
+ }
+ else if(btInfo == 0x29)
+ {
+ pCoexDm->btStatus = BT_STATE_8723A_1ANT_HID_BUSY;
+ bBtBusy = true;
+ }
+ else if(btInfo == 0x3b)
+ {
+ pCoexDm->btStatus = BT_STATE_8723A_1ANT_HID_SCO_BUSY;
+ bBtBusy = true;
+ }
+ }
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy);
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &bBtBusy);
+ if(bForceLps)
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ else
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
+
+ if( (BT_STATE_8723A_1ANT_NO_CONNECTION == pCoexDm->btStatus) ||
+ (BT_STATE_8723A_1ANT_CONNECT_IDLE == pCoexDm->btStatus) )
+ {
+ if(pCoexSta->bC2hBtInquiryPage)
+ pCoexDm->btStatus = BT_STATE_8723A_1ANT_INQ_OR_PAG;
+ }
+}
+
+VOID
+EXhalbtc8723a1ant_StackOperationNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ if(BTC_STACK_OP_INQ_PAGE_PAIR_START == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], StackOP Inquiry/page/pair start notify\n"));
+ }
+ else if(BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], StackOP Inquiry/page/pair finish notify\n"));
+ }
+}
+
+VOID
+EXhalbtc8723a1ant_HaltNotify(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ halbtc8723a1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0);
+
+ halbtc8723a1ant_LowPenaltyRa(pBtCoexist, FORCE_EXEC, FALSE);
+ halbtc8723a1ant_RfShrink(pBtCoexist, FORCE_EXEC, FALSE);
+
+ halbtc8723a1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, true);
+ EXhalbtc8723a1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT);
+}
+
+VOID
+EXhalbtc8723a1ant_Periodical(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE, bWifiConnected=FALSE;
+
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], 1Ant Periodical!!\n"));
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+
+ // work around for c2h hang
+ wa_halbtc8723a1ant_MonitorC2h(pBtCoexist);
+
+ halbtc8723a1ant_QueryBtInfo(pBtCoexist);
+ halbtc8723a1ant_MonitorBtCtr(pBtCoexist);
+ halbtc8723a1ant_MonitorBtEnableDisable(pBtCoexist);
+
+
+ if(bScan)
+ return;
+ if(bLink)
+ return;
+
+ if(bWifiConnected)
+ {
+ if(pBtCoexist->btInfo.bBtDisabled)
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9);
+
+ halbtc8723a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a1ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE);
+ }
+ else
+ {
+ halbtc8723a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a1ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a1ant_CoexForWifiConnect(pBtCoexist);
+ }
+ }
+ else
+ {
+ halbtc8723a1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+
+ halbtc8723a1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a1ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE);
+ }
+}
+
+
+#endif
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.h b/drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.h
new file mode 100644
index 000000000000..60992f59eb37
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/habtc8723a1ant.h
@@ -0,0 +1,176 @@
+//===========================================
+// The following is for 8723A 1Ant BT Co-exist definition
+//===========================================
+#define BT_INFO_8723A_1ANT_B_FTP BIT7
+#define BT_INFO_8723A_1ANT_B_A2DP BIT6
+#define BT_INFO_8723A_1ANT_B_HID BIT5
+#define BT_INFO_8723A_1ANT_B_SCO_BUSY BIT4
+#define BT_INFO_8723A_1ANT_B_ACL_BUSY BIT3
+#define BT_INFO_8723A_1ANT_B_INQ_PAGE BIT2
+#define BT_INFO_8723A_1ANT_B_SCO_ESCO BIT1
+#define BT_INFO_8723A_1ANT_B_CONNECTION BIT0
+
+typedef enum _BT_STATE_8723A_1ANT{
+ BT_STATE_8723A_1ANT_DISABLED = 0,
+ BT_STATE_8723A_1ANT_NO_CONNECTION = 1,
+ BT_STATE_8723A_1ANT_CONNECT_IDLE = 2,
+ BT_STATE_8723A_1ANT_INQ_OR_PAG = 3,
+ BT_STATE_8723A_1ANT_ACL_ONLY_BUSY = 4,
+ BT_STATE_8723A_1ANT_SCO_ONLY_BUSY = 5,
+ BT_STATE_8723A_1ANT_ACL_SCO_BUSY = 6,
+ BT_STATE_8723A_1ANT_HID_BUSY = 7,
+ BT_STATE_8723A_1ANT_HID_SCO_BUSY = 8,
+ BT_STATE_8723A_1ANT_MAX
+}BT_STATE_8723A_1ANT, *PBT_STATE_8723A_1ANT;
+
+#define BTC_RSSI_COEX_THRESH_TOL_8723A_1ANT 2
+
+typedef enum _BT_INFO_SRC_8723A_1ANT{
+ BT_INFO_SRC_8723A_1ANT_WIFI_FW = 0x0,
+ BT_INFO_SRC_8723A_1ANT_BT_RSP = 0x1,
+ BT_INFO_SRC_8723A_1ANT_BT_ACTIVE_SEND = 0x2,
+ BT_INFO_SRC_8723A_1ANT_MAX
+}BT_INFO_SRC_8723A_1ANT,*PBT_INFO_SRC_8723A_1ANT;
+
+typedef enum _BT_8723A_1ANT_BT_STATUS{
+ BT_8723A_1ANT_BT_STATUS_IDLE = 0x0,
+ BT_8723A_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
+ BT_8723A_1ANT_BT_STATUS_NON_IDLE = 0x2,
+ BT_8723A_1ANT_BT_STATUS_MAX
+}BT_8723A_1ANT_BT_STATUS,*PBT_8723A_1ANT_BT_STATUS;
+
+typedef enum _BT_8723A_1ANT_COEX_ALGO{
+ BT_8723A_1ANT_COEX_ALGO_UNDEFINED = 0x0,
+ BT_8723A_1ANT_COEX_ALGO_SCO = 0x1,
+ BT_8723A_1ANT_COEX_ALGO_HID = 0x2,
+ BT_8723A_1ANT_COEX_ALGO_A2DP = 0x3,
+ BT_8723A_1ANT_COEX_ALGO_PANEDR = 0x4,
+ BT_8723A_1ANT_COEX_ALGO_PANHS = 0x5,
+ BT_8723A_1ANT_COEX_ALGO_PANEDR_A2DP = 0x6,
+ BT_8723A_1ANT_COEX_ALGO_PANEDR_HID = 0x7,
+ BT_8723A_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x8,
+ BT_8723A_1ANT_COEX_ALGO_HID_A2DP = 0x9,
+ BT_8723A_1ANT_COEX_ALGO_MAX
+}BT_8723A_1ANT_COEX_ALGO,*PBT_8723A_1ANT_COEX_ALGO;
+
+typedef struct _COEX_DM_8723A_1ANT{
+ // fw mechanism
+ BOOLEAN bCurIgnoreWlanAct;
+ BOOLEAN bPreIgnoreWlanAct;
+ u1Byte prePsTdma;
+ u1Byte curPsTdma;
+ u1Byte psTdmaPara[5];
+ u1Byte psTdmaDuAdjType;
+ u4Byte psTdmaMonitorCnt;
+ u4Byte psTdmaGlobalCnt;
+ BOOLEAN bResetTdmaAdjust;
+ BOOLEAN bPrePsTdmaOn;
+ BOOLEAN bCurPsTdmaOn;
+
+ // sw mechanism
+ BOOLEAN bPreRfRxLpfShrink;
+ BOOLEAN bCurRfRxLpfShrink;
+ u4Byte btRf0x1eBackup;
+ BOOLEAN bPreLowPenaltyRa;
+ BOOLEAN bCurLowPenaltyRa;
+ u4Byte preVal0x6c0;
+ u4Byte curVal0x6c0;
+ u4Byte preVal0x6c8;
+ u4Byte curVal0x6c8;
+ u1Byte preVal0x6cc;
+ u1Byte curVal0x6cc;
+ BOOLEAN limited_dig;
+
+ // algorithm related
+ u1Byte preAlgorithm;
+ u1Byte curAlgorithm;
+ u1Byte btStatus;
+ u1Byte wifiChnlInfo[3];
+} COEX_DM_8723A_1ANT, *PCOEX_DM_8723A_1ANT;
+
+typedef struct _COEX_STA_8723A_1ANT{
+ u4Byte highPriorityTx;
+ u4Byte highPriorityRx;
+ u4Byte lowPriorityTx;
+ u4Byte lowPriorityRx;
+ u1Byte btRssi;
+ u1Byte preBtRssiState;
+ u1Byte preBtRssiState1;
+ u1Byte preWifiRssiState[4];
+ BOOLEAN bC2hBtInfoReqSent;
+ u1Byte btInfoC2h[BT_INFO_SRC_8723A_1ANT_MAX][10];
+ u4Byte btInfoC2hCnt[BT_INFO_SRC_8723A_1ANT_MAX];
+ BOOLEAN bC2hBtInquiryPage;
+ u1Byte btRetryCnt;
+ u1Byte btInfoExt;
+ //BOOLEAN bHoldForStackOperation;
+ //u1Byte bHoldPeriodCnt;
+ // this is for c2h hang work-around
+ u4Byte c2hHangDetectCnt;
+}COEX_STA_8723A_1ANT, *PCOEX_STA_8723A_1ANT;
+
+//===========================================
+// The following is interface which will notify coex module.
+//===========================================
+VOID
+EXhalbtc8723a1ant_InitHwConfig(
+ IN PBTC_COEXIST pBtCoexist
+ );
+VOID
+EXhalbtc8723a1ant_InitCoexDm(
+ IN PBTC_COEXIST pBtCoexist
+ );
+VOID
+EXhalbtc8723a1ant_IpsNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8723a1ant_LpsNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8723a1ant_ScanNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8723a1ant_ConnectNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8723a1ant_MediaStatusNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8723a1ant_SpecialPacketNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8723a1ant_BtInfoNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN pu1Byte tmpBuf,
+ IN u1Byte length
+ );
+VOID
+EXhalbtc8723a1ant_StackOperationNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8723a1ant_HaltNotify(
+ IN PBTC_COEXIST pBtCoexist
+ );
+VOID
+EXhalbtc8723a1ant_Periodical(
+ IN PBTC_COEXIST pBtCoexist
+ );
+VOID
+EXhalbtc8723a1ant_DisplayCoexInfo(
+ IN PBTC_COEXIST pBtCoexist
+ );
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbt_precomp.h b/drivers/staging/rtl8821ae/btcoexist/halbt_precomp.h
new file mode 100644
index 000000000000..d538ba3d0a2e
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/halbt_precomp.h
@@ -0,0 +1,99 @@
+/******************************************************************************
+ *
+ * Copyright(c) 2007 - 2011 Realtek Corporation. All rights reserved.
+ *
+ * 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
+ *
+ *
+ ******************************************************************************/
+#ifndef __HALBT_PRECOMP_H__
+#define __HALBT_PRECOMP_H__
+/*************************************************************
+ * include files
+ *************************************************************/
+#include "../wifi.h"
+#include "../efuse.h"
+#include "../base.h"
+#include "../regd.h"
+#include "../cam.h"
+#include "../ps.h"
+#include "../pci.h"
+#include "../rtl8821ae/reg.h"
+#include "../rtl8821ae/def.h"
+#include "../rtl8821ae/phy.h"
+#include "../rtl8821ae/dm.h"
+#include "../rtl8821ae/fw.h"
+#include "../rtl8821ae/led.h"
+#include "../rtl8821ae/hw.h"
+#include "../rtl8821ae/pwrseqcmd.h"
+#include "../rtl8821ae/pwrseq.h"
+
+#include "halbtcoutsrc.h"
+
+
+#include "halbtc8192e2ant.h"
+#include "halbtc8723b1ant.h"
+#include "halbtc8723b2ant.h"
+
+
+
+#define GetDefaultAdapter(padapter) padapter
+
+
+#define BIT0 0x00000001
+#define BIT1 0x00000002
+#define BIT2 0x00000004
+#define BIT3 0x00000008
+#define BIT4 0x00000010
+#define BIT5 0x00000020
+#define BIT6 0x00000040
+#define BIT7 0x00000080
+#define BIT8 0x00000100
+#define BIT9 0x00000200
+#define BIT10 0x00000400
+#define BIT11 0x00000800
+#define BIT12 0x00001000
+#define BIT13 0x00002000
+#define BIT14 0x00004000
+#define BIT15 0x00008000
+#define BIT16 0x00010000
+#define BIT17 0x00020000
+#define BIT18 0x00040000
+#define BIT19 0x00080000
+#define BIT20 0x00100000
+#define BIT21 0x00200000
+#define BIT22 0x00400000
+#define BIT23 0x00800000
+#define BIT24 0x01000000
+#define BIT25 0x02000000
+#define BIT26 0x04000000
+#define BIT27 0x08000000
+#define BIT28 0x10000000
+#define BIT29 0x20000000
+#define BIT30 0x40000000
+#define BIT31 0x80000000
+
+#define MASKBYTE0 0xff
+#define MASKBYTE1 0xff00
+#define MASKBYTE2 0xff0000
+#define MASKBYTE3 0xff000000
+#define MASKHWORD 0xffff0000
+#define MASKLWORD 0x0000ffff
+#define MASKDWORD 0xffffffff
+#define MASK12BITS 0xfff
+#define MASKH4BITS 0xf0000000
+#define MASKOFDM_D 0xffc00000
+#define MASKCCK 0x3f3f3f3f
+
+#endif /* __HALBT_PRECOMP_H__ */
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.c b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.c
new file mode 100644
index 000000000000..973d0ea82cb8
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.c
@@ -0,0 +1,3891 @@
+//============================================================
+// Description:
+//
+// This file is for 8192e1ant Co-exist mechanism
+//
+// History
+// 2012/11/15 Cosa first check in.
+//
+//============================================================
+
+//============================================================
+// include files
+//============================================================
+#include "Mp_Precomp.h"
+#if(BT_30_SUPPORT == 1)
+//============================================================
+// Global variables, these are static variables
+//============================================================
+static COEX_DM_8192E_1ANT GLCoexDm8192e1Ant;
+static PCOEX_DM_8192E_1ANT pCoexDm=&GLCoexDm8192e1Ant;
+static COEX_STA_8192E_1ANT GLCoexSta8192e1Ant;
+static PCOEX_STA_8192E_1ANT pCoexSta=&GLCoexSta8192e1Ant;
+
+const char *const GLBtInfoSrc8192e1Ant[]={
+ "BT Info[wifi fw]",
+ "BT Info[bt rsp]",
+ "BT Info[bt auto report]",
+};
+
+u4Byte GLCoexVerDate8192e1Ant=20130729;
+u4Byte GLCoexVer8192e1Ant=0x10;
+
+//============================================================
+// local function proto type if needed
+//============================================================
+//============================================================
+// local function start with halbtc8192e1ant_
+//============================================================
+u1Byte
+halbtc8192e1ant_BtRssiState(
+ u1Byte levelNum,
+ u1Byte rssiThresh,
+ u1Byte rssiThresh1
+ )
+{
+ s4Byte btRssi=0;
+ u1Byte btRssiState=pCoexSta->preBtRssiState;
+
+ btRssi = pCoexSta->btRssi;
+
+ if(levelNum == 2)
+ {
+ if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) ||
+ (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT))
+ {
+ btRssiState = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to High\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at Low\n"));
+ }
+ }
+ else
+ {
+ if(btRssi < rssiThresh)
+ {
+ btRssiState = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Low\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at High\n"));
+ }
+ }
+ }
+ else if(levelNum == 3)
+ {
+ if(rssiThresh > rssiThresh1)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi thresh error!!\n"));
+ return pCoexSta->preBtRssiState;
+ }
+
+ if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) ||
+ (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT))
+ {
+ btRssiState = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Medium\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at Low\n"));
+ }
+ }
+ else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) ||
+ (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM))
+ {
+ if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT))
+ {
+ btRssiState = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to High\n"));
+ }
+ else if(btRssi < rssiThresh)
+ {
+ btRssiState = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Low\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at Medium\n"));
+ }
+ }
+ else
+ {
+ if(btRssi < rssiThresh1)
+ {
+ btRssiState = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Medium\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at High\n"));
+ }
+ }
+ }
+
+ pCoexSta->preBtRssiState = btRssiState;
+
+ return btRssiState;
+}
+
+u1Byte
+halbtc8192e1ant_WifiRssiState(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte index,
+ IN u1Byte levelNum,
+ IN u1Byte rssiThresh,
+ IN u1Byte rssiThresh1
+ )
+{
+ s4Byte wifiRssi=0;
+ u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index];
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi);
+
+ if(levelNum == 2)
+ {
+ if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) ||
+ (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT))
+ {
+ wifiRssiState = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to High\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at Low\n"));
+ }
+ }
+ else
+ {
+ if(wifiRssi < rssiThresh)
+ {
+ wifiRssiState = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Low\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at High\n"));
+ }
+ }
+ }
+ else if(levelNum == 3)
+ {
+ if(rssiThresh > rssiThresh1)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI thresh error!!\n"));
+ return pCoexSta->preWifiRssiState[index];
+ }
+
+ if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) ||
+ (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT))
+ {
+ wifiRssiState = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Medium\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at Low\n"));
+ }
+ }
+ else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) ||
+ (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM))
+ {
+ if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT))
+ {
+ wifiRssiState = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to High\n"));
+ }
+ else if(wifiRssi < rssiThresh)
+ {
+ wifiRssiState = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Low\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at Medium\n"));
+ }
+ }
+ else
+ {
+ if(wifiRssi < rssiThresh1)
+ {
+ wifiRssiState = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Medium\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at High\n"));
+ }
+ }
+ }
+
+ pCoexSta->preWifiRssiState[index] = wifiRssiState;
+
+ return wifiRssiState;
+}
+
+VOID
+halbtc8192e1ant_Updatera_mask(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u1Byte type,
+ IN u4Byte rateMask
+ )
+{
+ if(BTC_RATE_DISABLE == type)
+ {
+ pCoexDm->curra_mask |= rateMask; // disable rate
+ }
+ else if(BTC_RATE_ENABLE == type)
+ {
+ pCoexDm->curra_mask &= ~rateMask; // enable rate
+ }
+
+ if( bForceExec || (pCoexDm->prera_mask != pCoexDm->curra_mask))
+ {
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_UPDATE_ra_mask, &pCoexDm->curra_mask);
+ }
+ pCoexDm->prera_mask = pCoexDm->curra_mask;
+}
+
+VOID
+halbtc8192e1ant_MonitorBtCtr(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u4Byte regHPTxRx, regLPTxRx, u4Tmp;
+ u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0;
+ u1Byte u1Tmp;
+
+ regHPTxRx = 0x770;
+ regLPTxRx = 0x774;
+
+ u4Tmp = pBtCoexist->btc_read_4byte(pBtCoexist, regHPTxRx);
+ regHPTx = u4Tmp & MASKLWORD;
+ regHPRx = (u4Tmp & MASKHWORD)>>16;
+
+ u4Tmp = pBtCoexist->btc_read_4byte(pBtCoexist, regLPTxRx);
+ regLPTx = u4Tmp & MASKLWORD;
+ regLPRx = (u4Tmp & MASKHWORD)>>16;
+
+ pCoexSta->highPriorityTx = regHPTx;
+ pCoexSta->highPriorityRx = regHPRx;
+ pCoexSta->lowPriorityTx = regLPTx;
+ pCoexSta->lowPriorityRx = regLPRx;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
+ regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
+ regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx));
+
+ // reset counter
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x76e, 0xc);
+}
+
+VOID
+halbtc8192e1ant_QueryBtInfo(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ pCoexSta->bC2hBtInfoReqSent = true;
+
+ H2C_Parameter[0] |= BIT0; // trigger
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], Query Bt Info, FW write 0x61=0x%x\n",
+ H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x61, 1, H2C_Parameter);
+}
+
+BOOLEAN
+halbtc8192e1ant_IsWifiStatusChanged(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ static BOOLEAN bPreWifiBusy=FALSE, bPreUnder4way=FALSE, bPreBtHsOn=FALSE;
+ BOOLEAN bWifiBusy=FALSE, bUnder4way=FALSE, bBtHsOn=FALSE;
+ BOOLEAN bWifiConnected=FALSE;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way);
+
+ if(bWifiConnected)
+ {
+ if(bWifiBusy != bPreWifiBusy)
+ {
+ bPreWifiBusy = bWifiBusy;
+ return true;
+ }
+ if(bUnder4way != bPreUnder4way)
+ {
+ bPreUnder4way = bUnder4way;
+ return true;
+ }
+ if(bBtHsOn != bPreBtHsOn)
+ {
+ bPreBtHsOn = bBtHsOn;
+ return true;
+ }
+ }
+
+ return FALSE;
+}
+
+VOID
+halbtc8192e1ant_UpdateBtLinkInfo(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->bt_link_info;
+
+ pBtLinkInfo->bBtLinkExist = pCoexSta->bBtLinkExist;
+ pBtLinkInfo->bScoExist = pCoexSta->bScoExist;
+ pBtLinkInfo->bA2dpExist = pCoexSta->bA2dpExist;
+ pBtLinkInfo->bPanExist = pCoexSta->bPanExist;
+ pBtLinkInfo->bHidExist = pCoexSta->bHidExist;
+
+ // check if Sco only
+ if( pBtLinkInfo->bScoExist &&
+ !pBtLinkInfo->bA2dpExist &&
+ !pBtLinkInfo->bPanExist &&
+ !pBtLinkInfo->bHidExist )
+ pBtLinkInfo->bScoOnly = true;
+ else
+ pBtLinkInfo->bScoOnly = FALSE;
+
+ // check if A2dp only
+ if( !pBtLinkInfo->bScoExist &&
+ pBtLinkInfo->bA2dpExist &&
+ !pBtLinkInfo->bPanExist &&
+ !pBtLinkInfo->bHidExist )
+ pBtLinkInfo->bA2dpOnly = true;
+ else
+ pBtLinkInfo->bA2dpOnly = FALSE;
+
+ // check if Pan only
+ if( !pBtLinkInfo->bScoExist &&
+ !pBtLinkInfo->bA2dpExist &&
+ pBtLinkInfo->bPanExist &&
+ !pBtLinkInfo->bHidExist )
+ pBtLinkInfo->bPanOnly = true;
+ else
+ pBtLinkInfo->bPanOnly = FALSE;
+
+ // check if Hid only
+ if( !pBtLinkInfo->bScoExist &&
+ !pBtLinkInfo->bA2dpExist &&
+ !pBtLinkInfo->bPanExist &&
+ pBtLinkInfo->bHidExist )
+ pBtLinkInfo->bHidOnly = true;
+ else
+ pBtLinkInfo->bHidOnly = FALSE;
+}
+
+u1Byte
+halbtc8192e1ant_ActionAlgorithm(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->bt_link_info;
+ BOOLEAN bBtHsOn=FALSE;
+ u1Byte algorithm=BT_8192E_1ANT_COEX_ALGO_UNDEFINED;
+ u1Byte numOfDiffProfile=0;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+
+ if(!pBtLinkInfo->bBtLinkExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], No BT link exists!!!\n"));
+ return algorithm;
+ }
+
+ if(pBtLinkInfo->bScoExist)
+ numOfDiffProfile++;
+ if(pBtLinkInfo->bHidExist)
+ numOfDiffProfile++;
+ if(pBtLinkInfo->bPanExist)
+ numOfDiffProfile++;
+ if(pBtLinkInfo->bA2dpExist)
+ numOfDiffProfile++;
+
+ if(numOfDiffProfile == 1)
+ {
+ if(pBtLinkInfo->bScoExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO only\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_SCO;
+ }
+ else
+ {
+ if(pBtLinkInfo->bHidExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID only\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_HID;
+ }
+ else if(pBtLinkInfo->bA2dpExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP only\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_A2DP;
+ }
+ else if(pBtLinkInfo->bPanExist)
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN(HS) only\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_PANHS;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN(EDR) only\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR;
+ }
+ }
+ }
+ }
+ else if(numOfDiffProfile == 2)
+ {
+ if(pBtLinkInfo->bScoExist)
+ {
+ if(pBtLinkInfo->bHidExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_HID;
+ }
+ else if(pBtLinkInfo->bA2dpExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + A2DP ==> SCO\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_SCO;
+ }
+ else if(pBtLinkInfo->bPanExist)
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + PAN(HS)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_SCO;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + PAN(EDR)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ else
+ {
+ if( pBtLinkInfo->bHidExist &&
+ pBtLinkInfo->bA2dpExist )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + A2DP\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP;
+ }
+ else if( pBtLinkInfo->bHidExist &&
+ pBtLinkInfo->bPanExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ else if( pBtLinkInfo->bPanExist &&
+ pBtLinkInfo->bA2dpExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_A2DP_PANHS;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_A2DP;
+ }
+ }
+ }
+ }
+ else if(numOfDiffProfile == 3)
+ {
+ if(pBtLinkInfo->bScoExist)
+ {
+ if( pBtLinkInfo->bHidExist &&
+ pBtLinkInfo->bA2dpExist )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + A2DP ==> HID\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_HID;
+ }
+ else if( pBtLinkInfo->bHidExist &&
+ pBtLinkInfo->bPanExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + PAN(HS)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + PAN(EDR)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ else if( pBtLinkInfo->bPanExist &&
+ pBtLinkInfo->bA2dpExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + A2DP + PAN(HS)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_SCO;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ else
+ {
+ if( pBtLinkInfo->bHidExist &&
+ pBtLinkInfo->bPanExist &&
+ pBtLinkInfo->bA2dpExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ }
+ }
+ }
+ }
+ else if(numOfDiffProfile >= 3)
+ {
+ if(pBtLinkInfo->bScoExist)
+ {
+ if( pBtLinkInfo->bHidExist &&
+ pBtLinkInfo->bPanExist &&
+ pBtLinkInfo->bA2dpExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n"));
+
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n"));
+ algorithm = BT_8192E_1ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ }
+
+ return algorithm;
+}
+
+VOID
+halbtc8192e1ant_SetFwDacSwingLevel(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte dacSwingLvl
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ // There are several type of dacswing
+ // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6
+ H2C_Parameter[0] = dacSwingLvl;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], Set Dac Swing Level=0x%x\n", dacSwingLvl));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x64=0x%x\n", H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x64, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8192e1ant_SetFwDecBtPwr(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte decBtPwrLvl
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ H2C_Parameter[0] = decBtPwrLvl;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], decrease Bt Power level = %d, FW write 0x62=0x%x\n",
+ decBtPwrLvl, H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x62, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8192e1ant_DecBtPwr(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u1Byte decBtPwrLvl
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s Dec BT power level = %d\n",
+ (bForceExec? "force to":""), decBtPwrLvl));
+ pCoexDm->curBtDecPwrLvl = decBtPwrLvl;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], BtDecPwrLvl=%d, curBtDecPwrLvl=%d\n",
+ pCoexDm->preBtDecPwrLvl, pCoexDm->curBtDecPwrLvl));
+
+ if(pCoexDm->preBtDecPwrLvl == pCoexDm->curBtDecPwrLvl)
+ return;
+ }
+ halbtc8192e1ant_SetFwDecBtPwr(pBtCoexist, pCoexDm->curBtDecPwrLvl);
+
+ pCoexDm->preBtDecPwrLvl = pCoexDm->curBtDecPwrLvl;
+}
+
+VOID
+halbtc8192e1ant_SetFwBtLnaConstrain(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bBtLnaConsOn
+ )
+{
+ u1Byte H2C_Parameter[2] ={0};
+
+ H2C_Parameter[0] = 0x3; // opCode, 0x3=BT_SET_LNA_CONSTRAIN
+
+ if(bBtLnaConsOn)
+ {
+ H2C_Parameter[1] |= BIT0;
+ }
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], set BT LNA Constrain: %s, FW write 0x69=0x%x\n",
+ (bBtLnaConsOn? "ON!!":"OFF!!"),
+ H2C_Parameter[0]<<8|H2C_Parameter[1]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x69, 2, H2C_Parameter);
+}
+
+VOID
+halbtc8192e1ant_SetBtLnaConstrain(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bBtLnaConsOn
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s BT Constrain = %s\n",
+ (bForceExec? "force":""), ((bBtLnaConsOn)? "ON":"OFF")));
+ pCoexDm->bCurBtLnaConstrain = bBtLnaConsOn;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPreBtLnaConstrain=%d, bCurBtLnaConstrain=%d\n",
+ pCoexDm->bPreBtLnaConstrain, pCoexDm->bCurBtLnaConstrain));
+
+ if(pCoexDm->bPreBtLnaConstrain == pCoexDm->bCurBtLnaConstrain)
+ return;
+ }
+ halbtc8192e1ant_SetFwBtLnaConstrain(pBtCoexist, pCoexDm->bCurBtLnaConstrain);
+
+ pCoexDm->bPreBtLnaConstrain = pCoexDm->bCurBtLnaConstrain;
+}
+
+VOID
+halbtc8192e1ant_SetFwBtPsdMode(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte btPsdMode
+ )
+{
+ u1Byte H2C_Parameter[2] ={0};
+
+ H2C_Parameter[0] = 0x2; // opCode, 0x2=BT_SET_PSD_MODE
+
+ H2C_Parameter[1] = btPsdMode;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], set BT PSD mode=0x%x, FW write 0x69=0x%x\n",
+ H2C_Parameter[1],
+ H2C_Parameter[0]<<8|H2C_Parameter[1]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x69, 2, H2C_Parameter);
+}
+
+
+VOID
+halbtc8192e1ant_SetBtPsdMode(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u1Byte btPsdMode
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s BT PSD mode = 0x%x\n",
+ (bForceExec? "force":""), btPsdMode));
+ pCoexDm->bCurBtPsdMode = btPsdMode;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPreBtPsdMode=0x%x, bCurBtPsdMode=0x%x\n",
+ pCoexDm->bPreBtPsdMode, pCoexDm->bCurBtPsdMode));
+
+ if(pCoexDm->bPreBtPsdMode == pCoexDm->bCurBtPsdMode)
+ return;
+ }
+ halbtc8192e1ant_SetFwBtPsdMode(pBtCoexist, pCoexDm->bCurBtPsdMode);
+
+ pCoexDm->bPreBtPsdMode = pCoexDm->bCurBtPsdMode;
+}
+
+
+VOID
+halbtc8192e1ant_SetBtAutoReport(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bEnableAutoReport
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ H2C_Parameter[0] = 0;
+
+ if(bEnableAutoReport)
+ {
+ H2C_Parameter[0] |= BIT0;
+ }
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n",
+ (bEnableAutoReport? "Enabled!!":"Disabled!!"), H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x68, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8192e1ant_BtAutoReport(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bEnableAutoReport
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s BT Auto report = %s\n",
+ (bForceExec? "force to":""), ((bEnableAutoReport)? "Enabled":"Disabled")));
+ pCoexDm->bCurBtAutoReport = bEnableAutoReport;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPreBtAutoReport=%d, bCurBtAutoReport=%d\n",
+ pCoexDm->bPreBtAutoReport, pCoexDm->bCurBtAutoReport));
+
+ if(pCoexDm->bPreBtAutoReport == pCoexDm->bCurBtAutoReport)
+ return;
+ }
+ halbtc8192e1ant_SetBtAutoReport(pBtCoexist, pCoexDm->bCurBtAutoReport);
+
+ pCoexDm->bPreBtAutoReport = pCoexDm->bCurBtAutoReport;
+}
+
+VOID
+halbtc8192e1ant_FwDacSwingLvl(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u1Byte fwDacSwingLvl
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s set FW Dac Swing level = %d\n",
+ (bForceExec? "force to":""), fwDacSwingLvl));
+ pCoexDm->curFwDacSwingLvl = fwDacSwingLvl;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], preFwDacSwingLvl=%d, curFwDacSwingLvl=%d\n",
+ pCoexDm->preFwDacSwingLvl, pCoexDm->curFwDacSwingLvl));
+
+ if(pCoexDm->preFwDacSwingLvl == pCoexDm->curFwDacSwingLvl)
+ return;
+ }
+
+ halbtc8192e1ant_SetFwDacSwingLevel(pBtCoexist, pCoexDm->curFwDacSwingLvl);
+
+ pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl;
+}
+
+VOID
+halbtc8192e1ant_SetSwRfRxLpfCorner(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bRxRfShrinkOn
+ )
+{
+ if(bRxRfShrinkOn)
+ {
+ //Shrink RF Rx LPF corner
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Shrink RF Rx LPF corner!!\n"));
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xf0ff7);
+ }
+ else
+ {
+ //Resume RF Rx LPF corner
+ // After initialized, we can use pCoexDm->btRf0x1eBackup
+ if(pBtCoexist->initilized)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Resume RF Rx LPF corner!!\n"));
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup);
+ }
+ }
+}
+
+VOID
+halbtc8192e1ant_RfShrink(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bRxRfShrinkOn
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn Rx RF Shrink = %s\n",
+ (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF")));
+ pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreRfRxLpfShrink=%d, bCurRfRxLpfShrink=%d\n",
+ pCoexDm->bPreRfRxLpfShrink, pCoexDm->bCurRfRxLpfShrink));
+
+ if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink)
+ return;
+ }
+ halbtc8192e1ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink);
+
+ pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink;
+}
+
+VOID
+halbtc8192e1ant_SetSwPenaltyTxRateAdaptive(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bLowPenaltyRa
+ )
+{
+ u1Byte tmpU1;
+
+ tmpU1 = pBtCoexist->btc_read_1byte(pBtCoexist, 0x4fd);
+ tmpU1 |= BIT0;
+ if(bLowPenaltyRa)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Tx rate adaptive, set low penalty!!\n"));
+ tmpU1 &= ~BIT2;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Tx rate adaptive, set normal!!\n"));
+ tmpU1 |= BIT2;
+ }
+
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x4fd, tmpU1);
+}
+
+VOID
+halbtc8192e1ant_LowPenaltyRa(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bLowPenaltyRa
+ )
+{
+ return;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn LowPenaltyRA = %s\n",
+ (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF")));
+ pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreLowPenaltyRa=%d, bCurLowPenaltyRa=%d\n",
+ pCoexDm->bPreLowPenaltyRa, pCoexDm->bCurLowPenaltyRa));
+
+ if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa)
+ return;
+ }
+ halbtc8192e1ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa);
+
+ pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa;
+}
+
+VOID
+halbtc8192e1ant_SetDacSwingReg(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u4Byte level
+ )
+{
+ u1Byte val=(u1Byte)level;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Write SwDacSwing = 0x%x\n", level));
+ pBtCoexist->btc_write_1byte_bitmask(pBtCoexist, 0x883, 0x3e, val);
+}
+
+VOID
+halbtc8192e1ant_SetSwFullTimeDacSwing(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bSwDacSwingOn,
+ IN u4Byte swDacSwingLvl
+ )
+{
+ if(bSwDacSwingOn)
+ {
+ halbtc8192e1ant_SetDacSwingReg(pBtCoexist, swDacSwingLvl);
+ }
+ else
+ {
+ halbtc8192e1ant_SetDacSwingReg(pBtCoexist, 0x18);
+ }
+}
+
+
+VOID
+halbtc8192e1ant_DacSwing(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bDacSwingOn,
+ IN u4Byte dacSwingLvl
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n",
+ (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl));
+ pCoexDm->bCurDacSwingOn = bDacSwingOn;
+ pCoexDm->curDacSwingLvl = dacSwingLvl;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl=0x%x, bCurDacSwingOn=%d, curDacSwingLvl=0x%x\n",
+ pCoexDm->bPreDacSwingOn, pCoexDm->preDacSwingLvl,
+ pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl));
+
+ if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) &&
+ (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) )
+ return;
+ }
+ mdelay(30);
+ halbtc8192e1ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl);
+
+ pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn;
+ pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl;
+}
+
+VOID
+halbtc8192e1ant_SetAdcBackOff(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bAdcBackOff
+ )
+{
+ if(bAdcBackOff)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], BB BackOff Level On!\n"));
+ pBtCoexist->btc_write_1byte_bitmask(pBtCoexist, 0x8db, 0x60, 0x3);
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], BB BackOff Level Off!\n"));
+ pBtCoexist->btc_write_1byte_bitmask(pBtCoexist, 0x8db, 0x60, 0x1);
+ }
+}
+
+VOID
+halbtc8192e1ant_AdcBackOff(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bAdcBackOff
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn AdcBackOff = %s\n",
+ (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF")));
+ pCoexDm->bCurAdcBackOff = bAdcBackOff;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreAdcBackOff=%d, bCurAdcBackOff=%d\n",
+ pCoexDm->bPreAdcBackOff, pCoexDm->bCurAdcBackOff));
+
+ if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff)
+ return;
+ }
+ halbtc8192e1ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff);
+
+ pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff;
+}
+
+VOID
+halbtc8192e1ant_SetAgcTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bAgcTableEn
+ )
+{
+ u1Byte rssiAdjustVal=0;
+
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x02000);
+ if(bAgcTableEn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Agc Table On!\n"));
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x3fa58);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x37a58);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x2fa58);
+ rssiAdjustVal = 8;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Agc Table Off!\n"));
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x39258);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x31258);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x3b, 0xfffff, 0x29258);
+ }
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0xef, 0xfffff, 0x0);
+
+ // set rssiAdjustVal for wifi module.
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal);
+}
+
+
+VOID
+halbtc8192e1ant_AgcTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bAgcTableEn
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s %s Agc Table\n",
+ (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable")));
+ pCoexDm->bCurAgcTableEn = bAgcTableEn;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n",
+ pCoexDm->bPreAgcTableEn, pCoexDm->bCurAgcTableEn));
+
+ if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn)
+ return;
+ }
+ halbtc8192e1ant_SetAgcTable(pBtCoexist, bAgcTableEn);
+
+ pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn;
+}
+
+VOID
+halbtc8192e1ant_SetCoexTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u4Byte val0x6c0,
+ IN u4Byte val0x6c4,
+ IN u4Byte val0x6c8,
+ IN u1Byte val0x6cc
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x6c0, val0x6c0);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x6c4, val0x6c4);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x6c8, val0x6c8);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc));
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x6cc, val0x6cc);
+}
+
+VOID
+halbtc8192e1ant_CoexTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u4Byte val0x6c0,
+ IN u4Byte val0x6c4,
+ IN u4Byte val0x6c8,
+ IN u1Byte val0x6cc
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n",
+ (bForceExec? "force to":""), val0x6c0, val0x6c4, val0x6c8, val0x6cc));
+ pCoexDm->curVal0x6c0 = val0x6c0;
+ pCoexDm->curVal0x6c4 = val0x6c4;
+ pCoexDm->curVal0x6c8 = val0x6c8;
+ pCoexDm->curVal0x6cc = val0x6cc;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], preVal0x6c0=0x%x, preVal0x6c4=0x%x, preVal0x6c8=0x%x, preVal0x6cc=0x%x !!\n",
+ pCoexDm->preVal0x6c0, pCoexDm->preVal0x6c4, pCoexDm->preVal0x6c8, pCoexDm->preVal0x6cc));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], curVal0x6c0=0x%x, curVal0x6c4=0x%x, curVal0x6c8=0x%x, curVal0x6cc=0x%x !!\n",
+ pCoexDm->curVal0x6c0, pCoexDm->curVal0x6c4, pCoexDm->curVal0x6c8, pCoexDm->curVal0x6cc));
+
+ if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) &&
+ (pCoexDm->preVal0x6c4 == pCoexDm->curVal0x6c4) &&
+ (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) &&
+ (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) )
+ return;
+ }
+ halbtc8192e1ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c4, val0x6c8, val0x6cc);
+
+ pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0;
+ pCoexDm->preVal0x6c4 = pCoexDm->curVal0x6c4;
+ pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8;
+ pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc;
+}
+
+VOID
+halbtc8192e1ant_CoexTableWithType(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u1Byte type
+ )
+{
+ switch(type)
+ {
+ case 0:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x55555555, 0xffffff, 0x3);
+ break;
+ case 1:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x55555555, 0x5a5a5a5a, 0xffffff, 0x3);
+ break;
+ case 2:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x5a5a5a5a, 0x5a5a5a5a, 0xffffff, 0x3);
+ break;
+ case 3:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0xaaaaaaaa, 0xaaaaaaaa, 0xffffff, 0x3);
+ break;
+ case 4:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0xffffffff, 0xffffffff, 0xffffff, 0x3);
+ break;
+ case 5:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x5fff5fff, 0x5fff5fff, 0xffffff, 0x3);
+ break;
+ case 6:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5a5a5a5a, 0xffffff, 0x3);
+ break;
+ case 7:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0xddffddff, 0xddffddff, 0xffffff, 0x3);
+ break;
+ case 8:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x55ff55ff, 0x5afa5afa, 0xffffff, 0x3);
+ break;
+ case 9:
+ halbtc8192e1ant_CoexTable(pBtCoexist, bForceExec, 0x5f5f5f5f, 0x5f5f5f5f, 0xffffff, 0x3);
+ break;
+ default:
+ break;
+ }
+}
+
+VOID
+halbtc8192e1ant_SetFwIgnoreWlanAct(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bEnable
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ if(bEnable)
+ {
+ H2C_Parameter[0] |= BIT0; // function enable
+ }
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n",
+ H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x63, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8192e1ant_IgnoreWlanAct(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bEnable
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s turn Ignore WlanAct %s\n",
+ (bForceExec? "force to":""), (bEnable? "ON":"OFF")));
+ pCoexDm->bCurIgnoreWlanAct = bEnable;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPreIgnoreWlanAct = %d, bCurIgnoreWlanAct = %d!!\n",
+ pCoexDm->bPreIgnoreWlanAct, pCoexDm->bCurIgnoreWlanAct));
+
+ if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct)
+ return;
+ }
+ halbtc8192e1ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable);
+
+ pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct;
+}
+
+VOID
+halbtc8192e1ant_SetFwPstdma(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte byte1,
+ IN u1Byte byte2,
+ IN u1Byte byte3,
+ IN u1Byte byte4,
+ IN u1Byte byte5
+ )
+{
+ u1Byte H2C_Parameter[5] ={0};
+
+ H2C_Parameter[0] = byte1;
+ H2C_Parameter[1] = byte2;
+ H2C_Parameter[2] = byte3;
+ H2C_Parameter[3] = byte4;
+ H2C_Parameter[4] = byte5;
+
+ pCoexDm->psTdmaPara[0] = byte1;
+ pCoexDm->psTdmaPara[1] = byte2;
+ pCoexDm->psTdmaPara[2] = byte3;
+ pCoexDm->psTdmaPara[3] = byte4;
+ pCoexDm->psTdmaPara[4] = byte5;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n",
+ H2C_Parameter[0],
+ H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x60, 5, H2C_Parameter);
+}
+
+VOID
+halbtc8192e1ant_SetLpsRpwm(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte lpsVal,
+ IN u1Byte rpwmVal
+ )
+{
+ u1Byte lps=lpsVal;
+ u1Byte rpwm=rpwmVal;
+
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_U1_1ANT_LPS, &lps);
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_U1_1ANT_RPWM, &rpwm);
+}
+
+VOID
+halbtc8192e1ant_LpsRpwm(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u1Byte lpsVal,
+ IN u1Byte rpwmVal
+ )
+{
+ BOOLEAN bForceExecPwrCmd=FALSE;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s set lps/rpwm=0x%x/0x%x \n",
+ (bForceExec? "force to":""), lpsVal, rpwmVal));
+ pCoexDm->curLps = lpsVal;
+ pCoexDm->curRpwm = rpwmVal;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], preLps/curLps=0x%x/0x%x, preRpwm/curRpwm=0x%x/0x%x!!\n",
+ pCoexDm->preLps, pCoexDm->curLps, pCoexDm->preRpwm, pCoexDm->curRpwm));
+
+ if( (pCoexDm->preLps == pCoexDm->curLps) &&
+ (pCoexDm->preRpwm == pCoexDm->curRpwm) )
+ {
+ return;
+ }
+ }
+ halbtc8192e1ant_SetLpsRpwm(pBtCoexist, lpsVal, rpwmVal);
+
+ pCoexDm->preLps = pCoexDm->curLps;
+ pCoexDm->preRpwm = pCoexDm->curRpwm;
+}
+
+VOID
+halbtc8192e1ant_SwMechanism1(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bShrinkRxLPF,
+ IN BOOLEAN bLowPenaltyRA,
+ IN BOOLEAN limited_dig,
+ IN BOOLEAN bBTLNAConstrain
+ )
+{
+ //halbtc8192e1ant_RfShrink(pBtCoexist, NORMAL_EXEC, bShrinkRxLPF);
+ //halbtc8192e1ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, bLowPenaltyRA);
+
+ //no limited DIG
+ //halbtc8192e1ant_SetBtLnaConstrain(pBtCoexist, NORMAL_EXEC, bBTLNAConstrain);
+}
+
+VOID
+halbtc8192e1ant_SwMechanism2(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bAGCTableShift,
+ IN BOOLEAN bADCBackOff,
+ IN BOOLEAN bSWDACSwing,
+ IN u4Byte dacSwingLvl
+ )
+{
+ //halbtc8192e1ant_AgcTable(pBtCoexist, NORMAL_EXEC, bAGCTableShift);
+ //halbtc8192e1ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, bADCBackOff);
+ //halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, bSWDACSwing, dacSwingLvl);
+}
+
+VOID
+halbtc8192e1ant_PsTdma(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bTurnOn,
+ IN u1Byte type
+ )
+{
+ BOOLEAN bTurnOnByCnt=FALSE;
+ u1Byte psTdmaTypeByCnt=0, rssiAdjustVal=0;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s turn %s PS TDMA, type=%d\n",
+ (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type));
+ pCoexDm->bCurPsTdmaOn = bTurnOn;
+ pCoexDm->curPsTdma = type;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n",
+ pCoexDm->bPrePsTdmaOn, pCoexDm->bCurPsTdmaOn));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n",
+ pCoexDm->prePsTdma, pCoexDm->curPsTdma));
+
+ if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) &&
+ (pCoexDm->prePsTdma == pCoexDm->curPsTdma) )
+ return;
+ }
+ if(bTurnOn)
+ {
+ switch(type)
+ {
+ default:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x53, 0x2c, 0x03, 0x10, 0x50);
+ break;
+ case 1:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x53, 0x2c, 0x03, 0x10, 0x50);
+ rssiAdjustVal = 11;
+ break;
+ case 2:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x53, 0x25, 0x03, 0x10, 0x50);
+ rssiAdjustVal = 14;
+ break;
+ case 3:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x40);
+ break;
+ case 4:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x14, 0x0);
+ rssiAdjustVal = 17;
+ break;
+ case 5:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x61, 0x15, 0x3, 0x31, 0x0);
+ break;
+ case 6:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0x3, 0x0, 0x0);
+ break;
+ case 7:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x13, 0xc, 0x5, 0x0, 0x0);
+ break;
+ case 8:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0);
+ break;
+ case 9:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x53, 0x1e, 0x03, 0x10, 0x50);
+ rssiAdjustVal = 18;
+ break;
+ case 10:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0xa, 0x0, 0x40);
+ break;
+ case 11:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x53, 0x12, 0x03, 0x10, 0x50);
+ rssiAdjustVal = 20;
+ break;
+ case 12:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xeb, 0xa, 0x3, 0x31, 0x18);
+ break;
+
+ case 15:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x13, 0xa, 0x3, 0x8, 0x0);
+ break;
+ case 16:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x10, 0x0);
+ rssiAdjustVal = 18;
+ break;
+
+ case 18:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x25, 0x3, 0x10, 0x0);
+ rssiAdjustVal = 14;
+ break;
+
+ case 20:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x13, 0x25, 0x25, 0x0, 0x0);
+ break;
+ case 21:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x20, 0x3, 0x10, 0x40);
+ break;
+ case 22:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x13, 0x8, 0x8, 0x0, 0x40);
+ break;
+ case 23:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x18);
+ rssiAdjustVal = 22;
+ break;
+ case 24:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x15, 0x3, 0x31, 0x18);
+ rssiAdjustVal = 22;
+ break;
+ case 25:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18);
+ rssiAdjustVal = 22;
+ break;
+ case 26:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0x3, 0x31, 0x18);
+ rssiAdjustVal = 22;
+ break;
+ case 27:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x3, 0x31, 0x98);
+ rssiAdjustVal = 22;
+ break;
+ case 28:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x69, 0x25, 0x3, 0x31, 0x0);
+ break;
+ case 29:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xab, 0x1a, 0x1a, 0x1, 0x10);
+ break;
+ case 30:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x93, 0x15, 0x3, 0x14, 0x0);
+ break;
+ case 31:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1a, 0x1a, 0, 0x58);
+ break;
+ case 32:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xab, 0xa, 0x3, 0x31, 0x90);
+ break;
+ case 33:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xa3, 0x25, 0x3, 0x30, 0x90);
+ break;
+ case 34:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x1a, 0x1a, 0x0, 0x10);
+ break;
+ case 35:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x0, 0x10);
+ break;
+ case 36:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xd3, 0x12, 0x3, 0x14, 0x50);
+ break;
+ case 37:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x53, 0x25, 0x3, 0x10, 0x50);
+ break;
+ case 38:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x90);
+ break;
+ }
+ }
+ else
+ {
+ // disable PS tdma
+ switch(type)
+ {
+ case 8: //0x778 = 1, ant2PTA
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x8, 0x0, 0x0, 0x0, 0x0);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x92c, 0x4);
+ break;
+ case 0: //0x778 = 1, ant2BT
+ default:
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0);
+ mdelay(5);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x92c, 0x20);
+ break;
+ case 9: //0x778 = 1, ant2WIFI
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x92c, 0x4);
+ break;
+ case 10: //0x778 = 3, ant2BT
+ halbtc8192e1ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x8, 0x0);
+ mdelay(5);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x92c, 0x20);
+ break;
+ }
+ }
+ rssiAdjustVal =0;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_1ANT_COEX_TYPE, &rssiAdjustVal);
+
+ // update pre state
+ pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn;
+ pCoexDm->prePsTdma = pCoexDm->curPsTdma;
+}
+
+VOID
+halbtc8192e1ant_SetSwitchSsType(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte ssType
+ )
+{
+ u1Byte mimoPs=BTC_MIMO_PS_DYNAMIC;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], REAL set SS Type = %d\n", ssType));
+
+ if(ssType == 1)
+ {
+ halbtc8192e1ant_Updatera_mask(pBtCoexist, FORCE_EXEC, BTC_RATE_DISABLE, 0xfff00000); // disable 2ss
+ halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0);
+ // switch ofdm path
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0xc04, 0x11);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0xd04, 0x1);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x90c, 0x81111111);
+ // switch cck patch
+ pBtCoexist->btc_write_1byte_bitmask(pBtCoexist, 0xe77, 0x4, 0x1);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0xa07, 0x81);
+ mimoPs=BTC_MIMO_PS_STATIC;
+ }
+ else if(ssType == 2)
+ {
+ halbtc8192e1ant_Updatera_mask(pBtCoexist, FORCE_EXEC, BTC_RATE_ENABLE, 0xfff00000); // enable 2ss
+ halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0xc04, 0x33);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0xd04, 0x3);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x90c, 0x81121313);
+ pBtCoexist->btc_write_1byte_bitmask(pBtCoexist, 0xe77, 0x4, 0x0);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0xa07, 0x41);
+ mimoPs=BTC_MIMO_PS_DYNAMIC;
+ }
+
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_SEND_MIMO_PS, &mimoPs); // set rx 1ss or 2ss
+}
+
+VOID
+halbtc8192e1ant_SwitchSsType(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u1Byte newSsType
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], %s Switch SS Type = %d\n",
+ (bForceExec? "force to":""), newSsType));
+ pCoexDm->curSsType = newSsType;
+
+ if(!bForceExec)
+ {
+ if(pCoexDm->preSsType == pCoexDm->curSsType)
+ return;
+ }
+ halbtc8192e1ant_SetSwitchSsType(pBtCoexist, pCoexDm->curSsType);
+
+ pCoexDm->preSsType = pCoexDm->curSsType;
+}
+
+VOID
+halbtc8192e1ant_CoexAllOff(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+
+ // sw all off
+ halbtc8192e1ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE);
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+
+
+ // hw all off
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
+}
+
+BOOLEAN
+halbtc8192e1ant_IsCommonAction(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BOOLEAN bCommon=FALSE, bWifiConnected=FALSE, bWifiBusy=FALSE;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
+
+ if(!bWifiConnected &&
+ BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi non connected-idle + BT non connected-idle!!\n"));
+ halbtc8192e1ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE);
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+
+ bCommon = true;
+ }
+ else if(bWifiConnected &&
+ (BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi connected + BT non connected-idle!!\n"));
+ halbtc8192e1ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE);
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+
+ bCommon = true;
+ }
+ else if(!bWifiConnected &&
+ (BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi non connected-idle + BT connected-idle!!\n"));
+ halbtc8192e1ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE);
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+
+ bCommon = true;
+ }
+ else if(bWifiConnected &&
+ (BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi connected + BT connected-idle!!\n"));
+ halbtc8192e1ant_SwMechanism1(pBtCoexist,true,true,true,true);
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+
+ bCommon = true;
+ }
+ else if(!bWifiConnected &&
+ (BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi non connected-idle + BT Busy!!\n"));
+ halbtc8192e1ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE);
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+
+ bCommon = true;
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism1(pBtCoexist,true,true,true,true);
+
+ bCommon = FALSE;
+ }
+
+ return bCommon;
+}
+
+
+VOID
+halbtc8192e1ant_TdmaDurationAdjustForAcl(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte wifiStatus
+ )
+{
+ static s4Byte up,dn,m,n,WaitCount;
+ s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration
+ u1Byte retryCount=0, btInfoExt;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], TdmaDurationAdjustForAcl()\n"));
+
+ if( (BT_8192E_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) ||
+ (BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) ||
+ (BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifiStatus) )
+ {
+ if( pCoexDm->curPsTdma != 1 &&
+ pCoexDm->curPsTdma != 2 &&
+ pCoexDm->curPsTdma != 3 &&
+ pCoexDm->curPsTdma != 9 )
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+ pCoexDm->psTdmaDuAdjType = 9;
+
+ up = 0;
+ dn = 0;
+ m = 1;
+ n= 3;
+ result = 0;
+ WaitCount = 0;
+ }
+ return;
+ }
+
+ if(!pCoexDm->bAutoTdmaAdjust)
+ {
+ pCoexDm->bAutoTdmaAdjust = true;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], first run TdmaDurationAdjust()!!\n"));
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+ pCoexDm->psTdmaDuAdjType = 2;
+ //============
+ up = 0;
+ dn = 0;
+ m = 1;
+ n= 3;
+ result = 0;
+ WaitCount = 0;
+ }
+ else
+ {
+ //accquire the BT TRx retry count from BT_Info byte2
+ retryCount = pCoexSta->btRetryCnt;
+ btInfoExt = pCoexSta->btInfoExt;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], retryCount = %d\n", retryCount));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], up=%d, dn=%d, m=%d, n=%d, WaitCount=%d\n",
+ up, dn, m, n, WaitCount));
+ result = 0;
+ WaitCount++;
+
+ if(retryCount == 0) // no retry in the last 2-second duration
+ {
+ up++;
+ dn--;
+
+ if (dn <= 0)
+ dn = 0;
+
+ if(up >= n) // if 連續 n 個2秒 retry count為0, 則調寬WiFi duration
+ {
+ WaitCount = 0;
+ n = 3;
+ up = 0;
+ dn = 0;
+ result = 1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], Increase wifi duration!!\n"));
+ }
+ }
+ else if (retryCount <= 3) // <=3 retry in the last 2-second duration
+ {
+ up--;
+ dn++;
+
+ if (up <= 0)
+ up = 0;
+
+ if (dn == 2) // if 連續 2 個2秒 retry count< 3, 則調窄WiFi duration
+ {
+ if (WaitCount <= 2)
+ m++; // 避免一直在兩個level中來回
+ else
+ m = 1;
+
+ if ( m >= 20) //m 最大值 = 20 ' 最大120秒 recheck是否調整 WiFi duration.
+ m = 20;
+
+ n = 3*m;
+ up = 0;
+ dn = 0;
+ WaitCount = 0;
+ result = -1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], Decrease wifi duration for retryCounter<3!!\n"));
+ }
+ }
+ else //retry count > 3, 只要1次 retry count > 3, 則調窄WiFi duration
+ {
+ if (WaitCount == 1)
+ m++; // 避免一直在兩個level中來回
+ else
+ m = 1;
+
+ if ( m >= 20) //m 最大值 = 20 ' 最大120秒 recheck是否調整 WiFi duration.
+ m = 20;
+
+ n = 3*m;
+ up = 0;
+ dn = 0;
+ WaitCount = 0;
+ result = -1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], Decrease wifi duration for retryCounter>3!!\n"));
+ }
+
+ if(result == -1)
+ {
+ if( (BT_INFO_8192E_1ANT_A2DP_BASIC_RATE(btInfoExt)) &&
+ ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) )
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+ pCoexDm->psTdmaDuAdjType = 9;
+ }
+ else if(pCoexDm->curPsTdma == 1)
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+ pCoexDm->psTdmaDuAdjType = 2;
+ }
+ else if(pCoexDm->curPsTdma == 2)
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+ pCoexDm->psTdmaDuAdjType = 9;
+ }
+ else if(pCoexDm->curPsTdma == 9)
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+ pCoexDm->psTdmaDuAdjType = 11;
+ }
+ }
+ else if(result == 1)
+ {
+ if( (BT_INFO_8192E_1ANT_A2DP_BASIC_RATE(btInfoExt)) &&
+ ((pCoexDm->curPsTdma == 1) ||(pCoexDm->curPsTdma == 2)) )
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+ pCoexDm->psTdmaDuAdjType = 9;
+ }
+ else if(pCoexDm->curPsTdma == 11)
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+ pCoexDm->psTdmaDuAdjType = 9;
+ }
+ else if(pCoexDm->curPsTdma == 9)
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+ pCoexDm->psTdmaDuAdjType = 2;
+ }
+ else if(pCoexDm->curPsTdma == 2)
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 1);
+ pCoexDm->psTdmaDuAdjType = 1;
+ }
+ }
+
+ if( pCoexDm->curPsTdma != 1 &&
+ pCoexDm->curPsTdma != 2 &&
+ pCoexDm->curPsTdma != 9 &&
+ pCoexDm->curPsTdma != 11 )
+ {
+ // recover to previous adjust type
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, pCoexDm->psTdmaDuAdjType);
+ }
+ }
+}
+
+u1Byte
+halbtc8192e1ant_PsTdmaTypeByWifiRssi(
+ IN s4Byte wifiRssi,
+ IN s4Byte preWifiRssi,
+ IN u1Byte wifiRssiThresh
+ )
+{
+ u1Byte psTdmaType=0;
+
+ if(wifiRssi > preWifiRssi)
+ {
+ if(wifiRssi > (wifiRssiThresh+5))
+ {
+ psTdmaType = 26;
+ }
+ else
+ {
+ psTdmaType = 25;
+ }
+ }
+ else
+ {
+ if(wifiRssi > wifiRssiThresh)
+ {
+ psTdmaType = 26;
+ }
+ else
+ {
+ psTdmaType = 25;
+ }
+ }
+
+ return psTdmaType;
+}
+
+VOID
+halbtc8192e1ant_PsTdmaCheckForPowerSaveState(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bNewPsState
+ )
+{
+ u1Byte lpsMode=0x0;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_LPS_MODE, &lpsMode);
+
+ if(lpsMode) // already under LPS state
+ {
+ if(bNewPsState)
+ {
+ // keep state under LPS, do nothing.
+ }
+ else
+ {
+ // will leave LPS state, turn off psTdma first
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ }
+ }
+ else // NO PS state
+ {
+ if(bNewPsState)
+ {
+ // will enter LPS state, turn off psTdma first
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ }
+ else
+ {
+ // keep state under NO PS state, do nothing.
+ }
+ }
+}
+
+VOID
+halbtc8192e1ant_PowerSaveState(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte psType,
+ IN u1Byte lpsVal,
+ IN u1Byte rpwmVal
+ )
+{
+ BOOLEAN bLowPwrDisable=FALSE;
+
+ switch(psType)
+ {
+ case BTC_PS_WIFI_NATIVE:
+ // recover to original 32k low power setting
+ bLowPwrDisable = FALSE;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable);
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
+ break;
+ case BTC_PS_LPS_ON:
+ halbtc8192e1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, true);
+ halbtc8192e1ant_LpsRpwm(pBtCoexist, NORMAL_EXEC, lpsVal, rpwmVal);
+ // when coex force to enter LPS, do not enter 32k low power.
+ bLowPwrDisable = true;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable);
+ // power save must executed before psTdma.
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_ENTER_LPS, NULL);
+ break;
+ case BTC_PS_LPS_OFF:
+ halbtc8192e1ant_PsTdmaCheckForPowerSaveState(pBtCoexist, FALSE);
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ break;
+ default:
+ break;
+ }
+}
+
+
+VOID
+halbtc8192e1ant_ActionWifiOnly(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9);
+}
+
+VOID
+halbtc8192e1ant_MonitorBtEnableDisable(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ static BOOLEAN bPreBtDisabled=FALSE;
+ static u4Byte btDisableCnt=0;
+ BOOLEAN bBtActive=true, bBtDisabled=FALSE;
+
+ // This function check if bt is disabled
+
+ if( pCoexSta->highPriorityTx == 0 &&
+ pCoexSta->highPriorityRx == 0 &&
+ pCoexSta->lowPriorityTx == 0 &&
+ pCoexSta->lowPriorityRx == 0)
+ {
+ bBtActive = FALSE;
+ }
+ if( pCoexSta->highPriorityTx == 0xffff &&
+ pCoexSta->highPriorityRx == 0xffff &&
+ pCoexSta->lowPriorityTx == 0xffff &&
+ pCoexSta->lowPriorityRx == 0xffff)
+ {
+ bBtActive = FALSE;
+ }
+ if(bBtActive)
+ {
+ btDisableCnt = 0;
+ bBtDisabled = FALSE;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is enabled !!\n"));
+ }
+ else
+ {
+ btDisableCnt++;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], bt all counters=0, %d times!!\n",
+ btDisableCnt));
+ if(btDisableCnt >= 2)
+ {
+ bBtDisabled = true;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is disabled !!\n"));
+ halbtc8192e1ant_ActionWifiOnly(pBtCoexist);
+ }
+ }
+ if(bPreBtDisabled != bBtDisabled)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is from %s to %s!!\n",
+ (bPreBtDisabled ? "disabled":"enabled"),
+ (bBtDisabled ? "disabled":"enabled")));
+ bPreBtDisabled = bBtDisabled;
+ if(!bBtDisabled)
+ {
+ }
+ else
+ {
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_LEAVE_LPS, NULL);
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_NORMAL_LPS, NULL);
+ }
+ }
+}
+
+//=============================================
+//
+// Software Coex Mechanism start
+//
+//=============================================
+
+// SCO only or SCO+PAN(HS)
+VOID
+halbtc8192e1ant_ActionSco(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState;
+ u4Byte wifiBw;
+
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,true,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+
+VOID
+halbtc8192e1ant_ActionHid(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState;
+ u4Byte wifiBw;
+
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,FALSE,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+//A2DP only / PAN(EDR) only/ A2DP+PAN(HS)
+VOID
+halbtc8192e1ant_ActionA2dp(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState;
+ u4Byte wifiBw;
+
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,true,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+VOID
+halbtc8192e1ant_ActionA2dpPanHs(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState, btInfoExt;
+ u4Byte wifiBw;
+
+ btInfoExt = pCoexSta->btInfoExt;
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,true,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+VOID
+halbtc8192e1ant_ActionPanEdr(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState;
+ u4Byte wifiBw;
+
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,true,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+
+//PAN(HS) only
+VOID
+halbtc8192e1ant_ActionPanHs(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState;
+ u4Byte wifiBw;
+
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,true,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+//PAN(EDR)+A2DP
+VOID
+halbtc8192e1ant_ActionPanEdrA2dp(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState, btInfoExt;
+ u4Byte wifiBw;
+
+ btInfoExt = pCoexSta->btInfoExt;
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,true,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+VOID
+halbtc8192e1ant_ActionPanEdrHid(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState;
+ u4Byte wifiBw;
+
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,true,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+// HID+A2DP+PAN(EDR)
+VOID
+halbtc8192e1ant_ActionHidA2dpPanEdr(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState, btInfoExt;
+ u4Byte wifiBw;
+
+ btInfoExt = pCoexSta->btInfoExt;
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,true,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+VOID
+halbtc8192e1ant_ActionHidA2dp(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte wifiRssiState, btInfoExt;
+ u4Byte wifiBw;
+
+ btInfoExt = pCoexSta->btInfoExt;
+ wifiRssiState = halbtc8192e1ant_WifiRssiState(pBtCoexist, 0, 2, 25, 0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,true,FALSE,0x18);
+ }
+ }
+ else
+ {
+ // sw mechanism
+ if( (wifiRssiState == BTC_RSSI_STATE_HIGH) ||
+ (wifiRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,true,true,FALSE,0x18);
+ }
+ else
+ {
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+ }
+ }
+}
+
+//=============================================
+//
+// Non-Software Coex Mechanism start
+//
+//=============================================
+VOID
+halbtc8192e1ant_ActionBtInquiry(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->bt_link_info;
+ BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE;
+
+ // Note:
+ // Do not do DacSwing here, use original setting.
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+ if(bBtHsOn)
+ return;
+
+ if(!bWifiConnected)
+ {
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
+ }
+ else if( (pBtLinkInfo->bScoExist) ||
+ (pBtLinkInfo->bHidOnly) )
+ {
+ // SCO/HID-only busy
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 32);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1);
+ }
+ else
+ {
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x0);
+
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 30);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
+ }
+}
+
+VOID
+halbtc8192e1ant_ActionBtScoHidOnlyBusy(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte wifiStatus
+ )
+{
+ PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->bt_link_info;
+ u1Byte btRssiState=BTC_RSSI_STATE_HIGH;
+
+ if(BT_8192E_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus)
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
+ }
+ else
+ {
+ if(pBtLinkInfo->bHidOnly)
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
+ }
+ else
+ {
+ // dec bt power for diff level
+ btRssiState = halbtc8192e1ant_BtRssiState(3, 34, 42);
+ if( (btRssiState == BTC_RSSI_STATE_LOW) ||
+ (btRssiState == BTC_RSSI_STATE_STAY_LOW) )
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ }
+ else if( (btRssiState == BTC_RSSI_STATE_MEDIUM) ||
+ (btRssiState == BTC_RSSI_STATE_STAY_MEDIUM) )
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 2);
+ }
+ else if( (btRssiState == BTC_RSSI_STATE_HIGH) ||
+ (btRssiState == BTC_RSSI_STATE_STAY_HIGH) )
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 6);
+ }
+
+ // sw dacSwing
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, true, 0xc);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 7);
+ }
+ }
+}
+
+VOID
+halbtc8192e1ant_ActionHs(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->bt_link_info;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action for HS!!!\n"));
+
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+
+ if(BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)
+ {
+ // error, should not be here
+ pCoexDm->errorCondition = 1;
+ }
+ else if(BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, true, 6);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 10);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
+ }
+ else if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus &&
+ !pBtCoexist->bt_link_info.bHidOnly)
+ {
+ if(pCoexDm->curSsType == 1)
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, true, 6);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 10);
+ //halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 38);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
+ }
+ }
+ else
+ {
+ halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_BUSY);
+ }
+}
+
+VOID
+halbtc8192e1ant_ActionWifiConnectedBtAclBusy(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte wifiStatus
+ )
+{
+ PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->bt_link_info;
+
+ if(pBtLinkInfo->bHidOnly)
+ {
+ halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist, wifiStatus);
+ pCoexDm->bAutoTdmaAdjust = FALSE;
+ return;
+ }
+
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+
+ if( (pBtLinkInfo->bA2dpOnly) ||
+ (pBtLinkInfo->bHidExist&&pBtLinkInfo->bA2dpExist) )
+ {
+ halbtc8192e1ant_TdmaDurationAdjustForAcl(pBtCoexist, wifiStatus);
+ }
+ else if( (pBtLinkInfo->bPanOnly) ||
+ (pBtLinkInfo->bHidExist&&pBtLinkInfo->bPanExist) )
+ {
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+ pCoexDm->bAutoTdmaAdjust = FALSE;
+ }
+ else
+ {
+ if( (BT_8192E_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN == wifiStatus) ||
+ (BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SCAN == wifiStatus) ||
+ (BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT == wifiStatus) )
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+ else
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+ pCoexDm->bAutoTdmaAdjust = FALSE;
+ }
+
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 1);
+}
+
+
+VOID
+halbtc8192e1ant_ActionWifiNotConnected(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ // power save state
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
+}
+
+VOID
+halbtc8192e1ant_ActionWifiNotConnectedAssoAuthScan(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 0);
+}
+
+VOID
+halbtc8192e1ant_ActionWifiConnectedScan(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ // power save state
+ if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus && !pBtCoexist->bt_link_info.bHidOnly)
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x0);
+ else
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+
+ if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus)
+ {
+ halbtc8192e1ant_ActionWifiConnectedBtAclBusy(pBtCoexist,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SCAN);
+ }
+ else if( (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) ||
+ (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) )
+ {
+ halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SCAN);
+ }
+ else
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
+ }
+}
+
+
+VOID
+halbtc8192e1ant_ActionWifiConnectedSpecialPacket(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ // power save state
+ if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus && !pBtCoexist->bt_link_info.bHidOnly)
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x0);
+ else
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+
+ if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus)
+ {
+ halbtc8192e1ant_ActionWifiConnectedBtAclBusy(pBtCoexist,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT);
+ }
+ else
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
+ }
+}
+
+VOID
+halbtc8192e1ant_ActionWifiConnected(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BOOLEAN bWifiConnected=FALSE, bWifiBusy=FALSE;
+ BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE;
+ BOOLEAN bUnder4way=FALSE;
+ u4Byte wifiBw;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], CoexForWifiConnect()===>\n"));
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ if(!bWifiConnected)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], CoexForWifiConnect(), return for wifi not connected<===\n"));
+ return;
+ }
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS, &bUnder4way);
+ if(bUnder4way)
+ {
+ halbtc8192e1ant_ActionWifiConnectedSpecialPacket(pBtCoexist);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], CoexForWifiConnect(), return for wifi is under 4way<===\n"));
+ return;
+ }
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam);
+ if(bScan || bLink || bRoam)
+ {
+ halbtc8192e1ant_ActionWifiConnectedScan(pBtCoexist);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], CoexForWifiConnect(), return for wifi is under scan<===\n"));
+ return;
+ }
+
+ // power save state
+ if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus && !pBtCoexist->bt_link_info.bHidOnly)
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_LPS_ON, 0x50, 0x0);
+ else
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
+ if(!bWifiBusy)
+ {
+ if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus)
+ {
+ halbtc8192e1ant_ActionWifiConnectedBtAclBusy(pBtCoexist,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_IDLE);
+ }
+ else if( (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) ||
+ (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) )
+ {
+ halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_IDLE);
+ }
+ else
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
+ }
+ }
+ else
+ {
+ if(BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 5);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
+ }
+ else if(BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 5);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
+ }
+ else if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus)
+ {
+ halbtc8192e1ant_ActionWifiConnectedBtAclBusy(pBtCoexist,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_BUSY);
+ }
+ else if( (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) ||
+ (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) )
+ {
+ halbtc8192e1ant_ActionBtScoHidOnlyBusy(pBtCoexist,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_BUSY);
+ }
+ else
+ {
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, 0);
+ halbtc8192e1ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, NORMAL_EXEC, 2);
+ }
+ }
+}
+
+VOID
+halbtc8192e1ant_RunSwCoexistMechanism(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BOOLEAN bWifiUnder5G=FALSE, bWifiBusy=FALSE, bWifiConnected=FALSE;
+ u1Byte btInfoOriginal=0, btRetryCnt=0;
+ u1Byte algorithm=0;
+
+ return;
+
+ algorithm = halbtc8192e1ant_ActionAlgorithm(pBtCoexist);
+ pCoexDm->curAlgorithm = algorithm;
+
+ if(halbtc8192e1ant_IsCommonAction(pBtCoexist))
+ {
+ }
+ else
+ {
+ switch(pCoexDm->curAlgorithm)
+ {
+ case BT_8192E_1ANT_COEX_ALGO_SCO:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = SCO.\n"));
+ halbtc8192e1ant_ActionSco(pBtCoexist);
+ break;
+ case BT_8192E_1ANT_COEX_ALGO_HID:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = HID.\n"));
+ halbtc8192e1ant_ActionHid(pBtCoexist);
+ break;
+ case BT_8192E_1ANT_COEX_ALGO_A2DP:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = A2DP.\n"));
+ halbtc8192e1ant_ActionA2dp(pBtCoexist);
+ break;
+ case BT_8192E_1ANT_COEX_ALGO_A2DP_PANHS:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = A2DP+PAN(HS).\n"));
+ halbtc8192e1ant_ActionA2dpPanHs(pBtCoexist);
+ break;
+ case BT_8192E_1ANT_COEX_ALGO_PANEDR:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = PAN(EDR).\n"));
+ halbtc8192e1ant_ActionPanEdr(pBtCoexist);
+ break;
+ case BT_8192E_1ANT_COEX_ALGO_PANHS:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = HS mode.\n"));
+ halbtc8192e1ant_ActionPanHs(pBtCoexist);
+ break;
+ case BT_8192E_1ANT_COEX_ALGO_PANEDR_A2DP:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = PAN+A2DP.\n"));
+ halbtc8192e1ant_ActionPanEdrA2dp(pBtCoexist);
+ break;
+ case BT_8192E_1ANT_COEX_ALGO_PANEDR_HID:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = PAN(EDR)+HID.\n"));
+ halbtc8192e1ant_ActionPanEdrHid(pBtCoexist);
+ break;
+ case BT_8192E_1ANT_COEX_ALGO_HID_A2DP_PANEDR:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = HID+A2DP+PAN.\n"));
+ halbtc8192e1ant_ActionHidA2dpPanEdr(pBtCoexist);
+ break;
+ case BT_8192E_1ANT_COEX_ALGO_HID_A2DP:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = HID+A2DP.\n"));
+ halbtc8192e1ant_ActionHidA2dp(pBtCoexist);
+ break;
+ default:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Action algorithm = coexist All Off!!\n"));
+ halbtc8192e1ant_CoexAllOff(pBtCoexist);
+ break;
+ }
+ pCoexDm->preAlgorithm = pCoexDm->curAlgorithm;
+ }
+}
+
+VOID
+halbtc8192e1ant_RunCoexistMechanism(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->bt_link_info;
+ BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], RunCoexistMechanism()===>\n"));
+
+ if(pBtCoexist->manual_control)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], RunCoexistMechanism(), return for Manual CTRL <===\n"));
+ return;
+ }
+
+ if(pBtCoexist->bStopCoexDm)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], RunCoexistMechanism(), return for Stop Coex DM <===\n"));
+ return;
+ }
+
+ if(pCoexSta->bUnderIps)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], wifi is under IPS !!!\n"));
+ return;
+ }
+
+ halbtc8192e1ant_RunSwCoexistMechanism(pBtCoexist);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+ if(pCoexSta->bC2hBtInquiryPage)
+ {
+ halbtc8192e1ant_ActionBtInquiry(pBtCoexist);
+ return;
+ }
+
+ // 1ss or 2ss
+ if(pBtLinkInfo->bScoExist)
+ {
+ halbtc8192e1ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 1);
+ }
+ else if(bBtHsOn)
+ {
+ if(pBtLinkInfo->bHidOnly)
+ halbtc8192e1ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 2);
+ else
+ halbtc8192e1ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 1);
+ }
+ else
+ halbtc8192e1ant_SwitchSsType(pBtCoexist, NORMAL_EXEC, 2);
+
+ if(bBtHsOn)
+ {
+ halbtc8192e1ant_ActionHs(pBtCoexist);
+ return;
+ }
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ if(!bWifiConnected)
+ {
+ BOOLEAN bScan=FALSE, bLink=FALSE, bRoam=FALSE;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], wifi is non connected-idle !!!\n"));
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam);
+
+ if(bScan || bLink || bRoam)
+ halbtc8192e1ant_ActionWifiNotConnectedAssoAuthScan(pBtCoexist);
+ else
+ halbtc8192e1ant_ActionWifiNotConnected(pBtCoexist);
+ }
+ else
+ {
+ halbtc8192e1ant_ActionWifiConnected(pBtCoexist);
+ }
+}
+
+VOID
+halbtc8192e1ant_InitCoexDm(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ // force to reset coex mechanism
+ halbtc8192e1ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 6);
+ halbtc8192e1ant_DecBtPwr(pBtCoexist, FORCE_EXEC, 0);
+
+ // sw all off
+ halbtc8192e1ant_SwMechanism1(pBtCoexist,FALSE,FALSE,FALSE,FALSE);
+ halbtc8192e1ant_SwMechanism2(pBtCoexist,FALSE,FALSE,FALSE,0x18);
+
+ halbtc8192e1ant_SwitchSsType(pBtCoexist, FORCE_EXEC, 2);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 8);
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0);
+}
+
+//============================================================
+// work around function start with wa_halbtc8192e1ant_
+//============================================================
+//============================================================
+// extern function start with EXhalbtc8192e1ant_
+//============================================================
+VOID
+EXhalbtc8192e1ant_InitHwConfig(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u4Byte u4Tmp=0;
+ u16 u2Tmp=0;
+ u1Byte u1Tmp=0;
+
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], 1Ant Init HW Config!!\n"));
+
+ // backup rf 0x1e value
+ pCoexDm->btRf0x1eBackup =
+ pBtCoexist->btc_get_rf_reg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff);
+
+ // antenna sw ctrl to bt
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x4f, 0x6);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x944, 0x24);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x930, 0x700700);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x92c, 0x20);
+ if(pBtCoexist->chipInterface == BTC_INTF_USB)
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x64, 0x30430004);
+ else
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x64, 0x30030004);
+
+ halbtc8192e1ant_CoexTableWithType(pBtCoexist, FORCE_EXEC, 0);
+
+ // antenna switch control parameter
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x858, 0x55555555);
+
+ // coex parameters
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x778, 0x1);
+ // 0x790[5:0]=0x5
+ u1Tmp = pBtCoexist->btc_read_1byte(pBtCoexist, 0x790);
+ u1Tmp &= 0xc0;
+ u1Tmp |= 0x5;
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x790, u1Tmp);
+
+ // enable counter statistics
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x76e, 0x4);
+
+ // enable PTA
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x40, 0x20);
+ // enable mailbox interface
+ u2Tmp = pBtCoexist->btc_read_2byte(pBtCoexist, 0x40);
+ u2Tmp |= BIT9;
+ pBtCoexist->btc_write_2byte(pBtCoexist, 0x40, u2Tmp);
+
+ // enable PTA I2C mailbox
+ u1Tmp = pBtCoexist->btc_read_1byte(pBtCoexist, 0x101);
+ u1Tmp |= BIT4;
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x101, u1Tmp);
+
+ // enable bt clock when wifi is disabled.
+ u1Tmp = pBtCoexist->btc_read_1byte(pBtCoexist, 0x93);
+ u1Tmp |= BIT0;
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x93, u1Tmp);
+ // enable bt clock when suspend.
+ u1Tmp = pBtCoexist->btc_read_1byte(pBtCoexist, 0x7);
+ u1Tmp |= BIT0;
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x7, u1Tmp);
+}
+
+VOID
+EXhalbtc8192e1ant_InitCoexDm(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], Coex Mechanism Init!!\n"));
+
+ pBtCoexist->bStopCoexDm = FALSE;
+
+ halbtc8192e1ant_InitCoexDm(pBtCoexist);
+}
+
+VOID
+EXhalbtc8192e1ant_DisplayCoexInfo(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ struct btc_board_info * pBoardInfo=&pBtCoexist->board_info;
+ PBTC_STACK_INFO pStackInfo=&pBtCoexist->stack_info;
+ PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->bt_link_info;
+ pu1Byte cliBuf=pBtCoexist->cli_buf;
+ u1Byte u1Tmp[4], i, btInfoExt, psTdmaCase=0;
+ u4Byte u4Tmp[4];
+ BOOLEAN bRoam=FALSE, bScan=FALSE, bLink=FALSE, bWifiUnder5G=FALSE;
+ BOOLEAN bBtHsOn=FALSE, bWifiBusy=FALSE;
+ s4Byte wifiRssi=0, btHsRssi=0;
+ u4Byte wifiBw, wifiTrafficDir;
+ u1Byte wifiDot11Chnl, wifiHsChnl;
+ u4Byte fwVer=0, btPatchVer=0;
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[BT Coexist info]============");
+ CL_PRINTF(cliBuf);
+
+ if(pBtCoexist->manual_control)
+ {
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Under Manual Control]============");
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ==========================================");
+ CL_PRINTF(cliBuf);
+ }
+ if(pBtCoexist->bStopCoexDm)
+ {
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ============[Coex is STOPPED]============");
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n ==========================================");
+ CL_PRINTF(cliBuf);
+ }
+
+ if(!pBoardInfo->bt_exist)
+ {
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
+ CL_PRINTF(cliBuf);
+ return;
+ }
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:", \
+ pBoardInfo->pg_ant_num, pBoardInfo->btdm_ant_num);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d", "BT stack/ hci ext ver", \
+ ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)", "CoexVer/ FwVer/ PatchVer", \
+ GLCoexVerDate8192e1Ant, GLCoexVer8192e1Ant, fwVer, btPatchVer, btPatchVer);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_WIFI_DOT11_CHNL, &wifiDot11Chnl);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifiHsChnl);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)", "Dot11 channel / HsChnl(HsMode)", \
+ wifiDot11Chnl, wifiHsChnl, bBtHsOn);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ", "H2C Wifi inform bt chnl Info", \
+ pCoexDm->wifiChnlInfo[0], pCoexDm->wifiChnlInfo[1],
+ pCoexDm->wifiChnlInfo[2]);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "Wifi rssi/ HS rssi", \
+ wifiRssi, btHsRssi);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ", "Wifi bLink/ bRoam/ bScan", \
+ bLink, bRoam, bScan);
+ CL_PRINTF(cliBuf);
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_UNDER_5G, &bWifiUnder5G);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_BUSY, &bWifiBusy);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION, &wifiTrafficDir);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ", "Wifi status", \
+ (bWifiUnder5G? "5G":"2.4G"),
+ ((BTC_WIFI_BW_LEGACY==wifiBw)? "Legacy": (((BTC_WIFI_BW_HT40==wifiBw)? "HT40":"HT20"))),
+ ((!bWifiBusy)? "idle": ((BTC_WIFI_TRAFFIC_TX==wifiTrafficDir)? "uplink":"downlink")));
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ", "BT [status/ rssi/ retryCnt]", \
+ ((pBtCoexist->btInfo.bBtDisabled)? ("disabled"): ((pCoexSta->bC2hBtInquiryPage)?("inquiry/page scan"):((BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE == pCoexDm->btStatus)? "non-connected idle":
+ ( (BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus)? "connected-idle":"busy")))),
+ pCoexSta->btRssi, pCoexSta->btRetryCnt);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d", "SCO/HID/PAN/A2DP", \
+ pBtLinkInfo->bScoExist, pBtLinkInfo->bHidExist, pBtLinkInfo->bPanExist, pBtLinkInfo->bA2dpExist);
+ CL_PRINTF(cliBuf);
+ pBtCoexist->btc_disp_dbg_msg(pBtCoexist, BTC_DBG_DISP_BT_LINK_INFO);
+
+ btInfoExt = pCoexSta->btInfoExt;
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s", "BT Info A2DP rate", \
+ (btInfoExt&BIT0)? "Basic rate":"EDR rate");
+ CL_PRINTF(cliBuf);
+
+ for(i=0; i<BT_INFO_SRC_8192E_1ANT_MAX; i++)
+ {
+ if(pCoexSta->btInfoC2hCnt[i])
+ {
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x %02x %02x(%d)", GLBtInfoSrc8192e1Ant[i], \
+ pCoexSta->btInfoC2h[i][0], pCoexSta->btInfoC2h[i][1],
+ pCoexSta->btInfoC2h[i][2], pCoexSta->btInfoC2h[i][3],
+ pCoexSta->btInfoC2h[i][4], pCoexSta->btInfoC2h[i][5],
+ pCoexSta->btInfoC2h[i][6], pCoexSta->btInfoC2hCnt[i]);
+ CL_PRINTF(cliBuf);
+ }
+ }
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s, (0x%x/0x%x)", "PS state, IPS/LPS, (lps/rpwm)", \
+ ((pCoexSta->bUnderIps? "IPS ON":"IPS OFF")),
+ ((pCoexSta->bUnderLps? "LPS ON":"LPS OFF")),
+ pBtCoexist->btInfo.lps1Ant,
+ pBtCoexist->btInfo.rpwm_1ant);
+ CL_PRINTF(cliBuf);
+ pBtCoexist->btc_disp_dbg_msg(pBtCoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "SS Type", \
+ pCoexDm->curSsType);
+ CL_PRINTF(cliBuf);
+
+ if(!pBtCoexist->manual_control)
+ {
+ // Sw mechanism
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Sw mechanism]============");
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d/ %d ", "SM1[ShRf/ LpRA/ LimDig/ btLna]", \
+ pCoexDm->bCurRfRxLpfShrink, pCoexDm->bCurLowPenaltyRa, pCoexDm->limited_dig, pCoexDm->bCurBtLnaConstrain);
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ", "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]", \
+ pCoexDm->bCurAgcTableEn, pCoexDm->bCurAdcBackOff, pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/ %s/ %d ", "DelBA/ BtCtrlAgg/ AggSize", \
+ (pBtCoexist->btInfo.reject_agg_pkt? "Yes":"No"), (pBtCoexist->btInfo.b_bt_ctrl_agg_buf_size? "Yes":"No"),
+ pBtCoexist->btInfo.aggBufSize);
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Rate Mask", \
+ pBtCoexist->btInfo.ra_mask);
+ CL_PRINTF(cliBuf);
+
+ // Fw mechanism
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Fw mechanism]============");
+ CL_PRINTF(cliBuf);
+
+ psTdmaCase = pCoexDm->curPsTdma;
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)", "PS TDMA", \
+ pCoexDm->psTdmaPara[0], pCoexDm->psTdmaPara[1],
+ pCoexDm->psTdmaPara[2], pCoexDm->psTdmaPara[3],
+ pCoexDm->psTdmaPara[4], psTdmaCase, pCoexDm->bAutoTdmaAdjust);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Latest error condition(should be 0)", \
+ pCoexDm->errorCondition);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ", "DecBtPwrLvl/ IgnWlanAct", \
+ pCoexDm->curBtDecPwrLvl, pCoexDm->bCurIgnoreWlanAct);
+ CL_PRINTF(cliBuf);
+ }
+
+ // Hw setting
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s", "============[Hw setting]============");
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "RF-A, 0x1e initVal", \
+ pCoexDm->btRf0x1eBackup);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0xc04);
+ u4Tmp[1] = pBtCoexist->btc_read_4byte(pBtCoexist, 0xd04);
+ u4Tmp[2] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x90c);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x", "0xc04/ 0xd04/ 0x90c", \
+ u4Tmp[0], u4Tmp[1], u4Tmp[2]);
+ CL_PRINTF(cliBuf);
+
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x778);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x778", \
+ u1Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x92c);
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x930);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x92c/ 0x930", \
+ (u1Tmp[0]), u4Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x40);
+ u1Tmp[1] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x4f);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x40/ 0x4f", \
+ u1Tmp[0], u1Tmp[1]);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x550);
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x522);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x", "0x550(bcn ctrl)/0x522", \
+ u4Tmp[0], u1Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0xc50);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)", \
+ u4Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ u4Tmp[0] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x6c0);
+ u4Tmp[1] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x6c4);
+ u4Tmp[2] = pBtCoexist->btc_read_4byte(pBtCoexist, 0x6c8);
+ u1Tmp[0] = pBtCoexist->btc_read_1byte(pBtCoexist, 0x6cc);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x", "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)", \
+ u4Tmp[0], u4Tmp[1], u4Tmp[2], u1Tmp[0]);
+ CL_PRINTF(cliBuf);
+
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x770(hp rx[31:16]/tx[15:0])", \
+ pCoexSta->highPriorityRx, pCoexSta->highPriorityTx);
+ CL_PRINTF(cliBuf);
+ CL_SPRINTF(cliBuf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d", "0x774(lp rx[31:16]/tx[15:0])", \
+ pCoexSta->lowPriorityRx, pCoexSta->lowPriorityTx);
+ CL_PRINTF(cliBuf);
+#if(BT_AUTO_REPORT_ONLY_8192E_1ANT == 1)
+ halbtc8192e1ant_MonitorBtCtr(pBtCoexist);
+#endif
+
+ pBtCoexist->btc_disp_dbg_msg(pBtCoexist, BTC_DBG_DISP_COEX_STATISTICS);
+}
+
+
+VOID
+EXhalbtc8192e1ant_IpsNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ u4Byte u4Tmp=0;
+
+ if(pBtCoexist->manual_control || pBtCoexist->bStopCoexDm)
+ return;
+
+ if(BTC_IPS_ENTER == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], IPS ENTER notify\n"));
+ pCoexSta->bUnderIps = true;
+ halbtc8192e1ant_CoexAllOff(pBtCoexist);
+ }
+ else if(BTC_IPS_LEAVE == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], IPS LEAVE notify\n"));
+ pCoexSta->bUnderIps = FALSE;
+ }
+}
+
+VOID
+EXhalbtc8192e1ant_LpsNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ if(pBtCoexist->manual_control || pBtCoexist->bStopCoexDm)
+ return;
+
+ if(BTC_LPS_ENABLE == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], LPS ENABLE notify\n"));
+ pCoexSta->bUnderLps = true;
+ }
+ else if(BTC_LPS_DISABLE == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], LPS DISABLE notify\n"));
+ pCoexSta->bUnderLps = FALSE;
+ }
+}
+
+VOID
+EXhalbtc8192e1ant_ScanNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE;
+
+ if(pBtCoexist->manual_control ||
+ pBtCoexist->bStopCoexDm ||
+ pBtCoexist->btInfo.bBtDisabled )
+ return;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+ if(pCoexSta->bC2hBtInquiryPage)
+ {
+ halbtc8192e1ant_ActionBtInquiry(pBtCoexist);
+ return;
+ }
+ else if(bBtHsOn)
+ {
+ halbtc8192e1ant_ActionHs(pBtCoexist);
+ return;
+ }
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ if(BTC_SCAN_START == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], SCAN START notify\n"));
+ if(!bWifiConnected) // non-connected scan
+ {
+ halbtc8192e1ant_ActionWifiNotConnectedAssoAuthScan(pBtCoexist);
+ }
+ else // wifi is connected
+ {
+ halbtc8192e1ant_ActionWifiConnectedScan(pBtCoexist);
+ }
+ }
+ else if(BTC_SCAN_FINISH == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], SCAN FINISH notify\n"));
+ if(!bWifiConnected) // non-connected scan
+ {
+ halbtc8192e1ant_ActionWifiNotConnected(pBtCoexist);
+ }
+ else
+ {
+ halbtc8192e1ant_ActionWifiConnected(pBtCoexist);
+ }
+ }
+}
+
+VOID
+EXhalbtc8192e1ant_ConnectNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ BOOLEAN bWifiConnected=FALSE, bBtHsOn=FALSE;
+
+ if(pBtCoexist->manual_control ||
+ pBtCoexist->bStopCoexDm ||
+ pBtCoexist->btInfo.bBtDisabled )
+ return;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+ if(pCoexSta->bC2hBtInquiryPage)
+ {
+ halbtc8192e1ant_ActionBtInquiry(pBtCoexist);
+ return;
+ }
+ else if(bBtHsOn)
+ {
+ halbtc8192e1ant_ActionHs(pBtCoexist);
+ return;
+ }
+
+ if(BTC_ASSOCIATE_START == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], CONNECT START notify\n"));
+ halbtc8192e1ant_ActionWifiNotConnectedAssoAuthScan(pBtCoexist);
+ }
+ else if(BTC_ASSOCIATE_FINISH == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], CONNECT FINISH notify\n"));
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ if(!bWifiConnected) // non-connected scan
+ {
+ halbtc8192e1ant_ActionWifiNotConnected(pBtCoexist);
+ }
+ else
+ {
+ halbtc8192e1ant_ActionWifiConnected(pBtCoexist);
+ }
+ }
+}
+
+VOID
+EXhalbtc8192e1ant_MediaStatusNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ u1Byte H2C_Parameter[3] ={0};
+ u4Byte wifiBw;
+ u1Byte wifiCentralChnl;
+
+ if(pBtCoexist->manual_control ||
+ pBtCoexist->bStopCoexDm ||
+ pBtCoexist->btInfo.bBtDisabled )
+ return;
+
+ if(BTC_MEDIA_CONNECT == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], MEDIA connect notify\n"));
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], MEDIA disconnect notify\n"));
+ }
+
+ // only 2.4G we need to inform bt the chnl mask
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl);
+ if( (BTC_MEDIA_CONNECT == type) &&
+ (wifiCentralChnl <= 14) )
+ {
+ H2C_Parameter[0] = 0x1;
+ H2C_Parameter[1] = wifiCentralChnl;
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ H2C_Parameter[2] = 0x30;
+ else
+ H2C_Parameter[2] = 0x20;
+ }
+
+ pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0];
+ pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1];
+ pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2];
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x66=0x%x\n",
+ H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x66, 3, H2C_Parameter);
+}
+
+VOID
+EXhalbtc8192e1ant_SpecialPacketNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ BOOLEAN bBtHsOn=FALSE;
+
+ if(pBtCoexist->manual_control ||
+ pBtCoexist->bStopCoexDm ||
+ pBtCoexist->btInfo.bBtDisabled )
+ return;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+ if(pCoexSta->bC2hBtInquiryPage)
+ {
+ halbtc8192e1ant_ActionBtInquiry(pBtCoexist);
+ return;
+ }
+ else if(bBtHsOn)
+ {
+ halbtc8192e1ant_ActionHs(pBtCoexist);
+ return;
+ }
+
+ if( BTC_PACKET_DHCP == type ||
+ BTC_PACKET_EAPOL == type )
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], special Packet(%d) notify\n", type));
+ halbtc8192e1ant_ActionWifiConnectedSpecialPacket(pBtCoexist);
+ }
+}
+
+VOID
+EXhalbtc8192e1ant_BtInfoNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN pu1Byte tmpBuf,
+ IN u1Byte length
+ )
+{
+ PBTC_BT_LINK_INFO pBtLinkInfo=&pBtCoexist->bt_link_info;
+ u1Byte btInfo=0;
+ u1Byte i, rspSource=0;
+ static u4Byte setBtPsdMode=0;
+ BOOLEAN bBtBusy=FALSE, limited_dig=FALSE;
+ BOOLEAN bWifiConnected=FALSE;
+ BOOLEAN b_bt_ctrl_agg_buf_size=FALSE;
+
+ pCoexSta->bC2hBtInfoReqSent = FALSE;
+
+ rspSource = tmpBuf[0]&0xf;
+ if(rspSource >= BT_INFO_SRC_8192E_1ANT_MAX)
+ rspSource = BT_INFO_SRC_8192E_1ANT_WIFI_FW;
+ pCoexSta->btInfoC2hCnt[rspSource]++;
+
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], Bt info[%d], length=%d, hex data=[", rspSource, length));
+ for(i=0; i<length; i++)
+ {
+ pCoexSta->btInfoC2h[rspSource][i] = tmpBuf[i];
+ if(i == 1)
+ btInfo = tmpBuf[i];
+ if(i == length-1)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("0x%02x]\n", tmpBuf[i]));
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("0x%02x, ", tmpBuf[i]));
+ }
+ }
+
+ if(pBtCoexist->btInfo.bBtDisabled)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), return for BT is disabled <===\n"));
+ return;
+ }
+
+ if(pBtCoexist->manual_control)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), return for Manual CTRL<===\n"));
+ return;
+ }
+ if(pBtCoexist->bStopCoexDm)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), return for Coex STOPPED!!<===\n"));
+ return;
+ }
+
+ if(BT_INFO_SRC_8192E_1ANT_WIFI_FW != rspSource)
+ {
+ pCoexSta->btRetryCnt = // [3:0]
+ pCoexSta->btInfoC2h[rspSource][2]&0xf;
+
+ pCoexSta->btRssi =
+ pCoexSta->btInfoC2h[rspSource][3]*2+10;
+
+ pCoexSta->btInfoExt =
+ pCoexSta->btInfoC2h[rspSource][4];
+
+ // Here we need to resend some wifi info to BT
+ // because bt is reset and loss of the info.
+ if( (pCoexSta->btInfoExt & BIT1) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BT ext info bit1 check, send wifi BW&Chnl to BT!!\n"));
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ if(bWifiConnected)
+ {
+ EXhalbtc8192e1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_CONNECT);
+ }
+ else
+ {
+ EXhalbtc8192e1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT);
+ }
+
+ setBtPsdMode = 0;
+ }
+
+ // test-chip bt patch only rsp the status for BT_RSP,
+ // so temporary we consider the following only under BT_RSP
+ if(BT_INFO_SRC_8192E_1ANT_BT_RSP == rspSource)
+ {
+ if( (pCoexSta->btInfoExt & BIT3) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BT ext info bit3 check, set BT NOT to ignore Wlan active!!\n"));
+ halbtc8192e1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE);
+ }
+ else
+ {
+ // BT already NOT ignore Wlan active, do nothing here.
+ }
+#if(BT_AUTO_REPORT_ONLY_8192E_1ANT == 0)
+ if( (pCoexSta->btInfoExt & BIT4) )
+ {
+ // BT auto report already enabled, do nothing
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BT ext info bit4 check, set BT to enable Auto Report!!\n"));
+ halbtc8192e1ant_BtAutoReport(pBtCoexist, FORCE_EXEC, true);
+ }
+#endif
+ }
+ }
+
+ // check BIT2 first ==> check if bt is under inquiry or page scan
+ if(btInfo & BT_INFO_8192E_1ANT_B_INQ_PAGE)
+ pCoexSta->bC2hBtInquiryPage = true;
+ else
+ pCoexSta->bC2hBtInquiryPage = FALSE;
+
+ // set link exist status
+ if(!(btInfo&BT_INFO_8192E_1ANT_B_CONNECTION))
+ {
+ pCoexSta->bBtLinkExist = FALSE;
+ pCoexSta->bPanExist = FALSE;
+ pCoexSta->bA2dpExist = FALSE;
+ pCoexSta->bHidExist = FALSE;
+ pCoexSta->bScoExist = FALSE;
+ }
+ else // connection exists
+ {
+ pCoexSta->bBtLinkExist = true;
+ if(btInfo & BT_INFO_8192E_1ANT_B_FTP)
+ pCoexSta->bPanExist = true;
+ else
+ pCoexSta->bPanExist = FALSE;
+ if(btInfo & BT_INFO_8192E_1ANT_B_A2DP)
+ pCoexSta->bA2dpExist = true;
+ else
+ pCoexSta->bA2dpExist = FALSE;
+ if(btInfo & BT_INFO_8192E_1ANT_B_HID)
+ pCoexSta->bHidExist = true;
+ else
+ pCoexSta->bHidExist = FALSE;
+ if(btInfo & BT_INFO_8192E_1ANT_B_SCO_ESCO)
+ pCoexSta->bScoExist = true;
+ else
+ pCoexSta->bScoExist = FALSE;
+ }
+
+ halbtc8192e1ant_UpdateBtLinkInfo(pBtCoexist);
+
+ if(!(btInfo&BT_INFO_8192E_1ANT_B_CONNECTION))
+ {
+ pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt non-connected idle!!!\n"));
+ }
+ else if(btInfo == BT_INFO_8192E_1ANT_B_CONNECTION) // connection exists but no busy
+ {
+ pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt connected-idle!!!\n"));
+ }
+ else if((btInfo&BT_INFO_8192E_1ANT_B_SCO_ESCO) ||
+ (btInfo&BT_INFO_8192E_1ANT_B_SCO_BUSY))
+ {
+ pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_SCO_BUSY;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt sco busy!!!\n"));
+ }
+ else if( (btInfo&BT_INFO_8192E_1ANT_B_ACL_BUSY) ||
+ (btInfo&BT_INFO_8192E_1ANT_B_A2DP) ||
+ (btInfo&BT_INFO_8192E_1ANT_B_FTP) )
+ {
+ if(BT_8192E_1ANT_BT_STATUS_ACL_BUSY != pCoexDm->btStatus)
+ pCoexDm->bAutoTdmaAdjust = FALSE;
+ pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_ACL_BUSY;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt acl busy!!!\n"));
+ }
+ else
+ {
+ pCoexDm->btStatus = BT_8192E_1ANT_BT_STATUS_MAX;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], BtInfoNotify(), bt non-defined state!!!\n"));
+ }
+
+ // ra mask check
+ if(pBtLinkInfo->bScoExist || pBtLinkInfo->bHidExist)
+ {
+ halbtc8192e1ant_Updatera_mask(pBtCoexist, NORMAL_EXEC, BTC_RATE_DISABLE, 0x00000003); // disable tx cck 1M/2M
+ }
+ else
+ {
+ halbtc8192e1ant_Updatera_mask(pBtCoexist, NORMAL_EXEC, BTC_RATE_ENABLE, 0x00000003); // enable tx cck 1M/2M
+ }
+
+ if( (BT_8192E_1ANT_BT_STATUS_ACL_BUSY == pCoexDm->btStatus) ||
+ (BT_8192E_1ANT_BT_STATUS_SCO_BUSY == pCoexDm->btStatus) ||
+ (BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY == pCoexDm->btStatus) )
+ {
+ bBtBusy = true;
+ limited_dig = true;
+ if(pBtLinkInfo->bHidExist)
+ b_bt_ctrl_agg_buf_size = true;
+ }
+ else
+ {
+ bBtBusy = FALSE;
+ limited_dig = FALSE;
+ }
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy);
+
+ //============================================
+ // Aggregation related setting
+ //============================================
+ // if sco, reject AddBA
+ //pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT, &bRejApAggPkt);
+
+ // decide BT control aggregation buf size or not
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE, &b_bt_ctrl_agg_buf_size);
+ // real update aggregation setting
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
+ //============================================
+
+ pCoexDm->limited_dig = limited_dig;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
+
+ halbtc8192e1ant_RunCoexistMechanism(pBtCoexist);
+}
+
+VOID
+EXhalbtc8192e1ant_StackOperationNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ if(BTC_STACK_OP_INQ_PAGE_PAIR_START == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], StackOP Inquiry/page/pair start notify\n"));
+ }
+ else if(BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type)
+ {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], StackOP Inquiry/page/pair finish notify\n"));
+ }
+}
+
+VOID
+EXhalbtc8192e1ant_HaltNotify(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], Halt notify\n"));
+
+ pBtCoexist->bStopCoexDm = true;
+ halbtc8192e1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, true);
+
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+
+ halbtc8192e1ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0);
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x4f, 0xf);
+
+ EXhalbtc8192e1ant_MediaStatusNotify(pBtCoexist, BTC_MEDIA_DISCONNECT);
+}
+
+VOID
+EXhalbtc8192e1ant_PnpNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte pnpState
+ )
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, ("[BTCoex], Pnp notify\n"));
+
+ if(BTC_WIFI_PNP_SLEEP == pnpState)
+ {
+ pBtCoexist->bStopCoexDm = true;
+ halbtc8192e1ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, true);
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9);
+ }
+ else if(BTC_WIFI_PNP_WAKE_UP == pnpState)
+ {
+
+ }
+}
+
+VOID
+EXhalbtc8192e1ant_Periodical(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ static u1Byte disVerInfoCnt=0;
+ u4Byte fwVer=0, btPatchVer=0;
+ struct btc_board_info * pBoardInfo=&pBtCoexist->board_info;
+ PBTC_STACK_INFO pStackInfo=&pBtCoexist->stack_info;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], ==========================Periodical===========================\n"));
+
+ if(disVerInfoCnt <= 5)
+ {
+ disVerInfoCnt += 1;
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], ****************************************************************\n"));
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n", \
+ pBoardInfo->pg_ant_num, pBoardInfo->btdm_ant_num, pBoardInfo->btdm_ant_pos));
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], BT stack/ hci ext ver = %s / %d\n", \
+ ((pStackInfo->bProfileNotified)? "Yes":"No"), pStackInfo->hciVersion));
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_BT_PATCH_VER, &btPatchVer);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_FW_VER, &fwVer);
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n", \
+ GLCoexVerDate8192e1Ant, GLCoexVer8192e1Ant, fwVer, btPatchVer, btPatchVer));
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT, ("[BTCoex], ****************************************************************\n"));
+ }
+#if(BT_AUTO_REPORT_ONLY_8192E_1ANT == 0)
+ halbtc8192e1ant_QueryBtInfo(pBtCoexist);
+ halbtc8192e1ant_MonitorBtCtr(pBtCoexist);
+ halbtc8192e1ant_MonitorBtEnableDisable(pBtCoexist);
+#else
+ if( halbtc8192e1ant_IsWifiStatusChanged(pBtCoexist) ||
+ pCoexDm->bAutoTdmaAdjust)
+ {
+ halbtc8192e1ant_RunCoexistMechanism(pBtCoexist);
+ }
+#endif
+}
+
+VOID
+EXhalbtc8192e1ant_DbgControl(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte opCode,
+ IN u1Byte opLen,
+ IN pu1Byte pData
+ )
+{
+ switch(opCode)
+ {
+ case BTC_DBG_SET_COEX_NORMAL:
+ pBtCoexist->manual_control = FALSE;
+ halbtc8192e1ant_InitCoexDm(pBtCoexist);
+ break;
+ case BTC_DBG_SET_COEX_WIFI_ONLY:
+ pBtCoexist->manual_control = true;
+ halbtc8192e1ant_PowerSaveState(pBtCoexist, BTC_PS_WIFI_NATIVE, 0x0, 0x0);
+ halbtc8192e1ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 9);
+ break;
+ case BTC_DBG_SET_COEX_BT_ONLY:
+ // todo
+ break;
+ default:
+ break;
+ }
+}
+#endif
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.h b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.h
new file mode 100644
index 000000000000..a759b758faef
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e1ant.h
@@ -0,0 +1,226 @@
+//===========================================
+// The following is for 8192E_1ANT BT Co-exist definition
+//===========================================
+#define BT_AUTO_REPORT_ONLY_8192E_1ANT 0
+
+#define BT_INFO_8192E_1ANT_B_FTP BIT7
+#define BT_INFO_8192E_1ANT_B_A2DP BIT6
+#define BT_INFO_8192E_1ANT_B_HID BIT5
+#define BT_INFO_8192E_1ANT_B_SCO_BUSY BIT4
+#define BT_INFO_8192E_1ANT_B_ACL_BUSY BIT3
+#define BT_INFO_8192E_1ANT_B_INQ_PAGE BIT2
+#define BT_INFO_8192E_1ANT_B_SCO_ESCO BIT1
+#define BT_INFO_8192E_1ANT_B_CONNECTION BIT0
+
+#define BT_INFO_8192E_1ANT_A2DP_BASIC_RATE(_BT_INFO_EXT_) \
+ (((_BT_INFO_EXT_&BIT0))? true:FALSE)
+
+#define BTC_RSSI_COEX_THRESH_TOL_8192E_1ANT 2
+
+typedef enum _BT_INFO_SRC_8192E_1ANT{
+ BT_INFO_SRC_8192E_1ANT_WIFI_FW = 0x0,
+ BT_INFO_SRC_8192E_1ANT_BT_RSP = 0x1,
+ BT_INFO_SRC_8192E_1ANT_BT_ACTIVE_SEND = 0x2,
+ BT_INFO_SRC_8192E_1ANT_MAX
+}BT_INFO_SRC_8192E_1ANT,*PBT_INFO_SRC_8192E_1ANT;
+
+typedef enum _BT_8192E_1ANT_BT_STATUS{
+ BT_8192E_1ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
+ BT_8192E_1ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
+ BT_8192E_1ANT_BT_STATUS_INQ_PAGE = 0x2,
+ BT_8192E_1ANT_BT_STATUS_ACL_BUSY = 0x3,
+ BT_8192E_1ANT_BT_STATUS_SCO_BUSY = 0x4,
+ BT_8192E_1ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
+ BT_8192E_1ANT_BT_STATUS_MAX
+}BT_8192E_1ANT_BT_STATUS,*PBT_8192E_1ANT_BT_STATUS;
+
+typedef enum _BT_8192E_1ANT_WIFI_STATUS{
+ BT_8192E_1ANT_WIFI_STATUS_NON_CONNECTED_IDLE = 0x0,
+ BT_8192E_1ANT_WIFI_STATUS_NON_CONNECTED_ASSO_AUTH_SCAN = 0x1,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SCAN = 0x2,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_SPECIAL_PKT = 0x3,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_IDLE = 0x4,
+ BT_8192E_1ANT_WIFI_STATUS_CONNECTED_BUSY = 0x5,
+ BT_8192E_1ANT_WIFI_STATUS_MAX
+}BT_8192E_1ANT_WIFI_STATUS,*PBT_8192E_1ANT_WIFI_STATUS;
+
+typedef enum _BT_8192E_1ANT_COEX_ALGO{
+ BT_8192E_1ANT_COEX_ALGO_UNDEFINED = 0x0,
+ BT_8192E_1ANT_COEX_ALGO_SCO = 0x1,
+ BT_8192E_1ANT_COEX_ALGO_HID = 0x2,
+ BT_8192E_1ANT_COEX_ALGO_A2DP = 0x3,
+ BT_8192E_1ANT_COEX_ALGO_A2DP_PANHS = 0x4,
+ BT_8192E_1ANT_COEX_ALGO_PANEDR = 0x5,
+ BT_8192E_1ANT_COEX_ALGO_PANHS = 0x6,
+ BT_8192E_1ANT_COEX_ALGO_PANEDR_A2DP = 0x7,
+ BT_8192E_1ANT_COEX_ALGO_PANEDR_HID = 0x8,
+ BT_8192E_1ANT_COEX_ALGO_HID_A2DP_PANEDR = 0x9,
+ BT_8192E_1ANT_COEX_ALGO_HID_A2DP = 0xa,
+ BT_8192E_1ANT_COEX_ALGO_MAX = 0xb,
+}BT_8192E_1ANT_COEX_ALGO,*PBT_8192E_1ANT_COEX_ALGO;
+
+typedef struct _COEX_DM_8192E_1ANT{
+ // fw mechanism
+ u1Byte preBtDecPwrLvl;
+ u1Byte curBtDecPwrLvl;
+ BOOLEAN bPreBtLnaConstrain;
+ BOOLEAN bCurBtLnaConstrain;
+ u1Byte bPreBtPsdMode;
+ u1Byte bCurBtPsdMode;
+ u1Byte preFwDacSwingLvl;
+ u1Byte curFwDacSwingLvl;
+ BOOLEAN bCurIgnoreWlanAct;
+ BOOLEAN bPreIgnoreWlanAct;
+ u1Byte prePsTdma;
+ u1Byte curPsTdma;
+ u1Byte psTdmaPara[5];
+ u1Byte psTdmaDuAdjType;
+ BOOLEAN bAutoTdmaAdjust;
+ BOOLEAN bPrePsTdmaOn;
+ BOOLEAN bCurPsTdmaOn;
+ BOOLEAN bPreBtAutoReport;
+ BOOLEAN bCurBtAutoReport;
+ u1Byte preLps;
+ u1Byte curLps;
+ u1Byte preRpwm;
+ u1Byte curRpwm;
+
+ // sw mechanism
+ BOOLEAN bPreRfRxLpfShrink;
+ BOOLEAN bCurRfRxLpfShrink;
+ u4Byte btRf0x1eBackup;
+ BOOLEAN bPreLowPenaltyRa;
+ BOOLEAN bCurLowPenaltyRa;
+ BOOLEAN bPreDacSwingOn;
+ u4Byte preDacSwingLvl;
+ BOOLEAN bCurDacSwingOn;
+ u4Byte curDacSwingLvl;
+ BOOLEAN bPreAdcBackOff;
+ BOOLEAN bCurAdcBackOff;
+ BOOLEAN bPreAgcTableEn;
+ BOOLEAN bCurAgcTableEn;
+ u4Byte preVal0x6c0;
+ u4Byte curVal0x6c0;
+ u4Byte preVal0x6c4;
+ u4Byte curVal0x6c4;
+ u4Byte preVal0x6c8;
+ u4Byte curVal0x6c8;
+ u1Byte preVal0x6cc;
+ u1Byte curVal0x6cc;
+ BOOLEAN limited_dig;
+
+ // algorithm related
+ u1Byte preAlgorithm;
+ u1Byte curAlgorithm;
+ u1Byte btStatus;
+ u1Byte wifiChnlInfo[3];
+
+ u1Byte preSsType;
+ u1Byte curSsType;
+
+ u4Byte prera_mask;
+ u4Byte curra_mask;
+
+ u1Byte errorCondition;
+} COEX_DM_8192E_1ANT, *PCOEX_DM_8192E_1ANT;
+
+typedef struct _COEX_STA_8192E_1ANT{
+ BOOLEAN bBtLinkExist;
+ BOOLEAN bScoExist;
+ BOOLEAN bA2dpExist;
+ BOOLEAN bHidExist;
+ BOOLEAN bPanExist;
+
+ BOOLEAN bUnderLps;
+ BOOLEAN bUnderIps;
+ u4Byte highPriorityTx;
+ u4Byte highPriorityRx;
+ u4Byte lowPriorityTx;
+ u4Byte lowPriorityRx;
+ u1Byte btRssi;
+ u1Byte preBtRssiState;
+ u1Byte preWifiRssiState[4];
+ BOOLEAN bC2hBtInfoReqSent;
+ u1Byte btInfoC2h[BT_INFO_SRC_8192E_1ANT_MAX][10];
+ u4Byte btInfoC2hCnt[BT_INFO_SRC_8192E_1ANT_MAX];
+ BOOLEAN bC2hBtInquiryPage;
+ u1Byte btRetryCnt;
+ u1Byte btInfoExt;
+}COEX_STA_8192E_1ANT, *PCOEX_STA_8192E_1ANT;
+
+//===========================================
+// The following is interface which will notify coex module.
+//===========================================
+VOID
+EXhalbtc8192e1ant_InitHwConfig(
+ IN PBTC_COEXIST pBtCoexist
+ );
+VOID
+EXhalbtc8192e1ant_InitCoexDm(
+ IN PBTC_COEXIST pBtCoexist
+ );
+VOID
+EXhalbtc8192e1ant_IpsNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8192e1ant_LpsNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8192e1ant_ScanNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8192e1ant_ConnectNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8192e1ant_MediaStatusNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8192e1ant_SpecialPacketNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8192e1ant_BtInfoNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN pu1Byte tmpBuf,
+ IN u1Byte length
+ );
+VOID
+EXhalbtc8192e1ant_StackOperationNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ );
+VOID
+EXhalbtc8192e1ant_HaltNotify(
+ IN PBTC_COEXIST pBtCoexist
+ );
+VOID
+EXhalbtc8192e1ant_PnpNotify(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte pnpState
+ );
+VOID
+EXhalbtc8192e1ant_Periodical(
+ IN PBTC_COEXIST pBtCoexist
+ );
+VOID
+EXhalbtc8192e1ant_DisplayCoexInfo(
+ IN PBTC_COEXIST pBtCoexist
+ );
+VOID
+EXhalbtc8192e1ant_DbgControl(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte opCode,
+ IN u1Byte opLen,
+ IN pu1Byte pData
+ );
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.c b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.c
new file mode 100644
index 000000000000..44ec78562e2d
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.c
@@ -0,0 +1,4242 @@
+/**************************************************************
+ * Description:
+ *
+ * This file is for RTL8192E Co-exist mechanism
+ *
+ * History
+ * 2012/11/15 Cosa first check in.
+ *
+ **************************************************************/
+
+/**************************************************************
+ * include files
+ **************************************************************/
+#include "halbt_precomp.h"
+#if 1
+/**************************************************************
+ * Global variables, these are static variables
+ **************************************************************/
+static struct coex_dm_8192e_2ant glcoex_dm_8192e_2ant;
+static struct coex_dm_8192e_2ant *coex_dm = &glcoex_dm_8192e_2ant;
+static struct coex_sta_8192e_2ant glcoex_sta_8192e_2ant;
+static struct coex_sta_8192e_2ant *coex_sta = &glcoex_sta_8192e_2ant;
+
+const char *const GLBtInfoSrc8192e2Ant[]={
+ "BT Info[wifi fw]",
+ "BT Info[bt rsp]",
+ "BT Info[bt auto report]",
+};
+
+u32 glcoex_ver_date_8192e_2ant = 20130902;
+u32 glcoex_ver_8192e_2ant = 0x34;
+
+/**************************************************************
+ * local function proto type if needed
+ **************************************************************/
+/**************************************************************
+ * local function start with halbtc8192e2ant_
+ **************************************************************/
+u8 halbtc8192e2ant_btrssi_state(u8 level_num, u8 rssi_thresh, u8 rssi_thresh1)
+{
+ int btrssi=0;
+ u8 btrssi_state = coex_sta->pre_bt_rssi_state;
+
+ btrssi = coex_sta->bt_rssi;
+
+ if (level_num == 2) {
+ if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi pre state=LOW\n");
+ if (btrssi >= (rssi_thresh +
+ BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
+ btrssi_state = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state switch to High\n");
+ } else {
+ btrssi_state = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state stay at Low\n");
+ }
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi pre state=HIGH\n");
+ if (btrssi < rssi_thresh) {
+ btrssi_state = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state switch to Low\n");
+ } else {
+ btrssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state stay at High\n");
+ }
+ }
+ } else if (level_num == 3) {
+ if (rssi_thresh > rssi_thresh1) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi thresh error!!\n");
+ return coex_sta->pre_bt_rssi_state;
+ }
+
+ if ((coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_bt_rssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi pre state=LOW\n");
+ if(btrssi >= (rssi_thresh +
+ BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
+ btrssi_state = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state switch to Medium\n");
+ } else {
+ btrssi_state = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state stay at Low\n");
+ }
+ } else if ((coex_sta->pre_bt_rssi_state ==
+ BTC_RSSI_STATE_MEDIUM) ||
+ (coex_sta->pre_bt_rssi_state ==
+ BTC_RSSI_STATE_STAY_MEDIUM)) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "[BTCoex], BT Rssi pre state=MEDIUM\n");
+ if (btrssi >= (rssi_thresh1 +
+ BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
+ btrssi_state = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state switch to High\n");
+ } else if (btrssi < rssi_thresh) {
+ btrssi_state = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state switch to Low\n");
+ } else {
+ btrssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state stay at Medium\n");
+ }
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi pre state=HIGH\n");
+ if (btrssi < rssi_thresh1) {
+ btrssi_state = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state switch to Medium\n");
+ } else {
+ btrssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE,
+ "BT Rssi state stay at High\n");
+ }
+ }
+ }
+
+ coex_sta->pre_bt_rssi_state = btrssi_state;
+
+ return btrssi_state;
+}
+
+u8 halbtc8192e2ant_wifirssi_state(struct btc_coexist * btcoexist, u8 index,
+ u8 level_num, u8 rssi_thresh, u8 rssi_thresh1)
+{
+ int wifirssi = 0;
+ u8 wifirssi_state = coex_sta->pre_wifi_rssi_state[index];
+
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifirssi);
+
+ if (level_num == 2) {
+ if ((coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_STAY_LOW)) {
+ if (wifirssi >= (rssi_thresh +
+ BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
+ wifirssi_state = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state switch to High\n");
+ } else {
+ wifirssi_state = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state stay at Low\n");
+ }
+ } else {
+ if (wifirssi < rssi_thresh) {
+ wifirssi_state = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state switch to Low\n");
+ } else {
+ wifirssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state stay at High\n");
+ }
+ }
+ } else if (level_num == 3) {
+ if (rssi_thresh > rssi_thresh1) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI thresh error!!\n");
+ return coex_sta->pre_wifi_rssi_state[index];
+ }
+
+ if ((coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_LOW) ||
+ (coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_STAY_LOW)) {
+ if (wifirssi >= (rssi_thresh +
+ BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
+ wifirssi_state = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state switch to Medium\n");
+ } else {
+ wifirssi_state = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state stay at Low\n");
+ }
+ } else if ((coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_MEDIUM) ||
+ (coex_sta->pre_wifi_rssi_state[index] ==
+ BTC_RSSI_STATE_STAY_MEDIUM)) {
+ if (wifirssi >= (rssi_thresh1 +
+ BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT)) {
+ wifirssi_state = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state switch to High\n");
+ } else if (wifirssi < rssi_thresh) {
+ wifirssi_state = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state switch to Low\n");
+ } else {
+ wifirssi_state = BTC_RSSI_STATE_STAY_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state stay at Medium\n");
+ }
+ } else {
+ if (wifirssi < rssi_thresh1) {
+ wifirssi_state = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state switch to Medium\n");
+ } else {
+ wifirssi_state = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_WIFI_RSSI_STATE,
+ "wifi RSSI state stay at High\n");
+ }
+ }
+ }
+
+ coex_sta->pre_wifi_rssi_state[index] = wifirssi_state;
+
+ return wifirssi_state;
+}
+
+void halbtc8192e2ant_monitor_bt_enable_disable(struct btc_coexist *btcoexist)
+{
+ static bool pre_bt_disabled = false;
+ static u32 bt_disable_cnt = 0;
+ bool bt_active = true, bt_disabled = false;
+
+ /* This function check if bt is disabled */
+
+ if (coex_sta->high_priority_tx == 0 &&
+ coex_sta->high_priority_rx == 0 &&
+ coex_sta->low_priority_tx == 0 &&
+ coex_sta->low_priority_rx == 0)
+ bt_active = false;
+
+ if (coex_sta->high_priority_tx == 0xffff &&
+ coex_sta->high_priority_rx == 0xffff &&
+ coex_sta->low_priority_tx == 0xffff &&
+ coex_sta->low_priority_rx == 0xffff)
+ bt_active = false;
+
+ if (bt_active) {
+ bt_disable_cnt = 0;
+ bt_disabled = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
+ &bt_disabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
+ "[BTCoex], BT is enabled !!\n");
+ } else {
+ bt_disable_cnt++;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
+ "[BTCoex], bt all counters=0, %d times!!\n",
+ bt_disable_cnt);
+ if (bt_disable_cnt >= 2) {
+ bt_disabled = true;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_DISABLE,
+ &bt_disabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
+ "[BTCoex], BT is disabled !!\n");
+ }
+ }
+ if (pre_bt_disabled != bt_disabled) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
+ "[BTCoex], BT is from %s to %s!!\n",
+ (pre_bt_disabled ? "disabled":"enabled"),
+ (bt_disabled ? "disabled":"enabled"));
+ pre_bt_disabled = bt_disabled;
+ }
+}
+
+u32 halbtc8192e2ant_decidera_mask(struct btc_coexist *btcoexist,
+ u8 sstype, u32 ra_masktype)
+{
+ u32 disra_mask = 0x0;
+
+ switch (ra_masktype) {
+ case 0: /* normal mode */
+ if (sstype == 2)
+ disra_mask = 0x0; /* enable 2ss */
+ else
+ disra_mask = 0xfff00000;/* disable 2ss */
+ break;
+ case 1: /* disable cck 1/2 */
+ if(sstype == 2)
+ disra_mask = 0x00000003;/* enable 2ss */
+ else
+ disra_mask = 0xfff00003;/* disable 2ss */
+ break;
+ case 2: /* disable cck 1/2/5.5, ofdm 6/9/12/18/24, mcs 0/1/2/3/4 */
+ if(sstype == 2)
+ disra_mask = 0x0001f1f7;/* enable 2ss */
+ else
+ disra_mask = 0xfff1f1f7;/* disable 2ss */
+ break;
+ default:
+ break;
+ }
+
+ return disra_mask;
+}
+
+void halbtc8192e2ant_Updatera_mask(struct btc_coexist *btcoexist,
+ bool force_exec, u32 dis_ratemask)
+{
+ coex_dm->curra_mask = dis_ratemask;
+
+ if (force_exec || (coex_dm->prera_mask != coex_dm->curra_mask))
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_UPDATE_ra_mask,
+ &coex_dm->curra_mask);
+ coex_dm->prera_mask = coex_dm->curra_mask;
+}
+
+void halbtc8192e2ant_autorate_fallback_retry(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
+{
+ bool wifi_under_bmode = false;
+
+ coex_dm->cur_arfrtype = type;
+
+ if (force_exec || (coex_dm->pre_arfrtype != coex_dm->cur_arfrtype)) {
+ switch (coex_dm->cur_arfrtype) {
+ case 0: /* normal mode */
+ btcoexist->btc_write_4byte(btcoexist, 0x430,
+ coex_dm->backup_arfr_cnt1);
+ btcoexist->btc_write_4byte(btcoexist, 0x434,
+ coex_dm->backup_arfr_cnt2);
+ break;
+ case 1:
+ btcoexist->btc_get(btcoexist,
+ BTC_GET_BL_WIFI_UNDER_B_MODE,
+ &wifi_under_bmode);
+ if (wifi_under_bmode) {
+ btcoexist->btc_write_4byte(btcoexist, 0x430,
+ 0x0);
+ btcoexist->btc_write_4byte(btcoexist, 0x434,
+ 0x01010101);
+ } else {
+ btcoexist->btc_write_4byte(btcoexist, 0x430,
+ 0x0);
+ btcoexist->btc_write_4byte(btcoexist, 0x434,
+ 0x04030201);
+ }
+ break;
+ default:
+ break;
+ }
+ }
+
+ coex_dm->pre_arfrtype = coex_dm->cur_arfrtype;
+}
+
+void halbtc8192e2ant_retrylimit(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
+{
+ coex_dm->cur_retrylimit_type = type;
+
+ if (force_exec || (coex_dm->pre_retrylimit_type !=
+ coex_dm->cur_retrylimit_type)) {
+ switch (coex_dm->cur_retrylimit_type) {
+ case 0: /* normal mode */
+ btcoexist->btc_write_2byte(btcoexist, 0x42a,
+ coex_dm->backup_retrylimit);
+ break;
+ case 1: /* retry limit=8 */
+ btcoexist->btc_write_2byte(btcoexist, 0x42a,
+ 0x0808);
+ break;
+ default:
+ break;
+ }
+ }
+
+ coex_dm->pre_retrylimit_type = coex_dm->cur_retrylimit_type;
+}
+
+void halbtc8192e2ant_ampdu_maxtime(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
+{
+ coex_dm->cur_ampdutime_type = type;
+
+ if (force_exec || (coex_dm->pre_ampdutime_type !=
+ coex_dm->cur_ampdutime_type)) {
+ switch (coex_dm->cur_ampdutime_type) {
+ case 0: /* normal mode */
+ btcoexist->btc_write_1byte(btcoexist, 0x456,
+ coex_dm->backup_ampdu_maxtime);
+ break;
+ case 1: /* AMPDU timw = 0x38 * 32us */
+ btcoexist->btc_write_1byte(btcoexist, 0x456, 0x38);
+ break;
+ default:
+ break;
+ }
+ }
+
+ coex_dm->pre_ampdutime_type = coex_dm->cur_ampdutime_type;
+}
+
+void halbtc8192e2ant_limited_tx(struct btc_coexist *btcoexist,
+ bool force_exec, u8 ra_masktype, u8 arfr_type,
+ u8 retrylimit_type, u8 ampdutime_type)
+{
+ u32 disra_mask = 0x0;
+
+ coex_dm->curra_masktype = ra_masktype;
+ disra_mask = halbtc8192e2ant_decidera_mask(btcoexist,
+ coex_dm->cur_sstype,
+ ra_masktype);
+ halbtc8192e2ant_Updatera_mask(btcoexist, force_exec, disra_mask);
+
+ halbtc8192e2ant_autorate_fallback_retry(btcoexist, force_exec,
+ arfr_type);
+ halbtc8192e2ant_retrylimit(btcoexist, force_exec, retrylimit_type);
+ halbtc8192e2ant_ampdu_maxtime(btcoexist, force_exec, ampdutime_type);
+}
+
+void halbtc8192e2ant_limited_rx(struct btc_coexist *btcoexist,
+ bool force_exec, bool rej_ap_agg_pkt,
+ bool b_bt_ctrl_agg_buf_size,
+ u8 agg_buf_size)
+{
+ bool reject_rx_agg = rej_ap_agg_pkt;
+ bool bt_ctrl_rx_agg_size = b_bt_ctrl_agg_buf_size;
+ u8 rx_agg_size = agg_buf_size;
+
+ /*********************************************
+ * Rx Aggregation related setting
+ *********************************************/
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_TO_REJ_AP_AGG_PKT,
+ &reject_rx_agg);
+ /* decide BT control aggregation buf size or not */
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_CTRL_AGG_SIZE,
+ &bt_ctrl_rx_agg_size);
+ /* aggregation buf size, only work
+ * when BT control Rx aggregation size. */
+ btcoexist->btc_set(btcoexist, BTC_SET_U1_AGG_BUF_SIZE, &rx_agg_size);
+ /* real update aggregation setting */
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_AGGREGATE_CTRL, NULL);
+
+
+}
+
+void halbtc8192e2ant_monitor_bt_ctr(struct btc_coexist *btcoexist)
+{
+ u32 reg_hp_txrx, reg_lp_txrx, u32tmp;
+ u32 reg_hp_tx = 0, reg_hp_rx = 0, reg_lp_tx = 0, reg_lp_rx = 0;
+
+ reg_hp_txrx = 0x770;
+ reg_lp_txrx = 0x774;
+
+ u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_hp_txrx);
+ reg_hp_tx = u32tmp & MASKLWORD;
+ reg_hp_rx = (u32tmp & MASKHWORD)>>16;
+
+ u32tmp = btcoexist->btc_read_4byte(btcoexist, reg_lp_txrx);
+ reg_lp_tx = u32tmp & MASKLWORD;
+ reg_lp_rx = (u32tmp & MASKHWORD)>>16;
+
+ coex_sta->high_priority_tx = reg_hp_tx;
+ coex_sta->high_priority_rx = reg_hp_rx;
+ coex_sta->low_priority_tx = reg_lp_tx;
+ coex_sta->low_priority_rx = reg_lp_rx;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
+ "[BTCoex] High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
+ reg_hp_txrx, reg_hp_tx, reg_hp_tx, reg_hp_rx, reg_hp_rx);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR,
+ "[BTCoex] Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
+ reg_lp_txrx, reg_lp_tx, reg_lp_tx, reg_lp_rx, reg_lp_rx);
+
+ /* reset counter */
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0xc);
+}
+
+void halbtc8192e2ant_querybt_info(struct btc_coexist *btcoexist)
+{
+ u8 h2c_parameter[1] ={0};
+
+ coex_sta->c2h_bt_info_req_sent = true;
+
+ h2c_parameter[0] |= BIT0; /* trigger */
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+ "[BTCoex], Query Bt Info, FW write 0x61=0x%x\n",
+ h2c_parameter[0]);
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x61, 1, h2c_parameter);
+}
+
+bool halbtc8192e2ant_iswifi_status_changed(struct btc_coexist *btcoexist)
+{
+ static bool pre_wifi_busy = false;
+ static bool pre_under_4way = false, pre_bt_hson = false;
+ bool wifi_busy = false, under_4way = false, bt_hson = false;
+ bool wifi_connected = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_4_WAY_PROGRESS,
+ &under_4way);
+
+ if (wifi_connected) {
+ if (wifi_busy != pre_wifi_busy) {
+ pre_wifi_busy = wifi_busy;
+ return true;
+ }
+ if (under_4way != pre_under_4way) {
+ pre_under_4way = under_4way;
+ return true;
+ }
+ if (bt_hson != pre_bt_hson) {
+ pre_bt_hson = bt_hson;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+void halbtc8192e2ant_update_btlink_info(struct btc_coexist *btcoexist)
+{
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool bt_hson = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
+
+ bt_link_info->bt_link_exist = coex_sta->bt_link_exist;
+ bt_link_info->sco_exist = coex_sta->sco_exist;
+ bt_link_info->a2dp_exist = coex_sta->a2dp_exist;
+ bt_link_info->pan_exist = coex_sta->pan_exist;
+ bt_link_info->hid_exist = coex_sta->hid_exist;
+
+ /* work around for HS mode. */
+ if (bt_hson) {
+ bt_link_info->pan_exist = true;
+ bt_link_info->bt_link_exist = true;
+ }
+
+ /* check if Sco only */
+ if (bt_link_info->sco_exist &&
+ !bt_link_info->a2dp_exist &&
+ !bt_link_info->pan_exist &&
+ !bt_link_info->hid_exist)
+ bt_link_info->sco_only = true;
+ else
+ bt_link_info->sco_only = false;
+
+ /* check if A2dp only */
+ if (!bt_link_info->sco_exist &&
+ bt_link_info->a2dp_exist &&
+ !bt_link_info->pan_exist &&
+ !bt_link_info->hid_exist)
+ bt_link_info->a2dp_only = true;
+ else
+ bt_link_info->a2dp_only = false;
+
+ /* check if Pan only */
+ if (!bt_link_info->sco_exist &&
+ !bt_link_info->a2dp_exist &&
+ bt_link_info->pan_exist &&
+ !bt_link_info->hid_exist)
+ bt_link_info->pan_only = true;
+ else
+ bt_link_info->pan_only = false;
+
+ /* check if Hid only */
+ if (!bt_link_info->sco_exist &&
+ !bt_link_info->a2dp_exist &&
+ !bt_link_info->pan_exist &&
+ bt_link_info->hid_exist)
+ bt_link_info->hid_only = true;
+ else
+ bt_link_info->hid_only = false;
+}
+
+u8 halbtc8192e2ant_action_algorithm(struct btc_coexist *btcoexist)
+{
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ struct btc_stack_info *stack_info = &btcoexist->stack_info;
+ bool bt_hson=false;
+ u8 algorithm = BT_8192E_2ANT_COEX_ALGO_UNDEFINED;
+ u8 numOfDiffProfile = 0;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
+
+ if (!bt_link_info->bt_link_exist) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "No BT link exists!!!\n");
+ return algorithm;
+ }
+
+ if (bt_link_info->sco_exist)
+ numOfDiffProfile++;
+ if (bt_link_info->hid_exist)
+ numOfDiffProfile++;
+ if (bt_link_info->pan_exist)
+ numOfDiffProfile++;
+ if (bt_link_info->a2dp_exist)
+ numOfDiffProfile++;
+
+ if (numOfDiffProfile == 1) {
+ if (bt_link_info->sco_exist) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO only\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
+ } else {
+ if (bt_link_info->hid_exist) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "HID only\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_HID;
+ } else if (bt_link_info->a2dp_exist) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "A2DP only\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_A2DP;
+ } else if (bt_link_info->pan_exist) {
+ if (bt_hson) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "PAN(HS) only\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_PANHS;
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "PAN(EDR) only\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_PANEDR;
+ }
+ }
+ }
+ } else if (numOfDiffProfile == 2) {
+ if (bt_link_info->sco_exist) {
+ if (bt_link_info->hid_exist) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO + HID\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
+ } else if (bt_link_info->a2dp_exist) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO + A2DP ==> SCO\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
+ } else if (bt_link_info->pan_exist) {
+ if (bt_hson) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO + PAN(HS)\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO + PAN(EDR)\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_SCO_PAN;
+ }
+ }
+ } else {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->a2dp_exist) {
+ if (stack_info->num_of_hid >= 2) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "HID*2 + A2DP\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "HID + A2DP\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_HID_A2DP;
+ }
+ } else if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist) {
+ if (bt_hson) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "HID + PAN(HS)\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_HID;
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "HID + PAN(EDR)\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ } else if (bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hson) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "A2DP + PAN(HS)\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS;
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "A2DP + PAN(EDR)\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP;
+ }
+ }
+ }
+ } else if (numOfDiffProfile == 3) {
+ if (bt_link_info->sco_exist) {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->a2dp_exist) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO + HID + A2DP ==> HID\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
+ } else if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist) {
+ if (bt_hson) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO + HID + PAN(HS)\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO + HID + PAN(EDR)\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_SCO_PAN;
+ }
+ } else if (bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hson) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO + A2DP + PAN(HS)\n");
+ algorithm = BT_8192E_2ANT_COEX_ALGO_SCO;
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO + A2DP + PAN(EDR)\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ } else {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hson) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "HID + A2DP + PAN(HS)\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_HID_A2DP;
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "HID + A2DP + PAN(EDR)\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ }
+ }
+ }
+ } else if (numOfDiffProfile >= 3) {
+ if (bt_link_info->sco_exist) {
+ if (bt_link_info->hid_exist &&
+ bt_link_info->pan_exist &&
+ bt_link_info->a2dp_exist) {
+ if (bt_hson) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "ErrorSCO+HID+A2DP+PAN(HS)\n");
+
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "SCO+HID+A2DP+PAN(EDR)\n");
+ algorithm =
+ BT_8192E_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ }
+
+ return algorithm;
+}
+
+void halbtc8192e2ant_setfw_dac_swinglevel(struct btc_coexist *btcoexist,
+ u8 dac_swinglvl)
+{
+ u8 h2c_parameter[1] ={0};
+
+ /* There are several type of dacswing
+ * 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6 */
+ h2c_parameter[0] = dac_swinglvl;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+ "[BTCoex], Set Dac Swing Level=0x%x\n", dac_swinglvl);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+ "[BTCoex], FW write 0x64=0x%x\n", h2c_parameter[0]);
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x64, 1, h2c_parameter);
+}
+
+void halbtc8192e2ant_set_fwdec_btpwr(struct btc_coexist *btcoexist,
+ u8 dec_btpwr_lvl)
+{
+ u8 h2c_parameter[1] ={0};
+
+ h2c_parameter[0] = dec_btpwr_lvl;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+ "[BTCoex] decrease Bt Power level = %d, FW write 0x62=0x%x\n",
+ dec_btpwr_lvl, h2c_parameter[0]);
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x62, 1, h2c_parameter);
+}
+
+void halbtc8192e2ant_dec_btpwr(struct btc_coexist *btcoexist,
+ bool force_exec, u8 dec_btpwr_lvl)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
+ "[BTCoex], %s Dec BT power level = %d\n",
+ (force_exec? "force to":""), dec_btpwr_lvl);
+ coex_dm->cur_dec_bt_pwr = dec_btpwr_lvl;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], preBtDecPwrLvl=%d, curBtDecPwrLvl=%d\n",
+ coex_dm->pre_dec_bt_pwr, coex_dm->cur_dec_bt_pwr);
+ }
+ halbtc8192e2ant_set_fwdec_btpwr(btcoexist, coex_dm->cur_dec_bt_pwr);
+
+ coex_dm->pre_dec_bt_pwr = coex_dm->cur_dec_bt_pwr;
+}
+
+void halbtc8192e2ant_set_bt_autoreport(struct btc_coexist *btcoexist,
+ bool enable_autoreport)
+{
+ u8 h2c_parameter[1] ={0};
+
+ h2c_parameter[0] = 0;
+
+ if (enable_autoreport)
+ h2c_parameter[0] |= BIT0;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+ "[BTCoex], BT FW auto report : %s, FW write 0x68=0x%x\n",
+ (enable_autoreport? "Enabled!!":"Disabled!!"),
+ h2c_parameter[0]);
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x68, 1, h2c_parameter);
+}
+
+void halbtc8192e2ant_bt_autoreport(struct btc_coexist *btcoexist,
+ bool force_exec, bool enable_autoreport)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
+ "[BTCoex], %s BT Auto report = %s\n",
+ (force_exec? "force to":""),
+ ((enable_autoreport)? "Enabled":"Disabled"));
+ coex_dm->cur_bt_auto_report = enable_autoreport;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex] bPreBtAutoReport=%d, bCurBtAutoReport=%d\n",
+ coex_dm->pre_bt_auto_report,
+ coex_dm->cur_bt_auto_report);
+
+ if (coex_dm->pre_bt_auto_report == coex_dm->cur_bt_auto_report)
+ return;
+ }
+ halbtc8192e2ant_set_bt_autoreport(btcoexist,
+ coex_dm->cur_bt_auto_report);
+
+ coex_dm->pre_bt_auto_report = coex_dm->cur_bt_auto_report;
+}
+
+void halbtc8192e2ant_fw_dac_swinglvl(struct btc_coexist *btcoexist,
+ bool force_exec, u8 fw_dac_swinglvl)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
+ "[BTCoex], %s set FW Dac Swing level = %d\n",
+ (force_exec? "force to":""), fw_dac_swinglvl);
+ coex_dm->cur_fw_dac_swing_lvl = fw_dac_swinglvl;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex] preFwDacSwingLvl=%d, curFwDacSwingLvl=%d\n",
+ coex_dm->pre_fw_dac_swing_lvl,
+ coex_dm->cur_fw_dac_swing_lvl);
+
+ if (coex_dm->pre_fw_dac_swing_lvl ==
+ coex_dm->cur_fw_dac_swing_lvl)
+ return;
+ }
+
+ halbtc8192e2ant_setfw_dac_swinglevel(btcoexist,
+ coex_dm->cur_fw_dac_swing_lvl);
+
+ coex_dm->pre_fw_dac_swing_lvl = coex_dm->cur_fw_dac_swing_lvl;
+}
+
+void halbtc8192e2ant_set_sw_rf_rx_lpf_corner(struct btc_coexist *btcoexist,
+ bool rx_rf_shrink_on)
+{
+ if (rx_rf_shrink_on) {
+ /* Shrink RF Rx LPF corner */
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], Shrink RF Rx LPF corner!!\n");
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e,
+ 0xfffff, 0xffffc);
+ } else {
+ /* Resume RF Rx LPF corner
+ * After initialized, we can use coex_dm->btRf0x1eBackup */
+ if (btcoexist->initilized) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], Resume RF Rx LPF corner!!\n");
+ btcoexist->btc_set_rf_reg(btcoexist, BTC_RF_A, 0x1e,
+ 0xfffff,
+ coex_dm->bt_rf0x1e_backup);
+ }
+ }
+}
+
+void halbtc8192e2ant_rf_shrink(struct btc_coexist *btcoexist,
+ bool force_exec, bool rx_rf_shrink_on)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
+ "[BTCoex], %s turn Rx RF Shrink = %s\n",
+ (force_exec? "force to":""), ((rx_rf_shrink_on)? "ON":"OFF"));
+ coex_dm->cur_rf_rx_lpf_shrink = rx_rf_shrink_on;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "[BTCoex]bPreRfRxLpfShrink=%d,bCurRfRxLpfShrink=%d\n",
+ coex_dm->pre_rf_rx_lpf_shrink,
+ coex_dm->cur_rf_rx_lpf_shrink);
+
+ if (coex_dm->pre_rf_rx_lpf_shrink ==
+ coex_dm->cur_rf_rx_lpf_shrink)
+ return;
+ }
+ halbtc8192e2ant_set_sw_rf_rx_lpf_corner(btcoexist,
+ coex_dm->cur_rf_rx_lpf_shrink);
+
+ coex_dm->pre_rf_rx_lpf_shrink = coex_dm->cur_rf_rx_lpf_shrink;
+}
+
+void halbtc8192e2ant_set_sw_penalty_tx_rateadaptive(
+ struct btc_coexist *btcoexist,
+ bool low_penalty_ra)
+{
+ u8 h2c_parameter[6] ={0};
+
+ h2c_parameter[0] = 0x6; /* opCode, 0x6= Retry_Penalty */
+
+ if (low_penalty_ra) {
+ h2c_parameter[1] |= BIT0;
+ /* normal rate except MCS7/6/5, OFDM54/48/36 */
+ h2c_parameter[2] = 0x00;
+ h2c_parameter[3] = 0xf7; /* MCS7 or OFDM54 */
+ h2c_parameter[4] = 0xf8; /* MCS6 or OFDM48 */
+ h2c_parameter[5] = 0xf9; /* MCS5 or OFDM36 */
+ }
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+ "[BTCoex], set WiFi Low-Penalty Retry: %s",
+ (low_penalty_ra? "ON!!":"OFF!!"));
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x69, 6, h2c_parameter);
+}
+
+void halbtc8192e2ant_low_penalty_ra(struct btc_coexist *btcoexist,
+ bool force_exec, bool low_penalty_ra)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
+ "[BTCoex], %s turn LowPenaltyRA = %s\n",
+ (force_exec? "force to":""), ((low_penalty_ra)? "ON":"OFF"));
+ coex_dm->cur_low_penalty_ra = low_penalty_ra;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "[BTCoex] bPreLowPenaltyRa=%d, bCurLowPenaltyRa=%d\n",
+ coex_dm->pre_low_penalty_ra,
+ coex_dm->cur_low_penalty_ra);
+
+ if (coex_dm->pre_low_penalty_ra ==
+ coex_dm->cur_low_penalty_ra)
+ return;
+ }
+ halbtc8192e2ant_set_sw_penalty_tx_rateadaptive(btcoexist,
+ coex_dm->cur_low_penalty_ra);
+
+ coex_dm->pre_low_penalty_ra = coex_dm->cur_low_penalty_ra;
+}
+
+void halbtc8192e2ant_set_dac_swingreg(struct btc_coexist *btcoexist,
+ u32 level)
+{
+ u8 val = (u8)level;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], Write SwDacSwing = 0x%x\n", level);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0x883, 0x3e, val);
+}
+
+void halbtc8192e2ant_setsw_fulltime_dacswing(struct btc_coexist *btcoexist,
+ bool sw_dac_swingon,
+ u32 sw_dac_swinglvl)
+{
+ if (sw_dac_swingon)
+ halbtc8192e2ant_set_dac_swingreg(btcoexist, sw_dac_swinglvl);
+ else
+ halbtc8192e2ant_set_dac_swingreg(btcoexist, 0x18);
+}
+
+
+void halbtc8192e2ant_DacSwing(struct btc_coexist *btcoexist,
+ bool force_exec, bool dac_swingon,
+ u32 dac_swinglvl)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
+ "[BTCoex], %s turn DacSwing=%s, dac_swinglvl=0x%x\n",
+ (force_exec? "force to":""),
+ ((dac_swingon)? "ON":"OFF"), dac_swinglvl);
+ coex_dm->cur_dac_swing_on = dac_swingon;
+ coex_dm->cur_dac_swing_lvl = dac_swinglvl;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl=0x%x, ",
+ coex_dm->pre_dac_swing_on,
+ coex_dm->pre_dac_swing_lvl);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "bCurDacSwingOn=%d, curDacSwingLvl=0x%x\n",
+ coex_dm->cur_dac_swing_on,
+ coex_dm->cur_dac_swing_lvl);
+
+ if ((coex_dm->pre_dac_swing_on == coex_dm->cur_dac_swing_on) &&
+ (coex_dm->pre_dac_swing_lvl == coex_dm->cur_dac_swing_lvl))
+ return;
+ }
+ mdelay(30);
+ halbtc8192e2ant_setsw_fulltime_dacswing(btcoexist, dac_swingon,
+ dac_swinglvl);
+
+ coex_dm->pre_dac_swing_on = coex_dm->cur_dac_swing_on;
+ coex_dm->pre_dac_swing_lvl = coex_dm->cur_dac_swing_lvl;
+}
+
+void halbtc8192e2ant_set_adc_backoff(struct btc_coexist *btcoexist,
+ bool adc_backoff)
+{
+ if(adc_backoff)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], BB BackOff Level On!\n");
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xc05, 0x30, 0x3);
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], BB BackOff Level Off!\n");
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xc05, 0x30, 0x1);
+ }
+}
+
+void halbtc8192e2ant_adc_backoff(struct btc_coexist *btcoexist,
+ bool force_exec, bool adc_backoff)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
+ "[BTCoex], %s turn AdcBackOff = %s\n",
+ (force_exec? "force to":""), ((adc_backoff)? "ON":"OFF"));
+ coex_dm->cur_adc_back_off = adc_backoff;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "[BTCoex], bPreAdcBackOff=%d, bCurAdcBackOff=%d\n",
+ coex_dm->pre_adc_back_off, coex_dm->cur_adc_back_off);
+
+ if (coex_dm->pre_adc_back_off == coex_dm->cur_adc_back_off)
+ return;
+ }
+ halbtc8192e2ant_set_adc_backoff(btcoexist, coex_dm->cur_adc_back_off);
+
+ coex_dm->pre_adc_back_off = coex_dm->cur_adc_back_off;
+}
+
+void halbtc8192e2ant_set_agc_table(struct btc_coexist *btcoexist,
+ bool agc_table_en)
+{
+
+ /* BB AGC Gain Table */
+ if (agc_table_en) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], BB Agc Table On!\n");
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x0a1A0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x091B0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x081C0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x071D0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x061E0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0x051F0001);
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], BB Agc Table Off!\n");
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xaa1A0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa91B0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa81C0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa71D0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa61E0001);
+ btcoexist->btc_write_4byte(btcoexist, 0xc78, 0xa51F0001);
+ }
+}
+
+void halbtc8192e2ant_AgcTable(struct btc_coexist *btcoexist,
+ bool force_exec, bool agc_table_en)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
+ "[BTCoex], %s %s Agc Table\n",
+ (force_exec? "force to":""),
+ ((agc_table_en)? "Enable":"Disable"));
+ coex_dm->cur_agc_table_en = agc_table_en;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n",
+ coex_dm->pre_agc_table_en, coex_dm->cur_agc_table_en);
+
+ if (coex_dm->pre_agc_table_en == coex_dm->cur_agc_table_en)
+ return;
+ }
+ halbtc8192e2ant_set_agc_table(btcoexist, agc_table_en);
+
+ coex_dm->pre_agc_table_en = coex_dm->cur_agc_table_en;
+}
+
+void halbtc8192e2ant_set_coex_table(struct btc_coexist *btcoexist,
+ u32 val0x6c0, u32 val0x6c4,
+ u32 val0x6c8, u8 val0x6cc)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0);
+ btcoexist->btc_write_4byte(btcoexist, 0x6c0, val0x6c0);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], set coex table, set 0x6c4=0x%x\n", val0x6c4);
+ btcoexist->btc_write_4byte(btcoexist, 0x6c4, val0x6c4);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8);
+ btcoexist->btc_write_4byte(btcoexist, 0x6c8, val0x6c8);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC,
+ "[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc);
+ btcoexist->btc_write_1byte(btcoexist, 0x6cc, val0x6cc);
+}
+
+void halbtc8192e2ant_coex_table(struct btc_coexist *btcoexist, bool force_exec,
+ u32 val0x6c0, u32 val0x6c4,
+ u32 val0x6c8, u8 val0x6cc)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
+ "[BTCoex], %s write Coex Table 0x6c0=0x%x, ",
+ (force_exec? "force to":""), val0x6c0);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW,
+ "0x6c4=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n",
+ val0x6c4, val0x6c8, val0x6cc);
+ coex_dm->cur_val0x6c0 = val0x6c0;
+ coex_dm->cur_val0x6c4 = val0x6c4;
+ coex_dm->cur_val0x6c8 = val0x6c8;
+ coex_dm->cur_val0x6cc = val0x6cc;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "[BTCoex], preVal0x6c0=0x%x, preVal0x6c4=0x%x, ",
+ coex_dm->pre_val0x6c0, coex_dm->pre_val0x6c4);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "preVal0x6c8=0x%x, preVal0x6cc=0x%x !!\n",
+ coex_dm->pre_val0x6c8, coex_dm->pre_val0x6cc);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "[BTCoex], curVal0x6c0=0x%x, curVal0x6c4=0x%x, \n",
+ coex_dm->cur_val0x6c0, coex_dm->cur_val0x6c4);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL,
+ "curVal0x6c8=0x%x, curVal0x6cc=0x%x !!\n",
+ coex_dm->cur_val0x6c8, coex_dm->cur_val0x6cc);
+
+ if ((coex_dm->pre_val0x6c0 == coex_dm->cur_val0x6c0) &&
+ (coex_dm->pre_val0x6c4 == coex_dm->cur_val0x6c4) &&
+ (coex_dm->pre_val0x6c8 == coex_dm->cur_val0x6c8) &&
+ (coex_dm->pre_val0x6cc == coex_dm->cur_val0x6cc))
+ return;
+ }
+ halbtc8192e2ant_set_coex_table(btcoexist, val0x6c0, val0x6c4,
+ val0x6c8, val0x6cc);
+
+ coex_dm->pre_val0x6c0 = coex_dm->cur_val0x6c0;
+ coex_dm->pre_val0x6c4 = coex_dm->cur_val0x6c4;
+ coex_dm->pre_val0x6c8 = coex_dm->cur_val0x6c8;
+ coex_dm->pre_val0x6cc = coex_dm->cur_val0x6cc;
+}
+
+void halbtc8192e2ant_coex_table_with_type(struct btc_coexist *btcoexist,
+ bool force_exec, u8 type)
+{
+ switch (type) {
+ case 0:
+ halbtc8192e2ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x5a5a5a5a, 0xffffff, 0x3);
+ break;
+ case 1:
+ halbtc8192e2ant_coex_table(btcoexist, force_exec, 0x5a5a5a5a,
+ 0x5a5a5a5a, 0xffffff, 0x3);
+ break;
+ case 2:
+ halbtc8192e2ant_coex_table(btcoexist, force_exec, 0x55555555,
+ 0x5ffb5ffb, 0xffffff, 0x3);
+ break;
+ case 3:
+ halbtc8192e2ant_coex_table(btcoexist, force_exec, 0xdfffdfff,
+ 0x5fdb5fdb, 0xffffff, 0x3);
+ break;
+ case 4:
+ halbtc8192e2ant_coex_table(btcoexist, force_exec, 0xdfffdfff,
+ 0x5ffb5ffb, 0xffffff, 0x3);
+ break;
+ default:
+ break;
+ }
+}
+
+void halbtc8192e2ant_set_fw_ignore_wlanact(struct btc_coexist *btcoexist,
+ bool enable)
+{
+ u8 h2c_parameter[1] ={0};
+
+ if (enable)
+ h2c_parameter[0] |= BIT0; /* function enable */
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+ "[BTCoex]set FW for BT Ignore Wlan_Act, FW write 0x63=0x%x\n",
+ h2c_parameter[0]);
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x63, 1, h2c_parameter);
+}
+
+void halbtc8192e2ant_IgnoreWlanAct(struct btc_coexist *btcoexist,
+ bool force_exec, bool enable)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
+ "[BTCoex], %s turn Ignore WlanAct %s\n",
+ (force_exec? "force to":""), (enable? "ON":"OFF"));
+ coex_dm->cur_ignore_wlan_act = enable;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], bPreIgnoreWlanAct = %d ",
+ coex_dm->pre_ignore_wlan_act);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "bCurIgnoreWlanAct = %d!!\n",
+ coex_dm->cur_ignore_wlan_act);
+
+ if (coex_dm->pre_ignore_wlan_act ==
+ coex_dm->cur_ignore_wlan_act)
+ return;
+ }
+ halbtc8192e2ant_set_fw_ignore_wlanact(btcoexist, enable);
+
+ coex_dm->pre_ignore_wlan_act = coex_dm->cur_ignore_wlan_act;
+}
+
+void halbtc8192e2ant_SetFwPstdma(struct btc_coexist *btcoexist, u8 byte1,
+ u8 byte2, u8 byte3, u8 byte4, u8 byte5)
+{
+ u8 h2c_parameter[5] ={0};
+
+ h2c_parameter[0] = byte1;
+ h2c_parameter[1] = byte2;
+ h2c_parameter[2] = byte3;
+ h2c_parameter[3] = byte4;
+ h2c_parameter[4] = byte5;
+
+ coex_dm->ps_tdma_para[0] = byte1;
+ coex_dm->ps_tdma_para[1] = byte2;
+ coex_dm->ps_tdma_para[2] = byte3;
+ coex_dm->ps_tdma_para[3] = byte4;
+ coex_dm->ps_tdma_para[4] = byte5;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+ "[BTCoex], FW write 0x60(5bytes)=0x%x%08x\n",
+ h2c_parameter[0],
+ h2c_parameter[1] << 24 | h2c_parameter[2] << 16 |
+ h2c_parameter[3] << 8 | h2c_parameter[4]);
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x60, 5, h2c_parameter);
+}
+
+void halbtc8192e2ant_sw_mechanism1(struct btc_coexist *btcoexist,
+ bool shrink_rx_lpf, bool low_penalty_ra,
+ bool limited_dig, bool btlan_constrain)
+{
+ halbtc8192e2ant_rf_shrink(btcoexist, NORMAL_EXEC, shrink_rx_lpf);
+}
+
+void halbtc8192e2ant_sw_mechanism2(struct btc_coexist *btcoexist,
+ bool agc_table_shift, bool adc_backoff,
+ bool sw_dac_swing, u32 dac_swinglvl)
+{
+ halbtc8192e2ant_AgcTable(btcoexist, NORMAL_EXEC, agc_table_shift);
+ halbtc8192e2ant_DacSwing(btcoexist, NORMAL_EXEC, sw_dac_swing,
+ dac_swinglvl);
+}
+
+void halbtc8192e2ant_ps_tdma(struct btc_coexist *btcoexist,
+ bool force_exec, bool turn_on, u8 type)
+{
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
+ "[BTCoex], %s turn %s PS TDMA, type=%d\n",
+ (force_exec? "force to":""), (turn_on? "ON":"OFF"), type);
+ coex_dm->cur_ps_tdma_on = turn_on;
+ coex_dm->cur_ps_tdma = type;
+
+ if (!force_exec) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n",
+ coex_dm->pre_ps_tdma_on, coex_dm->cur_ps_tdma_on);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n",
+ coex_dm->pre_ps_tdma, coex_dm->cur_ps_tdma);
+
+ if ((coex_dm->pre_ps_tdma_on == coex_dm->cur_ps_tdma_on) &&
+ (coex_dm->pre_ps_tdma == coex_dm->cur_ps_tdma))
+ return;
+ }
+ if (turn_on) {
+ switch (type) {
+ case 1:
+ default:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
+ 0x1a, 0xe1, 0x90);
+ break;
+ case 2:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
+ 0x12, 0xe1, 0x90);
+ break;
+ case 3:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c,
+ 0x3, 0xf1, 0x90);
+ break;
+ case 4:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x10,
+ 0x3, 0xf1, 0x90);
+ break;
+ case 5:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
+ 0x1a, 0x60, 0x90);
+ break;
+ case 6:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
+ 0x12, 0x60, 0x90);
+ break;
+ case 7:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c,
+ 0x3, 0x70, 0x90);
+ break;
+ case 8:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xa3, 0x10,
+ 0x3, 0x70, 0x90);
+ break;
+ case 9:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
+ 0x1a, 0xe1, 0x10);
+ break;
+ case 10:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
+ 0x12, 0xe1, 0x10);
+ break;
+ case 11:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c,
+ 0x3, 0xf1, 0x10);
+ break;
+ case 12:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x10,
+ 0x3, 0xf1, 0x10);
+ break;
+ case 13:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
+ 0x1a, 0xe0, 0x10);
+ break;
+ case 14:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
+ 0x12, 0xe0, 0x10);
+ break;
+ case 15:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1c,
+ 0x3, 0xf0, 0x10);
+ break;
+ case 16:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x12,
+ 0x3, 0xf0, 0x10);
+ break;
+ case 17:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0x61, 0x20,
+ 0x03, 0x10, 0x10);
+ break;
+ case 18:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x5,
+ 0x5, 0xe1, 0x90);
+ break;
+ case 19:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x25,
+ 0x25, 0xe1, 0x90);
+ break;
+ case 20:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x25,
+ 0x25, 0x60, 0x90);
+ break;
+ case 21:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x15,
+ 0x03, 0x70, 0x90);
+ break;
+ case 71:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0xe3, 0x1a,
+ 0x1a, 0xe1, 0x90);
+ break;
+ }
+ } else {
+ /* disable PS tdma */
+ switch (type) {
+ default:
+ case 0:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0x8, 0x0, 0x0,
+ 0x0, 0x0);
+ btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x4);
+ break;
+ case 1:
+ halbtc8192e2ant_SetFwPstdma(btcoexist, 0x0, 0x0, 0x0,
+ 0x8, 0x0);
+ mdelay(5);
+ btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20);
+ break;
+ }
+ }
+
+ /* update pre state */
+ coex_dm->pre_ps_tdma_on = coex_dm->cur_ps_tdma_on;
+ coex_dm->pre_ps_tdma = coex_dm->cur_ps_tdma;
+}
+
+void halbtc8192e2ant_set_switch_sstype(struct btc_coexist *btcoexist, u8 sstype)
+{
+ u8 mimops = BTC_MIMO_PS_DYNAMIC;
+ u32 disra_mask = 0x0;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], REAL set SS Type = %d\n", sstype);
+
+ disra_mask = halbtc8192e2ant_decidera_mask(btcoexist, sstype,
+ coex_dm->curra_masktype);
+ halbtc8192e2ant_Updatera_mask(btcoexist, FORCE_EXEC, disra_mask);
+
+ if (sstype == 1) {
+ halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1);
+ /* switch ofdm path */
+ btcoexist->btc_write_1byte(btcoexist, 0xc04, 0x11);
+ btcoexist->btc_write_1byte(btcoexist, 0xd04, 0x1);
+ btcoexist->btc_write_4byte(btcoexist, 0x90c, 0x81111111);
+ /* switch cck patch */
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x1);
+ btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x81);
+ mimops=BTC_MIMO_PS_STATIC;
+ } else if (sstype == 2) {
+ halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 0);
+ btcoexist->btc_write_1byte(btcoexist, 0xc04, 0x33);
+ btcoexist->btc_write_1byte(btcoexist, 0xd04, 0x3);
+ btcoexist->btc_write_4byte(btcoexist, 0x90c, 0x81121313);
+ btcoexist->btc_write_1byte_bitmask(btcoexist, 0xe77, 0x4, 0x0);
+ btcoexist->btc_write_1byte(btcoexist, 0xa07, 0x41);
+ mimops=BTC_MIMO_PS_DYNAMIC;
+ }
+ /* set rx 1ss or 2ss */
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_SEND_MIMO_PS, &mimops);
+}
+
+void halbtc8192e2ant_switch_sstype(struct btc_coexist *btcoexist,
+ bool force_exec, u8 new_sstype)
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], %s Switch SS Type = %d\n",
+ (force_exec? "force to":""), new_sstype);
+ coex_dm->cur_sstype = new_sstype;
+
+ if (!force_exec) {
+ if (coex_dm->pre_sstype == coex_dm->cur_sstype)
+ return;
+ }
+ halbtc8192e2ant_set_switch_sstype(btcoexist, coex_dm->cur_sstype);
+
+ coex_dm->pre_sstype = coex_dm->cur_sstype;
+}
+
+void halbtc8192e2ant_coex_alloff(struct btc_coexist *btcoexist)
+{
+ /* fw all off */
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+
+ /* sw all off */
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false, false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
+
+ /* hw all off */
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+}
+
+void halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+ /* force to reset coex mechanism */
+
+ halbtc8192e2ant_ps_tdma(btcoexist, FORCE_EXEC, false, 1);
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, FORCE_EXEC, 6);
+ halbtc8192e2ant_dec_btpwr(btcoexist, FORCE_EXEC, 0);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+ halbtc8192e2ant_switch_sstype(btcoexist, FORCE_EXEC, 2);
+
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false, false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
+}
+
+void halbtc8192e2ant_action_bt_inquiry(struct btc_coexist *btcoexist)
+{
+ bool low_pwr_disable = true;
+
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
+ &low_pwr_disable);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 3);
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false, false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false, false, 0x18);
+}
+
+bool halbtc8192e2ant_is_common_action(struct btc_coexist *btcoexist)
+{
+ struct btc_bt_link_info *bt_link_info = &btcoexist->bt_link_info;
+ bool common = false, wifi_connected = false, wifi_busy = false;
+ bool bt_hson = false, low_pwr_disable = false;
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+
+ if (bt_link_info->sco_exist || bt_link_info->hid_exist)
+ halbtc8192e2ant_limited_tx(btcoexist, NORMAL_EXEC, 1, 0, 0, 0);
+ else
+ halbtc8192e2ant_limited_tx(btcoexist, NORMAL_EXEC, 0, 0, 0, 0);
+
+ if (!wifi_connected) {
+ low_pwr_disable = false;
+ btcoexist->btc_set(btcoexist, BTC_SET_ACT_DISABLE_LOW_POWER,
+ &low_pwr_disable);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], Wifi non-connected idle!!\n");
+
+ if ((BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
+ coex_dm->bt_status) ||
+ (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE ==
+ coex_dm->bt_status)) {
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC,
+ 2);
+ halbtc8192e2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 0);
+ } else {
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC,
+ 1);
+ halbtc8192e2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 0);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 1);
+ }
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false, false,
+ false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false, false,
+ 0x18);
+
+ common = true;
+ } else {
+ if (BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
+ coex_dm->bt_status) {
+ low_pwr_disable = false;
+ btcoexist->btc_set(btcoexist,
+ BTC_SET_ACT_DISABLE_LOW_POWER,
+ &low_pwr_disable);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Wifi connected + BT non connected-idle!!\n");
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC,
+ 2);
+ halbtc8192e2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 0);
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC,
+ 6);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+
+ common = true;
+ } else if (BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE ==
+ coex_dm->bt_status) {
+ low_pwr_disable = true;
+ btcoexist->btc_set(btcoexist,
+ BTC_SET_ACT_DISABLE_LOW_POWER,
+ &low_pwr_disable);
+
+ if (bt_hson)
+ return false;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Wifi connected + BT connected-idle!!\n");
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC,
+ 2);
+ halbtc8192e2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC, 1);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false,
+ 0);
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC,
+ 6);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+
+ common = true;
+ } else {
+ low_pwr_disable = true;
+ btcoexist->btc_set(btcoexist,
+ BTC_SET_ACT_DISABLE_LOW_POWER,
+ &low_pwr_disable);
+
+ if (wifi_busy) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Wifi Connected-Busy + BT Busy!!\n");
+ common = false;
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Wifi Connected-Idle + BT Busy!!\n");
+
+ halbtc8192e2ant_switch_sstype(btcoexist,
+ NORMAL_EXEC, 1);
+ halbtc8192e2ant_coex_table_with_type(btcoexist,
+ NORMAL_EXEC,
+ 2);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true, 21);
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist,
+ NORMAL_EXEC, 6);
+ halbtc8192e2ant_dec_btpwr(btcoexist,
+ NORMAL_EXEC, 0);
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false,
+ false, false,
+ false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false,
+ false, false,
+ 0x18);
+ common = true;
+ }
+ }
+ }
+ return common;
+}
+
+void halbtc8192e2ant_tdma_duration_adjust(struct btc_coexist *btcoexist,
+ bool sco_hid, bool tx_pause,
+ u8 max_interval)
+{
+ static int up, dn, m, n, wait_cnt;
+ /* 0: no change, +1: increase WiFi duration,
+ * -1: decrease WiFi duration */
+ int result;
+ u8 retry_cnt = 0;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW,
+ "[BTCoex], TdmaDurationAdjust()\n");
+
+ if (!coex_dm->auto_tdma_adjust) {
+ coex_dm->auto_tdma_adjust = true;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], first run TdmaDurationAdjust()!!\n");
+ if (sco_hid) {
+ if (tx_pause) {
+ if (max_interval == 1) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 13);
+ coex_dm->ps_tdma_du_adj_type = 13;
+ } else if (max_interval == 2) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 14);
+ coex_dm->ps_tdma_du_adj_type = 14;
+ } else if (max_interval == 3) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type = 15;
+ } else {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type = 15;
+ }
+ } else {
+ if (max_interval == 1) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 9);
+ coex_dm->ps_tdma_du_adj_type = 9;
+ } else if (max_interval == 2) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 10);
+ coex_dm->ps_tdma_du_adj_type = 10;
+ } else if (max_interval == 3) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type = 11;
+ } else {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type = 11;
+ }
+ }
+ } else {
+ if (tx_pause) {
+ if (max_interval == 1) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 5);
+ coex_dm->ps_tdma_du_adj_type = 5;
+ } else if (max_interval == 2) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 6);
+ coex_dm->ps_tdma_du_adj_type = 6;
+ } else if (max_interval == 3) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type = 7;
+ } else {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type = 7;
+ }
+ } else {
+ if (max_interval == 1) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 1);
+ coex_dm->ps_tdma_du_adj_type = 1;
+ } else if (max_interval == 2) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+ } else if (max_interval == 3) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type = 3;
+ } else {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type = 3;
+ }
+ }
+ }
+
+ up = 0;
+ dn = 0;
+ m = 1;
+ n= 3;
+ result = 0;
+ wait_cnt = 0;
+ } else {
+ /* accquire the BT TRx retry count from BT_Info byte2 */
+ retry_cnt = coex_sta->bt_retry_cnt;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], retry_cnt = %d\n", retry_cnt);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], up=%d, dn=%d, m=%d, n=%d, wait_cnt=%d\n",
+ up, dn, m, n, wait_cnt);
+ result = 0;
+ wait_cnt++;
+ /* no retry in the last 2-second duration */
+ if (retry_cnt == 0) {
+ up++;
+ dn--;
+
+ if (dn <= 0)
+ dn = 0;
+
+ if (up >= n) {
+ wait_cnt = 0;
+ n = 3;
+ up = 0;
+ dn = 0;
+ result = 1;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_TRACE_FW_DETAIL,
+ "[BTCoex]Increase wifi duration!!\n");
+ }
+ } else if (retry_cnt <= 3) {
+ up--;
+ dn++;
+
+ if (up <= 0)
+ up = 0;
+
+ if (dn == 2) {
+ if (wait_cnt <= 2)
+ m++;
+ else
+ m = 1;
+
+ if (m >= 20)
+ m = 20;
+
+ n = 3 * m;
+ up = 0;
+ dn = 0;
+ wait_cnt = 0;
+ result = -1;
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_TRACE_FW_DETAIL,
+ "Reduce wifi duration for retry<3\n");
+ }
+ } else {
+ if (wait_cnt == 1)
+ m++;
+ else
+ m = 1;
+
+ if (m >= 20)
+ m = 20;
+
+ n = 3*m;
+ up = 0;
+ dn = 0;
+ wait_cnt = 0;
+ result = -1;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "Decrease wifi duration for retryCounter>3!!\n");
+ }
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], max Interval = %d\n", max_interval);
+ if (max_interval == 1) {
+ if (tx_pause) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], TxPause = 1\n");
+
+ if (coex_dm->cur_ps_tdma == 71) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 5);
+ coex_dm->ps_tdma_du_adj_type = 5;
+ } else if (coex_dm->cur_ps_tdma == 1) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 5);
+ coex_dm->ps_tdma_du_adj_type = 5;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 6);
+ coex_dm->ps_tdma_du_adj_type = 6;
+ } else if (coex_dm->cur_ps_tdma == 3) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type = 7;
+ } else if (coex_dm->cur_ps_tdma == 4) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 8);
+ coex_dm->ps_tdma_du_adj_type = 8;
+ }
+ if (coex_dm->cur_ps_tdma == 9) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 13);
+ coex_dm->ps_tdma_du_adj_type = 13;
+ } else if (coex_dm->cur_ps_tdma == 10) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 14);
+ coex_dm->ps_tdma_du_adj_type = 14;
+ } else if (coex_dm->cur_ps_tdma == 11) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type = 15;
+ } else if (coex_dm->cur_ps_tdma == 12) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 16);
+ coex_dm->ps_tdma_du_adj_type = 16;
+ }
+
+ if (result == -1) {
+ if (coex_dm->cur_ps_tdma == 5) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 6);
+ coex_dm->ps_tdma_du_adj_type =
+ 6;
+ } else if (coex_dm->cur_ps_tdma == 6) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type =
+ 7;
+ } else if (coex_dm->cur_ps_tdma == 7) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 8);
+ coex_dm->ps_tdma_du_adj_type =
+ 8;
+ } else if (coex_dm->cur_ps_tdma == 13) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 14);
+ coex_dm->ps_tdma_du_adj_type =
+ 14;
+ } else if (coex_dm->cur_ps_tdma == 14) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type =
+ 15;
+ } else if (coex_dm->cur_ps_tdma == 15) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 16);
+ coex_dm->ps_tdma_du_adj_type =
+ 16;
+ }
+ } else if (result == 1) {
+ if (coex_dm->cur_ps_tdma == 8) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type =
+ 7;
+ } else if (coex_dm->cur_ps_tdma == 7) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 6);
+ coex_dm->ps_tdma_du_adj_type =
+ 6;
+ } else if (coex_dm->cur_ps_tdma == 6) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 5);
+ coex_dm->ps_tdma_du_adj_type =
+ 5;
+ } else if (coex_dm->cur_ps_tdma == 16) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type =
+ 15;
+ } else if (coex_dm->cur_ps_tdma == 15) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 14);
+ coex_dm->ps_tdma_du_adj_type =
+ 14;
+ } else if (coex_dm->cur_ps_tdma == 14) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 13);
+ coex_dm->ps_tdma_du_adj_type =
+ 13;
+ }
+ }
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], TxPause = 0\n");
+ if (coex_dm->cur_ps_tdma == 5) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 71);
+ coex_dm->ps_tdma_du_adj_type = 71;
+ } else if (coex_dm->cur_ps_tdma == 6) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+ } else if (coex_dm->cur_ps_tdma == 7) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type = 3;
+ } else if (coex_dm->cur_ps_tdma == 8) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 4);
+ coex_dm->ps_tdma_du_adj_type = 4;
+ }
+ if (coex_dm->cur_ps_tdma == 13) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 9);
+ coex_dm->ps_tdma_du_adj_type = 9;
+ } else if (coex_dm->cur_ps_tdma == 14) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 10);
+ coex_dm->ps_tdma_du_adj_type = 10;
+ } else if (coex_dm->cur_ps_tdma == 15) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type = 11;
+ } else if (coex_dm->cur_ps_tdma == 16) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 12);
+ coex_dm->ps_tdma_du_adj_type = 12;
+ }
+
+ if (result == -1) {
+ if (coex_dm->cur_ps_tdma == 71) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 1);
+ coex_dm->ps_tdma_du_adj_type =
+ 1;
+ } else if (coex_dm->cur_ps_tdma == 1) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type =
+ 2;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type =
+ 3;
+ } else if (coex_dm->cur_ps_tdma == 3) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 4);
+ coex_dm->ps_tdma_du_adj_type =
+ 4;
+ } else if (coex_dm->cur_ps_tdma == 9) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 10);
+ coex_dm->ps_tdma_du_adj_type =
+ 10;
+ } else if (coex_dm->cur_ps_tdma == 10) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type =
+ 11;
+ } else if (coex_dm->cur_ps_tdma == 11) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 12);
+ coex_dm->ps_tdma_du_adj_type =
+ 12;
+ }
+ } else if (result == 1) {
+ if (coex_dm->cur_ps_tdma == 4) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type =
+ 3;
+ } else if (coex_dm->cur_ps_tdma == 3) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type =
+ 2;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 1);
+ coex_dm->ps_tdma_du_adj_type =
+ 1;
+ } else if (coex_dm->cur_ps_tdma == 1) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 71);
+ coex_dm->ps_tdma_du_adj_type =
+ 71;
+ } else if (coex_dm->cur_ps_tdma == 12) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type =
+ 11;
+ } else if (coex_dm->cur_ps_tdma == 11) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 10);
+ coex_dm->ps_tdma_du_adj_type =
+ 10;
+ } else if (coex_dm->cur_ps_tdma == 10) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 9);
+ coex_dm->ps_tdma_du_adj_type =
+ 9;
+ }
+ }
+ }
+ } else if (max_interval == 2) {
+ if (tx_pause) {
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], TxPause = 1\n");
+ if (coex_dm->cur_ps_tdma == 1) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 6);
+ coex_dm->ps_tdma_du_adj_type = 6;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 6);
+ coex_dm->ps_tdma_du_adj_type = 6;
+ } else if (coex_dm->cur_ps_tdma == 3) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type = 7;
+ } else if (coex_dm->cur_ps_tdma == 4) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 8);
+ coex_dm->ps_tdma_du_adj_type = 8;
+ }
+ if (coex_dm->cur_ps_tdma == 9) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 14);
+ coex_dm->ps_tdma_du_adj_type = 14;
+ } else if (coex_dm->cur_ps_tdma == 10) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 14);
+ coex_dm->ps_tdma_du_adj_type = 14;
+ } else if (coex_dm->cur_ps_tdma == 11) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type = 15;
+ } else if (coex_dm->cur_ps_tdma == 12) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 16);
+ coex_dm->ps_tdma_du_adj_type = 16;
+ }
+ if (result == -1) {
+ if (coex_dm->cur_ps_tdma == 5) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 6);
+ coex_dm->ps_tdma_du_adj_type =
+ 6;
+ } else if (coex_dm->cur_ps_tdma == 6) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type =
+ 7;
+ } else if (coex_dm->cur_ps_tdma == 7) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 8);
+ coex_dm->ps_tdma_du_adj_type =
+ 8;
+ } else if (coex_dm->cur_ps_tdma == 13) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 14);
+ coex_dm->ps_tdma_du_adj_type =
+ 14;
+ } else if (coex_dm->cur_ps_tdma == 14) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type =
+ 15;
+ } else if (coex_dm->cur_ps_tdma == 15) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 16);
+ coex_dm->ps_tdma_du_adj_type =
+ 16;
+ }
+ } else if (result == 1) {
+ if (coex_dm->cur_ps_tdma == 8) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type =
+ 7;
+ } else if (coex_dm->cur_ps_tdma == 7) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 6);
+ coex_dm->ps_tdma_du_adj_type =
+ 6;
+ } else if (coex_dm->cur_ps_tdma == 6) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 6);
+ coex_dm->ps_tdma_du_adj_type =
+ 6;
+ } else if (coex_dm->cur_ps_tdma == 16) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type =
+ 15;
+ } else if (coex_dm->cur_ps_tdma == 15) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 14);
+ coex_dm->ps_tdma_du_adj_type =
+ 14;
+ } else if (coex_dm->cur_ps_tdma == 14) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 14);
+ coex_dm->ps_tdma_du_adj_type =
+ 14;
+ }
+ }
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], TxPause = 0\n");
+ if (coex_dm->cur_ps_tdma == 5) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+ } else if (coex_dm->cur_ps_tdma == 6) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type = 2;
+ } else if (coex_dm->cur_ps_tdma == 7) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type = 3;
+ } else if (coex_dm->cur_ps_tdma == 8) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 4);
+ coex_dm->ps_tdma_du_adj_type = 4;
+ }
+ if (coex_dm->cur_ps_tdma == 13) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 10);
+ coex_dm->ps_tdma_du_adj_type = 10;
+ } else if (coex_dm->cur_ps_tdma == 14) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 10);
+ coex_dm->ps_tdma_du_adj_type = 10;
+ } else if (coex_dm->cur_ps_tdma == 15) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type = 11;
+ } else if (coex_dm->cur_ps_tdma == 16) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 12);
+ coex_dm->ps_tdma_du_adj_type = 12;
+ }
+ if (result == -1) {
+ if (coex_dm->cur_ps_tdma == 1) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type =
+ 2;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type =
+ 3;
+ } else if (coex_dm->cur_ps_tdma == 3) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 4);
+ coex_dm->ps_tdma_du_adj_type =
+ 4;
+ } else if (coex_dm->cur_ps_tdma == 9) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 10);
+ coex_dm->ps_tdma_du_adj_type =
+ 10;
+ } else if (coex_dm->cur_ps_tdma == 10) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type =
+ 11;
+ } else if (coex_dm->cur_ps_tdma == 11) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 12);
+ coex_dm->ps_tdma_du_adj_type =
+ 12;
+ }
+ } else if (result == 1) {
+ if (coex_dm->cur_ps_tdma == 4) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type =
+ 3;
+ } else if (coex_dm->cur_ps_tdma == 3) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type =
+ 2;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 2);
+ coex_dm->ps_tdma_du_adj_type =
+ 2;
+ } else if(coex_dm->cur_ps_tdma == 12) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type =
+ 11;
+ } else if(coex_dm->cur_ps_tdma == 11) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 10);
+ coex_dm->ps_tdma_du_adj_type =
+ 10;
+ } else if(coex_dm->cur_ps_tdma == 10) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 10);
+ coex_dm->ps_tdma_du_adj_type =
+ 10;
+ }
+ }
+ }
+ } else if (max_interval == 3) {
+ if (tx_pause) {
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], TxPause = 1\n");
+ if (coex_dm->cur_ps_tdma == 1) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type = 7;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type = 7;
+ } else if (coex_dm->cur_ps_tdma == 3) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type = 7;
+ } else if (coex_dm->cur_ps_tdma == 4) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 8);
+ coex_dm->ps_tdma_du_adj_type = 8;
+ }
+ if (coex_dm->cur_ps_tdma == 9) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type = 15;
+ } else if (coex_dm->cur_ps_tdma == 10) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type = 15;
+ } else if (coex_dm->cur_ps_tdma == 11) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type = 15;
+ } else if (coex_dm->cur_ps_tdma == 12) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 16);
+ coex_dm->ps_tdma_du_adj_type = 16;
+ }
+ if (result == -1) {
+ if (coex_dm->cur_ps_tdma == 5) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type =
+ 7;
+ } else if (coex_dm->cur_ps_tdma == 6) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type =
+ 7;
+ } else if (coex_dm->cur_ps_tdma == 7) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 8);
+ coex_dm->ps_tdma_du_adj_type =
+ 8;
+ } else if (coex_dm->cur_ps_tdma == 13) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type =
+ 15;
+ } else if (coex_dm->cur_ps_tdma == 14) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type =
+ 15;
+ } else if (coex_dm->cur_ps_tdma == 15) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 16);
+ coex_dm->ps_tdma_du_adj_type =
+ 16;
+ }
+ } else if (result == 1) {
+ if (coex_dm->cur_ps_tdma == 8) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type =
+ 7;
+ } else if (coex_dm->cur_ps_tdma == 7) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type =
+ 7;
+ } else if (coex_dm->cur_ps_tdma == 6) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 7);
+ coex_dm->ps_tdma_du_adj_type =
+ 7;
+ } else if (coex_dm->cur_ps_tdma == 16) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type =
+ 15;
+ } else if (coex_dm->cur_ps_tdma == 15) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type =
+ 15;
+ } else if (coex_dm->cur_ps_tdma == 14) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 15);
+ coex_dm->ps_tdma_du_adj_type =
+ 15;
+ }
+ }
+ } else {
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], TxPause = 0\n");
+ if (coex_dm->cur_ps_tdma == 5) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type = 3;
+ } else if (coex_dm->cur_ps_tdma == 6) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type = 3;
+ } else if (coex_dm->cur_ps_tdma == 7) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type = 3;
+ } else if (coex_dm->cur_ps_tdma == 8) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 4);
+ coex_dm->ps_tdma_du_adj_type = 4;
+ }
+ if (coex_dm->cur_ps_tdma == 13) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type = 11;
+ } else if (coex_dm->cur_ps_tdma == 14) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type = 11;
+ } else if (coex_dm->cur_ps_tdma == 15) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type = 11;
+ } else if (coex_dm->cur_ps_tdma == 16) {
+ halbtc8192e2ant_ps_tdma(btcoexist,
+ NORMAL_EXEC,
+ true, 12);
+ coex_dm->ps_tdma_du_adj_type = 12;
+ }
+ if (result == -1) {
+ if (coex_dm->cur_ps_tdma == 1) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type =
+ 3;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type =
+ 3;
+ } else if (coex_dm->cur_ps_tdma == 3) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 4);
+ coex_dm->ps_tdma_du_adj_type =
+ 4;
+ } else if (coex_dm->cur_ps_tdma == 9) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type =
+ 11;
+ } else if (coex_dm->cur_ps_tdma == 10) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type =
+ 11;
+ } else if (coex_dm->cur_ps_tdma == 11) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 12);
+ coex_dm->ps_tdma_du_adj_type =
+ 12;
+ }
+ } else if (result == 1) {
+ if (coex_dm->cur_ps_tdma == 4) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type =
+ 3;
+ } else if (coex_dm->cur_ps_tdma == 3) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type =
+ 3;
+ } else if (coex_dm->cur_ps_tdma == 2) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 3);
+ coex_dm->ps_tdma_du_adj_type =
+ 3;
+ } else if (coex_dm->cur_ps_tdma == 12) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type =
+ 11;
+ } else if (coex_dm->cur_ps_tdma == 11) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type =
+ 11;
+ } else if (coex_dm->cur_ps_tdma == 10) {
+ halbtc8192e2ant_ps_tdma(
+ btcoexist,
+ NORMAL_EXEC,
+ true, 11);
+ coex_dm->ps_tdma_du_adj_type =
+ 11;
+ }
+ }
+ }
+ }
+ }
+
+ /* if current PsTdma not match with
+ * the recorded one (when scan, dhcp...),
+ * then we have to adjust it back to the previous record one. */
+ if (coex_dm->cur_ps_tdma != coex_dm->ps_tdma_du_adj_type) {
+ bool scan = false, link = false, roam = false;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], PsTdma type dismatch!!!, " );
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL,
+ "curPsTdma=%d, recordPsTdma=%d\n",
+ coex_dm->cur_ps_tdma, coex_dm->ps_tdma_du_adj_type);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+
+ if ( !scan && !link && !roam)
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC,
+ true,
+ coex_dm->ps_tdma_du_adj_type);
+ else
+ BTC_PRINT(BTC_MSG_ALGORITHM,
+ ALGO_TRACE_FW_DETAIL,
+ "[BTCoex], roaming/link/scan is under progress, will adjust next time!!!\n");
+ }
+}
+
+/* SCO only or SCO+PAN(HS) */
+void halbtc8192e2ant_action_sco(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ /* sw mechanism */
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x6);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x6);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x6);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x6);
+ }
+ }
+}
+
+void halbtc8192e2ant_action_sco_pan(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_STAY_LOW;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 4);
+
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
+ }
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ /* sw mechanism */
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x6);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x6);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x6);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x6);
+ }
+ }
+}
+
+void halbtc8192e2ant_action_hid(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state=BTC_RSSI_STATE_HIGH;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 13);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 9);
+ }
+
+ /* sw mechanism */
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ }
+}
+
+/* A2DP only / PAN(EDR) only/ A2DP+PAN(HS) */
+void halbtc8192e2ant_action_a2dp(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
+ u32 wifi_bw;
+ bool long_dist = false;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW ||
+ btrssi_state == BTC_RSSI_STATE_STAY_LOW) &&
+ (wifirssi_state == BTC_RSSI_STATE_LOW ||
+ wifirssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], A2dp, wifi/bt rssi both LOW!!\n");
+ long_dist = true;
+ }
+ if (long_dist) {
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, true,
+ 0x4);
+ } else {
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false,
+ 0x8);
+ }
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+
+ if (long_dist)
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 0);
+ else
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+
+
+ if (long_dist) {
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 17);
+ coex_dm->auto_tdma_adjust = false;
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ } else {
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
+ true, 1);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
+ false, 1);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, false,
+ false, 1);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ }
+ }
+
+ /* sw mechanism */
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ }
+}
+
+void halbtc8192e2ant_action_a2dp_pan_hs(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, true, 2);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, false,
+ 2);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, false,
+ 2);
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ }
+
+ /* sw mechanism */
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ true, 0x6);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ true, 0x6);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ true, 0x6);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ true, 0x6);
+ }
+ }
+}
+
+void halbtc8192e2ant_action_pan_edr(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 5);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 1);
+ }
+
+ /* sw mechanism */
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ }
+}
+
+/* PAN(HS) only */
+void halbtc8192e2ant_action_pan_hs(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ }
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, false, 1);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ }
+}
+
+/* PAN(EDR)+A2DP */
+void halbtc8192e2ant_action_pan_edr_a2dp(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state=BTC_RSSI_STATE_HIGH;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 2);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, true, 3);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, false,
+ 3);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, false, false,
+ 3);
+ }
+
+ /* sw mechanism */
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, false,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ }
+}
+
+void halbtc8192e2ant_action_pan_edr_hid(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 14);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ halbtc8192e2ant_ps_tdma(btcoexist, NORMAL_EXEC, true, 10);
+ }
+
+ /* sw mechanism */
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ }
+}
+
+/* HID+A2DP+PAN(EDR) */
+void halbtc8192e2ant_action_hid_a2dp_pan_edr(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ halbtc8192e2ant_fw_dac_swinglvl(btcoexist, NORMAL_EXEC, 6);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, true, 3);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 3);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 3);
+ }
+
+ /* sw mechanism */
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ }
+}
+
+void halbtc8192e2ant_action_hid_a2dp(struct btc_coexist *btcoexist)
+{
+ u8 wifirssi_state, btrssi_state = BTC_RSSI_STATE_HIGH;
+ u32 wifi_bw;
+
+ wifirssi_state = halbtc8192e2ant_wifirssi_state(btcoexist, 0, 2, 15, 0);
+ btrssi_state = halbtc8192e2ant_btrssi_state(3, 34, 42);
+
+ halbtc8192e2ant_switch_sstype(btcoexist, NORMAL_EXEC, 1);
+ halbtc8192e2ant_limited_rx(btcoexist, NORMAL_EXEC, false, false, 0x8);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, NORMAL_EXEC, 3);
+
+ if ((btrssi_state == BTC_RSSI_STATE_LOW) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_LOW)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 0);
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, true, 2);
+ } else if ((btrssi_state == BTC_RSSI_STATE_MEDIUM) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_MEDIUM)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 2);
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 2);
+ } else if ((btrssi_state == BTC_RSSI_STATE_HIGH) ||
+ (btrssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_dec_btpwr(btcoexist, NORMAL_EXEC, 4);
+ halbtc8192e2ant_tdma_duration_adjust(btcoexist, true, false, 2);
+ }
+
+ /* sw mechanism */
+ if (BTC_WIFI_BW_HT40 == wifi_bw) {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, true, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ } else {
+ if ((wifirssi_state == BTC_RSSI_STATE_HIGH) ||
+ (wifirssi_state == BTC_RSSI_STATE_STAY_HIGH)) {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, true, false,
+ false, 0x18);
+ } else {
+ halbtc8192e2ant_sw_mechanism1(btcoexist, false, true,
+ false, false);
+ halbtc8192e2ant_sw_mechanism2(btcoexist, false, false,
+ false, 0x18);
+ }
+ }
+}
+
+void halbtc8192e2ant_run_coexist_mechanism(struct btc_coexist *btcoexist)
+{
+ u8 algorithm = 0;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], RunCoexistMechanism()===>\n");
+
+ if (btcoexist->manual_control) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], return for Manual CTRL <===\n");
+ return;
+ }
+
+ if (coex_sta->under_ips) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], wifi is under IPS !!!\n");
+ return;
+ }
+
+ algorithm = halbtc8192e2ant_action_algorithm(btcoexist);
+ if (coex_sta->c2h_bt_inquiry_page &&
+ (BT_8192E_2ANT_COEX_ALGO_PANHS != algorithm)) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], BT is under inquiry/page scan !!\n");
+ halbtc8192e2ant_action_bt_inquiry(btcoexist);
+ return;
+ }
+
+ coex_dm->cur_algorithm = algorithm;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], Algorithm = %d \n", coex_dm->cur_algorithm);
+
+ if (halbtc8192e2ant_is_common_action(btcoexist)) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], Action 2-Ant common.\n");
+ coex_dm->auto_tdma_adjust = false;
+ } else {
+ if (coex_dm->cur_algorithm != coex_dm->pre_algorithm) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex] preAlgorithm=%d, curAlgorithm=%d\n",
+ coex_dm->pre_algorithm,
+ coex_dm->cur_algorithm);
+ coex_dm->auto_tdma_adjust = false;
+ }
+ switch (coex_dm->cur_algorithm) {
+ case BT_8192E_2ANT_COEX_ALGO_SCO:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = SCO.\n");
+ halbtc8192e2ant_action_sco(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_SCO_PAN:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = SCO+PAN(EDR).\n");
+ halbtc8192e2ant_action_sco_pan(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_HID:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = HID.\n");
+ halbtc8192e2ant_action_hid(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_A2DP:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = A2DP.\n");
+ halbtc8192e2ant_action_a2dp(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = A2DP+PAN(HS).\n");
+ halbtc8192e2ant_action_a2dp_pan_hs(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_PANEDR:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = PAN(EDR).\n");
+ halbtc8192e2ant_action_pan_edr(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_PANHS:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = HS mode.\n");
+ halbtc8192e2ant_action_pan_hs(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = PAN+A2DP.\n");
+ halbtc8192e2ant_action_pan_edr_a2dp(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_PANEDR_HID:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = PAN(EDR)+HID.\n");
+ halbtc8192e2ant_action_pan_edr_hid(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = HID+A2DP+PAN.\n");
+ halbtc8192e2ant_action_hid_a2dp_pan_edr(btcoexist);
+ break;
+ case BT_8192E_2ANT_COEX_ALGO_HID_A2DP:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = HID+A2DP.\n");
+ halbtc8192e2ant_action_hid_a2dp(btcoexist);
+ break;
+ default:
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "Action 2-Ant, algorithm = unknown!!\n");
+ /* halbtc8192e2ant_coex_alloff(btcoexist); */
+ break;
+ }
+ coex_dm->pre_algorithm = coex_dm->cur_algorithm;
+ }
+}
+
+void halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist, bool backup)
+{
+ u16 u16tmp = 0;
+ u8 u8tmp = 0;
+
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+ "[BTCoex], 2Ant Init HW Config!!\n");
+
+ if (backup) {
+ /* backup rf 0x1e value */
+ coex_dm->bt_rf0x1e_backup =
+ btcoexist->btc_get_rf_reg(btcoexist, BTC_RF_A,
+ 0x1e, 0xfffff);
+
+ coex_dm->backup_arfr_cnt1 = btcoexist->btc_read_4byte(btcoexist,
+ 0x430);
+ coex_dm->backup_arfr_cnt2 = btcoexist->btc_read_4byte(btcoexist,
+ 0x434);
+ coex_dm->backup_retrylimit = btcoexist->btc_read_2byte(
+ btcoexist,
+ 0x42a);
+ coex_dm->backup_ampdu_maxtime = btcoexist->btc_read_1byte(
+ btcoexist,
+ 0x456);
+ }
+
+ /* antenna sw ctrl to bt */
+ btcoexist->btc_write_1byte(btcoexist, 0x4f, 0x6);
+ btcoexist->btc_write_1byte(btcoexist, 0x944, 0x24);
+ btcoexist->btc_write_4byte(btcoexist, 0x930, 0x700700);
+ btcoexist->btc_write_1byte(btcoexist, 0x92c, 0x20);
+ if (btcoexist->chip_interface == BTC_INTF_USB)
+ btcoexist->btc_write_4byte(btcoexist, 0x64, 0x30430004);
+ else
+ btcoexist->btc_write_4byte(btcoexist, 0x64, 0x30030004);
+
+ halbtc8192e2ant_coex_table_with_type(btcoexist, FORCE_EXEC, 0);
+
+ /* antenna switch control parameter */
+ btcoexist->btc_write_4byte(btcoexist, 0x858, 0x55555555);
+
+ /* coex parameters */
+ btcoexist->btc_write_1byte(btcoexist, 0x778, 0x3);
+ /* 0x790[5:0]=0x5 */
+ u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x790);
+ u8tmp &= 0xc0;
+ u8tmp |= 0x5;
+ btcoexist->btc_write_1byte(btcoexist, 0x790, u8tmp);
+
+ /* enable counter statistics */
+ btcoexist->btc_write_1byte(btcoexist, 0x76e, 0x4);
+
+ /* enable PTA */
+ btcoexist->btc_write_1byte(btcoexist, 0x40, 0x20);
+ /* enable mailbox interface */
+ u16tmp = btcoexist->btc_read_2byte(btcoexist, 0x40);
+ u16tmp |= BIT9;
+ btcoexist->btc_write_2byte(btcoexist, 0x40, u16tmp);
+
+ /* enable PTA I2C mailbox */
+ u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x101);
+ u8tmp |= BIT4;
+ btcoexist->btc_write_1byte(btcoexist, 0x101, u8tmp);
+
+ /* enable bt clock when wifi is disabled. */
+ u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x93);
+ u8tmp |= BIT0;
+ btcoexist->btc_write_1byte(btcoexist, 0x93, u8tmp);
+ /* enable bt clock when suspend. */
+ u8tmp = btcoexist->btc_read_1byte(btcoexist, 0x7);
+ u8tmp |= BIT0;
+ btcoexist->btc_write_1byte(btcoexist, 0x7, u8tmp);
+}
+
+/*************************************************************
+ * work around function start with wa_halbtc8192e2ant_
+ *************************************************************/
+
+/************************************************************
+ * extern function start with EXhalbtc8192e2ant_
+ ************************************************************/
+
+void ex_halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist)
+{
+ halbtc8192e2ant_init_hwconfig(btcoexist, true);
+}
+
+void ex_halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist)
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+ "[BTCoex], Coex Mechanism Init!!\n");
+ halbtc8192e2ant_init_coex_dm(btcoexist);
+}
+
+void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist)
+{
+ struct btc_board_info *board_info = &btcoexist->board_info;
+ struct btc_stack_info*stack_info = &btcoexist->stack_info;
+ u8 *cli_buf = btcoexist->cli_buf;
+ u8 u8tmp[4], i, bt_info_ext, ps_tdma_case = 0;
+ u16 u16tmp[4];
+ u32 u32tmp[4];
+ bool roam = false, scan = false, link = false, wifi_under_5g = false;
+ bool bt_hson = false, wifi_busy = false;
+ int wifirssi = 0, bt_hs_rssi = 0;
+ u32 wifi_bw, wifi_traffic_dir;
+ u8 wifi_dot11_chnl, wifi_hs_chnl;
+ u32 fw_ver = 0, bt_patch_ver = 0;
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ "\r\n ============[BT Coexist info]============");
+ CL_PRINTF(cli_buf);
+
+ if (btcoexist->manual_control) {
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ "\r\n ===========[Under Manual Control]===========");
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ "\r\n ==========================================");
+ CL_PRINTF(cli_buf);
+ }
+
+ if (!board_info->bt_exist) {
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n BT not exists !!!");
+ CL_PRINTF(cli_buf);
+ return;
+ }
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ "\r\n %-35s = %d/ %d ", "Ant PG number/ Ant mechanism:",
+ board_info->pg_ant_num, board_info->btdm_ant_num);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %d",
+ "BT stack/ hci ext ver",
+ ((stack_info->profile_notified) ? "Yes" : "No"),
+ stack_info->hci_version);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER, &bt_patch_ver);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ "\r\n %-35s = %d_%d/ 0x%x/ 0x%x(%d)",
+ "CoexVer/ FwVer/ PatchVer",
+ glcoex_ver_date_8192e_2ant, glcoex_ver_8192e_2ant,
+ fw_ver, bt_patch_ver, bt_patch_ver);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_HS_OPERATION, &bt_hson);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_DOT11_CHNL,
+ &wifi_dot11_chnl);
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_HS_CHNL, &wifi_hs_chnl);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d(%d)",
+ "Dot11 channel / HsMode(HsChnl)",
+ wifi_dot11_chnl, bt_hson, wifi_hs_chnl);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %02x %02x %02x ",
+ "H2C Wifi inform bt chnl Info", coex_dm->wifi_chnl_info[0],
+ coex_dm->wifi_chnl_info[1], coex_dm->wifi_chnl_info[2]);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_WIFI_RSSI, &wifirssi);
+ btcoexist->btc_get(btcoexist, BTC_GET_S4_HS_RSSI, &bt_hs_rssi);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ "Wifi rssi/ HS rssi", wifirssi, bt_hs_rssi);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_SCAN, &scan);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_LINK, &link);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_ROAM, &roam);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
+ "Wifi link/ roam/ scan", link, roam, scan);
+ CL_PRINTF(cli_buf);
+
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_UNDER_5G, &wifi_under_5g);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_BUSY, &wifi_busy);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_TRAFFIC_DIRECTION,
+ &wifi_traffic_dir);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s / %s/ %s ",
+ "Wifi status", (wifi_under_5g ? "5G" : "2.4G"),
+ ((BTC_WIFI_BW_LEGACY == wifi_bw) ? "Legacy" :
+ (((BTC_WIFI_BW_HT40 == wifi_bw) ? "HT40" : "HT20"))),
+ ((!wifi_busy) ? "idle" :
+ ((BTC_WIFI_TRAFFIC_TX == wifi_traffic_dir) ?
+ "uplink" : "downlink")));
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = [%s/ %d/ %d] ",
+ "BT [status/ rssi/ retryCnt]",
+ ((btcoexist->bt_info.bt_disabled) ? ("disabled") :
+ ((coex_sta->c2h_bt_inquiry_page) ?
+ ("inquiry/page scan") :
+ ((BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE ==
+ coex_dm->bt_status) ? "non-connected idle" :
+ ((BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE ==
+ coex_dm->bt_status) ? "connected-idle" : "busy")))),
+ coex_sta->bt_rssi, coex_sta->bt_retry_cnt);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d / %d / %d / %d",
+ "SCO/HID/PAN/A2DP", stack_info->sco_exist,
+ stack_info->hid_exist, stack_info->pan_exist,
+ stack_info->a2dp_exist);
+ CL_PRINTF(cli_buf);
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_BT_LINK_INFO);
+
+ bt_info_ext = coex_sta->bt_info_ext;
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s",
+ "BT Info A2DP rate",
+ (bt_info_ext&BIT0) ? "Basic rate" : "EDR rate");
+ CL_PRINTF(cli_buf);
+
+ for (i=0; i<BT_INFO_SRC_8192E_2ANT_MAX; i++) {
+ if (coex_sta->bt_info_c2h_cnt[i]) {
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ "\r\n %-35s = %02x %02x %02x %02x ",
+ GLBtInfoSrc8192e2Ant[i],
+ coex_sta->bt_info_c2h[i][0],
+ coex_sta->bt_info_c2h[i][1],
+ coex_sta->bt_info_c2h[i][2],
+ coex_sta->bt_info_c2h[i][3]);
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ "%02x %02x %02x(%d)",
+ coex_sta->bt_info_c2h[i][4],
+ coex_sta->bt_info_c2h[i][5],
+ coex_sta->bt_info_c2h[i][6],
+ coex_sta->bt_info_c2h_cnt[i]);
+ CL_PRINTF(cli_buf);
+ }
+ }
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %s/%s",
+ "PS state, IPS/LPS",
+ ((coex_sta->under_ips ? "IPS ON" : "IPS OFF")),
+ ((coex_sta->under_lps ? "LPS ON" : "LPS OFF")));
+ CL_PRINTF(cli_buf);
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_FW_PWR_MODE_CMD);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "SS Type",
+ coex_dm->cur_sstype);
+ CL_PRINTF(cli_buf);
+
+ /* Sw mechanism */
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ "============[Sw mechanism]============");
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d ",
+ "SM1[ShRf/ LpRA/ LimDig]", coex_dm->cur_rf_rx_lpf_shrink,
+ coex_dm->cur_low_penalty_ra, coex_dm->limited_dig);
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d/ %d(0x%x) ",
+ "SM2[AgcT/ AdcB/ SwDacSwing(lvl)]",
+ coex_dm->cur_agc_table_en, coex_dm->cur_adc_back_off,
+ coex_dm->cur_dac_swing_on, coex_dm->cur_dac_swing_lvl);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x ", "Rate Mask",
+ btcoexist->bt_info.ra_mask);
+ CL_PRINTF(cli_buf);
+
+ /* Fw mechanism */
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ "============[Fw mechanism]============");
+ CL_PRINTF(cli_buf);
+
+ ps_tdma_case = coex_dm->cur_ps_tdma;
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ "\r\n %-35s = %02x %02x %02x %02x %02x case-%d (auto:%d)",
+ "PS TDMA", coex_dm->ps_tdma_para[0],
+ coex_dm->ps_tdma_para[1], coex_dm->ps_tdma_para[2],
+ coex_dm->ps_tdma_para[3], coex_dm->ps_tdma_para[4],
+ ps_tdma_case, coex_dm->auto_tdma_adjust);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d ",
+ "DecBtPwr/ IgnWlanAct",
+ coex_dm->cur_dec_bt_pwr, coex_dm->cur_ignore_wlan_act);
+ CL_PRINTF(cli_buf);
+
+ /* Hw setting */
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s",
+ "============[Hw setting]============");
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x",
+ "RF-A, 0x1e initVal", coex_dm->bt_rf0x1e_backup);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
+ "backup ARFR1/ARFR2/RL/AMaxTime", coex_dm->backup_arfr_cnt1,
+ coex_dm->backup_arfr_cnt2, coex_dm->backup_retrylimit,
+ coex_dm->backup_ampdu_maxtime);
+ CL_PRINTF(cli_buf);
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x430);
+ u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x434);
+ u16tmp[0] = btcoexist->btc_read_2byte(btcoexist, 0x42a);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x456);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/0x%x/0x%x/0x%x",
+ "0x430/0x434/0x42a/0x456",
+ u32tmp[0], u32tmp[1], u16tmp[0], u8tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc04);
+ u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0xd04);
+ u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x90c);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x/ 0x%x",
+ "0xc04/ 0xd04/ 0x90c", u32tmp[0], u32tmp[1], u32tmp[2]);
+ CL_PRINTF(cli_buf);
+
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x778);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0x778",
+ u8tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x92c);
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x930);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ "0x92c/ 0x930", (u8tmp[0]), u32tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x40);
+ u8tmp[1] = btcoexist->btc_read_1byte(btcoexist, 0x4f);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ "0x40/ 0x4f", u8tmp[0], u8tmp[1]);
+ CL_PRINTF(cli_buf);
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x550);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x522);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x/ 0x%x",
+ "0x550(bcn ctrl)/0x522", u32tmp[0], u8tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0xc50);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = 0x%x", "0xc50(dig)",
+ u32tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ u32tmp[0] = btcoexist->btc_read_4byte(btcoexist, 0x6c0);
+ u32tmp[1] = btcoexist->btc_read_4byte(btcoexist, 0x6c4);
+ u32tmp[2] = btcoexist->btc_read_4byte(btcoexist, 0x6c8);
+ u8tmp[0] = btcoexist->btc_read_1byte(btcoexist, 0x6cc);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE,
+ "\r\n %-35s = 0x%x/ 0x%x/ 0x%x/ 0x%x",
+ "0x6c0/0x6c4/0x6c8/0x6cc(coexTable)",
+ u32tmp[0], u32tmp[1], u32tmp[2], u8tmp[0]);
+ CL_PRINTF(cli_buf);
+
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ "0x770(hp rx[31:16]/tx[15:0])",
+ coex_sta->high_priority_rx, coex_sta->high_priority_tx);
+ CL_PRINTF(cli_buf);
+ CL_SPRINTF(cli_buf, BT_TMP_BUF_SIZE, "\r\n %-35s = %d/ %d",
+ "0x774(lp rx[31:16]/tx[15:0])",
+ coex_sta->low_priority_rx, coex_sta->low_priority_tx);
+ CL_PRINTF(cli_buf);
+#if(BT_AUTO_REPORT_ONLY_8192E_2ANT == 1)
+ halbtc8192e2ant_monitor_bt_ctr(btcoexist);
+#endif
+ btcoexist->btc_disp_dbg_msg(btcoexist, BTC_DBG_DISP_COEX_STATISTICS);
+}
+
+
+void ex_halbtc8192e2ant_ips_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ if (BTC_IPS_ENTER == type) {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], IPS ENTER notify\n");
+ coex_sta->under_ips = true;
+ halbtc8192e2ant_coex_alloff(btcoexist);
+ } else if (BTC_IPS_LEAVE == type) {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], IPS LEAVE notify\n");
+ coex_sta->under_ips = false;
+ }
+}
+
+void ex_halbtc8192e2ant_lps_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ if (BTC_LPS_ENABLE == type) {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], LPS ENABLE notify\n");
+ coex_sta->under_lps = true;
+ } else if (BTC_LPS_DISABLE == type) {
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], LPS DISABLE notify\n");
+ coex_sta->under_lps = false;
+ }
+}
+
+void ex_halbtc8192e2ant_scan_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ if (BTC_SCAN_START == type)
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], SCAN START notify\n");
+ else if(BTC_SCAN_FINISH == type)
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], SCAN FINISH notify\n");
+}
+
+void ex_halbtc8192e2ant_connect_notify(struct btc_coexist *btcoexist, u8 type)
+{
+ if (BTC_ASSOCIATE_START == type)
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], CONNECT START notify\n");
+ else if(BTC_ASSOCIATE_FINISH == type)
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], CONNECT FINISH notify\n");
+}
+
+void ex_halbtc8192e2ant_media_status_notify(struct btc_coexist *btcoexist,
+ u8 type)
+{
+ u8 h2c_parameter[3] ={0};
+ u32 wifi_bw;
+ u8 wifi_center_chnl;
+
+ if (btcoexist->manual_control ||
+ btcoexist->stop_coex_dm ||
+ btcoexist->bt_info.bt_disabled)
+ return;
+
+ if (BTC_MEDIA_CONNECT == type)
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], MEDIA connect notify\n");
+ else
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], MEDIA disconnect notify\n");
+
+ /* only 2.4G we need to inform bt the chnl mask */
+ btcoexist->btc_get(btcoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL,
+ &wifi_center_chnl);
+ if ((BTC_MEDIA_CONNECT == type) &&
+ (wifi_center_chnl <= 14)) {
+ h2c_parameter[0] = 0x1;
+ h2c_parameter[1] = wifi_center_chnl;
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_BW, &wifi_bw);
+ if (BTC_WIFI_BW_HT40 == wifi_bw)
+ h2c_parameter[2] = 0x30;
+ else
+ h2c_parameter[2] = 0x20;
+ }
+
+ coex_dm->wifi_chnl_info[0] = h2c_parameter[0];
+ coex_dm->wifi_chnl_info[1] = h2c_parameter[1];
+ coex_dm->wifi_chnl_info[2] = h2c_parameter[2];
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC,
+ "[BTCoex], FW write 0x66=0x%x\n",
+ h2c_parameter[0] << 16 | h2c_parameter[1] << 8 |
+ h2c_parameter[2]);
+
+ btcoexist->btc_fill_h2c(btcoexist, 0x66, 3, h2c_parameter);
+}
+
+void ex_halbtc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist,
+ u8 type)
+{
+ if (type == BTC_PACKET_DHCP)
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], DHCP Packet notify\n");
+ }
+
+void ex_halbtc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist,
+ u8 *tmp_buf, u8 length )
+{
+ u8 bt_info = 0;
+ u8 i, rspSource = 0;
+ bool bt_busy = false, limited_dig = false;
+ bool wifi_connected = false;
+
+ coex_sta->c2h_bt_info_req_sent = false;
+
+ rspSource = tmp_buf[0] & 0xf;
+ if (rspSource >= BT_INFO_SRC_8192E_2ANT_MAX)
+ rspSource = BT_INFO_SRC_8192E_2ANT_WIFI_FW;
+ coex_sta->bt_info_c2h_cnt[rspSource]++;
+
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex], Bt info[%d], length=%d, hex data=[",
+ rspSource, length);
+ for (i = 0; i < length; i++) {
+ coex_sta->bt_info_c2h[rspSource][i] = tmp_buf[i];
+ if (i == 1)
+ bt_info = tmp_buf[i];
+ if (i == length-1)
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "0x%02x]\n", tmp_buf[i]);
+ else
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "0x%02x, ", tmp_buf[i]);
+ }
+
+ if (BT_INFO_SRC_8192E_2ANT_WIFI_FW != rspSource) {
+ coex_sta->bt_retry_cnt = /* [3:0] */
+ coex_sta->bt_info_c2h[rspSource][2] & 0xf;
+
+ coex_sta->bt_rssi =
+ coex_sta->bt_info_c2h[rspSource][3] * 2 + 10;
+
+ coex_sta->bt_info_ext =
+ coex_sta->bt_info_c2h[rspSource][4];
+
+ /* Here we need to resend some wifi info to BT
+ * because bt is reset and loss of the info. */
+ if ((coex_sta->bt_info_ext & BIT1)) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "bit1, send wifi BW&Chnl to BT!!\n");
+ btcoexist->btc_get(btcoexist, BTC_GET_BL_WIFI_CONNECTED,
+ &wifi_connected);
+ if (wifi_connected)
+ ex_halbtc8192e2ant_media_status_notify(
+ btcoexist,
+ BTC_MEDIA_CONNECT);
+ else
+ ex_halbtc8192e2ant_media_status_notify(
+ btcoexist,
+ BTC_MEDIA_DISCONNECT);
+ }
+
+ if ((coex_sta->bt_info_ext & BIT3)) {
+ if (!btcoexist->manual_control &&
+ !btcoexist->stop_coex_dm) {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "bit3, BT NOT ignore Wlan active!\n");
+ halbtc8192e2ant_IgnoreWlanAct(btcoexist,
+ FORCE_EXEC,
+ false);
+ }
+ } else {
+ /* BT already NOT ignore Wlan active,
+ * do nothing here. */
+ }
+
+#if(BT_AUTO_REPORT_ONLY_8192E_2ANT == 0)
+ if ((coex_sta->bt_info_ext & BIT4)) {
+ /* BT auto report already enabled, do nothing */
+ } else {
+ halbtc8192e2ant_bt_autoreport(btcoexist, FORCE_EXEC,
+ true);
+ }
+#endif
+ }
+
+ /* check BIT2 first ==> check if bt is under inquiry or page scan */
+ if(bt_info & BT_INFO_8192E_2ANT_B_INQ_PAGE)
+ coex_sta->c2h_bt_inquiry_page = true;
+ else
+ coex_sta->c2h_bt_inquiry_page = false;
+
+ /* set link exist status */
+ if (!(bt_info&BT_INFO_8192E_2ANT_B_CONNECTION)) {
+ coex_sta->bt_link_exist = false;
+ coex_sta->pan_exist = false;
+ coex_sta->a2dp_exist = false;
+ coex_sta->hid_exist = false;
+ coex_sta->sco_exist = false;
+ } else {/* connection exists */
+ coex_sta->bt_link_exist = true;
+ if (bt_info & BT_INFO_8192E_2ANT_B_FTP)
+ coex_sta->pan_exist = true;
+ else
+ coex_sta->pan_exist = false;
+ if (bt_info & BT_INFO_8192E_2ANT_B_A2DP)
+ coex_sta->a2dp_exist = true;
+ else
+ coex_sta->a2dp_exist = false;
+ if (bt_info & BT_INFO_8192E_2ANT_B_HID)
+ coex_sta->hid_exist = true;
+ else
+ coex_sta->hid_exist = false;
+ if (bt_info & BT_INFO_8192E_2ANT_B_SCO_ESCO)
+ coex_sta->sco_exist = true;
+ else
+ coex_sta->sco_exist = false;
+ }
+
+ halbtc8192e2ant_update_btlink_info(btcoexist);
+
+ if (!(bt_info&BT_INFO_8192E_2ANT_B_CONNECTION)) {
+ coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], BT Non-Connected idle!!!\n");
+ } else if (bt_info == BT_INFO_8192E_2ANT_B_CONNECTION) {
+ coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], bt_infoNotify(), BT Connected-idle!!!\n");
+ } else if ((bt_info&BT_INFO_8192E_2ANT_B_SCO_ESCO) ||
+ (bt_info&BT_INFO_8192E_2ANT_B_SCO_BUSY)) {
+ coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_SCO_BUSY;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], bt_infoNotify(), BT SCO busy!!!\n");
+ } else if (bt_info&BT_INFO_8192E_2ANT_B_ACL_BUSY) {
+ coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_ACL_BUSY;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex], bt_infoNotify(), BT ACL busy!!!\n");
+ } else {
+ coex_dm->bt_status = BT_8192E_2ANT_BT_STATUS_MAX;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "[BTCoex]bt_infoNotify(), BT Non-Defined state!!!\n");
+ }
+
+ if ((BT_8192E_2ANT_BT_STATUS_ACL_BUSY == coex_dm->bt_status) ||
+ (BT_8192E_2ANT_BT_STATUS_SCO_BUSY == coex_dm->bt_status) ||
+ (BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY == coex_dm->bt_status)) {
+ bt_busy = true;
+ limited_dig = true;
+ } else {
+ bt_busy = false;
+ limited_dig = false;
+ }
+
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bt_busy);
+
+ coex_dm->limited_dig = limited_dig;
+ btcoexist->btc_set(btcoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
+
+ halbtc8192e2ant_run_coexist_mechanism(btcoexist);
+}
+
+void ex_halbtc8192e2ant_stack_operation_notify(struct btc_coexist *btcoexist,
+ u8 type)
+{
+ if (BTC_STACK_OP_INQ_PAGE_PAIR_START == type)
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex] StackOP Inquiry/page/pair start notify\n");
+ else if(BTC_STACK_OP_INQ_PAGE_PAIR_FINISH == type)
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY,
+ "[BTCoex] StackOP Inquiry/page/pair finish notify\n");
+}
+
+void ex_halbtc8192e2ant_halt_notify(struct btc_coexist *btcoexist)
+{
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_NOTIFY, "[BTCoex], Halt notify\n");
+
+ halbtc8192e2ant_IgnoreWlanAct(btcoexist, FORCE_EXEC, true);
+ ex_halbtc8192e2ant_media_status_notify(btcoexist, BTC_MEDIA_DISCONNECT);
+}
+
+void ex_halbtc8192e2ant_periodical(struct btc_coexist *btcoexist)
+{
+ static u8 dis_ver_info_cnt = 0;
+ u32 fw_ver = 0, bt_patch_ver = 0;
+ struct btc_board_info *board_info=&btcoexist->board_info;
+ struct btc_stack_info *stack_info=&btcoexist->stack_info;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE,
+ "=======================Periodical=======================\n");
+ if (dis_ver_info_cnt <= 5) {
+ dis_ver_info_cnt += 1;
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+ "************************************************\n");
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+ "Ant PG Num/ Ant Mech/ Ant Pos = %d/ %d/ %d\n",
+ board_info->pg_ant_num, board_info->btdm_ant_num,
+ board_info->btdm_ant_pos);
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+ "BT stack/ hci ext ver = %s / %d\n",
+ ((stack_info->profile_notified) ? "Yes" : "No"),
+ stack_info->hci_version);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_BT_PATCH_VER,
+ &bt_patch_ver);
+ btcoexist->btc_get(btcoexist, BTC_GET_U4_WIFI_FW_VER, &fw_ver);
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+ "CoexVer/ FwVer/ PatchVer = %d_%x/ 0x%x/ 0x%x(%d)\n",
+ glcoex_ver_date_8192e_2ant, glcoex_ver_8192e_2ant,
+ fw_ver, bt_patch_ver, bt_patch_ver);
+ BTC_PRINT(BTC_MSG_INTERFACE, INTF_INIT,
+ "************************************************\n");
+ }
+
+#if(BT_AUTO_REPORT_ONLY_8192E_2ANT == 0)
+ halbtc8192e2ant_querybt_info(btcoexist);
+ halbtc8192e2ant_monitor_bt_ctr(btcoexist);
+ halbtc8192e2ant_monitor_bt_enable_disable(btcoexist);
+#else
+ if (halbtc8192e2ant_iswifi_status_changed(btcoexist) ||
+ coex_dm->auto_tdma_adjust)
+ halbtc8192e2ant_run_coexist_mechanism(btcoexist);
+#endif
+}
+
+
+#endif
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h
new file mode 100644
index 000000000000..6d109edb8950
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/halbtc8192e2ant.h
@@ -0,0 +1,162 @@
+/*****************************************************************
+ * The following is for 8192E 2Ant BT Co-exist definition
+ *****************************************************************/
+#define BT_AUTO_REPORT_ONLY_8192E_2ANT 0
+
+#define BT_INFO_8192E_2ANT_B_FTP BIT7
+#define BT_INFO_8192E_2ANT_B_A2DP BIT6
+#define BT_INFO_8192E_2ANT_B_HID BIT5
+#define BT_INFO_8192E_2ANT_B_SCO_BUSY BIT4
+#define BT_INFO_8192E_2ANT_B_ACL_BUSY BIT3
+#define BT_INFO_8192E_2ANT_B_INQ_PAGE BIT2
+#define BT_INFO_8192E_2ANT_B_SCO_ESCO BIT1
+#define BT_INFO_8192E_2ANT_B_CONNECTION BIT0
+
+#define BTC_RSSI_COEX_THRESH_TOL_8192E_2ANT 2
+
+enum bt_info_src_8192e_2ant{
+ BT_INFO_SRC_8192E_2ANT_WIFI_FW = 0x0,
+ BT_INFO_SRC_8192E_2ANT_BT_RSP = 0x1,
+ BT_INFO_SRC_8192E_2ANT_BT_ACTIVE_SEND = 0x2,
+ BT_INFO_SRC_8192E_2ANT_MAX
+};
+
+enum bt_8192e_2ant_bt_status{
+ BT_8192E_2ANT_BT_STATUS_NON_CONNECTED_IDLE = 0x0,
+ BT_8192E_2ANT_BT_STATUS_CONNECTED_IDLE = 0x1,
+ BT_8192E_2ANT_BT_STATUS_INQ_PAGE = 0x2,
+ BT_8192E_2ANT_BT_STATUS_ACL_BUSY = 0x3,
+ BT_8192E_2ANT_BT_STATUS_SCO_BUSY = 0x4,
+ BT_8192E_2ANT_BT_STATUS_ACL_SCO_BUSY = 0x5,
+ BT_8192E_2ANT_BT_STATUS_MAX
+};
+
+enum bt_8192e_2ant_coex_algo{
+ BT_8192E_2ANT_COEX_ALGO_UNDEFINED = 0x0,
+ BT_8192E_2ANT_COEX_ALGO_SCO = 0x1,
+ BT_8192E_2ANT_COEX_ALGO_SCO_PAN = 0x2,
+ BT_8192E_2ANT_COEX_ALGO_HID = 0x3,
+ BT_8192E_2ANT_COEX_ALGO_A2DP = 0x4,
+ BT_8192E_2ANT_COEX_ALGO_A2DP_PANHS = 0x5,
+ BT_8192E_2ANT_COEX_ALGO_PANEDR = 0x6,
+ BT_8192E_2ANT_COEX_ALGO_PANHS = 0x7,
+ BT_8192E_2ANT_COEX_ALGO_PANEDR_A2DP = 0x8,
+ BT_8192E_2ANT_COEX_ALGO_PANEDR_HID = 0x9,
+ BT_8192E_2ANT_COEX_ALGO_HID_A2DP_PANEDR = 0xa,
+ BT_8192E_2ANT_COEX_ALGO_HID_A2DP = 0xb,
+ BT_8192E_2ANT_COEX_ALGO_MAX = 0xc
+};
+
+struct coex_dm_8192e_2ant{
+ /* fw mechanism */
+ u8 pre_dec_bt_pwr;
+ u8 cur_dec_bt_pwr;
+ u8 pre_fw_dac_swing_lvl;
+ u8 cur_fw_dac_swing_lvl;
+ bool cur_ignore_wlan_act;
+ bool pre_ignore_wlan_act;
+ u8 pre_ps_tdma;
+ u8 cur_ps_tdma;
+ u8 ps_tdma_para[5];
+ u8 ps_tdma_du_adj_type;
+ bool reset_tdma_adjust;
+ bool auto_tdma_adjust;
+ bool pre_ps_tdma_on;
+ bool cur_ps_tdma_on;
+ bool pre_bt_auto_report;
+ bool cur_bt_auto_report;
+
+ /* sw mechanism */
+ bool pre_rf_rx_lpf_shrink;
+ bool cur_rf_rx_lpf_shrink;
+ u32 bt_rf0x1e_backup;
+ bool pre_low_penalty_ra;
+ bool cur_low_penalty_ra;
+ bool pre_dac_swing_on;
+ u32 pre_dac_swing_lvl;
+ bool cur_dac_swing_on;
+ u32 cur_dac_swing_lvl;
+ bool pre_adc_back_off;
+ bool cur_adc_back_off;
+ bool pre_agc_table_en;
+ bool cur_agc_table_en;
+ u32 pre_val0x6c0;
+ u32 cur_val0x6c0;
+ u32 pre_val0x6c4;
+ u32 cur_val0x6c4;
+ u32 pre_val0x6c8;
+ u32 cur_val0x6c8;
+ u8 pre_val0x6cc;
+ u8 cur_val0x6cc;
+ bool limited_dig;
+
+ u32 backup_arfr_cnt1; /* Auto Rate Fallback Retry cnt */
+ u32 backup_arfr_cnt2; /* Auto Rate Fallback Retry cnt */
+ u16 backup_retrylimit;
+ u8 backup_ampdu_maxtime;
+
+ /* algorithm related */
+ u8 pre_algorithm;
+ u8 cur_algorithm;
+ u8 bt_status;
+ u8 wifi_chnl_info[3];
+
+ u8 pre_sstype;
+ u8 cur_sstype;
+
+ u32 prera_mask;
+ u32 curra_mask;
+ u8 curra_masktype;
+ u8 pre_arfrtype;
+ u8 cur_arfrtype;
+ u8 pre_retrylimit_type;
+ u8 cur_retrylimit_type;
+ u8 pre_ampdutime_type;
+ u8 cur_ampdutime_type;
+};
+
+struct coex_sta_8192e_2ant{
+ bool bt_link_exist;
+ bool sco_exist;
+ bool a2dp_exist;
+ bool hid_exist;
+ bool pan_exist;
+
+ bool under_lps;
+ bool under_ips;
+ u32 high_priority_tx;
+ u32 high_priority_rx;
+ u32 low_priority_tx;
+ u32 low_priority_rx;
+ u8 bt_rssi;
+ u8 pre_bt_rssi_state;
+ u8 pre_wifi_rssi_state[4];
+ bool c2h_bt_info_req_sent;
+ u8 bt_info_c2h[BT_INFO_SRC_8192E_2ANT_MAX][10];
+ u32 bt_info_c2h_cnt[BT_INFO_SRC_8192E_2ANT_MAX];
+ bool c2h_bt_inquiry_page;
+ u8 bt_retry_cnt;
+ u8 bt_info_ext;
+};
+
+/****************************************************************
+ * The following is interface which will notify coex module.
+ ****************************************************************/
+void ex_halbtc8192e2ant_init_hwconfig(struct btc_coexist *btcoexist);
+void ex_halbtc8192e2ant_init_coex_dm(struct btc_coexist *btcoexist);
+void ex_halbtc8192e2ant_ips_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8192e2ant_lps_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8192e2ant_scan_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8192e2ant_connect_notify(struct btc_coexist *btcoexist, u8 type);
+void ex_halbtc8192e2ant_media_status_notify(struct btc_coexist *btcoexist,
+ u8 type);
+void ex_halbtc8192e2ant_special_packet_notify(struct btc_coexist *btcoexist,
+ u8 type);
+void ex_halbtc8192e2ant_bt_info_notify(struct btc_coexist *btcoexist,
+ u8 *tmpBuf,u8 length);
+void ex_halbtc8192e2ant_stack_operation_notify(struct btc_coexist *btcoexist,
+ u8 type);
+void ex_halbtc8192e2ant_halt_notify(struct btc_coexist *btcoexist);
+void ex_halbtc8192e2ant_periodical(struct btc_coexist *btcoexist);
+void ex_halbtc8192e2ant_display_coex_info(struct btc_coexist *btcoexist);
+
diff --git a/drivers/staging/rtl8821ae/btcoexist/halbtc8723a2ant.c b/drivers/staging/rtl8821ae/btcoexist/halbtc8723a2ant.c
new file mode 100644
index 000000000000..180d6f12e7b5
--- /dev/null
+++ b/drivers/staging/rtl8821ae/btcoexist/halbtc8723a2ant.c
@@ -0,0 +1,3780 @@
+//============================================================
+// Description:
+//
+// This file is for RTL8723A Co-exist mechanism
+//
+// History
+// 2012/08/22 Cosa first check in.
+// 2012/11/14 Cosa Revise for 8723A 2Ant out sourcing.
+//
+//============================================================
+
+//============================================================
+// include files
+//============================================================
+#include "Mp_Precomp.h"
+#if(BT_30_SUPPORT == 1)
+//============================================================
+// Global variables, these are static variables
+//============================================================
+static COEX_DM_8723A_2ANT GLCoexDm8723a2Ant;
+static PCOEX_DM_8723A_2ANT pCoexDm=&GLCoexDm8723a2Ant;
+static COEX_STA_8723A_2ANT GLCoexSta8723a2Ant;
+static PCOEX_STA_8723A_2ANT pCoexSta=&GLCoexSta8723a2Ant;
+
+const char *const GLBtInfoSrc8723a2Ant[]={
+ "BT Info[wifi fw]",
+ "BT Info[bt rsp]",
+ "BT Info[bt auto report]",
+};
+
+//============================================================
+// local function proto type if needed
+//============================================================
+//============================================================
+// local function start with halbtc8723a2ant_
+//============================================================
+BOOLEAN
+halbtc8723a2ant_IsWifiIdle(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BOOLEAN bWifiConnected=FALSE, bScan=FALSE, bLink=FALSE, bRoam=FALSE;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_SCAN, &bScan);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_LINK, &bLink);
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_ROAM, &bRoam);
+
+ if(bWifiConnected)
+ return FALSE;
+ if(bScan)
+ return FALSE;
+ if(bLink)
+ return FALSE;
+ if(bRoam)
+ return FALSE;
+
+ return true;
+}
+
+u1Byte
+halbtc8723a2ant_BtRssiState(
+ u1Byte levelNum,
+ u1Byte rssiThresh,
+ u1Byte rssiThresh1
+ )
+{
+ s4Byte btRssi=0;
+ u1Byte btRssiState=pCoexSta->preBtRssiState;
+
+ btRssi = pCoexSta->btRssi;
+
+ if(levelNum == 2)
+ {
+ if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) ||
+ (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT))
+ {
+ btRssiState = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to High\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at Low\n"));
+ }
+ }
+ else
+ {
+ if(btRssi < rssiThresh)
+ {
+ btRssiState = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Low\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at High\n"));
+ }
+ }
+ }
+ else if(levelNum == 3)
+ {
+ if(rssiThresh > rssiThresh1)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi thresh error!!\n"));
+ return pCoexSta->preBtRssiState;
+ }
+
+ if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_LOW) ||
+ (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(btRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT))
+ {
+ btRssiState = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Medium\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at Low\n"));
+ }
+ }
+ else if( (pCoexSta->preBtRssiState == BTC_RSSI_STATE_MEDIUM) ||
+ (pCoexSta->preBtRssiState == BTC_RSSI_STATE_STAY_MEDIUM))
+ {
+ if(btRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT))
+ {
+ btRssiState = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to High\n"));
+ }
+ else if(btRssi < rssiThresh)
+ {
+ btRssiState = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Low\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at Medium\n"));
+ }
+ }
+ else
+ {
+ if(btRssi < rssiThresh1)
+ {
+ btRssiState = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state switch to Medium\n"));
+ }
+ else
+ {
+ btRssiState = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_RSSI_STATE, ("[BTCoex], BT Rssi state stay at High\n"));
+ }
+ }
+ }
+
+ pCoexSta->preBtRssiState = btRssiState;
+
+ return btRssiState;
+}
+
+u1Byte
+halbtc8723a2ant_WifiRssiState(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte index,
+ IN u1Byte levelNum,
+ IN u1Byte rssiThresh,
+ IN u1Byte rssiThresh1
+ )
+{
+ s4Byte wifiRssi=0;
+ u1Byte wifiRssiState=pCoexSta->preWifiRssiState[index];
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_S4_WIFI_RSSI, &wifiRssi);
+
+ if(levelNum == 2)
+ {
+ if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) ||
+ (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT))
+ {
+ wifiRssiState = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to High\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at Low\n"));
+ }
+ }
+ else
+ {
+ if(wifiRssi < rssiThresh)
+ {
+ wifiRssiState = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Low\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at High\n"));
+ }
+ }
+ }
+ else if(levelNum == 3)
+ {
+ if(rssiThresh > rssiThresh1)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI thresh error!!\n"));
+ return pCoexSta->preWifiRssiState[index];
+ }
+
+ if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_LOW) ||
+ (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_LOW))
+ {
+ if(wifiRssi >= (rssiThresh+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT))
+ {
+ wifiRssiState = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Medium\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at Low\n"));
+ }
+ }
+ else if( (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_MEDIUM) ||
+ (pCoexSta->preWifiRssiState[index] == BTC_RSSI_STATE_STAY_MEDIUM))
+ {
+ if(wifiRssi >= (rssiThresh1+BTC_RSSI_COEX_THRESH_TOL_8723A_2ANT))
+ {
+ wifiRssiState = BTC_RSSI_STATE_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to High\n"));
+ }
+ else if(wifiRssi < rssiThresh)
+ {
+ wifiRssiState = BTC_RSSI_STATE_LOW;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Low\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at Medium\n"));
+ }
+ }
+ else
+ {
+ if(wifiRssi < rssiThresh1)
+ {
+ wifiRssiState = BTC_RSSI_STATE_MEDIUM;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state switch to Medium\n"));
+ }
+ else
+ {
+ wifiRssiState = BTC_RSSI_STATE_STAY_HIGH;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_WIFI_RSSI_STATE, ("[BTCoex], wifi RSSI state stay at High\n"));
+ }
+ }
+ }
+
+ pCoexSta->preWifiRssiState[index] = wifiRssiState;
+
+ return wifiRssiState;
+}
+
+VOID
+halbtc8723a2ant_IndicateWifiChnlBwInfo(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte type
+ )
+{
+ u1Byte H2C_Parameter[3] ={0};
+ u4Byte wifiBw;
+ u1Byte wifiCentralChnl;
+
+ // only 2.4G we need to inform bt the chnl mask
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U1_WIFI_CENTRAL_CHNL, &wifiCentralChnl);
+ if( (BTC_MEDIA_CONNECT == type) &&
+ (wifiCentralChnl <= 14) )
+ {
+ H2C_Parameter[0] = 0x1;
+ H2C_Parameter[1] = wifiCentralChnl;
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_U4_WIFI_BW, &wifiBw);
+ if(BTC_WIFI_BW_HT40 == wifiBw)
+ H2C_Parameter[2] = 0x30;
+ else
+ H2C_Parameter[2] = 0x20;
+ }
+
+ pCoexDm->wifiChnlInfo[0] = H2C_Parameter[0];
+ pCoexDm->wifiChnlInfo[1] = H2C_Parameter[1];
+ pCoexDm->wifiChnlInfo[2] = H2C_Parameter[2];
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x19=0x%x\n",
+ H2C_Parameter[0]<<16|H2C_Parameter[1]<<8|H2C_Parameter[2]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x19, 3, H2C_Parameter);
+}
+
+VOID
+halbtc8723a2ant_QueryBtInfo(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ pCoexSta->bC2hBtInfoReqSent = true;
+
+ H2C_Parameter[0] |= BIT0; // trigger
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], Query Bt Info, FW write 0x38=0x%x\n",
+ H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x38, 1, H2C_Parameter);
+}
+u1Byte
+halbtc8723a2ant_ActionAlgorithm(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ PBTC_STACK_INFO pStackInfo=&pBtCoexist->stack_info;
+ BOOLEAN bBtHsOn=FALSE, bBtBusy=FALSE, limited_dig=FALSE;
+ u1Byte algorithm=BT_8723A_2ANT_COEX_ALGO_UNDEFINED;
+ u1Byte numOfDiffProfile=0;
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn);
+
+ //======================
+ // here we get BT status first
+ //======================
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_IDLE;
+
+ if((pStackInfo->bScoExist) ||(bBtHsOn) ||(pStackInfo->bHidExist))
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO or HID or HS exists, set BT non-idle !!!\n"));
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_NON_IDLE;
+ }
+ else
+ {
+ // A2dp profile
+ if( (pBtCoexist->stack_info.numOfLink == 1) &&
+ (pStackInfo->bA2dpExist) )
+ {
+ if( (pCoexSta->lowPriorityTx+ pCoexSta->lowPriorityRx) < 100)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP, low priority tx+rx < 100, set BT connected-idle!!!\n"));
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP, low priority tx+rx >= 100, set BT non-idle!!!\n"));
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_NON_IDLE;
+ }
+ }
+ // Pan profile
+ if( (pBtCoexist->stack_info.numOfLink == 1) &&
+ (pStackInfo->bPanExist) )
+ {
+ if((pCoexSta->lowPriorityTx+ pCoexSta->lowPriorityRx) < 600)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN, low priority tx+rx < 600, set BT connected-idle!!!\n"));
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE;
+ }
+ else
+ {
+ if(pCoexSta->lowPriorityTx)
+ {
+ if((pCoexSta->lowPriorityRx /pCoexSta->lowPriorityTx)>9 )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN, low priority rx/tx > 9, set BT connected-idle!!!\n"));
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE;
+ }
+ }
+ }
+ if(BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN, set BT non-idle!!!\n"));
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_NON_IDLE;
+ }
+ }
+ // Pan+A2dp profile
+ if( (pBtCoexist->stack_info.numOfLink == 2) &&
+ (pStackInfo->bA2dpExist) &&
+ (pStackInfo->bPanExist) )
+ {
+ if((pCoexSta->lowPriorityTx+ pCoexSta->lowPriorityRx) < 600)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN+A2DP, low priority tx+rx < 600, set BT connected-idle!!!\n"));
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE;
+ }
+ else
+ {
+ if(pCoexSta->lowPriorityTx)
+ {
+ if((pCoexSta->lowPriorityRx /pCoexSta->lowPriorityTx)>9 )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN+A2DP, low priority rx/tx > 9, set BT connected-idle!!!\n"));
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE;
+ }
+ }
+ }
+ if(BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE != pCoexDm->btStatus)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN+A2DP, set BT non-idle!!!\n"));
+ pCoexDm->btStatus = BT_8723A_2ANT_BT_STATUS_NON_IDLE;
+ }
+ }
+ }
+ if(BT_8723A_2ANT_BT_STATUS_IDLE != pCoexDm->btStatus)
+ {
+ bBtBusy = true;
+ limited_dig = true;
+ }
+ else
+ {
+ bBtBusy = FALSE;
+ limited_dig = FALSE;
+ }
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_TRAFFIC_BUSY, &bBtBusy);
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_LIMITED_DIG, &limited_dig);
+ //======================
+
+ if(!pStackInfo->bBtLinkExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], No profile exists!!!\n"));
+ return algorithm;
+ }
+
+ if(pStackInfo->bScoExist)
+ numOfDiffProfile++;
+ if(pStackInfo->bHidExist)
+ numOfDiffProfile++;
+ if(pStackInfo->bPanExist)
+ numOfDiffProfile++;
+ if(pStackInfo->bA2dpExist)
+ numOfDiffProfile++;
+
+ if(numOfDiffProfile == 1)
+ {
+ if(pStackInfo->bScoExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO only\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_SCO;
+ }
+ else
+ {
+ if(pStackInfo->bHidExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID only\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_HID;
+ }
+ else if(pStackInfo->bA2dpExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP only\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_A2DP;
+ }
+ else if(pStackInfo->bPanExist)
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN(HS) only\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_PANHS;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], PAN(EDR) only\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR;
+ }
+ }
+ }
+ }
+ else if(numOfDiffProfile == 2)
+ {
+ if(pStackInfo->bScoExist)
+ {
+ if(pStackInfo->bHidExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_HID;
+ }
+ else if(pStackInfo->bA2dpExist)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + A2DP ==> SCO\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_SCO;
+ }
+ else if(pStackInfo->bPanExist)
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + PAN(HS)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_SCO;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + PAN(EDR)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ else
+ {
+ if( pStackInfo->bHidExist &&
+ pStackInfo->bA2dpExist )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + A2DP\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP;
+ }
+ else if( pStackInfo->bHidExist &&
+ pStackInfo->bPanExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + PAN(HS)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + PAN(EDR)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ else if( pStackInfo->bPanExist &&
+ pStackInfo->bA2dpExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP + PAN(HS)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], A2DP + PAN(EDR)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_A2DP;
+ }
+ }
+ }
+ }
+ else if(numOfDiffProfile == 3)
+ {
+ if(pStackInfo->bScoExist)
+ {
+ if( pStackInfo->bHidExist &&
+ pStackInfo->bA2dpExist )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + A2DP ==> HID\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_HID;
+ }
+ else if( pStackInfo->bHidExist &&
+ pStackInfo->bPanExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + PAN(HS)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + PAN(EDR)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ else if( pStackInfo->bPanExist &&
+ pStackInfo->bA2dpExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + A2DP + PAN(HS)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_SCO;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + A2DP + PAN(EDR) ==> HID\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ else
+ {
+ if( pStackInfo->bHidExist &&
+ pStackInfo->bPanExist &&
+ pStackInfo->bA2dpExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + A2DP + PAN(HS)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], HID + A2DP + PAN(EDR)\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_HID_A2DP_PANEDR;
+ }
+ }
+ }
+ }
+ else if(numOfDiffProfile >= 3)
+ {
+ if(pStackInfo->bScoExist)
+ {
+ if( pStackInfo->bHidExist &&
+ pStackInfo->bPanExist &&
+ pStackInfo->bA2dpExist )
+ {
+ if(bBtHsOn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Error!!! SCO + HID + A2DP + PAN(HS)\n"));
+
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], SCO + HID + A2DP + PAN(EDR)==>PAN(EDR)+HID\n"));
+ algorithm = BT_8723A_2ANT_COEX_ALGO_PANEDR_HID;
+ }
+ }
+ }
+ }
+
+ return algorithm;
+}
+
+BOOLEAN
+halbtc8723a2ant_NeedToDecBtPwr(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BOOLEAN bRet=FALSE;
+ BOOLEAN bBtHsOn=FALSE, bWifiConnected=FALSE;
+ s4Byte btHsRssi=0;
+
+ if(!pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_HS_OPERATION, &bBtHsOn))
+ return FALSE;
+ if(!pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected))
+ return FALSE;
+ if(!pBtCoexist->btc_get(pBtCoexist, BTC_GET_S4_HS_RSSI, &btHsRssi))
+ return FALSE;
+
+ if(bWifiConnected)
+ {
+ if(bBtHsOn)
+ {
+ if(btHsRssi > 37)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], Need to decrease bt power for HS mode!!\n"));
+ bRet = true;
+ }
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], Need to decrease bt power for Wifi is connected!!\n"));
+ bRet = true;
+ }
+ }
+
+ return bRet;
+}
+
+VOID
+halbtc8723a2ant_SetFwDacSwingLevel(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte dacSwingLvl
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ // There are several type of dacswing
+ // 0x18/ 0x10/ 0xc/ 0x8/ 0x4/ 0x6
+ H2C_Parameter[0] = dacSwingLvl;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], Set Dac Swing Level=0x%x\n", dacSwingLvl));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x29=0x%x\n", H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x29, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8723a2ant_SetFwDecBtPwr(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bDecBtPwr
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ H2C_Parameter[0] = 0;
+
+ if(bDecBtPwr)
+ {
+ H2C_Parameter[0] |= BIT1;
+ }
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], decrease Bt Power : %s, FW write 0x21=0x%x\n",
+ (bDecBtPwr? "Yes!!":"No!!"), H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x21, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8723a2ant_DecBtPwr(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bDecBtPwr
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s Dec BT power = %s\n",
+ (bForceExec? "force to":""), ((bDecBtPwr)? "ON":"OFF")));
+ pCoexDm->bCurDecBtPwr = bDecBtPwr;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPreDecBtPwr=%d, bCurDecBtPwr=%d\n",
+ pCoexDm->bPreDecBtPwr, pCoexDm->bCurDecBtPwr));
+
+ if(pCoexDm->bPreDecBtPwr == pCoexDm->bCurDecBtPwr)
+ return;
+ }
+ halbtc8723a2ant_SetFwDecBtPwr(pBtCoexist, pCoexDm->bCurDecBtPwr);
+
+ pCoexDm->bPreDecBtPwr = pCoexDm->bCurDecBtPwr;
+}
+
+VOID
+halbtc8723a2ant_FwDacSwingLvl(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u1Byte fwDacSwingLvl
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s set FW Dac Swing level = %d\n",
+ (bForceExec? "force to":""), fwDacSwingLvl));
+ pCoexDm->curFwDacSwingLvl = fwDacSwingLvl;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], preFwDacSwingLvl=%d, curFwDacSwingLvl=%d\n",
+ pCoexDm->preFwDacSwingLvl, pCoexDm->curFwDacSwingLvl));
+
+ if(pCoexDm->preFwDacSwingLvl == pCoexDm->curFwDacSwingLvl)
+ return;
+ }
+
+ halbtc8723a2ant_SetFwDacSwingLevel(pBtCoexist, pCoexDm->curFwDacSwingLvl);
+
+ pCoexDm->preFwDacSwingLvl = pCoexDm->curFwDacSwingLvl;
+}
+
+VOID
+halbtc8723a2ant_SetSwRfRxLpfCorner(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bRxRfShrinkOn
+ )
+{
+ if(bRxRfShrinkOn)
+ {
+ //Shrink RF Rx LPF corner
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Shrink RF Rx LPF corner!!\n"));
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, 0xf0ff7);
+ }
+ else
+ {
+ //Resume RF Rx LPF corner
+ // After initialized, we can use pCoexDm->btRf0x1eBackup
+ if(pBtCoexist->initilized)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Resume RF Rx LPF corner!!\n"));
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x1e, 0xfffff, pCoexDm->btRf0x1eBackup);
+ }
+ }
+}
+
+VOID
+halbtc8723a2ant_RfShrink(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bRxRfShrinkOn
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn Rx RF Shrink = %s\n",
+ (bForceExec? "force to":""), ((bRxRfShrinkOn)? "ON":"OFF")));
+ pCoexDm->bCurRfRxLpfShrink = bRxRfShrinkOn;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreRfRxLpfShrink=%d, bCurRfRxLpfShrink=%d\n",
+ pCoexDm->bPreRfRxLpfShrink, pCoexDm->bCurRfRxLpfShrink));
+
+ if(pCoexDm->bPreRfRxLpfShrink == pCoexDm->bCurRfRxLpfShrink)
+ return;
+ }
+ halbtc8723a2ant_SetSwRfRxLpfCorner(pBtCoexist, pCoexDm->bCurRfRxLpfShrink);
+
+ pCoexDm->bPreRfRxLpfShrink = pCoexDm->bCurRfRxLpfShrink;
+}
+
+VOID
+halbtc8723a2ant_SetSwPenaltyTxRateAdaptive(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bLowPenaltyRa
+ )
+{
+ u1Byte tmpU1;
+
+ tmpU1 = pBtCoexist->btc_read_1byte(pBtCoexist, 0x4fd);
+ tmpU1 |= BIT0;
+ if(bLowPenaltyRa)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Tx rate adaptive, set low penalty!!\n"));
+ tmpU1 &= ~BIT2;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Tx rate adaptive, set normal!!\n"));
+ tmpU1 |= BIT2;
+ }
+
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x4fd, tmpU1);
+}
+
+VOID
+halbtc8723a2ant_LowPenaltyRa(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bLowPenaltyRa
+ )
+{
+ return;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn LowPenaltyRA = %s\n",
+ (bForceExec? "force to":""), ((bLowPenaltyRa)? "ON":"OFF")));
+ pCoexDm->bCurLowPenaltyRa = bLowPenaltyRa;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreLowPenaltyRa=%d, bCurLowPenaltyRa=%d\n",
+ pCoexDm->bPreLowPenaltyRa, pCoexDm->bCurLowPenaltyRa));
+
+ if(pCoexDm->bPreLowPenaltyRa == pCoexDm->bCurLowPenaltyRa)
+ return;
+ }
+ halbtc8723a2ant_SetSwPenaltyTxRateAdaptive(pBtCoexist, pCoexDm->bCurLowPenaltyRa);
+
+ pCoexDm->bPreLowPenaltyRa = pCoexDm->bCurLowPenaltyRa;
+}
+
+VOID
+halbtc8723a2ant_SetSwFullTimeDacSwing(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bSwDacSwingOn,
+ IN u4Byte swDacSwingLvl
+ )
+{
+ if(bSwDacSwingOn)
+ {
+ pBtCoexist->btc_setBbReg(pBtCoexist, 0x880, 0xff000000, swDacSwingLvl);
+ }
+ else
+ {
+ pBtCoexist->btc_setBbReg(pBtCoexist, 0x880, 0xff000000, 0xc0);
+ }
+}
+
+
+VOID
+halbtc8723a2ant_DacSwing(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bDacSwingOn,
+ IN u4Byte dacSwingLvl
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn DacSwing=%s, dacSwingLvl=0x%x\n",
+ (bForceExec? "force to":""), ((bDacSwingOn)? "ON":"OFF"), dacSwingLvl));
+ pCoexDm->bCurDacSwingOn = bDacSwingOn;
+ pCoexDm->curDacSwingLvl = dacSwingLvl;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreDacSwingOn=%d, preDacSwingLvl=0x%x, bCurDacSwingOn=%d, curDacSwingLvl=0x%x\n",
+ pCoexDm->bPreDacSwingOn, pCoexDm->preDacSwingLvl,
+ pCoexDm->bCurDacSwingOn, pCoexDm->curDacSwingLvl));
+
+ if( (pCoexDm->bPreDacSwingOn == pCoexDm->bCurDacSwingOn) &&
+ (pCoexDm->preDacSwingLvl == pCoexDm->curDacSwingLvl) )
+ return;
+ }
+ mdelay(30);
+ halbtc8723a2ant_SetSwFullTimeDacSwing(pBtCoexist, bDacSwingOn, dacSwingLvl);
+
+ pCoexDm->bPreDacSwingOn = pCoexDm->bCurDacSwingOn;
+ pCoexDm->preDacSwingLvl = pCoexDm->curDacSwingLvl;
+}
+
+VOID
+halbtc8723a2ant_SetAdcBackOff(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bAdcBackOff
+ )
+{
+ if(bAdcBackOff)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], BB BackOff Level On!\n"));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc04,0x3a07611);
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], BB BackOff Level Off!\n"));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc04,0x3a05611);
+ }
+}
+
+VOID
+halbtc8723a2ant_AdcBackOff(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bAdcBackOff
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s turn AdcBackOff = %s\n",
+ (bForceExec? "force to":""), ((bAdcBackOff)? "ON":"OFF")));
+ pCoexDm->bCurAdcBackOff = bAdcBackOff;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreAdcBackOff=%d, bCurAdcBackOff=%d\n",
+ pCoexDm->bPreAdcBackOff, pCoexDm->bCurAdcBackOff));
+
+ if(pCoexDm->bPreAdcBackOff == pCoexDm->bCurAdcBackOff)
+ return;
+ }
+ halbtc8723a2ant_SetAdcBackOff(pBtCoexist, pCoexDm->bCurAdcBackOff);
+
+ pCoexDm->bPreAdcBackOff = pCoexDm->bCurAdcBackOff;
+}
+
+VOID
+halbtc8723a2ant_SetAgcTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bAgcTableEn
+ )
+{
+ u1Byte rssiAdjustVal=0;
+
+ if(bAgcTableEn)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Agc Table On!\n"));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x4e1c0001);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x4d1d0001);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x4c1e0001);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x4b1f0001);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x4a200001);
+
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xdc000);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x90000);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x51000);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x12000);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x1a, 0xfffff, 0x00355);
+
+ rssiAdjustVal = 6;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], Agc Table Off!\n"));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x641c0001);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x631d0001);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x621e0001);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x611f0001);
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0xc78,0x60200001);
+
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x32000);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0x71000);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xb0000);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x12, 0xfffff, 0xfc000);
+ pBtCoexist->btc_set_rf_reg(pBtCoexist, BTC_RF_A, 0x1a, 0xfffff, 0x30355);
+ }
+
+ // set rssiAdjustVal for wifi module.
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_U1_RSSI_ADJ_VAL_FOR_AGC_TABLE_ON, &rssiAdjustVal);
+}
+
+
+VOID
+halbtc8723a2ant_AgcTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bAgcTableEn
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s %s Agc Table\n",
+ (bForceExec? "force to":""), ((bAgcTableEn)? "Enable":"Disable")));
+ pCoexDm->bCurAgcTableEn = bAgcTableEn;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], bPreAgcTableEn=%d, bCurAgcTableEn=%d\n",
+ pCoexDm->bPreAgcTableEn, pCoexDm->bCurAgcTableEn));
+
+ if(pCoexDm->bPreAgcTableEn == pCoexDm->bCurAgcTableEn)
+ return;
+ }
+ halbtc8723a2ant_SetAgcTable(pBtCoexist, bAgcTableEn);
+
+ pCoexDm->bPreAgcTableEn = pCoexDm->bCurAgcTableEn;
+}
+
+VOID
+halbtc8723a2ant_SetCoexTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u4Byte val0x6c0,
+ IN u4Byte val0x6c8,
+ IN u1Byte val0x6cc
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c0=0x%x\n", val0x6c0));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x6c0, val0x6c0);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6c8=0x%x\n", val0x6c8));
+ pBtCoexist->btc_write_4byte(pBtCoexist, 0x6c8, val0x6c8);
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_EXEC, ("[BTCoex], set coex table, set 0x6cc=0x%x\n", val0x6cc));
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x6cc, val0x6cc);
+}
+
+VOID
+halbtc8723a2ant_CoexTable(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN u4Byte val0x6c0,
+ IN u4Byte val0x6c8,
+ IN u1Byte val0x6cc
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW, ("[BTCoex], %s write Coex Table 0x6c0=0x%x, 0x6c8=0x%x, 0x6cc=0x%x\n",
+ (bForceExec? "force to":""), val0x6c0, val0x6c8, val0x6cc));
+ pCoexDm->curVal0x6c0 = val0x6c0;
+ pCoexDm->curVal0x6c8 = val0x6c8;
+ pCoexDm->curVal0x6cc = val0x6cc;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], preVal0x6c0=0x%x, preVal0x6c8=0x%x, preVal0x6cc=0x%x !!\n",
+ pCoexDm->preVal0x6c0, pCoexDm->preVal0x6c8, pCoexDm->preVal0x6cc));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_SW_DETAIL, ("[BTCoex], curVal0x6c0=0x%x, curVal0x6c8=0x%x, curVal0x6cc=0x%x !!\n",
+ pCoexDm->curVal0x6c0, pCoexDm->curVal0x6c8, pCoexDm->curVal0x6cc));
+
+ if( (pCoexDm->preVal0x6c0 == pCoexDm->curVal0x6c0) &&
+ (pCoexDm->preVal0x6c8 == pCoexDm->curVal0x6c8) &&
+ (pCoexDm->preVal0x6cc == pCoexDm->curVal0x6cc) )
+ return;
+ }
+ halbtc8723a2ant_SetCoexTable(pBtCoexist, val0x6c0, val0x6c8, val0x6cc);
+
+ pCoexDm->preVal0x6c0 = pCoexDm->curVal0x6c0;
+ pCoexDm->preVal0x6c8 = pCoexDm->curVal0x6c8;
+ pCoexDm->preVal0x6cc = pCoexDm->curVal0x6cc;
+}
+
+VOID
+halbtc8723a2ant_SetFwIgnoreWlanAct(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bEnable
+ )
+{
+ u1Byte H2C_Parameter[1] ={0};
+
+ if(bEnable)
+ {
+ H2C_Parameter[0] |= BIT0; // function enable
+ }
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], set FW for BT Ignore Wlan_Act, FW write 0x25=0x%x\n",
+ H2C_Parameter[0]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x25, 1, H2C_Parameter);
+}
+
+VOID
+halbtc8723a2ant_IgnoreWlanAct(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bEnable
+ )
+{
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s turn Ignore WlanAct %s\n",
+ (bForceExec? "force to":""), (bEnable? "ON":"OFF")));
+ pCoexDm->bCurIgnoreWlanAct = bEnable;
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPreIgnoreWlanAct = %d, bCurIgnoreWlanAct = %d!!\n",
+ pCoexDm->bPreIgnoreWlanAct, pCoexDm->bCurIgnoreWlanAct));
+
+ if(pCoexDm->bPreIgnoreWlanAct == pCoexDm->bCurIgnoreWlanAct)
+ return;
+ }
+ halbtc8723a2ant_SetFwIgnoreWlanAct(pBtCoexist, bEnable);
+
+ pCoexDm->bPreIgnoreWlanAct = pCoexDm->bCurIgnoreWlanAct;
+}
+
+VOID
+halbtc8723a2ant_SetFwPstdma(
+ IN PBTC_COEXIST pBtCoexist,
+ IN u1Byte byte1,
+ IN u1Byte byte2,
+ IN u1Byte byte3,
+ IN u1Byte byte4,
+ IN u1Byte byte5
+ )
+{
+ u1Byte H2C_Parameter[5] ={0};
+
+ H2C_Parameter[0] = byte1;
+ H2C_Parameter[1] = byte2;
+ H2C_Parameter[2] = byte3;
+ H2C_Parameter[3] = byte4;
+ H2C_Parameter[4] = byte5;
+
+ pCoexDm->psTdmaPara[0] = byte1;
+ pCoexDm->psTdmaPara[1] = byte2;
+ pCoexDm->psTdmaPara[2] = byte3;
+ pCoexDm->psTdmaPara[3] = byte4;
+ pCoexDm->psTdmaPara[4] = byte5;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_EXEC, ("[BTCoex], FW write 0x3a(5bytes)=0x%x%08x\n",
+ H2C_Parameter[0],
+ H2C_Parameter[1]<<24|H2C_Parameter[2]<<16|H2C_Parameter[3]<<8|H2C_Parameter[4]));
+
+ pBtCoexist->btc_fill_h2c(pBtCoexist, 0x3a, 5, H2C_Parameter);
+}
+
+VOID
+halbtc8723a2ant_PsTdma(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bForceExec,
+ IN BOOLEAN bTurnOn,
+ IN u1Byte type
+ )
+{
+ u4Byte btTxRxCnt=0;
+
+ btTxRxCnt = pCoexSta->highPriorityTx+pCoexSta->highPriorityRx+
+ pCoexSta->lowPriorityTx+pCoexSta->lowPriorityRx;
+
+ if(btTxRxCnt > 3000)
+ {
+ pCoexDm->bCurPsTdmaOn = true;
+ pCoexDm->curPsTdma = 8;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], turn ON PS TDMA, type=%d for BT tx/rx counters=%d(>3000)\n",
+ pCoexDm->curPsTdma, btTxRxCnt));
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], %s turn %s PS TDMA, type=%d\n",
+ (bForceExec? "force to":""), (bTurnOn? "ON":"OFF"), type));
+ pCoexDm->bCurPsTdmaOn = bTurnOn;
+ pCoexDm->curPsTdma = type;
+ }
+
+ if(!bForceExec)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], bPrePsTdmaOn = %d, bCurPsTdmaOn = %d!!\n",
+ pCoexDm->bPrePsTdmaOn, pCoexDm->bCurPsTdmaOn));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], prePsTdma = %d, curPsTdma = %d!!\n",
+ pCoexDm->prePsTdma, pCoexDm->curPsTdma));
+
+ if( (pCoexDm->bPrePsTdmaOn == pCoexDm->bCurPsTdmaOn) &&
+ (pCoexDm->prePsTdma == pCoexDm->curPsTdma) )
+ return;
+ }
+ if(pCoexDm->bCurPsTdmaOn)
+ {
+ switch(pCoexDm->curPsTdma)
+ {
+ case 1:
+ default:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x98);
+ break;
+ case 2:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x98);
+ break;
+ case 3:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0xe1, 0x98);
+ break;
+ case 4:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x5, 0x5, 0xe1, 0x80);
+ break;
+ case 5:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x98);
+ break;
+ case 6:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x98);
+ break;
+ case 7:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0x60, 0x98);
+ break;
+ case 8:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x5, 0x5, 0x60, 0x80);
+ break;
+ case 9:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0xe1, 0x98);
+ break;
+ case 10:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0xe1, 0x98);
+ break;
+ case 11:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0xe1, 0x98);
+ break;
+ case 12:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x98);
+ break;
+ case 13:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x1a, 0x1a, 0x60, 0x98);
+ break;
+ case 14:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x12, 0x12, 0x60, 0x98);
+ break;
+ case 15:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0xa, 0xa, 0x60, 0x98);
+ break;
+ case 16:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0x60, 0x98);
+ break;
+ case 17:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xa3, 0x2f, 0x2f, 0x60, 0x80);
+ break;
+ case 18:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x5, 0x5, 0xe1, 0x98);
+ break;
+ case 19:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0xe1, 0x98);
+ break;
+ case 20:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0xe3, 0x25, 0x25, 0x60, 0x98);
+ break;
+ }
+ }
+ else
+ {
+ // disable PS tdma
+ switch(pCoexDm->curPsTdma)
+ {
+ case 0:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x8, 0x0);
+ break;
+ case 1:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x0, 0x0);
+ break;
+ default:
+ halbtc8723a2ant_SetFwPstdma(pBtCoexist, 0x0, 0x0, 0x0, 0x8, 0x0);
+ break;
+ }
+ }
+
+ // update pre state
+ pCoexDm->bPrePsTdmaOn = pCoexDm->bCurPsTdmaOn;
+ pCoexDm->prePsTdma = pCoexDm->curPsTdma;
+}
+
+
+VOID
+halbtc8723a2ant_CoexAllOff(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ // fw all off
+ halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20);
+ halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+
+ // sw all off
+ halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+
+ // hw all off
+ halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+}
+
+VOID
+halbtc8723a2ant_InitCoexDm(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ // force to reset coex mechanism
+ halbtc8723a2ant_CoexTable(pBtCoexist, FORCE_EXEC, 0x55555555, 0xffff, 0x3);
+ halbtc8723a2ant_PsTdma(pBtCoexist, FORCE_EXEC, FALSE, 0);
+ halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, FORCE_EXEC, 0x20);
+ halbtc8723a2ant_DecBtPwr(pBtCoexist, FORCE_EXEC, FALSE);
+ halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE);
+
+ halbtc8723a2ant_AgcTable(pBtCoexist, FORCE_EXEC, FALSE);
+ halbtc8723a2ant_AdcBackOff(pBtCoexist, FORCE_EXEC, FALSE);
+ halbtc8723a2ant_LowPenaltyRa(pBtCoexist, FORCE_EXEC, FALSE);
+ halbtc8723a2ant_RfShrink(pBtCoexist, FORCE_EXEC, FALSE);
+ halbtc8723a2ant_DacSwing(pBtCoexist, FORCE_EXEC, FALSE, 0xc0);
+}
+
+VOID
+halbtc8723a2ant_BtInquiryPage(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BOOLEAN bLowPwrDisable=true;
+
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable);
+
+ halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+ halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 8);
+}
+
+VOID
+halbtc8723a2ant_BtEnableAction(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ BOOLEAN bWifiConnected=FALSE;
+
+ // Here we need to resend some wifi info to BT
+ // because bt is reset and loss of the info.
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+ if(bWifiConnected)
+ {
+ halbtc8723a2ant_IndicateWifiChnlBwInfo(pBtCoexist, BTC_MEDIA_CONNECT);
+ }
+ else
+ {
+ halbtc8723a2ant_IndicateWifiChnlBwInfo(pBtCoexist, BTC_MEDIA_DISCONNECT);
+ }
+
+ halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, FORCE_EXEC, FALSE);
+}
+
+VOID
+halbtc8723a2ant_MonitorBtCtr(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ u4Byte regHPTxRx, regLPTxRx, u4Tmp;
+ u4Byte regHPTx=0, regHPRx=0, regLPTx=0, regLPRx=0;
+ u1Byte u1Tmp;
+
+ regHPTxRx = 0x770;
+ regLPTxRx = 0x774;
+
+ u4Tmp = pBtCoexist->btc_read_4byte(pBtCoexist, regHPTxRx);
+ regHPTx = u4Tmp & MASKLWORD;
+ regHPRx = (u4Tmp & MASKHWORD)>>16;
+
+ u4Tmp = pBtCoexist->btc_read_4byte(pBtCoexist, regLPTxRx);
+ regLPTx = u4Tmp & MASKLWORD;
+ regLPRx = (u4Tmp & MASKHWORD)>>16;
+
+ pCoexSta->highPriorityTx = regHPTx;
+ pCoexSta->highPriorityRx = regHPRx;
+ pCoexSta->lowPriorityTx = regLPTx;
+ pCoexSta->lowPriorityRx = regLPRx;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], High Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
+ regHPTxRx, regHPTx, regHPTx, regHPRx, regHPRx));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], Low Priority Tx/Rx (reg 0x%x)=0x%x(%d)/0x%x(%d)\n",
+ regLPTxRx, regLPTx, regLPTx, regLPRx, regLPRx));
+
+ // reset counter
+ pBtCoexist->btc_write_1byte(pBtCoexist, 0x76e, 0xc);
+}
+
+VOID
+halbtc8723a2ant_MonitorBtEnableDisable(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ static BOOLEAN bPreBtDisabled=FALSE;
+ static u4Byte btDisableCnt=0;
+ BOOLEAN bBtActive=true, bBtDisabled=FALSE;
+
+ // This function check if bt is disabled
+
+ if( pCoexSta->highPriorityTx == 0 &&
+ pCoexSta->highPriorityRx == 0 &&
+ pCoexSta->lowPriorityTx == 0 &&
+ pCoexSta->lowPriorityRx == 0)
+ {
+ bBtActive = FALSE;
+ }
+ if( pCoexSta->highPriorityTx == 0xffff &&
+ pCoexSta->highPriorityRx == 0xffff &&
+ pCoexSta->lowPriorityTx == 0xffff &&
+ pCoexSta->lowPriorityRx == 0xffff)
+ {
+ bBtActive = FALSE;
+ }
+ if(bBtActive)
+ {
+ btDisableCnt = 0;
+ bBtDisabled = FALSE;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is enabled !!\n"));
+ }
+ else
+ {
+ btDisableCnt++;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], bt all counters=0, %d times!!\n",
+ btDisableCnt));
+ if(btDisableCnt >= 2)
+ {
+ bBtDisabled = true;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_BL_BT_DISABLE, &bBtDisabled);
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is disabled !!\n"));
+ }
+ }
+ if(bPreBtDisabled != bBtDisabled)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_BT_MONITOR, ("[BTCoex], BT is from %s to %s!!\n",
+ (bPreBtDisabled ? "disabled":"enabled"),
+ (bBtDisabled ? "disabled":"enabled")));
+ bPreBtDisabled = bBtDisabled;
+ if(!bBtDisabled)
+ {
+ halbtc8723a2ant_BtEnableAction(pBtCoexist);
+ }
+ }
+}
+
+BOOLEAN
+halbtc8723a2ant_IsCommonAction(
+ IN PBTC_COEXIST pBtCoexist
+ )
+{
+ PBTC_STACK_INFO pStackInfo=&pBtCoexist->stack_info;
+ BOOLEAN bCommon=FALSE, bWifiConnected=FALSE;
+ BOOLEAN bLowPwrDisable=FALSE;
+
+ if(!pStackInfo->bBtLinkExist)
+ {
+ bLowPwrDisable = FALSE;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable);
+ }
+ else
+ {
+ bLowPwrDisable = true;
+ pBtCoexist->btc_set(pBtCoexist, BTC_SET_ACT_DISABLE_LOW_POWER, &bLowPwrDisable);
+ }
+
+ pBtCoexist->btc_get(pBtCoexist, BTC_GET_BL_WIFI_CONNECTED, &bWifiConnected);
+
+ if(halbtc8723a2ant_IsWifiIdle(pBtCoexist) &&
+ BT_8723A_2ANT_BT_STATUS_IDLE == pCoexDm->btStatus)
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi idle + Bt idle!!\n"));
+
+ halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20);
+ halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+
+ halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+
+ bCommon = true;
+ }
+ else if(!halbtc8723a2ant_IsWifiIdle(pBtCoexist) &&
+ (BT_8723A_2ANT_BT_STATUS_IDLE == pCoexDm->btStatus) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi non-idle + BT idle!!\n"));
+
+ halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+ halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20);
+ halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, true);
+
+ halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+
+ bCommon = true;
+ }
+ else if(halbtc8723a2ant_IsWifiIdle(pBtCoexist) &&
+ (BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi idle + Bt connected idle!!\n"));
+
+ halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+ halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20);
+ halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+
+ halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+
+ bCommon = true;
+ }
+ else if(!halbtc8723a2ant_IsWifiIdle(pBtCoexist) &&
+ (BT_8723A_2ANT_BT_STATUS_CONNECTED_IDLE == pCoexDm->btStatus) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi non-idle + Bt connected idle!!\n"));
+
+ halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+ halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20);
+ halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+
+ halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+
+ bCommon = true;
+ }
+ else if(halbtc8723a2ant_IsWifiIdle(pBtCoexist) &&
+ (BT_8723A_2ANT_BT_STATUS_NON_IDLE == pCoexDm->btStatus) )
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi idle + BT non-idle!!\n"));
+
+ halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a2ant_CoexTable(pBtCoexist, NORMAL_EXEC, 0x55555555, 0xffff, 0x3);
+
+ halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, FALSE, 0);
+ halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20);
+ halbtc8723a2ant_DecBtPwr(pBtCoexist, NORMAL_EXEC, FALSE);
+
+ halbtc8723a2ant_AgcTable(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_AdcBackOff(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_DacSwing(pBtCoexist, NORMAL_EXEC, FALSE, 0xc0);
+
+ bCommon = true;
+ }
+ else
+ {
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE, ("[BTCoex], Wifi non-idle + BT non-idle!!\n"));
+ halbtc8723a2ant_LowPenaltyRa(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a2ant_RfShrink(pBtCoexist, NORMAL_EXEC, true);
+ halbtc8723a2ant_IgnoreWlanAct(pBtCoexist, NORMAL_EXEC, FALSE);
+ halbtc8723a2ant_FwDacSwingLvl(pBtCoexist, NORMAL_EXEC, 0x20);
+
+ bCommon = FALSE;
+ }
+
+ return bCommon;
+}
+VOID
+halbtc8723a2ant_TdmaDurationAdjust(
+ IN PBTC_COEXIST pBtCoexist,
+ IN BOOLEAN bScoHid,
+ IN BOOLEAN bTxPause,
+ IN u1Byte maxInterval
+ )
+{
+ static s4Byte up,dn,m,n,WaitCount;
+ s4Byte result; //0: no change, +1: increase WiFi duration, -1: decrease WiFi duration
+ u1Byte retryCount=0;
+
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW, ("[BTCoex], TdmaDurationAdjust()\n"));
+
+ if(pCoexDm->bResetTdmaAdjust)
+ {
+ pCoexDm->bResetTdmaAdjust = FALSE;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], first run TdmaDurationAdjust()!!\n"));
+ {
+ if(bScoHid)
+ {
+ if(bTxPause)
+ {
+ if(maxInterval == 1)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 13);
+ pCoexDm->psTdmaDuAdjType = 13;
+ }
+ else if(maxInterval == 2)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 14);
+ pCoexDm->psTdmaDuAdjType = 14;
+ }
+ else if(maxInterval == 3)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+ pCoexDm->psTdmaDuAdjType = 15;
+ }
+ else
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 15);
+ pCoexDm->psTdmaDuAdjType = 15;
+ }
+ }
+ else
+ {
+ if(maxInterval == 1)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 9);
+ pCoexDm->psTdmaDuAdjType = 9;
+ }
+ else if(maxInterval == 2)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 10);
+ pCoexDm->psTdmaDuAdjType = 10;
+ }
+ else if(maxInterval == 3)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+ pCoexDm->psTdmaDuAdjType = 11;
+ }
+ else
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 11);
+ pCoexDm->psTdmaDuAdjType = 11;
+ }
+ }
+ }
+ else
+ {
+ if(bTxPause)
+ {
+ if(maxInterval == 1)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 5);
+ pCoexDm->psTdmaDuAdjType = 5;
+ }
+ else if(maxInterval == 2)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 6);
+ pCoexDm->psTdmaDuAdjType = 6;
+ }
+ else if(maxInterval == 3)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+ pCoexDm->psTdmaDuAdjType = 7;
+ }
+ else
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 7);
+ pCoexDm->psTdmaDuAdjType = 7;
+ }
+ }
+ else
+ {
+ if(maxInterval == 1)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 1);
+ pCoexDm->psTdmaDuAdjType = 1;
+ }
+ else if(maxInterval == 2)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 2);
+ pCoexDm->psTdmaDuAdjType = 2;
+ }
+ else if(maxInterval == 3)
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+ pCoexDm->psTdmaDuAdjType = 3;
+ }
+ else
+ {
+ halbtc8723a2ant_PsTdma(pBtCoexist, NORMAL_EXEC, true, 3);
+ pCoexDm->psTdmaDuAdjType = 3;
+ }
+ }
+ }
+ }
+ //============
+ up = 0;
+ dn = 0;
+ m = 1;
+ n= 3;
+ result = 0;
+ WaitCount = 0;
+ }
+ else
+ {
+ //accquire the BT TRx retry count from BT_Info byte2
+ retryCount = pCoexSta->btRetryCnt;
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCoex], retryCount = %d\n", retryCount));
+ BTC_PRINT(BTC_MSG_ALGORITHM, ALGO_TRACE_FW_DETAIL, ("[BTCo